anothersequencer
Advanced tools
Comparing version 0.0.6 to 0.1.0
{ | ||
"name": "anothersequencer", | ||
"version": "0.0.6", | ||
"version": "0.1.0", | ||
"description": "Simple script tree sequencer in javascript. Allows creating fairly complex trees of sync/async functions or requestAnimationFrame functions with optional delays, as well as subscribing to particular outputs in the tree at any time.", | ||
@@ -21,3 +21,2 @@ "main": "sequencer.js", | ||
"dependencies": { | ||
"anotherstatemanager": "1.0.4" | ||
}, | ||
@@ -24,0 +23,0 @@ "bugs": { |
@@ -10,2 +10,6 @@ ## Javascript function sequencing | ||
import {Sequencer} from 'anothersequencer' | ||
//import {Sequencer} from './Sequencer.js' | ||
//in HTML: <script type='module' src='./Sequencer.js></script> | ||
//or for lazy: | ||
//document.head.insertAdjacentHTML(`<script type='module' src='./Sequencer.js></script>`) | ||
@@ -16,5 +20,5 @@ let sequencer = new Sequencer(); | ||
let sequence1 = [ | ||
first(){console.log('1'); return 2;}, | ||
second(input){console.log(input); return 3;}, //should log "2" | ||
async (input) => {console.log(input)} //yeah whatever | ||
(input){console.log('1'); return 2;}, | ||
(input){console.log(input); return 3;}, //should log "2" | ||
(input) => {console.log(input)} //yeah whatever | ||
]; | ||
@@ -24,13 +28,12 @@ | ||
let sequence2 = [{ | ||
tag:'begin' | ||
tag:'begin', | ||
operation:(input)=>{}, //the callback | ||
next:[{ | ||
delay:100 //milisecond delay before this operation is called | ||
delay:100, //milisecond delay before this operation is called | ||
operation:(input)=>{}, //next callback | ||
next:[ | ||
next:[ //functions on the next layer receive the previous layer's input and not each other's sequential input unlike the simpler sequence | ||
{ | ||
tag:'anotheroperation' //tags let you subscribe to these results | ||
tag:'anotheroperation', //tags let you subscribe to these results | ||
delay:100, | ||
operation:async (input)=>{}, //etc | ||
async:true //can toggle if the operations should run async, or use frame:true to use requestAnimationFrame | ||
}, | ||
@@ -40,3 +43,3 @@ { | ||
frame:true, //uses requestAnimationFrame which is a special async function for frame and context-limited calls | ||
//next:[{...}] | ||
next:'anothersequence' //can set | ||
} | ||
@@ -47,2 +50,18 @@ ] | ||
let sequence3 = { //can use objects for sequences instad of arrays | ||
tag:'a', | ||
operation:(input)=>{}, //the callback | ||
next:{ //objects instead of arrays | ||
tag:'b', | ||
operation:(input)=>{}, | ||
next:[{ | ||
tag:'c', | ||
operation:(input)=>{}, | ||
next:(prev) => {} //could set a function as the final .next operation | ||
} | ||
///,{...} | ||
] | ||
} | ||
} | ||
let onResult = (input) => { | ||
@@ -53,8 +72,11 @@ console.log(input); | ||
sequencer.addSequence('test1',sequence1); | ||
sequencer.addSequence('test2',sequence2); | ||
sequencer.addSequence('test3',sequence3); | ||
sequencer.runSequence('test1'); //can also tell it what layer to run from if there are multiple | ||
let sub = sequencer.subscribeToOperation('anotheroperation',onResult); //adds a triggered function on result | ||
//You could even, say, subscribe one tagged sequence to another tagged sequence. | ||
//sequencer.unsubscribeFromOperation('anotheroperation',sub); //leave sub blank to remove all triggers. You could even, say, subscribe one sequence to another tagged sequence even, I don't know why but sure it's cool. | ||
//sequencer.unsubscribeFromOperation('anotheroperation',sub); //leave sub blank to remove all triggers. | ||
@@ -61,0 +83,0 @@ ``` |
179
Sequencer.js
//Simple script sequencer | ||
// Joshua Brewster AGPL v3.0 | ||
// let sequence = { | ||
// sequencer.sequences = { | ||
// a:[{ | ||
@@ -19,3 +19,3 @@ // operation:(input)=>{}, | ||
// delay:100, | ||
// next:[{...}] | ||
// next:'anothersequence' | ||
// }, | ||
@@ -31,3 +31,2 @@ // (lastResult) => {} //can input plain functions into the next sequence layers if you want just some simple one-off calls | ||
import {StateManager} from 'anotherstatemanager' | ||
@@ -37,14 +36,62 @@ export class Sequencer { | ||
this.sequences = new Map(); | ||
this.state = new StateManager( | ||
undefined, | ||
undefined, | ||
false | ||
); //triggered-only state manager (no overhead) | ||
this.state = { | ||
pushToState:{}, | ||
data:{}, | ||
setState:(updateObj)=>{ | ||
Object.assign(this.pushToState,updateObj); | ||
if(Object.keys(this.triggers).length > 0) { | ||
// Object.assign(this.data,this.pushToState); | ||
for (const prop of Object.getOwnPropertyNames(this.triggers)) { | ||
if(this.pushToState[prop]) { | ||
this.data[prop] = this.pushToState[prop] | ||
delete this.pushToState[prop]; | ||
this.triggers[prop].forEach((obj)=>{ | ||
obj.onchange(this.data[prop]); | ||
}); | ||
} | ||
} | ||
} | ||
return this.pushToState; | ||
}, | ||
subscribeTrigger:(key,onchange=(res)=>{})=>{ | ||
if(key) { | ||
if(!this.triggers[key]) { | ||
this.triggers[key] = []; | ||
} | ||
let l = this.triggers[key].length; | ||
this.triggers[key].push({idx:l, onchange:onchange}); | ||
return this.triggers[key].length-1; | ||
} else return undefined; | ||
}, | ||
unsubscribeTrigger:(key,sub)=>{ | ||
let idx = undefined; | ||
let triggers = this.triggers[key] | ||
if (triggers){ | ||
let obj = triggers.find((o)=>{ | ||
if(o.idx===sub) {return true;} | ||
}); | ||
if(obj) triggers.splice(idx,1); | ||
} | ||
}, | ||
subscribeTriggerOnce(key=undefined,onchange=(value)=>{}) { | ||
let sub; | ||
let changed = (value) => { | ||
onchange(value); | ||
this.unsubscribeTrigger(key,sub); | ||
} | ||
sub = this.subscribeTrigger(key,changed); | ||
} | ||
} | ||
} | ||
addSequence(name,sequence=[]) { | ||
addSequence(name, sequence=[]) { | ||
this.sequences.set(name,sequence); | ||
} | ||
runSequence(name, runFromLayer=1) { | ||
add=this.addSequence | ||
async runSequence(name, input, runFromLayer=1) { | ||
let sequence = this.sequences.get(name); | ||
@@ -58,6 +105,6 @@ if(sequence) { | ||
} | ||
this.runSequenceLayer(nextlayer); | ||
await this.runSequenceLayer(nextlayer, input); | ||
} | ||
else { | ||
this.runSequenceLayer(sequence); | ||
await this.runSequenceLayer(sequence, input); | ||
} | ||
@@ -67,2 +114,4 @@ } | ||
run = this.runSequence; | ||
appendSequence( | ||
@@ -88,2 +137,4 @@ name, //name of sequence | ||
append = this.appendSequence; | ||
removeSequence(name,layer,index) { | ||
@@ -107,2 +158,4 @@ let sequence; | ||
remove = this.removeSequence; | ||
getSequence(name, layer=1) { | ||
@@ -125,60 +178,54 @@ let sequence = this.sequences.get(name); | ||
async runSequenceLayer(layer=[],previousResult) { | ||
layer.forEach((o) => { | ||
if(typeof o === 'function') { | ||
if(o.constructor.name == 'AsyncFunction') previousResult = await o(previousResult); //if the functions are in a basic sequence this passes results along | ||
else previousResult = o(previousResult); //can just shove functions into the sequencer | ||
} | ||
else if(o.delay) { | ||
if(o.async) { //async | ||
setTimeout( | ||
async ()=>{ | ||
get = this.getSequence; | ||
async runSequenceLayer(layer,previousResult) { | ||
if(typeof layer === 'function') { await layer(previousResult); } //can set functionsi in the .next position | ||
else if (typeof layer === 'string') { this.runSequence(layer,previousResult); } //can set sequences in the .next position by name | ||
else if (Array.isArray(layer)) { | ||
for(let i = 0; i < layer.length; i++) { | ||
let o = layer[i]; | ||
if(typeof o === 'function') { | ||
previousResult = await o(previousResult); //if the functions are in a basic sequence this passes results along | ||
} | ||
else if(o.delay) { | ||
if (o.frame && typeof requestAnimationFrame === 'function') { //or frame-timed operations | ||
setTimeout(async ()=> { | ||
requestAnimationFrame(async ()=>{ | ||
let result = await o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
}); | ||
}, o.delay) | ||
} | ||
else { | ||
setTimeout( | ||
async () => { | ||
let result = await o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
}, | ||
o.delay | ||
); | ||
} | ||
} | ||
else { | ||
if (o.frame) { | ||
requestAnimationFrame(async ()=>{ | ||
let result = await o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
}, | ||
o.delay | ||
); | ||
} | ||
else if (o.frame && requestAnimationFrame) { //or frame-timed operations | ||
setTimeout(()=> { | ||
requestAnimationFrame(()=>{ | ||
let result = o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) this.runSequenceLayer(o.next,result); | ||
}); | ||
}, o.delay) | ||
} | ||
else { | ||
setTimeout( | ||
() => { | ||
let result = layer.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) this.runSequenceLayer(o.next,result); | ||
}, | ||
o.delay | ||
); | ||
} | ||
} | ||
else { | ||
if(o.async) { | ||
let result = await o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
} | ||
else if (o.frame) { | ||
requestAnimationFrame(()=>{ | ||
let result = o.operation(previousResult); | ||
} | ||
else { | ||
let result = await o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) this.runSequenceLayer(o.next,result); | ||
}); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
} | ||
} | ||
else { | ||
let result = o.operation(previousResult); | ||
if(o.tag) this.state.setState(o.tag,result); | ||
if(o.next) await this.runSequenceLayer(o.next,result); | ||
} | ||
} | ||
}); | ||
}; | ||
} else if (typeof layer === 'object') { | ||
let result = await layer.operation(previousResult); | ||
if(layer.tag) this.state.setState(layer.tag,result); | ||
if(layer.next) await this.runSequenceLayer(layer.next,result); | ||
} | ||
} | ||
@@ -192,2 +239,4 @@ | ||
subscribe = this.subscribeToOperation; | ||
unsubscribeFromOperation(tag, sub) { | ||
@@ -200,4 +249,6 @@ if(tag) { | ||
unsubscribe = this.unsubscribeFromOperation; | ||
} | ||
export default Sequencer |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
58235
0
6
220
114
- Removedanotherstatemanager@1.0.4
- Removedanotherstatemanager@1.0.4(transitive)
- Removedobjectlisteners@1.0.2(transitive)