Socket
Socket
Sign inDemoInstall

rosmaro-binding-utils

Package Overview
Dependencies
3
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    rosmaro-binding-utils

Makes writing simple rosmaro bindings easier.


Version published
Weekly downloads
4
decreased by-66.67%
Maintainers
1
Created
Weekly downloads
 

Readme

Source

Rosmaro binding utilities

A set of utilities for writing Rosmaro handlers.

Snippet

import {
  typeHandler,
  defaultHandler,
  partialReturns,
  targetedActions,
  callChildren,
  supportEntryActions,
  triggerEntryActions
} from 'rosmaro-binding-utils';

const makeHandler = handlerPlan => supportEntryActions(targetedActions()(partialReturns(typeHandler({defaultHandler})(handlerPlan))));

// ...

const model = triggerEntryActions(rosmaro({graph, bindings}));

callChildren

Allows to call all the children at once.

import {callChildren} from 'rosmaro-binding-utils';
// It's transparent for the context of leaves.
const action = {type: 'DO_YOUR_JOB'};
const context = {a: 1, b: 2};
const children = {};
expect(
  fn({context, action, children})
).toEqual({
  context: {a: 1, b: 2},
  result: undefined,
  arrows: []
});
// It extends the arrow followed by a single child node.

const action = {type: 'DO_YOUR_JOB'};
const context = {a: 1, b: 2};
const children = {
  A: ({action}) => ({
    arrows: [[['main:A', 'x']]],
    result: 'AResult',
    context: {a: 2, b: 4},
  })
};
expect(
  callChildren({context, action, children})
).toEqual({
  context: {a: 2, b: 4},
  result: 'AResult',
  arrows: [
    [['main:A', 'x'], ['main', 'x']],
  ]
});
// Merges composites.
const action = {type: 'DO_YOUR_JOB'};
const context = {a: 1, b: 2};
const children = {
  A: ({action}) => ({
    arrows: [[['main:A', 'x']]],
    result: 'AResult',
    context: {a: 2, b: 2},
  }),
  B: ({action}) => ({
    arrows: [[['main:B', 'y']]],
    result: 'BResult',
    context: {a: 1, b: 4},
  })
};
expect(
  callChildren({context, action, children})
).toEqual({
  context: {a: 2, b: 4},
  result: {A: 'AResult', B: 'BResult'},
  arrows: [
    [['main:A', 'x'], ['main', 'x']],
    [['main:B', 'y'], ['main', 'y']],
  ]
});

defaultHandler

import 'defaultHandler' from 'rosmaro-binding-utils';

If a node has just one child, this handler is simply transparent.

If a node has many children, let's say A and B, then the result looks like this:

{
  data: {A: 'AResult', B: 'BResult'},
  effect: [
    {type: 'A_EFFECT_1'},
    {type: 'A_EFFECT_2'},
    {type: 'B_EFFECT_1'}
  ]
}

triggerEntryActions

Enable entry actions for Rosmaro nodes.

Installation

Import:

import {triggerEntryActions} from 'rosmaro-binding-utils';

Wrap the model with triggerEntryActions:

const myModel = rosmaro({bindings, graph});
const aModelThatTriggersEntryActions = triggerEntryActions(myModel);

Usage

Follow arrows and return effects from the ON_ENTRY handler:

{
  ON_ENTRY: ({context}) => ({
    arrow: 'started',
    effect: {type: 'START_AN_AWESOME_PROJECT'},
  })
}

extendArrows

"Extends" the given arrows in such a away that the parent nodes also follow them.

import {extendArrows} from 'rosmaro-binding-utils';

extendArrows(
  [
    [['a:a:a', 'x']], 
    [['a:a:b', 'y']]
  ]
)
/*
[
  [['a:a:a', 'x'], ['a:a', 'x']], 
  [['a:a:b', 'y'], ['a:a', 'y']]
]
*/
extendArrows(
  [
    [['a:a:a', 'x']], 
    [['a', 'y']]
  ]
)
/*
[
  [['a:a:a', 'x'], ['a:a', 'x']], 
  [['a', 'y']]
]
*/
extendArrows(
  [
    [['a:a:a', 'x']], 
    []
  ]
)
/*
[
  [['a:a:a', 'x'], ['a:a', 'x']], 
  []
]
*/

