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

Upcoming core rework #15

Open
solkimicreb opened this issue Mar 22, 2017 · 3 comments
Open

Upcoming core rework #15

solkimicreb opened this issue Mar 22, 2017 · 3 comments

Comments

@solkimicreb
Copy link
Member

solkimicreb commented Mar 22, 2017

The next release will include several breaking changes to the core. It aims to make the initial learning curve smaller and to simplify and speed up the core. Apart from the features mentioned here, I plan to add the following changes.

The component.useOnContent method will be removed

Instead only component.use will remain and middlewares behavior will be configurable with the middleware.$process array. It may contain code for COMPONENT, ELEMENT, TEXT and COMMENT nodes.

Take a look at the following snippet.

nx.component({root: true})
  .useOnContent(interpolate)
  .use(setup)
  .register('interpolate-comp')

function interpolate (node, state) {
  if (node instanceof Text) {
    node.nodeValue = node.nodeValue.replace(/\${(.+?)}/g, (match, prop) => state[prop])
  }
}

function setup (comp, state) {
  state.message = 'Hello World!'
}

It will turn into the following after the change.

nx.component({root: true})
  .use(interpolate)
  .use(setup)
  .register('interpolate-comp')

function interpolate (text, state) {
  text.nodeValue = text.nodeValue.replace(/\${(.+?)}/g, (match, prop) => state[prop])
}
interpolate.$process = [nx.types.TEXT]

function setup (comp, state) {
  state.message = 'Hello World!'
}

By default a middleware will only process the component node and non of its content. It moves complexity from the user to the contributors and middleware developers.

Middleware inheritance and the isolate config will be removed

Middlewares will no longer be inherited from ancestor components. Instead every component will have full control over what middleware it uses.

Take a look at the following snippet.

nx.components.app()
  .use((comp, state) => state.name = 'Bob')
  .register('app-comp')

nx.component().register('my-comp')
<app-comp>
  <my-comp>${name}</my-comp>
</app-comp>

In the current version this displays ‘Bob’, but in the next version it would display ‘${name}’. The reason is that my-comp wouldn’t inherit the interpolate middleware from app-comp.

Instead of relying on middleware inheritance the next release will introduce the base component which includes all of the important middlewares. It will serve as a base for most of the current components too. The above example could be rewritten as below with the next version.

nx.components.app()
  .use((comp, state) => state.name = 'Bob')
  .register('app-comp')

nx.components.base()
  .register('my-comp')
<app-comp>
  <my-comp>${name}</my-comp>
</app-comp>

This makes components more modular an easier to maintain as they take full responsibility of their behavior.

The this context in middlewares will be changed

Previously the this context inside middlewares was the currently processed node instance - which was also the first argument. This will change. The this context will always be the parent component instance (a web component). This means that for normal component middleares nothing will change. Content middlewares will get a reference to the parent component through the this context though.

To stay consistent, the this context will be set to the current component in every callback (attributes, observed functions, etc) too.

State boundaries will be reworked

State boundaries doesn’t always match with component boundaries in NX. For example the repeat attribute may add inheriting states to non component elements.

Handling state boundaries was a big hack, which was hidden by the attributes and props middleware. The next release will change this. The middleware.$boundary boolean prop will indicate that the middleware is a boundary middleware. NX injects the context/parent state into boundary middlewares on state boundaries instead of the new state. You probably won’t have to use this, but it makes developing complex middlewares easier for maintainers.

Many middlewares will be reworked

Most middlewares will be reworked form content to component middlewares (meaning that they will have middleware.$process=[nx.types.COMPONENT]). If all goes well, after the change only the attribute and interpolate middlewares will process content. Everything else will run only once on the component instance.

This removes a lot of unnecessary work and speeds up NX.

@solkimicreb
Copy link
Member Author

In the long term I hope to make a simple spec for the NX core, which could be implemented by anyone. If a framework or library implements the spec it becomes interoperable with any of the NX middlewares. This is the long term plan and this will be a step forward to achieve this.

@NetOpWibby
Copy link

This all sounds awesome. Simpler and more efficient is always better.

@janat08
Copy link

janat08 commented May 1, 2018

I think it would be best to implement this changes before the features in interest of stability, since the framework is expandable and you can expect other people to implement other features as needed. I hope youre returning to the project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants