Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

# ECMAScript proposal: Path traversal access to object parent properties (implementation). #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.DS_Store
.idea
node_modules
build
113 changes: 103 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,110 @@
# HolyJS Piter 2019 TCXX

It's repository for your TCXX proposals.
# ECMAScript proposal: Path traversal access to object parent properties (implementation).
- [Motivation](#motivation)
- [High-level API](#high-level-api)
- [How it works?](#how-it-works)
- [FAQ](#faq)

## Motivation

HolyJS is one of the biggest conferences about JavaScript in ex-USSR space. Our audience works with JS a lot and can advise some interesting new features which have to be in JavaScript standard. We in HolyJS want to help with it.
All JavaScript's objects can't remember their own parent objects. Here is one solution to this problem.

I was inspired by the [bstuff](https://github.com/bstuff)'s
[idea](https://github.com/HolyJS-TCXX/HolyJS-Piter-2019-TCXX/pull/3) and wrote a small implementation
(specially for [HolyJS Piter 2019](https://holyjs-piter.ru/)).

## High-level API

First you need to create some objects like:
```js
const someObject = {
propA: 'A1',
propB: {
propB1: 'B1',
propB2: 'B2',
}
}

const someSecondObject = someObject.propB
```

And after that you can access any properties of the parent object using the arrays syntax:
```js
console.log(someSecondObject['./']) // = { propB1: 'B1', propB2: 'B2' }
console.log(someSecondObject['../']) // = { propA: 'A1', propB: { propB1: 'B1', propB2: 'B2' } }
console.log(someSecondObject['../propA']) // = 'A1'
console.log(someSecondObject['../propB/propB2']) // = 'B2'
```

## How it works?

### Assembly

Gulp was used as an assembly tool, as it is simple and easy to use.

You can look at the configuration in the `gulpfile.js`.

### Plugin

In order to add objects "memory" about their parent objects, I wrote a plugin that parsed javascript code
and wrapped all objects by some functions. You can see the plugin implementation in the
`src/plugin/objectBindingPlugin.js`.

#### Parsing

For parsing code was selected the package [falafel](https://github.com/substack/node-falafel).

How I parsed code you can see in `src/plugin/parse.js`.

#### Wrapping

Your simple javascript code:
```js
const alex = {
name: 'Alex',
dateOfBirth: {
day: '04',
month: '03',
year: '1996'
},
}

const alexsDateOfBirth = alex.dateOfBirth

console.log(alexsDateOfBirth['../name'])
```

After building your code we will see the following in the bundle file:
```js
const createObject = () => { /* ... */ }
const getFromObject = () => { /* ... */ }

const person = createObject({
name: 'Alex',
dateOfBirth: {
day: '04',
month: '03',
year: '1996'
},
})

const alexsDateOfBirth = alex.dateOfBirth

console.log(getFromObject(alexsDateOfBirth, '../name'))
```

During HolyJS conference we are open for your proposals. On the closing of the conference programs committee of HolyJS would choose the best proposal and help to provide it to TC39 committee.
Function `createObject` returns modified object in which each object remembers its parent
(implementation: `src/plugin/service/createObject.js`).

## Proposal making guide
Function `getFromObject` returns requested property from an object
(implementation: `src/plugin/service/getFromObject.js`).

1. Think what your really need in JavaScript
1. Fill your proposal file based on [proposal template](https://github.com/HolyJS-TCXX/HolyJS-Piter-2019-TCXX/blob/master/proposal-template.md) (you can see [example](https://github.com/HolyJS-TCXX/HolyJS-Piter-2019-TCXX/blob/master/proposal-example.md))
1. Make pull request with your proposal into this repository

## FAQ

1. How can I test this solution? — *Just clone the repository and run the command
`npm i && npm run start`.*
1. Can I test this solution with my initial data? — *Sure. You should go to `src/data`
and either create a new javascript file or modify existing files.*
1. Don't you think that this solution is an anti-pattern? — *Yes, I think so. But when I had free
time, it became very interesting for me to implement something like this.*
1. Will this solution be compatible with other libraries? — *I don't know, this solution is
only to demonstrate the [bstuff](https://github.com/bstuff)'s idea in action :)*
10 changes: 10 additions & 0 deletions gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
const { src, dest } = require('gulp')
const fs = require('fs')
const concat = require('gulp-concat')
const gulpif = require('gulp-if')
const objectBindingPlugin = require('./src/plugin/objectBindingPlugin')

exports.default = () => src(['src/plugin/service/*.js', 'src/data/*.js'])
.pipe(gulpif((file) => !file.path.includes('service'), objectBindingPlugin()))
.pipe(concat('main.js'))
.pipe(dest('build/'))
Loading