extractParent

Extracts the parent node.

import {extractParent} from 'rosmaro-binding-utils';
extractParent('a') // null
extractParent('a:b:c') // 'a:b'

initialValueLens

Allows to set an initial value for parts which are undefined.

import {initialValueLens} from 'rosmaro-binding-utils';
// Alters the context if it is undefined.
testLens({
  lens: initialValueLens({a: 123}),
  zoomInInput: undefined, 
  zoomInOutput: {a: 123},
  zoomOutInput: {a: 123},
  zoomOutOutput: {a: 123},
})
// Does not alter empty objects.
testLens({
  lens: initialValueLens({a: 123}),
  zoomInInput: {}, 
  zoomInOutput: {},
  zoomOutInput: {},
  zoomOutOutput: {},
})

mergeArrows

Merges arrows from two sources into one set of arrows.

import {mergeContexts} from 'rosmaro-binding-utils';
mergeArrows([
  [
    [['a:a:a', 'x'], ['a:a', 'x'], ['a', 'x']],
    [['c:a:a', 'x'], ['c:a', 'x'], ['c', 'x']],
  ],
  [
    [['a:a:b', 'x'], ['a:a', 'x'], ['a', 'x']],
  ]
])
/*
[
  [['a:a:a', 'x'], ['a:a', 'x'], ['a', 'x']],
  [['c:a:a', 'x'], ['c:a', 'x'], ['c', 'x']],
  [['a:a:b', 'x'], ['a:a', 'x'], ['a', 'x']],
]
*/

mergeContexts

Applies differences between the initial context and the new contexts to the initial context.

import {mergeContexts} from 'rosmaro-binding-utils';
mergeContexts(
  {a: 123, b: 456},
  [
    {a: 123, b: 456},
    {a: 123, b: 456, c: 789},
    {a: 123, b: 456},
  ]
)
// {a: 123, b: 456, c: 789}
mergeContexts(
  {a: 123, b: 456, c: 789},
  [
    {a: 123, b: 456, c: 789},
    {a: 123, b: 456},
    {a: 123, b: 456, c: 789},
  ]
)
// {a: 123, b: 456}
mergeContexts(
  {a: 123, b: 456, c: 789},
  [
    {a: 123, b: 456, c: 789},
    {a: 123, b: 654, c: 789},
    {a: 123, b: 456, c: 789},
  ]
)
// {a: 123, b: 654, c: 789}

partialReturns

Takes a handler which may return just some of the data and returns a handler that always returns an object like {result: {data, effect}, arrows, context}.

import {partialReturns} from 'rosmaro-binding-utils';
// Allows to return just some result.
partialReturns(
  opts => ({resultOf: opts})
)({context: {a: 123}})
/*
({
  result: {
    data: {resultOf: {context: {a: 123}}},
    effect: undefined,
  },
  arrows: [],
  context: {a: 123}
})
*/
// Allows to return just an arrow.
partialReturns(
  opts => ({arrow: 'x'})
)({context: {a: 123}, node: {id: 'main:a:b'}})
/*
({
  result: {
    data: undefined,
    effect: undefined,
  },
  arrows: [[['main:a:b', 'x']]],
  context: {a: 123}
})
*/
// Allows to return just an effect.
partialReturns(
  opts => ({effect: {type: 'TICK'}})
)({context: {a: 123}})
/*
({
  result: {
    data: undefined,
    effect: {type: 'TICK'},
  },
  arrows: [],
  context: {a: 123}
})
*/
// Allows to return just some data and an effect.
partialReturns(
  opts => ({result: {theResult: opts.context}, effect: {type: 'TICK'}})
)({context: {a: 123}})
/*
({
  result: {
    data: {theResult: {a: 123}},
    effect: {type: 'TICK'},
  },
  arrows: [],
  context: {a: 123}
})
*/
// Allows to return an arrow, an effect, a context and some data
partialReturns(
  opts => ({
    arrow: 'x', 
    result: {theResult: opts.context}, 
    context: {a: 567}, 
    effect: {type: 'TICK'}
  })
)({context: {a: 123}, node: {id: 'main:a:b'}})
/*
({
  result: {
    data: {theResult: {a: 123}},
    effect: {type: 'TICK'},
  },
  arrows: [[['main:a:b', 'x']]],
  context: {a: 567}
})
*/
// Does not touch a result meeting the format requirements.
partialReturns(
  opts => ({
    arrows: [[['main:a:b', 'x']]], 
    result: {data: {theResult: opts.context}, effect: {type: 'TICK'}}, 
    context: {a: 567}, 
  })
)({context: {a: 123}})
/*
({
  arrows: [[['main:a:b', 'x']]], 
  result: {data: {theResult: {a: 123}}, effect: {type: 'TICK'}}, 
  context: {a: 567}, 
})
*/

sliceLens

Used to slice the context.

import {sliceLens} from 'rosmaro-binding-utils';
// Allows to work with just part of an object.
testLens({
  lens: sliceLens('b'),
  zoomInInput: {a: 123, b: {c: 456}}, 
  zoomInOutput: {c: 456},
  zoomOutInput: {c: 987},
  zoomOutOutput: {a: 123, b: {c: 987}}, 
})
// Returns undefined if the desired property does not exist.
testLens({
  lens: sliceLens('b'),
  zoomInInput: {a: 123}, 
  zoomInOutput: undefined,
  zoomOutInput: {c: 987},
  zoomOutOutput: {a: 123, b: {c: 987}}, 
})

targetedActions

Allows to dispatch an action targeted at a particular node.

The targetedActions function is used to modify a handler in two ways.

First, it makes it ignore an action if it has a target property that doesn't start with the node.id value passed to the handler. In other words, an action with target: 'main:a:b' is consumed by main, main:a and main:a:b handlers, but not by the main:a:c handler.

To make building targeted actions easier, every handler is injected a toNode function. It takes an action and returns a new one which is targeted at the handler's node.

import {targetedActions} from 'rosmaro-binding-utils';

const baseHandler = ({toNode}) => ({
  //...
  result: {
    'action targeted at this node': toNode({type: 'SOME_TARGETED_ACTION'})
  }
});

const handler = targetedActions()(baseHandler);

transparentLens

Does nothing to the context

import {transparentLens} from 'rosmaro-binding-utils';

testLens({
  lens: transparentLens,
  zoomInInput: {a: 123, b: {c: 987}}, 
  zoomInOutput: {a: 123, b: {c: 987}},
  zoomOutInput: {a: 123, b: {c: 987}},
  zoomOutOutput: {a: 123, b: {c: 987}},
})

typeHandler

Associated handlers with action types.

import {typeHandler} from 'rosmaro-binding-utils';

// The handler which is going to be used when the
// given action is neither FIRST_ACTION nor SECOND_ACTION.
const defaultHandler = (opts) => ({UNSUPPORTED_ACTION: opts});

// Handles actions of 'FIRST_ACTION' type.
const firstActionHandler = (opts) => ({FIRST_ACTION: opts});

// Handles actions of 'SECOND_ACTION' type.
const secondActionHandler = (opts) => ({SECOND_ACTION: opts});

// The whole handler.
const handler = typeHandler({defaultHandler})({
  // Actions of 'FIRST_ACTION' type are dispatched to this handler.
  FIRST_ACTION: firstActionHandler,
  // Actions of 'SECOND_ACTION' type are dispatched to this handler.
  SECOND_ACTION: secondActionHandler,
});

handler({action: {type: 'FIRST_ACTION'}, something: 'else'})
// {FIRST_ACTION: {action: {type: 'FIRST_ACTION'}, something: 'else'}}

handler({action: {type: 'SECOND_ACTION'}, something: 'else'})
// {SECOND_ACTION: {action: {type: 'SECOND_ACTION'}, something: 'else'}}

handler({action: {type: 'THIRD_ACTION'}, something: 'else'})
// {UNSUPPORTED_ACTION: {action: {type: 'THIRD_ACTION'}, something: 'else'}}

Keywords

FAQs

Last updated on 10 Mar 2019

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc