
Security News
PodRocket Podcast: Inside the Recent npm Supply Chain Attacks
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
@opuscapita/fsm-core
Advanced tools
Machine and its definition.
Run npm install @opuscapita/fsm-core
to get up and running.
import { MachineDefinition, Machine } from '@opuscapita/fsm-core';
Machine definition consist of:
const machineDefinition = new MachineDefinition({
schema: {
name: "invoice approval",
initialState: "open",
finalStates: ["approved"],
objectStateFieldName: "status",
transitions: [
{
from: "open",
event: "approve",
guards: [
{
"name": "validate",
"arguments": {
"argument1": "value1",
"argument2": "value2"
}
}
],
to: "approved",
actions: [
{
"name": "archive",
"arguments": {
"argument1": "value1",
"argument2": "value2"
}
}
],
automatic: [
{
"name": "lastlyUpdatedMoreThan24hAgo",
"arguments": {
"argument1": "value1",
"argument2": "value2"
}
}
]
}
]
},
actions: {
archive: function({argument1, argument1}) {}
},
conditions: {
validate: function({argument1, argument1}) {},
lastlyUpdatedMoreThan24hAgo: function({argument1, argument1}) {}
}
});
Defines machine transitions and initialization options. Could be presented as oriented graph, where each node represents state and directed edges are used to represent transition from one state to another.
In schema you needs to define an array of available machine transitions. Typically a transition is triggered by an event and happens between from and to states. Optionally each transition can have actions, guards and/or automatic (conditions).
You can define the initial state by setting the initialState property:
var machineDefinition = new MachineDefinition({
schema: {
initial: 'start'
transitions: [
{from: 'start', event: 'run', to: 'finish'}
]
}
});
const object = {status: 'none'};
const machine = new Machine(machineDefinition);
machine.start(object).then(({object}) => {
console.log(machine.currentState({object}));
// start
});
if initial state is not specified, then 'none' will be used (TBD)
You can define the final states (one or many) by setting the finalStates property:
var machineDefinition = new MachineDefinition({
schema: {
initial: 'start',
finalStates: ['finish'],
transitions: [
{from: 'start', event: 'run', to: 'finish'}
]
}
});
Actions (action = function) are executed during transition (not during existing or entering states). Action references specific function by name. Action implemented separately from schema. Each action accepts named arguments explicitly defined in transition and implicit arguments like object, from, to, etc. During transition machine executes each action in defined order. Each action gets actionExecutionResutls argument which serves as an accumulator from perviously called actions, where each property is an action name and value is value returned by action.
Guards are used to protect transitions. Guard works as 'if' condition. Technically guard is defined the same way like as action, it is a function. The difference is that it should always return boolean value (true or false).
Note: similar to Spring State Machine Guards
Transition could be marked as automatic using corresponding property. It could be:
Machine does not have own state, all the transitions are performed over object which state is changed by machine. Object is used by Machine as a mutable parameter passed to guards and actions.
var machineDefinition = new MachineDefinition({
schema: {
initial: 'start'
finalStates: ['finish'],
transitions: [
{from: 'start', event: 'run', to: 'finish'}
]
}
});
const object = {status: 'none'};
const machine = new Machine(machineDefinition);
machine.start(object).then(({object}) => {
console.log(machine.currentState({object}));
// start
return machine.sendEvent({object, event: 'start'})
}).then(({object}) => {
console.log(machine.currentState({object}));
// finish
});
var machineDefinition = new MachineDefinition({schema, guards, actions})
// register workflow
var machine = new Machine(machineDefinition, context);
// start/initialize machine/workflow
machine.start({object})
// returns a list of available transitions: {event, from, to, request..}, e.g. event
// request is used to pass parameters to guards for some dynamic calculation, e.g. when event availability depends
// on current user information as roles and etc.
machine.availableTransitions({object})
// returns a list of available automatic transitions: {event, from, to, ..}, e.g. event
// if machine schema is adequate then there should be not more than 1 such transition
machine.availableAutomaticTransitions({})
// send 'event' and pass addition 'request' data that is posted by user/app
// returns promise, in case of successful transition then function will be called
// with one parameter that is an JSON with the following structure:
// - object - object in new state (the same reference that is passed as parameter)
machine.sendEvent({object, event, request})
machine.currentState({ object }) // gets current state
machine.is({ object, state}) // is object in state
machine.isInFinalState({ object }) // returns true iff object is in one of final states
machine.can({ object, event }) // whether event is available
machine.cannot({ object, event }) // whether event is not available
// hooks (tbd)
machine.onStartTransition() // returns promise
machine.onFinishTransition() // returns promise
FAQs
FSM workflow (for Node.js)
We found that @opuscapita/fsm-core demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 7 open source maintainers collaborating on the project.
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.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.