@cycle-robot-drivers/action
Advanced tools
Comparing version 1.0.1 to 1.0.2
@@ -1,4 +0,4 @@ | ||
import { Stream } from 'xstream'; | ||
import { Reducer } from '@cycle/state'; | ||
import { GoalID } from './types'; | ||
import { Stream } from "xstream"; | ||
import { Reducer } from "@cycle/state"; | ||
import { GoalID } from "./types"; | ||
export declare enum S { | ||
@@ -5,0 +5,0 @@ PEND = "PEND", |
@@ -37,13 +37,13 @@ "use strict"; | ||
var results$ = xstream_1.default.combine.apply(null, results); | ||
return xstream_1.default.merge(goal$.filter(function (g) { return typeof g !== 'undefined' && g !== null; }).map(function (g) { | ||
return ({ type: SIGType.GOAL, value: utils_1.initGoal(g) }); | ||
}), cancel$.map(function (val) { return ({ type: SIGType.CANCEL, value: val }); }), results$.map(function (r) { return ({ type: SIGType.RESULTS, value: r }); })); | ||
return xstream_1.default.merge(goal$ | ||
.filter(function (g) { return typeof g !== "undefined" && g !== null; }) | ||
.map(function (g) { return ({ type: SIGType.GOAL, value: utils_1.initGoal(g) }); }), cancel$.map(function (val) { return ({ type: SIGType.CANCEL, value: val }); }), results$.map(function (r) { return ({ type: SIGType.RESULTS, value: r }); })); | ||
}; | ||
var reducer = function (input$) { | ||
var initReducer$ = xstream_1.default.of(function (prev) { | ||
if (typeof prev === 'undefined') { | ||
if (typeof prev === "undefined") { | ||
return { | ||
state: S.PEND, | ||
variables: null, | ||
outputs: null, | ||
outputs: null | ||
}; | ||
@@ -56,9 +56,10 @@ } | ||
var transitionReducer$ = input$.map(function (input) { return function (prev) { | ||
console.debug('input', input, 'prev', prev); | ||
if (prev.state === S.PEND && input.type === SIGType.GOAL) { | ||
var outputs = Object.keys(input.value.goal).reduce(function (acc, x) { | ||
acc[x] = { goal: { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} }; | ||
} | ||
}; | ||
return acc; | ||
@@ -70,5 +71,5 @@ }, {}); | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
outputs: outputs, | ||
outputs: outputs | ||
}; | ||
@@ -78,6 +79,8 @@ } | ||
var outputs = Object.keys(input.value.goal).reduce(function (acc, x) { | ||
acc[x] = { goal: { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} }; | ||
} | ||
}; | ||
return acc; | ||
@@ -89,3 +92,3 @@ }, {}); | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
@@ -95,6 +98,6 @@ outputs: __assign({}, outputs, { result: { | ||
goal_id: prev.variables.goal_id, | ||
status: types_1.Status.PREEMPTED, | ||
status: types_1.Status.PREEMPTED | ||
}, | ||
result: null, | ||
} }), | ||
result: null | ||
} }) | ||
}; | ||
@@ -113,6 +116,6 @@ } | ||
goal_id: prev.variables.goal_id, | ||
status: types_1.Status.PREEMPTED, | ||
status: types_1.Status.PREEMPTED | ||
}, | ||
result: null, | ||
} }), | ||
result: null | ||
} }) | ||
}; | ||
@@ -122,7 +125,7 @@ } | ||
var results = input.value; | ||
if (!isRace | ||
&& results | ||
.every(function (r) { return utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id); }) | ||
&& results | ||
.every(function (r) { return r.status.status === types_1.Status.SUCCEEDED; })) { | ||
if (!isRace && | ||
results.every(function (r) { | ||
return utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id); | ||
}) && | ||
results.every(function (r) { return r.status.status === types_1.Status.SUCCEEDED; })) { | ||
return __assign({}, prev, { state: S.PEND, variables: null, outputs: { | ||
@@ -132,14 +135,17 @@ result: { | ||
goal_id: prev.variables.goal_id, | ||
status: types_1.Status.SUCCEEDED, | ||
status: types_1.Status.SUCCEEDED | ||
}, | ||
result: input.value, | ||
}, | ||
result: input.value | ||
} | ||
} }); | ||
} | ||
else if (!!isRace | ||
&& results | ||
.some(function (r) { return (utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === types_1.Status.SUCCEEDED); })) { | ||
var result = results.filter(function (r) { return (utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === types_1.Status.SUCCEEDED); })[0]; // break the tie here | ||
else if (!!isRace && | ||
results.some(function (r) { | ||
return utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === types_1.Status.SUCCEEDED; | ||
})) { | ||
var result = results.filter(function (r) { | ||
return utils_1.isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === types_1.Status.SUCCEEDED; | ||
})[0]; // break the tie here | ||
return { | ||
@@ -152,7 +158,7 @@ state: S.PEND, | ||
goal_id: prev.variables.goal_id, | ||
status: types_1.Status.SUCCEEDED, | ||
status: types_1.Status.SUCCEEDED | ||
}, | ||
result: result.result, | ||
}, | ||
}, | ||
result: result.result // IDEA: {type: 'FaceExpression', value: result.result} | ||
} | ||
} | ||
}; | ||
@@ -166,4 +172,3 @@ } | ||
}); | ||
return __assign({}, prev, { variables: __assign({}, prev.variables, { activeActionNames: prev.variables.activeActionNames | ||
.filter(function (n) { return finishedActionNames_1.indexOf(n) === -1; }) }), outputs: null }); | ||
return __assign({}, prev, { variables: __assign({}, prev.variables, { activeActionNames: prev.variables.activeActionNames.filter(function (n) { return finishedActionNames_1.indexOf(n) === -1; }) }), outputs: null }); | ||
} | ||
@@ -176,19 +181,13 @@ } | ||
var output = function (reducerState$) { | ||
var outputs$ = reducerState$ | ||
.filter(function (m) { return !!m.outputs; }) | ||
.map(function (m) { return m.outputs; }); | ||
var outputs$ = reducerState$.filter(function (m) { return !!m.outputs; }).map(function (m) { return m.outputs; }); | ||
return actionNames.reduce(function (acc, x) { | ||
acc[x] = { | ||
goal: outputs$ | ||
.filter(function (o) { return !!o[x] && !!o[x].goal; }) | ||
.map(function (o) { return o[x].goal; }), | ||
goal: outputs$.filter(function (o) { return !!o[x] && !!o[x].goal; }).map(function (o) { return o[x].goal; }), | ||
cancel: outputs$ | ||
.filter(function (o) { return !!o[x] && !!o[x].cancel; }) | ||
.map(function (o) { return o[x].cancel; }), | ||
.map(function (o) { return o[x].cancel; }) | ||
}; | ||
return acc; | ||
}, { | ||
result: outputs$ | ||
.filter(function (o) { return !!o.result; }) | ||
.map(function (o) { return o.result; }) | ||
result: outputs$.filter(function (o) { return !!o.result; }).map(function (o) { return o.result; }) | ||
}); | ||
@@ -201,8 +200,9 @@ }; | ||
goal_id: utils_1.generateGoalID(), | ||
status: types_1.Status.SUCCEEDED, | ||
status: types_1.Status.SUCCEEDED | ||
}, | ||
result: null, | ||
result: null | ||
}); }; | ||
var results = actionNames | ||
.map(function (x) { return sources[x].result.startWith(createDummyResult()); }); | ||
var results = actionNames.map(function (x) { | ||
return sources[x].result.startWith(createDummyResult()); | ||
}); | ||
var input$ = input(sources.goal, sources.cancel, results); | ||
@@ -209,0 +209,0 @@ var reducer$ = reducer(input$); |
@@ -1,3 +0,3 @@ | ||
export { GoalID, Goal, Status, GoalStatus, Result, ActionSources, ActionSinks, EventSource, } from './types'; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult, } from './utils'; | ||
export { createConcurrentAction, } from './createConcurrentAction'; | ||
export { GoalID, Goal, Status, GoalStatus, Result, ActionSources, ActionSinks, EventSource } from "./types"; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult } from "./utils"; | ||
export { createConcurrentAction } from "./createConcurrentAction"; |
@@ -1,3 +0,3 @@ | ||
import Stream from 'xstream'; | ||
import { StateSource } from '@cycle/state'; | ||
import Stream from "xstream"; | ||
import { StateSource } from "@cycle/state"; | ||
export declare type GoalID = { | ||
@@ -4,0 +4,0 @@ stamp: Date | number | string; |
@@ -1,2 +0,2 @@ | ||
import { GoalID, Goal, GoalStatus, Result } from './types'; | ||
import { GoalID, Goal, GoalStatus, Result } from "./types"; | ||
export declare function generateGoalID({ stamp, id }?: { | ||
@@ -3,0 +3,0 @@ stamp?: any; |
@@ -12,5 +12,8 @@ "use strict"; | ||
return { | ||
stamp: typeof stamp === 'undefined' ? now : stamp, | ||
id: typeof id === 'undefined' | ||
? Math.random().toString(36).substring(2) + "-" + now.getTime() : id, | ||
stamp: typeof stamp === "undefined" ? now : stamp, | ||
id: typeof id === "undefined" | ||
? Math.random() | ||
.toString(36) | ||
.substring(2) + "-" + now.getTime() | ||
: id | ||
}; | ||
@@ -24,4 +27,3 @@ } | ||
goal_id: generateGoalID(), | ||
status: typeof options.status !== 'undefined' | ||
? options.status : types_1.Status.SUCCEEDED, | ||
status: typeof options.status !== "undefined" ? options.status : types_1.Status.SUCCEEDED | ||
}; | ||
@@ -35,3 +37,3 @@ } | ||
status: generateGoalStatus(options.status), | ||
result: typeof options.result !== 'undefined' ? options.result : null, | ||
result: typeof options.result !== "undefined" ? options.result : null | ||
}; | ||
@@ -42,8 +44,10 @@ } | ||
if (isGoal === void 0) { isGoal = function (g) { | ||
return typeof g === 'object' && g !== null && !!g.goal_id; | ||
return typeof g === "object" && g !== null && !!g.goal_id; | ||
}; } | ||
return isGoal(goal) ? goal : { | ||
goal_id: generateGoalID(), | ||
goal: goal, | ||
}; | ||
return isGoal(goal) | ||
? goal | ||
: { | ||
goal_id: generateGoalID(), | ||
goal: goal | ||
}; | ||
} | ||
@@ -55,3 +59,3 @@ exports.initGoal = initGoal; | ||
} | ||
return (first.stamp === second.stamp && first.id === second.id); | ||
return first.stamp === second.stamp && first.id === second.id; | ||
} | ||
@@ -70,4 +74,4 @@ exports.isEqualGoalID = isEqualGoalID; | ||
function isEqualGoalStatus(first, second) { | ||
return (isEqualGoalID(first.goal_id, second.goal_id) | ||
&& first.status === second.status); | ||
return (isEqualGoalID(first.goal_id, second.goal_id) && | ||
first.status === second.status); | ||
} | ||
@@ -84,11 +88,15 @@ exports.isEqualGoalStatus = isEqualGoalStatus; | ||
function selectActionResult(actionName) { | ||
return function (in$) { return in$ | ||
.filter(function (s) { return !!s | ||
&& !!s[actionName] | ||
&& !!s[actionName].outputs | ||
&& !!s[actionName].outputs.result; }) | ||
.map(function (s) { return s[actionName].outputs.result; }) | ||
.compose(dropRepeats_1.default(isEqualResult)); }; | ||
return function (in$) { | ||
return in$ | ||
.filter(function (s) { | ||
return !!s && | ||
!!s[actionName] && | ||
!!s[actionName].outputs && | ||
!!s[actionName].outputs.result; | ||
}) | ||
.map(function (s) { return s[actionName].outputs.result; }) | ||
.compose(dropRepeats_1.default(isEqualResult)); | ||
}; | ||
} | ||
exports.selectActionResult = selectActionResult; | ||
//# sourceMappingURL=utils.js.map |
@@ -1,4 +0,4 @@ | ||
import { Stream } from 'xstream'; | ||
import { Reducer } from '@cycle/state'; | ||
import { GoalID } from './types'; | ||
import { Stream } from "xstream"; | ||
import { Reducer } from "@cycle/state"; | ||
import { GoalID } from "./types"; | ||
export declare enum S { | ||
@@ -5,0 +5,0 @@ PEND = "PEND", |
@@ -12,5 +12,5 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
import xs from 'xstream'; | ||
import { Status } from './types'; | ||
import { initGoal, isEqualGoalID, generateGoalID } from './utils'; | ||
import xs from "xstream"; | ||
import { Status } from "./types"; | ||
import { initGoal, isEqualGoalID, generateGoalID } from "./utils"; | ||
// FSM types | ||
@@ -33,13 +33,13 @@ export var S; | ||
var results$ = xs.combine.apply(null, results); | ||
return xs.merge(goal$.filter(function (g) { return typeof g !== 'undefined' && g !== null; }).map(function (g) { | ||
return ({ type: SIGType.GOAL, value: initGoal(g) }); | ||
}), cancel$.map(function (val) { return ({ type: SIGType.CANCEL, value: val }); }), results$.map(function (r) { return ({ type: SIGType.RESULTS, value: r }); })); | ||
return xs.merge(goal$ | ||
.filter(function (g) { return typeof g !== "undefined" && g !== null; }) | ||
.map(function (g) { return ({ type: SIGType.GOAL, value: initGoal(g) }); }), cancel$.map(function (val) { return ({ type: SIGType.CANCEL, value: val }); }), results$.map(function (r) { return ({ type: SIGType.RESULTS, value: r }); })); | ||
}; | ||
var reducer = function (input$) { | ||
var initReducer$ = xs.of(function (prev) { | ||
if (typeof prev === 'undefined') { | ||
if (typeof prev === "undefined") { | ||
return { | ||
state: S.PEND, | ||
variables: null, | ||
outputs: null, | ||
outputs: null | ||
}; | ||
@@ -52,9 +52,10 @@ } | ||
var transitionReducer$ = input$.map(function (input) { return function (prev) { | ||
console.debug('input', input, 'prev', prev); | ||
if (prev.state === S.PEND && input.type === SIGType.GOAL) { | ||
var outputs = Object.keys(input.value.goal).reduce(function (acc, x) { | ||
acc[x] = { goal: { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} }; | ||
} | ||
}; | ||
return acc; | ||
@@ -66,5 +67,5 @@ }, {}); | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
outputs: outputs, | ||
outputs: outputs | ||
}; | ||
@@ -74,6 +75,8 @@ } | ||
var outputs = Object.keys(input.value.goal).reduce(function (acc, x) { | ||
acc[x] = { goal: { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} }; | ||
} | ||
}; | ||
return acc; | ||
@@ -85,3 +88,3 @@ }, {}); | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
@@ -91,6 +94,6 @@ outputs: __assign({}, outputs, { result: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.PREEMPTED, | ||
status: Status.PREEMPTED | ||
}, | ||
result: null, | ||
} }), | ||
result: null | ||
} }) | ||
}; | ||
@@ -109,6 +112,6 @@ } | ||
goal_id: prev.variables.goal_id, | ||
status: Status.PREEMPTED, | ||
status: Status.PREEMPTED | ||
}, | ||
result: null, | ||
} }), | ||
result: null | ||
} }) | ||
}; | ||
@@ -118,7 +121,7 @@ } | ||
var results = input.value; | ||
if (!isRace | ||
&& results | ||
.every(function (r) { return isEqualGoalID(r.status.goal_id, prev.variables.goal_id); }) | ||
&& results | ||
.every(function (r) { return r.status.status === Status.SUCCEEDED; })) { | ||
if (!isRace && | ||
results.every(function (r) { | ||
return isEqualGoalID(r.status.goal_id, prev.variables.goal_id); | ||
}) && | ||
results.every(function (r) { return r.status.status === Status.SUCCEEDED; })) { | ||
return __assign({}, prev, { state: S.PEND, variables: null, outputs: { | ||
@@ -128,14 +131,17 @@ result: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: input.value, | ||
}, | ||
result: input.value | ||
} | ||
} }); | ||
} | ||
else if (!!isRace | ||
&& results | ||
.some(function (r) { return (isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === Status.SUCCEEDED); })) { | ||
var result = results.filter(function (r) { return (isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === Status.SUCCEEDED); })[0]; // break the tie here | ||
else if (!!isRace && | ||
results.some(function (r) { | ||
return isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === Status.SUCCEEDED; | ||
})) { | ||
var result = results.filter(function (r) { | ||
return isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === Status.SUCCEEDED; | ||
})[0]; // break the tie here | ||
return { | ||
@@ -148,7 +154,7 @@ state: S.PEND, | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: result.result, | ||
}, | ||
}, | ||
result: result.result // IDEA: {type: 'FaceExpression', value: result.result} | ||
} | ||
} | ||
}; | ||
@@ -162,4 +168,3 @@ } | ||
}); | ||
return __assign({}, prev, { variables: __assign({}, prev.variables, { activeActionNames: prev.variables.activeActionNames | ||
.filter(function (n) { return finishedActionNames_1.indexOf(n) === -1; }) }), outputs: null }); | ||
return __assign({}, prev, { variables: __assign({}, prev.variables, { activeActionNames: prev.variables.activeActionNames.filter(function (n) { return finishedActionNames_1.indexOf(n) === -1; }) }), outputs: null }); | ||
} | ||
@@ -172,19 +177,13 @@ } | ||
var output = function (reducerState$) { | ||
var outputs$ = reducerState$ | ||
.filter(function (m) { return !!m.outputs; }) | ||
.map(function (m) { return m.outputs; }); | ||
var outputs$ = reducerState$.filter(function (m) { return !!m.outputs; }).map(function (m) { return m.outputs; }); | ||
return actionNames.reduce(function (acc, x) { | ||
acc[x] = { | ||
goal: outputs$ | ||
.filter(function (o) { return !!o[x] && !!o[x].goal; }) | ||
.map(function (o) { return o[x].goal; }), | ||
goal: outputs$.filter(function (o) { return !!o[x] && !!o[x].goal; }).map(function (o) { return o[x].goal; }), | ||
cancel: outputs$ | ||
.filter(function (o) { return !!o[x] && !!o[x].cancel; }) | ||
.map(function (o) { return o[x].cancel; }), | ||
.map(function (o) { return o[x].cancel; }) | ||
}; | ||
return acc; | ||
}, { | ||
result: outputs$ | ||
.filter(function (o) { return !!o.result; }) | ||
.map(function (o) { return o.result; }) | ||
result: outputs$.filter(function (o) { return !!o.result; }).map(function (o) { return o.result; }) | ||
}); | ||
@@ -197,8 +196,9 @@ }; | ||
goal_id: generateGoalID(), | ||
status: Status.SUCCEEDED, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: null, | ||
result: null | ||
}); }; | ||
var results = actionNames | ||
.map(function (x) { return sources[x].result.startWith(createDummyResult()); }); | ||
var results = actionNames.map(function (x) { | ||
return sources[x].result.startWith(createDummyResult()); | ||
}); | ||
var input$ = input(sources.goal, sources.cancel, results); | ||
@@ -205,0 +205,0 @@ var reducer$ = reducer(input$); |
@@ -1,3 +0,3 @@ | ||
export { GoalID, Goal, Status, GoalStatus, Result, ActionSources, ActionSinks, EventSource, } from './types'; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult, } from './utils'; | ||
export { createConcurrentAction, } from './createConcurrentAction'; | ||
export { GoalID, Goal, Status, GoalStatus, Result, ActionSources, ActionSinks, EventSource } from "./types"; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult } from "./utils"; | ||
export { createConcurrentAction } from "./createConcurrentAction"; |
@@ -1,4 +0,4 @@ | ||
export { Status, } from './types'; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult, } from './utils'; | ||
export { createConcurrentAction, } from './createConcurrentAction'; | ||
export { Status } from "./types"; | ||
export { generateGoalID, generateGoalStatus, generateResult, initGoal, isEqualGoalID, isEqualGoal, isEqualGoalStatus, isEqualResult, selectActionResult } from "./utils"; | ||
export { createConcurrentAction } from "./createConcurrentAction"; | ||
//# sourceMappingURL=index.js.map |
@@ -1,3 +0,3 @@ | ||
import Stream from 'xstream'; | ||
import { StateSource } from '@cycle/state'; | ||
import Stream from "xstream"; | ||
import { StateSource } from "@cycle/state"; | ||
export declare type GoalID = { | ||
@@ -4,0 +4,0 @@ stamp: Date | number | string; |
@@ -1,2 +0,2 @@ | ||
import { GoalID, Goal, GoalStatus, Result } from './types'; | ||
import { GoalID, Goal, GoalStatus, Result } from "./types"; | ||
export declare function generateGoalID({ stamp, id }?: { | ||
@@ -3,0 +3,0 @@ stamp?: any; |
@@ -1,3 +0,3 @@ | ||
import dropRepeats from 'xstream/extra/dropRepeats'; | ||
import { Status } from './types'; | ||
import dropRepeats from "xstream/extra/dropRepeats"; | ||
import { Status } from "./types"; | ||
export function generateGoalID(_a) { | ||
@@ -7,5 +7,8 @@ var _b = _a === void 0 ? {} : _a, _c = _b.stamp, stamp = _c === void 0 ? undefined : _c, _d = _b.id, id = _d === void 0 ? undefined : _d; | ||
return { | ||
stamp: typeof stamp === 'undefined' ? now : stamp, | ||
id: typeof id === 'undefined' | ||
? Math.random().toString(36).substring(2) + "-" + now.getTime() : id, | ||
stamp: typeof stamp === "undefined" ? now : stamp, | ||
id: typeof id === "undefined" | ||
? Math.random() | ||
.toString(36) | ||
.substring(2) + "-" + now.getTime() | ||
: id | ||
}; | ||
@@ -18,4 +21,3 @@ } | ||
goal_id: generateGoalID(), | ||
status: typeof options.status !== 'undefined' | ||
? options.status : Status.SUCCEEDED, | ||
status: typeof options.status !== "undefined" ? options.status : Status.SUCCEEDED | ||
}; | ||
@@ -28,3 +30,3 @@ } | ||
status: generateGoalStatus(options.status), | ||
result: typeof options.result !== 'undefined' ? options.result : null, | ||
result: typeof options.result !== "undefined" ? options.result : null | ||
}; | ||
@@ -34,8 +36,10 @@ } | ||
if (isGoal === void 0) { isGoal = function (g) { | ||
return typeof g === 'object' && g !== null && !!g.goal_id; | ||
return typeof g === "object" && g !== null && !!g.goal_id; | ||
}; } | ||
return isGoal(goal) ? goal : { | ||
goal_id: generateGoalID(), | ||
goal: goal, | ||
}; | ||
return isGoal(goal) | ||
? goal | ||
: { | ||
goal_id: generateGoalID(), | ||
goal: goal | ||
}; | ||
} | ||
@@ -46,3 +50,3 @@ export function isEqualGoalID(first, second) { | ||
} | ||
return (first.stamp === second.stamp && first.id === second.id); | ||
return first.stamp === second.stamp && first.id === second.id; | ||
} | ||
@@ -59,4 +63,4 @@ export function isEqualGoal(first, second) { | ||
export function isEqualGoalStatus(first, second) { | ||
return (isEqualGoalID(first.goal_id, second.goal_id) | ||
&& first.status === second.status); | ||
return (isEqualGoalID(first.goal_id, second.goal_id) && | ||
first.status === second.status); | ||
} | ||
@@ -71,10 +75,14 @@ export function isEqualResult(first, second) { | ||
export function selectActionResult(actionName) { | ||
return function (in$) { return in$ | ||
.filter(function (s) { return !!s | ||
&& !!s[actionName] | ||
&& !!s[actionName].outputs | ||
&& !!s[actionName].outputs.result; }) | ||
.map(function (s) { return s[actionName].outputs.result; }) | ||
.compose(dropRepeats(isEqualResult)); }; | ||
return function (in$) { | ||
return in$ | ||
.filter(function (s) { | ||
return !!s && | ||
!!s[actionName] && | ||
!!s[actionName].outputs && | ||
!!s[actionName].outputs.result; | ||
}) | ||
.map(function (s) { return s[actionName].outputs.result; }) | ||
.compose(dropRepeats(isEqualResult)); | ||
}; | ||
} | ||
//# sourceMappingURL=utils.js.map |
{ | ||
"name": "@cycle-robot-drivers/action", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "Utilities for cycle-robot-drivers packages", | ||
@@ -5,0 +5,0 @@ "author": "Michael Jae-Yoon Chung", |
@@ -1,36 +0,34 @@ | ||
import xs from 'xstream'; | ||
import {Stream} from 'xstream'; | ||
import {Reducer} from '@cycle/state'; | ||
import {GoalID, Status, Result} from './types'; | ||
import { | ||
initGoal, isEqualGoalID, generateGoalID | ||
} from './utils'; | ||
import xs from "xstream"; | ||
import { Stream } from "xstream"; | ||
import { Reducer } from "@cycle/state"; | ||
import { GoalID, Status, Result } from "./types"; | ||
import { initGoal, isEqualGoalID, generateGoalID } from "./utils"; | ||
// FSM types | ||
export enum S { | ||
PEND = 'PEND', | ||
RUN = 'RUN', | ||
PEND = "PEND", | ||
RUN = "RUN" | ||
} | ||
export enum SIGType { | ||
GOAL = 'GOAL', | ||
CANCEL = 'CANCEL', | ||
RESULTS = 'RESULTS', | ||
GOAL = "GOAL", | ||
CANCEL = "CANCEL", | ||
RESULTS = "RESULTS" | ||
} | ||
export type SIG = { | ||
type: SIGType, | ||
value: any, | ||
} | ||
type: SIGType; | ||
value: any; | ||
}; | ||
// Reducer types | ||
export interface State { | ||
state: S, | ||
state: S; | ||
variables: { | ||
goal_id: GoalID | ||
activeActionNames: string[], | ||
}, | ||
goal_id: GoalID; | ||
activeActionNames: string[]; | ||
}; | ||
outputs: { | ||
[actionNameOrResult: string]: any, | ||
}, | ||
[actionNameOrResult: string]: any; | ||
}; | ||
} | ||
@@ -40,3 +38,3 @@ | ||
actionNames: string[] = [], | ||
isRace: boolean = false, | ||
isRace: boolean = false | ||
) { | ||
@@ -46,21 +44,21 @@ const input = ( | ||
cancel$: Stream<any>, | ||
results: Stream<Result>[], | ||
results: Stream<Result>[] | ||
) => { | ||
const results$: Stream<Result[]> | ||
= xs.combine.apply(null, results); | ||
const results$: Stream<Result[]> = xs.combine.apply(null, results); | ||
return xs.merge( | ||
goal$.filter(g => typeof g !== 'undefined' && g !== null).map(g => | ||
({type: SIGType.GOAL, value: initGoal(g)})), | ||
cancel$.map(val => ({type: SIGType.CANCEL, value: val})), | ||
results$.map(r => ({type: SIGType.RESULTS, value: r})), | ||
goal$ | ||
.filter(g => typeof g !== "undefined" && g !== null) | ||
.map(g => ({ type: SIGType.GOAL, value: initGoal(g) })), | ||
cancel$.map(val => ({ type: SIGType.CANCEL, value: val })), | ||
results$.map(r => ({ type: SIGType.RESULTS, value: r })) | ||
); | ||
} | ||
}; | ||
const reducer = (input$: Stream<SIG>) => { | ||
const initReducer$: Stream<Reducer<State>> = xs.of(function (prev) { | ||
if (typeof prev === 'undefined') { | ||
const initReducer$: Stream<Reducer<State>> = xs.of(function(prev) { | ||
if (typeof prev === "undefined") { | ||
return { | ||
state: S.PEND, | ||
variables: null, | ||
outputs: null, | ||
outputs: null | ||
}; | ||
@@ -72,99 +70,54 @@ } else { | ||
const transitionReducer$: Stream<Reducer<State>> = input$.map(input => (prev: State): State => { | ||
console.debug('input', input, 'prev', prev); | ||
if (prev.state === S.PEND && input.type === SIGType.GOAL) { | ||
const outputs = Object.keys(input.value.goal).reduce((acc, x) => { | ||
acc[x] = {goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
}}; | ||
return acc; | ||
}, {}); | ||
return { | ||
state: S.RUN, | ||
variables: { | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
}, | ||
outputs, | ||
}; | ||
} else if (prev.state === S.RUN && input.type === SIGType.GOAL) { | ||
const outputs = Object.keys(input.value.goal).reduce((acc, x) => { | ||
acc[x] = {goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
}}; | ||
return acc; | ||
}, {}); | ||
return { | ||
state: S.RUN, | ||
variables: { | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs), | ||
}, | ||
outputs: { | ||
...outputs, | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.PREEMPTED, | ||
}, | ||
result: null, | ||
const transitionReducer$: Stream<Reducer<State>> = input$.map( | ||
input => (prev: State): State => { | ||
if (prev.state === S.PEND && input.type === SIGType.GOAL) { | ||
const outputs = Object.keys(input.value.goal).reduce((acc, x) => { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} | ||
}; | ||
return acc; | ||
}, {}); | ||
return { | ||
state: S.RUN, | ||
variables: { | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
}, | ||
}; | ||
} else if (prev.state === S.RUN && input.type === SIGType.CANCEL) { | ||
const outputs = prev.variables.activeActionNames.reduce((acc, x) => { | ||
acc[x] = {cancel: prev.variables.goal_id}; | ||
return acc; | ||
}, {}); | ||
return { | ||
state: S.PEND, | ||
variables: null, | ||
outputs: { | ||
...outputs, | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.PREEMPTED, | ||
}, | ||
result: null, | ||
outputs | ||
}; | ||
} else if (prev.state === S.RUN && input.type === SIGType.GOAL) { | ||
const outputs = Object.keys(input.value.goal).reduce((acc, x) => { | ||
acc[x] = { | ||
goal: { | ||
goal_id: input.value.goal_id, | ||
goal: input.value.goal[x] | ||
} | ||
}; | ||
return acc; | ||
}, {}); | ||
return { | ||
state: S.RUN, | ||
variables: { | ||
goal_id: input.value.goal_id, | ||
activeActionNames: Object.keys(outputs) | ||
}, | ||
}, | ||
}; | ||
} else if (prev.state === S.RUN && input.type === SIGType.RESULTS) { | ||
const results = input.value; | ||
if ( | ||
!isRace | ||
&& results | ||
.every(r => isEqualGoalID(r.status.goal_id, prev.variables.goal_id)) | ||
&& results | ||
.every(r => r.status.status === Status.SUCCEEDED) | ||
) { | ||
return { | ||
...prev, | ||
state: S.PEND, | ||
variables: null, | ||
outputs: { | ||
...outputs, | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED, | ||
status: Status.PREEMPTED | ||
}, | ||
result: input.value, | ||
}, | ||
}, | ||
result: null | ||
} | ||
} | ||
}; | ||
} else if ( | ||
!!isRace | ||
&& results | ||
.some(r => ( | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === Status.SUCCEEDED | ||
)) | ||
) { | ||
const result = results.filter(r => ( | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
&& r.status.status === Status.SUCCEEDED | ||
))[0]; // break the tie here | ||
} else if (prev.state === S.RUN && input.type === SIGType.CANCEL) { | ||
const outputs = prev.variables.activeActionNames.reduce((acc, x) => { | ||
acc[x] = { cancel: prev.variables.goal_id }; | ||
return acc; | ||
}, {}); | ||
return { | ||
@@ -174,55 +127,104 @@ state: S.PEND, | ||
outputs: { | ||
...outputs, | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED, | ||
status: Status.PREEMPTED | ||
}, | ||
result: result.result, // IDEA: {type: 'FaceExpression', value: result.result} | ||
result: null | ||
} | ||
} | ||
}; | ||
} else if (prev.state === S.RUN && input.type === SIGType.RESULTS) { | ||
const results = input.value; | ||
if ( | ||
!isRace && | ||
results.every(r => | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
) && | ||
results.every(r => r.status.status === Status.SUCCEEDED) | ||
) { | ||
return { | ||
...prev, | ||
state: S.PEND, | ||
variables: null, | ||
outputs: { | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: input.value | ||
} | ||
} | ||
}; | ||
} else if ( | ||
!!isRace && | ||
results.some( | ||
r => | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === Status.SUCCEEDED | ||
) | ||
) { | ||
const result = results.filter( | ||
r => | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) && | ||
r.status.status === Status.SUCCEEDED | ||
)[0]; // break the tie here | ||
return { | ||
state: S.PEND, | ||
variables: null, | ||
outputs: { | ||
result: { | ||
status: { | ||
goal_id: prev.variables.goal_id, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: result.result // IDEA: {type: 'FaceExpression', value: result.result} | ||
} | ||
} | ||
}; | ||
} else { | ||
const finishedActionNames = results.map((r, i) => | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
? actionNames[i] | ||
: null | ||
); | ||
return { | ||
...prev, | ||
variables: { | ||
...prev.variables, | ||
activeActionNames: prev.variables.activeActionNames.filter( | ||
n => finishedActionNames.indexOf(n) === -1 | ||
) | ||
}, | ||
}, | ||
}; | ||
} else { | ||
const finishedActionNames = results.map((r, i) => | ||
isEqualGoalID(r.status.goal_id, prev.variables.goal_id) | ||
? actionNames[i] | ||
: null | ||
); | ||
return { | ||
...prev, | ||
variables: { | ||
...prev.variables, | ||
activeActionNames: prev.variables.activeActionNames | ||
.filter(n => finishedActionNames.indexOf(n) === -1) | ||
}, | ||
outputs: null, | ||
}; | ||
outputs: null | ||
}; | ||
} | ||
} | ||
return prev; | ||
} | ||
return prev; | ||
}); | ||
); | ||
return xs.merge(initReducer$, transitionReducer$); | ||
} | ||
}; | ||
const output = (reducerState$: Stream<State>) => { | ||
const outputs$ = reducerState$ | ||
.filter(m => !!m.outputs) | ||
.map(m => m.outputs); | ||
const outputs$ = reducerState$.filter(m => !!m.outputs).map(m => m.outputs); | ||
return actionNames.reduce((acc, x) => { | ||
acc[x] = { | ||
goal: outputs$ | ||
.filter(o => !!o[x] && !!o[x].goal) | ||
.map(o => o[x].goal), | ||
cancel: outputs$ | ||
.filter(o => !!o[x] && !!o[x].cancel) | ||
.map(o => o[x].cancel), | ||
}; | ||
return acc; | ||
}, { | ||
result: outputs$ | ||
.filter(o => !!o.result) | ||
.map(o => o.result) | ||
}); | ||
} | ||
return actionNames.reduce( | ||
(acc, x) => { | ||
acc[x] = { | ||
goal: outputs$.filter(o => !!o[x] && !!o[x].goal).map(o => o[x].goal), | ||
cancel: outputs$ | ||
.filter(o => !!o[x] && !!o[x].cancel) | ||
.map(o => o[x].cancel) | ||
}; | ||
return acc; | ||
}, | ||
{ | ||
result: outputs$.filter(o => !!o.result).map(o => o.result) | ||
} | ||
); | ||
}; | ||
@@ -234,12 +236,13 @@ return function ConcurrentAction(sources) { | ||
goal_id: generateGoalID(), | ||
status: Status.SUCCEEDED, | ||
status: Status.SUCCEEDED | ||
}, | ||
result: null, | ||
result: null | ||
}); | ||
const results = actionNames | ||
.map(x => sources[x].result.startWith(createDummyResult())); | ||
const results = actionNames.map(x => | ||
sources[x].result.startWith(createDummyResult()) | ||
); | ||
const input$ = input(sources.goal, sources.cancel, results); | ||
const reducer$: Stream<Reducer<State>> = reducer(input$); | ||
const outputs = output(reducerState$) | ||
const outputs = output(reducerState$); | ||
return { | ||
@@ -249,3 +252,3 @@ ...outputs, | ||
}; | ||
} | ||
}; | ||
} |
@@ -9,4 +9,4 @@ export { | ||
ActionSinks, | ||
EventSource, | ||
} from './types'; | ||
EventSource | ||
} from "./types"; | ||
@@ -22,7 +22,5 @@ export { | ||
isEqualResult, | ||
selectActionResult, | ||
} from './utils'; | ||
selectActionResult | ||
} from "./utils"; | ||
export { | ||
createConcurrentAction, | ||
} from './createConcurrentAction'; | ||
export { createConcurrentAction } from "./createConcurrentAction"; |
@@ -1,48 +0,46 @@ | ||
import Stream from 'xstream'; | ||
import {StateSource} from '@cycle/state'; | ||
import Stream from "xstream"; | ||
import { StateSource } from "@cycle/state"; | ||
export type GoalID = { | ||
stamp: Date | number | string, | ||
id: string, | ||
stamp: Date | number | string; | ||
id: string; | ||
}; | ||
export type Goal = { | ||
goal_id: GoalID, | ||
goal: any, | ||
goal_id: GoalID; | ||
goal: any; | ||
}; | ||
export enum Status { | ||
ACTIVE = 'ACTIVE', | ||
PREEMPTED = 'PREEMPTED', | ||
SUCCEEDED = 'SUCCEEDED', | ||
ABORTED = 'ABORTED', | ||
ACTIVE = "ACTIVE", | ||
PREEMPTED = "PREEMPTED", | ||
SUCCEEDED = "SUCCEEDED", | ||
ABORTED = "ABORTED" | ||
} | ||
export type GoalStatus = { | ||
goal_id: GoalID, | ||
status: Status, | ||
goal_id: GoalID; | ||
status: Status; | ||
}; | ||
export type Result = { | ||
status: GoalStatus, | ||
result: any, | ||
status: GoalStatus; | ||
result: any; | ||
}; | ||
export interface ActionSources { | ||
state: StateSource<any>, | ||
goal: Stream<Goal>, | ||
cancel?: Stream<GoalID>, | ||
state: StateSource<any>; | ||
goal: Stream<Goal>; | ||
cancel?: Stream<GoalID>; | ||
} | ||
export interface ActionSinks { | ||
state: Stream<any>, | ||
feedback?: Stream<any>, | ||
status: Stream<GoalStatus>, | ||
result: Stream<Result>, | ||
state: Stream<any>; | ||
feedback?: Stream<any>; | ||
status: Stream<GoalStatus>; | ||
result: Stream<Result>; | ||
} | ||
export interface EventSource { | ||
events(eventType: string): any; | ||
} |
@@ -1,10 +0,17 @@ | ||
import dropRepeats from 'xstream/extra/dropRepeats'; | ||
import {GoalID, Goal, Status, GoalStatus, Result} from './types' | ||
import dropRepeats from "xstream/extra/dropRepeats"; | ||
import { GoalID, Goal, Status, GoalStatus, Result } from "./types"; | ||
export function generateGoalID({stamp = undefined, id = undefined} = {}): GoalID { | ||
export function generateGoalID({ | ||
stamp = undefined, | ||
id = undefined | ||
} = {}): GoalID { | ||
const now = new Date(); | ||
return { | ||
stamp: typeof stamp === 'undefined' ? now : stamp, | ||
id: typeof id === 'undefined' | ||
? `${Math.random().toString(36).substring(2)}-${now.getTime()}` : id, | ||
stamp: typeof stamp === "undefined" ? now : stamp, | ||
id: | ||
typeof id === "undefined" | ||
? `${Math.random() | ||
.toString(36) | ||
.substring(2)}-${now.getTime()}` | ||
: id | ||
}; | ||
@@ -17,12 +24,12 @@ } | ||
goal_id: generateGoalID(), | ||
status: typeof options.status !== 'undefined' | ||
? options.status : Status.SUCCEEDED, | ||
status: | ||
typeof options.status !== "undefined" ? options.status : Status.SUCCEEDED | ||
}; | ||
} | ||
export function generateResult(options?): Result{ | ||
export function generateResult(options?): Result { | ||
if (!options) options = {}; | ||
return { | ||
status: generateGoalStatus(options.status), | ||
result: typeof options.result !== 'undefined' ? options.result : null, | ||
result: typeof options.result !== "undefined" ? options.result : null | ||
}; | ||
@@ -34,8 +41,10 @@ } | ||
isGoal: (g: any) => boolean = g => | ||
typeof g === 'object' && g !== null && !!g.goal_id, | ||
typeof g === "object" && g !== null && !!g.goal_id | ||
): Goal { | ||
return isGoal(goal) ? goal : { | ||
goal_id: generateGoalID(), | ||
goal, | ||
}; | ||
return isGoal(goal) | ||
? goal | ||
: { | ||
goal_id: generateGoalID(), | ||
goal | ||
}; | ||
} | ||
@@ -47,3 +56,3 @@ | ||
} | ||
return (first.stamp === second.stamp && first.id === second.id); | ||
return first.stamp === second.stamp && first.id === second.id; | ||
} | ||
@@ -63,4 +72,4 @@ | ||
return ( | ||
isEqualGoalID(first.goal_id, second.goal_id) | ||
&& first.status === second.status | ||
isEqualGoalID(first.goal_id, second.goal_id) && | ||
first.status === second.status | ||
); | ||
@@ -78,9 +87,13 @@ } | ||
export function selectActionResult(actionName) { | ||
return (in$) => in$ | ||
.filter(s => !!s | ||
&& !!s[actionName] | ||
&& !!s[actionName].outputs | ||
&& !!s[actionName].outputs.result) | ||
.map(s => s[actionName].outputs.result) | ||
.compose(dropRepeats(isEqualResult)); | ||
} | ||
return in$ => | ||
in$ | ||
.filter( | ||
s => | ||
!!s && | ||
!!s[actionName] && | ||
!!s[actionName].outputs && | ||
!!s[actionName].outputs.result | ||
) | ||
.map(s => s[actionName].outputs.result) | ||
.compose(dropRepeats(isEqualResult)); | ||
} |
@@ -1,9 +0,9 @@ | ||
import {generateGoalID, isEqualGoalID} from '../src/utils' | ||
import { generateGoalID, isEqualGoalID } from "../src/utils"; | ||
describe('isEqual', () => { | ||
it('returns true for two GoalIDs with the same property values', () => { | ||
describe("isEqual", () => { | ||
it("returns true for two GoalIDs with the same property values", () => { | ||
const goalId1 = generateGoalID(); | ||
const goalId2 = {...goalId1}; | ||
const goalId2 = { ...goalId1 }; | ||
expect(isEqualGoalID(goalId1, goalId2)).toBe(true); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
63321
1171
0