Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

action-chain

Package Overview
Dependencies
Maintainers
1
Versions
152
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

action-chain - npm Package Compare versions

Comparing version 1.0.0-alpha1 to 1.0.1

es/types.d.ts

19

es/ActionBase.d.ts

@@ -1,2 +0,3 @@

import { ActionChain, Execution } from './ActionChain';
import { ActionChain } from './ActionChain';
import { ExecutionContext } from './types';
export declare class StopExecution {

@@ -6,9 +7,11 @@ value: any;

}
export interface ActionBase<Context, InitialValue, Value = InitialValue> {
(value: InitialValue): Value;
createOperatorResult(type: string, name: string, cb: any): [ActionChain<Context>, number, any];
export declare class ActionBase<Effects> {
private actionChain;
private initialActionId;
private runOperators?;
static nextActionId: number;
private currentExecutionId;
constructor(actionChain: ActionChain<Effects>, initialActionId?: number, runOperators?: (value: any, executionContext: ExecutionContext, newPath?: string) => any | Promise<any>);
getActionChain<ExtraEvents = {}>(): ActionChain<Effects, ExtraEvents>;
createOperatorResult: (type: string, name: string, cb: any) => [ActionChain<Effects, {}>, number, any];
}
export interface NoValueActionBase<Context, InitialValue, Value = InitialValue> extends ActionBase<Context, InitialValue, Value> {
(): Value;
}
export declare function actionBaseFactory<Context, InitialValue, Value = InitialValue>(actionChain: ActionChain<Context>, initialActionId?: number, runOperators?: (value: any, execution: Execution, path: string[]) => any | Promise<any>): InitialValue extends undefined ? NoValueActionBase<Context, InitialValue, Value> : ActionBase<Context, InitialValue, Value>;
import * as tslib_1 from "tslib";
actionBaseFactory.nextActionId = 0;
var StopExecution = /** @class */ (function () {

@@ -10,75 +9,52 @@ function StopExecution(value) {

export { StopExecution };
export function actionBaseFactory(actionChain, initialActionId, runOperators) {
if (initialActionId === void 0) { initialActionId = actionBaseFactory.nextActionId++; }
var currentExecutionId = 0;
return Object.assign(function (value) {
var initialOperator = typeof arguments[1] === 'undefined';
var execution = initialOperator
? {
operatorId: -1,
actionId: initialActionId,
executionId: currentExecutionId++,
}
: arguments[1];
var path = typeof arguments[2] === 'undefined' ? [] : arguments[2];
if (initialOperator) {
actionChain.emit('action:start', {
actionId: execution.actionId,
executionId: execution.executionId,
});
}
var returnValue = runOperators
? runOperators(value, execution, path)
: value;
if (initialOperator && returnValue instanceof Promise) {
returnValue.then(function () {
actionChain.emit('action:end', {
actionId: execution.actionId,
executionId: execution.executionId,
});
});
}
else if (initialOperator) {
actionChain.emit('action:end', {
actionId: execution.actionId,
executionId: execution.executionId,
});
}
return returnValue;
}, {
createOperatorResult: function (type, name, cb) {
var ActionBase = /** @class */ (function () {
function ActionBase(actionChain, initialActionId, runOperators) {
if (initialActionId === void 0) { initialActionId = ActionBase.nextActionId++; }
var _this = this;
this.actionChain = actionChain;
this.initialActionId = initialActionId;
this.runOperators = runOperators;
this.currentExecutionId = 0;
this.createOperatorResult = function (type, name, cb) {
return [
actionChain,
initialActionId,
function (props, execution, path) {
var prevResult = runOperators
? runOperators(props, execution, path)
_this.actionChain,
_this.initialActionId,
function (props, executionContext, newPath) {
var executionContextWithPath = {
__execution: executionContext.__execution,
__path: newPath
? executionContext.__path.concat(newPath)
: executionContext.__path.slice(),
};
var prevResult = _this.runOperators
? _this.runOperators(props, executionContextWithPath)
: props;
function produceResult(currentValue) {
var produceResult = function (currentValue) {
if (currentValue instanceof StopExecution) {
return currentValue.value;
return currentValue;
}
execution.operatorId++;
var context = actionChain.getContext(execution, path);
actionChain.emit('operator:start', tslib_1.__assign({ type: type,
var thisExecution = tslib_1.__assign({}, executionContextWithPath.__execution, { operatorId: executionContextWithPath.__execution.operatorId + 1 });
executionContextWithPath.__execution.operatorId++;
var path = executionContextWithPath.__path;
var effects = Object.assign({}, _this.actionChain.getEffects(thisExecution), executionContextWithPath);
_this.actionChain.emit('operator:start', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution));
var result = actionChain.getOptions().actionWrapper
? actionChain
.getOptions()
.actionWrapper(currentValue, context, cb)
: cb(currentValue, context);
path: path }, thisExecution));
var result = cb(effects, currentValue);
if (result instanceof Promise) {
_this.actionChain.emit('operator:async', tslib_1.__assign({ type: type,
name: name,
path: path, isAsync: true }, thisExecution));
return result.then(function (promiseResult) {
actionChain.emit('operator:end', tslib_1.__assign({ type: type,
_this.actionChain.emit('operator:end', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution, { isAsync: true, result: promiseResult }));
path: path }, thisExecution, { isAsync: true, result: promiseResult }));
return promiseResult;
});
}
actionChain.emit('operator:end', tslib_1.__assign({ type: type,
_this.actionChain.emit('operator:end', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution, { isAsync: false, result: result }));
path: path }, thisExecution, { isAsync: false, result: result }));
return result;
}
};
if (prevResult instanceof Promise) {

@@ -90,5 +66,55 @@ return prevResult.then(produceResult);

];
},
});
}
};
this.getActionChain = this.getActionChain.bind(this);
var instance = Object.assign(function (value) {
var initialOperator = typeof arguments[1] === 'undefined';
var newPath = typeof arguments[2] === 'undefined' ? null : arguments[2];
var executionContext = initialOperator
? {
__execution: {
operatorId: -1,
actionId: initialActionId,
executionId: instance.currentExecutionId++,
},
__path: [],
}
: arguments[1];
if (initialOperator) {
actionChain.emit('action:start', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
value: value,
});
}
var returnValue = runOperators
? runOperators(value, executionContext, newPath)
: value;
if (initialOperator && returnValue instanceof Promise) {
returnValue.then(function () {
actionChain.emit('action:end', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
});
});
}
else if (initialOperator) {
actionChain.emit('action:end', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
});
}
return returnValue;
}, this);
return instance;
}
ActionBase.prototype.getActionChain = function () {
return this.actionChain;
};
ActionBase.nextActionId = 0;
return ActionBase;
}());
export { ActionBase };
//# sourceMappingURL=ActionBase.js.map

@@ -1,18 +0,10 @@

import * as EventEmitter from 'eventemitter3';
export interface ActionChain<Context> extends EventEmitter {
getOptions(): ActionChainOptions;
getContext(execution: Execution, path: string[]): Context & {
execution: Execution;
path: string[];
};
import { EventEmitter } from 'betsy';
import { ActionChainEvents, Execution } from './types';
export declare class ActionChain<Effects, ExtraEvents = {}> extends EventEmitter<ActionChainEvents & ExtraEvents> {
private effects;
private options;
constructor(effects: Effects, options?: {
providerExceptions?: string[];
});
getEffects(thisExecution: Execution): Effects;
}
export declare type ActionChainOptions = {
actionWrapper?: any;
providerExceptions?: string[];
};
export declare type Execution = {
operatorId: number;
actionId: number;
executionId: number;
};
export declare function actionChainFactory<Context>(context: Context, options?: ActionChainOptions): ActionChain<Context>;
import * as tslib_1 from "tslib";
import * as EventEmitter from 'eventemitter3';
import { EventEmitter } from 'betsy';
import { proxifyEffects } from './utils';
var IS_DEVELOPMENT = process.env.NODE_ENV !== 'production';
export function actionChainFactory(context, options) {
if (options === void 0) { options = {}; }
options.providerExceptions = options.providerExceptions || [];
return Object.assign(new EventEmitter(), {
getOptions: function () {
return options;
},
getContext: function (execution, path) {
var _this = this;
var providers = Object.keys(context).reduce(function (currentContext, key) {
if (IS_DEVELOPMENT && options.providerExceptions.indexOf(key) === -1) {
currentContext[key] = Object.keys(context[key]).reduce(function (currentProvider, method) {
currentProvider[method] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _a;
var result = (_a = context[key])[method].apply(_a, args);
if (result instanceof Promise) {
result.then(function (promisedResult) {
_this.emit('provider', tslib_1.__assign({}, execution, { name: key, method: method, result: promisedResult }));
});
}
else {
_this.emit('provider', tslib_1.__assign({}, execution, { name: key, method: method,
result: result }));
}
return result;
};
return currentProvider;
}, {});
}
else {
currentContext[key] = context[key];
}
return currentContext;
}, {});
return Object.assign({}, providers, {
execution: execution,
path: path,
});
},
});
}
var ActionChain = /** @class */ (function (_super) {
tslib_1.__extends(ActionChain, _super);
function ActionChain(effects, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this) || this;
_this.effects = effects;
_this.options = options;
return _this;
}
ActionChain.prototype.getEffects = function (thisExecution) {
var _this = this;
if (IS_DEVELOPMENT) {
return proxifyEffects(this.effects, this.options.providerExceptions, function (effect) { return _this.emitAsync('effect', tslib_1.__assign({}, thisExecution, effect)); });
}
return this.effects;
};
return ActionChain;
}(EventEmitter));
export { ActionChain };
//# sourceMappingURL=ActionChain.js.map

@@ -1,3 +0,4 @@

export { actionBaseFactory, ActionBase } from './ActionBase';
export { actionFactory, Action, NoValueAction } from './Action';
export { actionChainFactory, ActionChain, Execution } from './ActionChain';
export { ActionBase, StopExecution } from './ActionBase';
export { ActionChain } from './ActionChain';
export { ActionExecution, Execution, ExecutionContext } from './types';
export { doNotProxy } from './utils';

@@ -1,4 +0,4 @@

export { actionBaseFactory } from './ActionBase';
export { actionFactory } from './Action';
export { actionChainFactory } from './ActionChain';
export { ActionBase, StopExecution } from './ActionBase';
export { ActionChain } from './ActionChain';
export { doNotProxy } from './utils';
//# sourceMappingURL=index.js.map

@@ -1,2 +0,33 @@

import { actionChainFactory, actionBaseFactory, actionFactory, } from './';
import * as tslib_1 from "tslib";
import { ActionBase, ActionChain } from './';
var Action = /** @class */ (function (_super) {
tslib_1.__extends(Action, _super);
function Action() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.test = function (cb) {
var operator = function (context, value) {
return cb(context, value);
};
var _a = _this.createOperatorResult('test', cb.name, operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return new Action(chain, initialActionId, runOperators);
};
_this.testFork = function (action) {
var operator = function (context, value) {
return action(value, context, 'fork');
};
var _a = _this.createOperatorResult('testFork', '', operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return new Action(chain, initialActionId, runOperators);
};
return _this;
}
return Action;
}(ActionBase));
var TestProvider = /** @class */ (function () {
function TestProvider() {
}
TestProvider.prototype.foo = function () {
return 'bar';
};
return TestProvider;
}());
var context = {

@@ -7,12 +38,30 @@ foo: {

},
nestedProvider: {
bar: function () {
return 'baz';
},
},
},
test: new TestProvider(),
};
var actionChain = actionChainFactory(context);
var actionChain = new ActionChain(context);
// FORCE SYNC EVENTS
actionChain.emitAsync = actionChain.emit.bind(actionChain);
var action = function () {
return actionFactory(actionChain);
return new Action(actionChain);
};
beforeEach(function () {
;
actionBaseFactory.nextActionId = 0;
ActionBase.nextActionId = 0;
});
describe('ACTION', function () {
test('should be able to give the action a name', function () {
expect.assertions(1);
var test = action();
test.displayName = 'My Name';
actionChain.once('action:start', function (execution) {
expect(execution.actionName).toEqual('My Name');
});
test();
});
});
describe('VALUE', function () {

@@ -27,6 +76,6 @@ test('should run and return result', function () {

expect.assertions(2);
var test = action().do(function (_, _a) {
var execution = _a.execution, path = _a.path;
expect(execution).toBeTruthy();
expect(path).toBeTruthy();
var test = action().test(function (_a) {
var __execution = _a.__execution, __path = _a.__path;
expect(__execution).toBeTruthy();
expect(__path).toBeTruthy();
});

@@ -37,17 +86,17 @@ test();

expect.assertions(1);
var foo = action().do(function (_, _a) {
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
foo();
fn();
});
});
describe('PROVIDER', function () {
test('should track execution of providers', function () {
describe('EFFECTS', function () {
test('should track execution of effects', function () {
expect.assertions(2);
var foo = action().do(function (_, _a) {
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
actionChain.once('provider', function (task) {
actionChain.once('effect', function (task) {
expect(task).toEqual({

@@ -59,7 +108,46 @@ operatorId: 0,

name: 'foo',
args: [],
result: 'baz',
});
});
foo();
fn();
});
test('should track execution of namespaced effects', function () {
expect.assertions(2);
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.nestedProvider.bar()).toBe('baz');
});
actionChain.once('effect', function (task) {
expect(task).toEqual({
operatorId: 0,
actionId: 0,
executionId: 0,
method: 'bar',
name: 'foo.nestedProvider',
args: [],
result: 'baz',
});
});
fn();
});
test('should track execution of class instance effects', function () {
expect.assertions(2);
var fn = action().test(function (_a) {
var test = _a.test;
expect(test.foo()).toBe('bar');
});
actionChain.once('effect', function (task) {
expect(task).toEqual({
operatorId: 0,
actionId: 0,
executionId: 0,
method: 'foo',
args: [],
name: 'test',
result: 'bar',
});
});
fn();
});
});

@@ -69,5 +157,3 @@ describe('ACTION CHAIN', function () {

expect.assertions(4);
var foo = action().map(function () {
return 'foo';
});
var fn = action().test(function () { return 'foo'; });
actionChain.once('action:start', function (data) {

@@ -85,3 +171,3 @@ expect(data).toEqual({

name: '',
type: 'map',
type: 'test',
path: [],

@@ -96,3 +182,3 @@ });

name: '',
type: 'map',
type: 'test',
isAsync: false,

@@ -109,3 +195,3 @@ path: [],

});
foo();
fn();
});

@@ -117,3 +203,3 @@ test('should track async execution', function () {

};
var test = action().map(foo);
var test = action().test(foo);
actionChain.once('operator:start', function (task) {

@@ -126,3 +212,3 @@ expect(task).toEqual({

path: [],
type: 'map',
type: 'test',
});

@@ -137,3 +223,3 @@ });

path: [],
type: 'map',
type: 'test',
isAsync: true,

@@ -145,137 +231,69 @@ result: 'foo',

});
test('should allow extending with new operators', function () {
var hasLogged = false;
function myActionFactory(actionChain, initialActionId, runOperators) {
return Object.assign(actionFactory(actionChain, initialActionId, runOperators), {
log: function () {
var operator = function (value) {
hasLogged = true;
return value;
};
var _a = this.createOperatorResult('log', '', operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return myActionFactory(chain, initialActionId, runOperators);
},
});
}
expect.assertions(3);
var myAction = function () {
return myActionFactory(actionChain);
};
var test = myAction().log();
actionChain.once('operator:start', function (data) {
expect(data).toEqual({
actionId: 0,
test('should track path execution', function () {
expect.assertions(4);
var forkAction = action().test(function () { return Promise.resolve('foo'); });
var test = action().testFork(forkAction);
actionChain.once('operator:start', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 0,
executionId: 0,
operatorId: 0,
name: '',
path: [],
type: 'log',
type: 'testFork',
});
actionChain.once('operator:start', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 1,
executionId: 0,
name: '',
path: ['fork'],
type: 'test',
});
});
});
actionChain.once('operator:end', function (data) {
expect(data).toEqual({
actionId: 0,
actionChain.once('operator:end', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 1,
executionId: 0,
operatorId: 0,
name: '',
type: 'log',
path: [],
isAsync: false,
path: ['fork'],
type: 'test',
isAsync: true,
result: 'foo',
});
actionChain.once('operator:end', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 0,
executionId: 0,
name: '',
path: [],
type: 'testFork',
isAsync: true,
result: 'foo',
});
});
});
test('foo');
expect(hasLogged).toBe(true);
return test();
});
});
describe('OPERATORS', function () {
test('do', function () {
expect.assertions(2);
var test = action().do(function (_, _a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
expect(test('foo')).toBe('foo');
});
test('map', function () {
test('should emit event when operator has async result', function () {
expect.assertions(1);
var test = action().map(function (value) {
return value.toUpperCase();
var test = action().test(function () { return Promise.resolve('foo'); });
actionChain.once('operator:async', function (task) {
expect(task).toEqual({
actionId: 0,
operatorId: 0,
executionId: 0,
name: '',
path: [],
isAsync: true,
type: 'test',
});
});
expect(test('foo')).toBe('FOO');
return test();
});
test('try - resolved', function () {
expect.assertions(1);
var test = action().try(function () { return Promise.resolve(); }, {
success: action().map(function () { return 'foo'; }),
error: action(),
});
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('foo');
});
});
test('try - rejected', function () {
expect.assertions(1);
var test = action().try(function () { return Promise.reject(new Error()); }, {
success: action().map(function () { return 'foo'; }),
error: action().map(function () { return 'bar'; }),
});
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('bar');
});
});
test('when - true', function () {
expect.assertions(1);
var test = action().when(function () { return true; }, {
true: action().map(function () { return 'foo'; }),
false: action(),
});
expect(test()).toBe('foo');
});
test('when - false', function () {
expect.assertions(1);
var test = action().when(function () { return false; }, {
true: action().map(function () { return 'foo'; }),
false: action().map(function () { return 'bar'; }),
});
expect(test()).toBe('bar');
});
test('when - true', function () {
expect.assertions(1);
var test = action().when(function () { return true; }, {
true: action().map(function () { return 'foo'; }),
false: action(),
});
expect(test()).toBe('foo');
});
test('filter - true', function () {
expect.assertions(1);
var test = action()
.filter(function () { return true; })
.map(function () { return 'bar'; });
expect(test('foo')).toBe('bar');
});
test('filter - false', function () {
expect.assertions(1);
var test = action()
.filter(function () { return false; })
.map(function () { return 'bar'; });
expect(test('foo')).toBe('foo');
});
test('debounce', function () {
expect.assertions(2);
var start = Date.now();
var end;
var test = action()
.debounce(100)
.do(function () {
end = Date.now();
})
.map(function () { return 'foo'; });
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('foo');
expect(end - start).toBeGreaterThanOrEqual(100);
});
});
});
//# sourceMappingURL=index.test.js.map

@@ -1,2 +0,3 @@

import { ActionChain, Execution } from './ActionChain';
import { ActionChain } from './ActionChain';
import { ExecutionContext } from './types';
export declare class StopExecution {

@@ -6,9 +7,11 @@ value: any;

}
export interface ActionBase<Context, InitialValue, Value = InitialValue> {
(value: InitialValue): Value;
createOperatorResult(type: string, name: string, cb: any): [ActionChain<Context>, number, any];
export declare class ActionBase<Effects> {
private actionChain;
private initialActionId;
private runOperators?;
static nextActionId: number;
private currentExecutionId;
constructor(actionChain: ActionChain<Effects>, initialActionId?: number, runOperators?: (value: any, executionContext: ExecutionContext, newPath?: string) => any | Promise<any>);
getActionChain<ExtraEvents = {}>(): ActionChain<Effects, ExtraEvents>;
createOperatorResult: (type: string, name: string, cb: any) => [ActionChain<Effects, {}>, number, any];
}
export interface NoValueActionBase<Context, InitialValue, Value = InitialValue> extends ActionBase<Context, InitialValue, Value> {
(): Value;
}
export declare function actionBaseFactory<Context, InitialValue, Value = InitialValue>(actionChain: ActionChain<Context>, initialActionId?: number, runOperators?: (value: any, execution: Execution, path: string[]) => any | Promise<any>): InitialValue extends undefined ? NoValueActionBase<Context, InitialValue, Value> : ActionBase<Context, InitialValue, Value>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
actionBaseFactory.nextActionId = 0;
var StopExecution = /** @class */ (function () {

@@ -12,75 +11,52 @@ function StopExecution(value) {

exports.StopExecution = StopExecution;
function actionBaseFactory(actionChain, initialActionId, runOperators) {
if (initialActionId === void 0) { initialActionId = actionBaseFactory.nextActionId++; }
var currentExecutionId = 0;
return Object.assign(function (value) {
var initialOperator = typeof arguments[1] === 'undefined';
var execution = initialOperator
? {
operatorId: -1,
actionId: initialActionId,
executionId: currentExecutionId++,
}
: arguments[1];
var path = typeof arguments[2] === 'undefined' ? [] : arguments[2];
if (initialOperator) {
actionChain.emit('action:start', {
actionId: execution.actionId,
executionId: execution.executionId,
});
}
var returnValue = runOperators
? runOperators(value, execution, path)
: value;
if (initialOperator && returnValue instanceof Promise) {
returnValue.then(function () {
actionChain.emit('action:end', {
actionId: execution.actionId,
executionId: execution.executionId,
});
});
}
else if (initialOperator) {
actionChain.emit('action:end', {
actionId: execution.actionId,
executionId: execution.executionId,
});
}
return returnValue;
}, {
createOperatorResult: function (type, name, cb) {
var ActionBase = /** @class */ (function () {
function ActionBase(actionChain, initialActionId, runOperators) {
if (initialActionId === void 0) { initialActionId = ActionBase.nextActionId++; }
var _this = this;
this.actionChain = actionChain;
this.initialActionId = initialActionId;
this.runOperators = runOperators;
this.currentExecutionId = 0;
this.createOperatorResult = function (type, name, cb) {
return [
actionChain,
initialActionId,
function (props, execution, path) {
var prevResult = runOperators
? runOperators(props, execution, path)
_this.actionChain,
_this.initialActionId,
function (props, executionContext, newPath) {
var executionContextWithPath = {
__execution: executionContext.__execution,
__path: newPath
? executionContext.__path.concat(newPath)
: executionContext.__path.slice(),
};
var prevResult = _this.runOperators
? _this.runOperators(props, executionContextWithPath)
: props;
function produceResult(currentValue) {
var produceResult = function (currentValue) {
if (currentValue instanceof StopExecution) {
return currentValue.value;
return currentValue;
}
execution.operatorId++;
var context = actionChain.getContext(execution, path);
actionChain.emit('operator:start', tslib_1.__assign({ type: type,
var thisExecution = tslib_1.__assign({}, executionContextWithPath.__execution, { operatorId: executionContextWithPath.__execution.operatorId + 1 });
executionContextWithPath.__execution.operatorId++;
var path = executionContextWithPath.__path;
var effects = Object.assign({}, _this.actionChain.getEffects(thisExecution), executionContextWithPath);
_this.actionChain.emit('operator:start', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution));
var result = actionChain.getOptions().actionWrapper
? actionChain
.getOptions()
.actionWrapper(currentValue, context, cb)
: cb(currentValue, context);
path: path }, thisExecution));
var result = cb(effects, currentValue);
if (result instanceof Promise) {
_this.actionChain.emit('operator:async', tslib_1.__assign({ type: type,
name: name,
path: path, isAsync: true }, thisExecution));
return result.then(function (promiseResult) {
actionChain.emit('operator:end', tslib_1.__assign({ type: type,
_this.actionChain.emit('operator:end', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution, { isAsync: true, result: promiseResult }));
path: path }, thisExecution, { isAsync: true, result: promiseResult }));
return promiseResult;
});
}
actionChain.emit('operator:end', tslib_1.__assign({ type: type,
_this.actionChain.emit('operator:end', tslib_1.__assign({ type: type,
name: name,
path: path }, context.execution, { isAsync: false, result: result }));
path: path }, thisExecution, { isAsync: false, result: result }));
return result;
}
};
if (prevResult instanceof Promise) {

@@ -92,6 +68,55 @@ return prevResult.then(produceResult);

];
},
});
}
exports.actionBaseFactory = actionBaseFactory;
};
this.getActionChain = this.getActionChain.bind(this);
var instance = Object.assign(function (value) {
var initialOperator = typeof arguments[1] === 'undefined';
var newPath = typeof arguments[2] === 'undefined' ? null : arguments[2];
var executionContext = initialOperator
? {
__execution: {
operatorId: -1,
actionId: initialActionId,
executionId: instance.currentExecutionId++,
},
__path: [],
}
: arguments[1];
if (initialOperator) {
actionChain.emit('action:start', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
value: value,
});
}
var returnValue = runOperators
? runOperators(value, executionContext, newPath)
: value;
if (initialOperator && returnValue instanceof Promise) {
returnValue.then(function () {
actionChain.emit('action:end', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
});
});
}
else if (initialOperator) {
actionChain.emit('action:end', {
actionId: executionContext.__execution.actionId,
executionId: executionContext.__execution.executionId,
actionName: instance.displayName,
});
}
return returnValue;
}, this);
return instance;
}
ActionBase.prototype.getActionChain = function () {
return this.actionChain;
};
ActionBase.nextActionId = 0;
return ActionBase;
}());
exports.ActionBase = ActionBase;
//# sourceMappingURL=ActionBase.js.map

@@ -1,18 +0,10 @@

import * as EventEmitter from 'eventemitter3';
export interface ActionChain<Context> extends EventEmitter {
getOptions(): ActionChainOptions;
getContext(execution: Execution, path: string[]): Context & {
execution: Execution;
path: string[];
};
import { EventEmitter } from 'betsy';
import { ActionChainEvents, Execution } from './types';
export declare class ActionChain<Effects, ExtraEvents = {}> extends EventEmitter<ActionChainEvents & ExtraEvents> {
private effects;
private options;
constructor(effects: Effects, options?: {
providerExceptions?: string[];
});
getEffects(thisExecution: Execution): Effects;
}
export declare type ActionChainOptions = {
actionWrapper?: any;
providerExceptions?: string[];
};
export declare type Execution = {
operatorId: number;
actionId: number;
executionId: number;
};
export declare function actionChainFactory<Context>(context: Context, options?: ActionChainOptions): ActionChain<Context>;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var EventEmitter = require("eventemitter3");
var betsy_1 = require("betsy");
var utils_1 = require("./utils");
var IS_DEVELOPMENT = process.env.NODE_ENV !== 'production';
function actionChainFactory(context, options) {
if (options === void 0) { options = {}; }
options.providerExceptions = options.providerExceptions || [];
return Object.assign(new EventEmitter(), {
getOptions: function () {
return options;
},
getContext: function (execution, path) {
var _this = this;
var providers = Object.keys(context).reduce(function (currentContext, key) {
if (IS_DEVELOPMENT && options.providerExceptions.indexOf(key) === -1) {
currentContext[key] = Object.keys(context[key]).reduce(function (currentProvider, method) {
currentProvider[method] = function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var _a;
var result = (_a = context[key])[method].apply(_a, args);
if (result instanceof Promise) {
result.then(function (promisedResult) {
_this.emit('provider', tslib_1.__assign({}, execution, { name: key, method: method, result: promisedResult }));
});
}
else {
_this.emit('provider', tslib_1.__assign({}, execution, { name: key, method: method,
result: result }));
}
return result;
};
return currentProvider;
}, {});
}
else {
currentContext[key] = context[key];
}
return currentContext;
}, {});
return Object.assign({}, providers, {
execution: execution,
path: path,
});
},
});
}
exports.actionChainFactory = actionChainFactory;
var ActionChain = /** @class */ (function (_super) {
tslib_1.__extends(ActionChain, _super);
function ActionChain(effects, options) {
if (options === void 0) { options = {}; }
var _this = _super.call(this) || this;
_this.effects = effects;
_this.options = options;
return _this;
}
ActionChain.prototype.getEffects = function (thisExecution) {
var _this = this;
if (IS_DEVELOPMENT) {
return utils_1.proxifyEffects(this.effects, this.options.providerExceptions, function (effect) { return _this.emitAsync('effect', tslib_1.__assign({}, thisExecution, effect)); });
}
return this.effects;
};
return ActionChain;
}(betsy_1.EventEmitter));
exports.ActionChain = ActionChain;
//# sourceMappingURL=ActionChain.js.map

@@ -1,3 +0,4 @@

export { actionBaseFactory, ActionBase } from './ActionBase';
export { actionFactory, Action, NoValueAction } from './Action';
export { actionChainFactory, ActionChain, Execution } from './ActionChain';
export { ActionBase, StopExecution } from './ActionBase';
export { ActionChain } from './ActionChain';
export { ActionExecution, Execution, ExecutionContext } from './types';
export { doNotProxy } from './utils';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ActionBase_1 = require("./ActionBase");
exports.actionBaseFactory = ActionBase_1.actionBaseFactory;
var Action_1 = require("./Action");
exports.actionFactory = Action_1.actionFactory;
exports.ActionBase = ActionBase_1.ActionBase;
exports.StopExecution = ActionBase_1.StopExecution;
var ActionChain_1 = require("./ActionChain");
exports.actionChainFactory = ActionChain_1.actionChainFactory;
exports.ActionChain = ActionChain_1.ActionChain;
var utils_1 = require("./utils");
exports.doNotProxy = utils_1.doNotProxy;
//# sourceMappingURL=index.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var _1 = require("./");
var Action = /** @class */ (function (_super) {
tslib_1.__extends(Action, _super);
function Action() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.test = function (cb) {
var operator = function (context, value) {
return cb(context, value);
};
var _a = _this.createOperatorResult('test', cb.name, operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return new Action(chain, initialActionId, runOperators);
};
_this.testFork = function (action) {
var operator = function (context, value) {
return action(value, context, 'fork');
};
var _a = _this.createOperatorResult('testFork', '', operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return new Action(chain, initialActionId, runOperators);
};
return _this;
}
return Action;
}(_1.ActionBase));
var TestProvider = /** @class */ (function () {
function TestProvider() {
}
TestProvider.prototype.foo = function () {
return 'bar';
};
return TestProvider;
}());
var context = {

@@ -9,12 +40,30 @@ foo: {

},
nestedProvider: {
bar: function () {
return 'baz';
},
},
},
test: new TestProvider(),
};
var actionChain = _1.actionChainFactory(context);
var actionChain = new _1.ActionChain(context);
// FORCE SYNC EVENTS
actionChain.emitAsync = actionChain.emit.bind(actionChain);
var action = function () {
return _1.actionFactory(actionChain);
return new Action(actionChain);
};
beforeEach(function () {
;
_1.actionBaseFactory.nextActionId = 0;
_1.ActionBase.nextActionId = 0;
});
describe('ACTION', function () {
test('should be able to give the action a name', function () {
expect.assertions(1);
var test = action();
test.displayName = 'My Name';
actionChain.once('action:start', function (execution) {
expect(execution.actionName).toEqual('My Name');
});
test();
});
});
describe('VALUE', function () {

@@ -29,6 +78,6 @@ test('should run and return result', function () {

expect.assertions(2);
var test = action().do(function (_, _a) {
var execution = _a.execution, path = _a.path;
expect(execution).toBeTruthy();
expect(path).toBeTruthy();
var test = action().test(function (_a) {
var __execution = _a.__execution, __path = _a.__path;
expect(__execution).toBeTruthy();
expect(__path).toBeTruthy();
});

@@ -39,17 +88,17 @@ test();

expect.assertions(1);
var foo = action().do(function (_, _a) {
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
foo();
fn();
});
});
describe('PROVIDER', function () {
test('should track execution of providers', function () {
describe('EFFECTS', function () {
test('should track execution of effects', function () {
expect.assertions(2);
var foo = action().do(function (_, _a) {
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
actionChain.once('provider', function (task) {
actionChain.once('effect', function (task) {
expect(task).toEqual({

@@ -61,7 +110,46 @@ operatorId: 0,

name: 'foo',
args: [],
result: 'baz',
});
});
foo();
fn();
});
test('should track execution of namespaced effects', function () {
expect.assertions(2);
var fn = action().test(function (_a) {
var foo = _a.foo;
expect(foo.nestedProvider.bar()).toBe('baz');
});
actionChain.once('effect', function (task) {
expect(task).toEqual({
operatorId: 0,
actionId: 0,
executionId: 0,
method: 'bar',
name: 'foo.nestedProvider',
args: [],
result: 'baz',
});
});
fn();
});
test('should track execution of class instance effects', function () {
expect.assertions(2);
var fn = action().test(function (_a) {
var test = _a.test;
expect(test.foo()).toBe('bar');
});
actionChain.once('effect', function (task) {
expect(task).toEqual({
operatorId: 0,
actionId: 0,
executionId: 0,
method: 'foo',
args: [],
name: 'test',
result: 'bar',
});
});
fn();
});
});

@@ -71,5 +159,3 @@ describe('ACTION CHAIN', function () {

expect.assertions(4);
var foo = action().map(function () {
return 'foo';
});
var fn = action().test(function () { return 'foo'; });
actionChain.once('action:start', function (data) {

@@ -87,3 +173,3 @@ expect(data).toEqual({

name: '',
type: 'map',
type: 'test',
path: [],

@@ -98,3 +184,3 @@ });

name: '',
type: 'map',
type: 'test',
isAsync: false,

@@ -111,3 +197,3 @@ path: [],

});
foo();
fn();
});

@@ -119,3 +205,3 @@ test('should track async execution', function () {

};
var test = action().map(foo);
var test = action().test(foo);
actionChain.once('operator:start', function (task) {

@@ -128,3 +214,3 @@ expect(task).toEqual({

path: [],
type: 'map',
type: 'test',
});

@@ -139,3 +225,3 @@ });

path: [],
type: 'map',
type: 'test',
isAsync: true,

@@ -147,137 +233,69 @@ result: 'foo',

});
test('should allow extending with new operators', function () {
var hasLogged = false;
function myActionFactory(actionChain, initialActionId, runOperators) {
return Object.assign(_1.actionFactory(actionChain, initialActionId, runOperators), {
log: function () {
var operator = function (value) {
hasLogged = true;
return value;
};
var _a = this.createOperatorResult('log', '', operator), chain = _a[0], initialActionId = _a[1], runOperators = _a[2];
return myActionFactory(chain, initialActionId, runOperators);
},
});
}
expect.assertions(3);
var myAction = function () {
return myActionFactory(actionChain);
};
var test = myAction().log();
actionChain.once('operator:start', function (data) {
expect(data).toEqual({
actionId: 0,
test('should track path execution', function () {
expect.assertions(4);
var forkAction = action().test(function () { return Promise.resolve('foo'); });
var test = action().testFork(forkAction);
actionChain.once('operator:start', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 0,
executionId: 0,
operatorId: 0,
name: '',
path: [],
type: 'log',
type: 'testFork',
});
actionChain.once('operator:start', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 1,
executionId: 0,
name: '',
path: ['fork'],
type: 'test',
});
});
});
actionChain.once('operator:end', function (data) {
expect(data).toEqual({
actionId: 0,
actionChain.once('operator:end', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 1,
executionId: 0,
operatorId: 0,
name: '',
type: 'log',
path: [],
isAsync: false,
path: ['fork'],
type: 'test',
isAsync: true,
result: 'foo',
});
actionChain.once('operator:end', function (task) {
expect(task).toEqual({
actionId: 1,
operatorId: 0,
executionId: 0,
name: '',
path: [],
type: 'testFork',
isAsync: true,
result: 'foo',
});
});
});
test('foo');
expect(hasLogged).toBe(true);
return test();
});
});
describe('OPERATORS', function () {
test('do', function () {
expect.assertions(2);
var test = action().do(function (_, _a) {
var foo = _a.foo;
expect(foo.bar()).toBe('baz');
});
expect(test('foo')).toBe('foo');
});
test('map', function () {
test('should emit event when operator has async result', function () {
expect.assertions(1);
var test = action().map(function (value) {
return value.toUpperCase();
var test = action().test(function () { return Promise.resolve('foo'); });
actionChain.once('operator:async', function (task) {
expect(task).toEqual({
actionId: 0,
operatorId: 0,
executionId: 0,
name: '',
path: [],
isAsync: true,
type: 'test',
});
});
expect(test('foo')).toBe('FOO');
return test();
});
test('try - resolved', function () {
expect.assertions(1);
var test = action().try(function () { return Promise.resolve(); }, {
success: action().map(function () { return 'foo'; }),
error: action(),
});
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('foo');
});
});
test('try - rejected', function () {
expect.assertions(1);
var test = action().try(function () { return Promise.reject(new Error()); }, {
success: action().map(function () { return 'foo'; }),
error: action().map(function () { return 'bar'; }),
});
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('bar');
});
});
test('when - true', function () {
expect.assertions(1);
var test = action().when(function () { return true; }, {
true: action().map(function () { return 'foo'; }),
false: action(),
});
expect(test()).toBe('foo');
});
test('when - false', function () {
expect.assertions(1);
var test = action().when(function () { return false; }, {
true: action().map(function () { return 'foo'; }),
false: action().map(function () { return 'bar'; }),
});
expect(test()).toBe('bar');
});
test('when - true', function () {
expect.assertions(1);
var test = action().when(function () { return true; }, {
true: action().map(function () { return 'foo'; }),
false: action(),
});
expect(test()).toBe('foo');
});
test('filter - true', function () {
expect.assertions(1);
var test = action()
.filter(function () { return true; })
.map(function () { return 'bar'; });
expect(test('foo')).toBe('bar');
});
test('filter - false', function () {
expect.assertions(1);
var test = action()
.filter(function () { return false; })
.map(function () { return 'bar'; });
expect(test('foo')).toBe('foo');
});
test('debounce', function () {
expect.assertions(2);
var start = Date.now();
var end;
var test = action()
.debounce(100)
.do(function () {
end = Date.now();
})
.map(function () { return 'foo'; });
return Promise.resolve(test()).then(function (value) {
expect(value).toBe('foo');
expect(end - start).toBeGreaterThanOrEqual(100);
});
});
});
//# sourceMappingURL=index.test.js.map
{
"name": "action-chain",
"version": "1.0.0-alpha1",
"version": "1.0.1",
"description": "Functional actions",

@@ -10,56 +10,23 @@ "author": "Christian Alfoni <christianalfoni@gmail.com>",

"module": "es/index.js",
"browser": "dist/bundle.js",
"types": "dist/bundle.d.ts",
"types": "lib/index.d.ts",
"scripts": {
"build": "npm run build:lib & npm run build:umd",
"build": "npm run build:lib & npm run build:es",
"build:lib": "tsc --outDir lib --module commonjs",
"build:es": "tsc --outDir es --module es2015",
"build:umd": "npm run build:es && rollup --config && dts-bundle --name dist/bundle --main es --outputAsModuleFolder",
"clean": "rimraf dist es lib coverage",
"clean": "rimraf es lib coverage",
"typecheck": "tsc --noEmit",
"lint": "eslint \"**/*.ts\" --fix",
"test": "jest --coverage",
"test:watch": "jest --watch --updateSnapshot",
"prepublishOnly": "npm run build",
"test": "jest",
"test:watch": "jest --watch --updateSnapshot --coverage false",
"prebuild": "npm run clean",
"postbuild": "rimraf {lib,es}/**/__tests__",
"posttest": "npm run typecheck && npm run lint",
"preversion": "npm test",
"postversion": "git push && git push --tags"
"posttest": "npm run typecheck"
},
"keywords": [ "action", "flow" ],
"files": [ "lib", "es", "dist" ],
"files": [ "lib", "es" ],
"dependencies": {
"@types/node": "^10.5.1",
"eventemitter3": "^3.1.0",
"tslib": "^1.9.3"
"tslib": "^1.9.3",
"betsy": "next"
},
"devDependencies": {
"@types/jest": "^23.1.4",
"dts-bundle": "^0.7.3",
"eslint": "^5.0.1",
"eslint-config-prettier": "^2.9.0",
"eslint-config-standard": "^11.0.0",
"eslint-plugin-import": "^2.13.0",
"eslint-plugin-node": "^6.0.1",
"eslint-plugin-prettier": "^2.6.1",
"eslint-plugin-promise": "^3.8.0",
"eslint-plugin-standard": "^3.1.0",
"eslint-plugin-typescript": "^0.12.0",
"jest-cli": "^23.2.0",
"pascal-case": "^2.0.1",
"prettier": "^1.13.7",
"react-test-renderer": "^16.4.1",
"rimraf": "^2.6.2",
"rollup": "^0.62.0",
"rollup-plugin-commonjs": "^9.1.3",
"rollup-plugin-node-builtins": "^2.1.2",
"rollup-plugin-node-globals": "^1.2.1",
"rollup-plugin-node-resolve": "^3.3.0",
"rollup-plugin-sourcemaps": "^0.4.2",
"rollup-plugin-uglify": "^4.0.0",
"ts-jest": "^23.0.0",
"typescript": "^2.9.2",
"typescript-eslint-parser": "^16.0.1"
}
"devDependencies": {}
}

@@ -45,5 +45,5 @@ # action-chain

// to not require a value
const action = <InitialValue>(): InitialValue extends undefined
? NoValueMyAction<Context, InitialValue>
: MyAction<Context, InitialValue> {
const action = function <InitialValue>(): InitialValue extends undefined
? NoValueAction<Context, InitialValue>
: Action<Context, InitialValue> {
return actionFactory<Context, InitialValue>(actionChain)

@@ -50,0 +50,0 @@ }

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc