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

Replace url-scheme-compiler with a cerebral-scheme-parser #4

Open
christianalfoni opened this issue Aug 10, 2016 · 2 comments
Open

Comments

@christianalfoni
Copy link
Contributor

Hello! :)

A lot has happened since the initial implementation of cerebral-addons and where we are today with our official operators. Who would know how productive a simple state:foo.bar could be. So I have been thinking a bit. How we can expose a simple API to build whatever schemes we want. There will of course still be official Cerebral operators, but it would be good to give developers the ability to create their own.

Basically we give:

import {parseScheme} from 'cerebral'

This function lets you pass in any string and it will parse the following for you, if matches scheme of target:value:

  1. target. The target is whatever is in front of the colon. Example: state:foo. The target is state. But it can be anything: state[myModule]:foo, where state[myModule] will be the target
  2. value. The value will be whatever is after the colon. Example: state:foo. The value is foo
  3. schemes. An array of schemes found in the value. Example: state:users.{{input:id}}. The schemes will be: [{target: 'input', value: 'id'}]

The parsed result will also give you a getValue(scheme =>) method. The callback allows you to return a replacement for the scheme in the value. There is also a getValuePromise(scheme =>) which does the same, only returning a promise. Lets look at an example.

Reimplement the SET operator

import {parseScheme} from 'cerebral'

function set(path, value) {
  const scheme = parseScheme(path);

  // scheme returns null if not a scheme
  if (!scheme || scheme.target !== 'state') {
    throw new Error('The set operator only supports setting to state target')
  }

  function action({input, state}) {
    const parsedPath = scheme.getValue(scheme => {
      if (!scheme || (scheme.target !== 'state' && scheme.target !== 'input')) {
        throw new Error('The set operator only supports state and input as target in inline schemes')
      }
      return (
        scheme.target === 'state' ?
          state.get(scheme.value)
        :
          input[scheme.value]
      )
    })

    state.set(parsedPath, value)
  }
  action.displayName = 'operator SET'

  return action
}

This implementation lets you do:

set('state:foo.{{input:bar}}', 'woop')
set('state:{{state:currentPath}}.{{input:bar}}', 'woop')

The point is that with this API it becomes very easy to reimplement all the operators and we allow you to develop your own custom scheme based action factories, whatever you come up with :)

Maybe you want to create your own set of operators that allows you to also access module and modules on the context, using cerebral-provider-modules. The HTTP service can very easily now create:

http('get:/items/{{input:id}}')
// or
http('patch:/items/{{state:currentItemId}}', 'state:currentItem')
// or
http('get:/items', {
  page: 'state:currentPage'
})

So basically instead of having a preset behaviour of compiling these strings we rather just parse it and give you the details to do whatever you want.

@bfitch
Copy link

bfitch commented Aug 10, 2016

As you can imagine, I think this is a GREAT idea! 😀 Giving factories full access to context will really open up a lot of very elegant, concise API's-- like the http example you gave. Very exciting that we can make these patterns first class citizens....it really is a unique to Cerebral.

@fricke
Copy link

fricke commented Aug 10, 2016

Nice! This will truly allow a lot of flexibility to use the operators however you'd like to use them in your application. And I agree, something very unique to cerebral!

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

No branches or pull requests

3 participants