New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@actorize/core

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@actorize/core - npm Package Compare versions

Comparing version
0.0.1
to
0.0.2
+79
src/integration.test.ts
import { createStore, createDirector, createNetworkInterface, createRouter } from './index'
function skiploop(time = 0) {
return new Promise(resolve => setTimeout(resolve, time))
}
describe('integration.test.ts', () => {
it('basic same thread use case', async () => {
const routerOneTwoLink = createNetworkInterface()
const routerTwoOneLink = createNetworkInterface()
routerOneTwoLink.handleLocalIncomingMessages((msg) => {
routerTwoOneLink.sendLocal(msg)
})
routerTwoOneLink.handleLocalIncomingMessages((msg) => {
routerOneTwoLink.sendLocal(msg)
})
const routerOne = createRouter({
domains: {
routerTwo: routerOneTwoLink
},
ownDomain: 'routerOne'
})
const storeOne = createStore()
const directorOne = createDirector({
store: storeOne,
routers: [routerOne]
})
const actorOne = directorOne.registerActor('one')
const mockfnOne = jest.fn()
actorOne.onMessage(mockfnOne)
const routerTwo = createRouter({
domains: {
routerOne: routerTwoOneLink
},
ownDomain: 'routerTwo'
})
const storeTwo = createStore()
const directorTwo = createDirector({
store: storeTwo,
routers: [routerTwo]
})
const actorTwo = directorTwo.registerActor('two')
const mockfnTwo = jest.fn()
actorTwo.onMessage(mockfnTwo)
expect(mockfnOne).toBeCalledTimes(0)
expect(mockfnTwo).toBeCalledTimes(0)
actorTwo.sendMessage('routerOne.one', 'hello')
await skiploop(100)
expect(mockfnOne).toBeCalledTimes(1)
expect(mockfnOne).toBeCalledWith([{ recipient: 'one', payload: 'hello', sender: 'routerTwo.two' }])
expect(mockfnTwo).toBeCalledTimes(0)
actorOne.sendMessage('routerTwo.two', 'hello')
await skiploop(100)
expect(mockfnTwo).toBeCalledTimes(1)
expect(mockfnTwo).toBeCalledWith([{ recipient: 'two', payload: 'hello', sender: 'routerOne.one' }])
})
})
import { createNetworkInterface, createRouter } from './index'
import { createStore } from '../index'
function skiploop() {
return new Promise(resolve => setTimeout(resolve, 0))
}
describe('network/index.ts', () => {
it('send av.', async () => {
const store = createStore()
const networkInterface = createNetworkInterface()
const mockFn = jest.fn();
networkInterface.handleLocalIncomingMessages(mockFn)
const router = createRouter({
ownDomain: 'local',
domains: {
other: networkInterface,
}
})
const msg = {
domain: 'other',
payload: {
sender: '',
payload: 'hello',
recipient: '',
}
}
expect(mockFn).toBeCalledTimes(0)
const success = router.handleIncomingMessage(msg, store)
expect(success).toBe(true)
expect(mockFn).toBeCalledTimes(1)
expect(mockFn).toBeCalledWith(msg)
})
it('send not av.', async () => {
const store = createStore()
const networkInterface = createNetworkInterface()
const mockFn = jest.fn();
networkInterface.handleLocalIncomingMessages(mockFn)
const router = createRouter({
ownDomain: 'local',
domains: {
other: networkInterface,
}
})
const msg = {
domain: 'testdomain',
payload: {
sender: '',
payload: 'hello',
recipient: '',
}
}
expect(mockFn).toBeCalledTimes(0)
const success = router.handleIncomingMessage(msg, store)
expect(success).toBe(false)
expect(mockFn).toBeCalledTimes(0)
})
it('local', async () => {
const store = createStore()
const networkInterface = createNetworkInterface()
const mockFn = jest.fn();
networkInterface.setLocalCallback(mockFn)
networkInterface.handleLocalIncomingMessages((msg) => {
networkInterface.sendLocal(msg)
})
const router = createRouter({
ownDomain: 'local',
domains: {
other: networkInterface,
}
})
const msg = {
domain: 'other',
payload: {
sender: '',
payload: 'hello',
recipient: '',
}
}
expect(mockFn).toBeCalledTimes(0)
const success = router.handleIncomingMessage(msg, store)
expect(success).toBe(true)
expect(mockFn).toBeCalledTimes(1)
expect(mockFn).toBeCalledWith(msg)
})
})
+22
-3

@@ -7,3 +7,3 @@ "use strict";

// TODO: patch those plugins and routers in here
function patchStoreWithPlugins(store) {
function patchStoreWithPlugins(store, routers) {
const pushMessage = async (recipient, payload, sender) => {

@@ -13,2 +13,14 @@ const recipientParts = recipient.split('.');

if (!isLocal) {
const networkmsg = {
domain: recipientParts[0],
payload: {
recipient: recipientParts[recipientParts.length - 1],
payload,
sender,
},
};
const found = routers.find(router => {
const success = router.handleIncomingMessage(networkmsg, store);
return success;
});
return;

@@ -24,4 +36,11 @@ }

function createDirector(options) {
const { store } = options;
const patchedStore = patchStoreWithPlugins(store);
const { store, routers = [] } = options;
const patchedStore = patchStoreWithPlugins(store, routers);
routers.forEach(router => {
router.interfaces.forEach(i => {
i.setLocalCallback((msg) => {
patchedStore.pushMessage(msg.payload.recipient, msg.payload.payload, msg.payload.sender);
});
});
});
const createActor = actor_1.createActorFactory({ store: patchedStore });

@@ -28,0 +47,0 @@ const registerActor = (name) => {

+1
-1

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

{"version":3,"file":"director.js","sourceRoot":"","sources":["../../../src/actor/director.ts"],"names":[],"mappings":";;;AAAA,mCAAmD;AAWnD,8CAA8C;AAC9C,gDAAgD;AAChD,SAAS,qBAAqB,CAAC,KAA4B;IACvD,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,OAA+B,EAAE,MAAc,EAAE,EAAE;QAC7F,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,KAAK,CAAC,CAAA;QAC3C,IAAI,CAAC,OAAO,EAAE;YACV,OAAM;SACT;QACD,OAAO,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IACxD,CAAC,CAAA;IACD,OAAO;QACH,GAAG,KAAK;QACR,WAAW;KACd,CAAA;AACL,CAAC;AAED,SAAgB,cAAc,CAAC,OAA8B;IACzD,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAA;IACzB,MAAM,YAAY,GAAG,qBAAqB,CAAC,KAAK,CAAC,CAAA;IACjD,MAAM,WAAW,GAAG,0BAAkB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAA;IAE/D,MAAM,aAAa,GAAG,CAAC,IAAY,EAAS,EAAE;QAC1C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC/B,OAAO,KAAK,CAAA;IAChB,CAAC,CAAA;IACD,OAAO;QACH,aAAa;KAChB,CAAA;AACL,CAAC;AAZD,wCAYC"}
{"version":3,"file":"director.js","sourceRoot":"","sources":["../../../src/actor/director.ts"],"names":[],"mappings":";;;AAAA,mCAAmD;AAanD,8CAA8C;AAC9C,gDAAgD;AAChD,SAAS,qBAAqB,CAAC,KAA4B,EAAE,OAAwB;IACnF,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,OAA+B,EAAE,MAAc,EAAE,EAAE;QAC/F,MAAM,cAAc,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,MAAM,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC,OAAO,EAAE;YACZ,MAAM,UAAU,GAAmB;gBACjC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC;gBACzB,OAAO,EAAE;oBACP,SAAS,EAAE,cAAc,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,CAAC;oBACpD,OAAO;oBACP,MAAM;iBACP;aACF,CAAA;YACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;gBAClC,MAAM,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;gBAC/D,OAAO,OAAO,CAAA;YAChB,CAAC,CAAC,CAAA;YACF,OAAM;SACP;QACD,OAAO,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAA;IACtD,CAAC,CAAA;IACD,OAAO;QACL,GAAG,KAAK;QACR,WAAW;KACZ,CAAA;AACH,CAAC;AAED,SAAgB,cAAc,CAAC,OAA8B;IAC3D,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IACvC,MAAM,YAAY,GAAG,qBAAqB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;IAC1D,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACvB,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE;YAC5B,CAAC,CAAC,gBAAgB,CAAC,CAAC,GAAmB,EAAE,EAAE;gBACzC,YAAY,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YAC1F,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IACF,MAAM,WAAW,GAAG,0BAAkB,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAA;IAE/D,MAAM,aAAa,GAAG,CAAC,IAAY,EAAS,EAAE;QAC5C,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAC/B,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IACD,OAAO;QACL,aAAa;KACd,CAAA;AACH,CAAC;AAnBD,wCAmBC"}

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

{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../../src/actor/dispatch.ts"],"names":[],"mappings":";;;AAEA,oCAAuC;AAEhC,KAAK,UAAU,QAAQ,CAAC,QAAkB,EAAE,SAAiB,EAAE,OAA+B,EAAE,gBAAgB,GAAG,KAAK;IAC3H,MAAM,eAAe,GAAG,oBAAY,EAAE,CAAA;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;IACrD,IAAI,WAAyC,CAAA;IAC7C,IAAI,gBAAgB,EAAE;QAClB,WAAW,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAChC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YACpB,CAAC,CAAC,CAAA;QACN,CAAC,CAAC,CAAA;KACL;IAED,MAAM,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAE3C,OAAO,WAAW,CAAA;AACtB,CAAC;AAfD,4BAeC"}
{"version":3,"file":"dispatch.js","sourceRoot":"","sources":["../../../src/actor/dispatch.ts"],"names":[],"mappings":";;;AAEA,oCAAuC;AAEhC,KAAK,UAAU,QAAQ,CAAC,QAAkB,EAAE,SAAiB,EAAE,OAA+B,EAAE,gBAAgB,GAAG,KAAK;IAC7H,MAAM,eAAe,GAAG,oBAAY,EAAE,CAAA;IACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,eAAe,CAAC,CAAA;IACrD,IAAI,WAAyC,CAAA;IAC7C,IAAI,gBAAgB,EAAE;QACpB,WAAW,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAClC,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE;gBACvB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YAClB,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;KACH;IAED,MAAM,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;IAG3C,OAAO,WAAW,CAAA;AACpB,CAAC;AAhBD,4BAgBC"}

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

{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/actor/store.ts"],"names":[],"mappings":";;;AAaA,SAAgB,WAAW;IACvB,IAAI,QAAQ,GAAc,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAwB,EAAE,CAAA;IAGzC,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,WAAW,GAAG,KAAK,EAAE,EAAE;QACjE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YACzC,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,GAAG,CAAA;QACzD,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,WAAW,EAAE;YACd,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBAC3B,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,GAAG,CAAC,CAAA;YAC5D,CAAC,CAAC,CAAA;SACL;QACD,OAAO,gBAAgB,CAAA;IAC3B,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,OAA+B,EAAE,MAAc,EAAE,EAAE;QAC7F,QAAQ,CAAC,IAAI,CAAC;YACV,SAAS;YACT,OAAO;YACP,MAAM;SACT,CAAC,CAAA;QACF,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE;YACtB,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;SACtC;IACL,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAE,QAAkC,EAAE,EAAE;QACxE,IAAI,OAAO,GAAG,CAAC,CAAC,CAAA;QAChB,MAAM,EAAE,GAAG,KAAK,IAAI,EAAE;YAClB,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAA;YACzC,IAAI,IAAI,CAAC,MAAM,EAAE;gBACb,QAAQ,CAAC,IAAI,CAAC,CAAA;aACjB;YAED,+BAA+B;QACnC,CAAC,CAAA;QACD,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,CAAA;QACzB,+BAA+B;QAC/B,OAAO,GAAG,EAAE;YACR,6BAA6B;YAC7B,OAAO,SAAS,CAAC,SAAS,CAAC,CAAA;QAC/B,CAAC,CAAA;IACL,CAAC,CAAA;IAED,OAAO;QACH,WAAW;QACX,WAAW;QACX,SAAS;KACZ,CAAA;AACL,CAAC;AAnDD,kCAmDC"}
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/actor/store.ts"],"names":[],"mappings":";;;AAaA,SAAgB,WAAW;IACzB,IAAI,QAAQ,GAAc,EAAE,CAAA;IAC5B,MAAM,SAAS,GAAwB,EAAE,CAAA;IAGzC,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,WAAW,GAAG,KAAK,EAAE,EAAE;QACnE,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;YAC3C,OAAO,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,GAAG,CAAA;QACvD,CAAC,CAAC,CAAA;QACF,IAAI,CAAC,WAAW,EAAE;YAChB,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBAC7B,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,IAAI,SAAS,KAAK,GAAG,CAAC,CAAA;YAC1D,CAAC,CAAC,CAAA;SACH;QACD,OAAO,gBAAgB,CAAA;IACzB,CAAC,CAAA;IAED,MAAM,WAAW,GAAG,KAAK,EAAE,SAAiB,EAAE,OAA+B,EAAE,MAAc,EAAE,EAAE;QAC/F,QAAQ,CAAC,IAAI,CAAC;YACZ,SAAS;YACT,OAAO;YACP,MAAM;SACP,CAAC,CAAA;QACF,IAAI,SAAS,CAAC,SAAS,CAAC,EAAE;YACxB,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAA;SACpC;IACH,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,SAAiB,EAAE,QAAkC,EAAE,EAAE;QAC1E,IAAI,OAAO,GAAG,CAAC,CAAC,CAAA;QAChB,MAAM,EAAE,GAAG,KAAK,IAAI,EAAE;YACpB,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,SAAS,CAAC,CAAA;YACzC,IAAI,IAAI,CAAC,MAAM,EAAE;gBACf,QAAQ,CAAC,IAAI,CAAC,CAAA;aACf;YAED,+BAA+B;QACjC,CAAC,CAAA;QACD,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,CAAA;QACzB,+BAA+B;QAC/B,OAAO,GAAG,EAAE;YACV,6BAA6B;YAC7B,OAAO,SAAS,CAAC,SAAS,CAAC,CAAA;QAC7B,CAAC,CAAA;IACH,CAAC,CAAA;IAED,OAAO;QACL,WAAW;QACX,WAAW;QACX,SAAS;KACV,CAAA;AACH,CAAC;AAnDD,kCAmDC"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createStore = exports.dispatch = exports.createDirector = void 0;
exports.createRouter = exports.createNetworkInterface = exports.createStore = exports.dispatch = exports.createDirector = void 0;
const actor_1 = require("./actor");

@@ -8,2 +8,5 @@ Object.defineProperty(exports, "createDirector", { enumerable: true, get: function () { return actor_1.createDirector; } });

Object.defineProperty(exports, "createStore", { enumerable: true, get: function () { return actor_1.createStore; } });
const network_1 = require("./network");
Object.defineProperty(exports, "createNetworkInterface", { enumerable: true, get: function () { return network_1.createNetworkInterface; } });
Object.defineProperty(exports, "createRouter", { enumerable: true, get: function () { return network_1.createRouter; } });
//# sourceMappingURL=index.js.map

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

{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkF;AAEzE,+FAFA,sBAAc,OAEA;AAAE,yFAFA,gBAAQ,OAEA;AAAqB,4FAFA,mBAAW,OAEA"}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkF;AAGzE,+FAHA,sBAAc,OAGA;AAAE,yFAHA,gBAAQ,OAGA;AAAqB,4FAHA,mBAAW,OAGA;AAFjE,uCAAiH;AAE9C,uGAF1D,gCAAsB,OAE0D;AAAE,6FAF1D,sBAAY,OAE0D"}
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createRouter = exports.createNetworkInterface = void 0;
const createNetworkInterface = () => {
const callbacks = [];
let localCallback = () => { };
return {
sendLocal: (msg) => {
localCallback(msg);
},
sendOutbound: (msg) => {
callbacks.forEach(cb => {
cb(msg);
});
},
handleLocalIncomingMessages: (cb) => {
callbacks.push(cb);
},
setLocalCallback: (cb) => {
localCallback = cb;
}
};
};
exports.createNetworkInterface = createNetworkInterface;
const createRouter = (args) => {
const interfaces = [];
Object.keys(args.domains).forEach(key => {
const i = args.domains[key];
// prevent duplication
if (interfaces.indexOf(i) === -1) {
interfaces.push(i);
}
});
const handleIncomingMessage = (msg, store) => {
if (msg.domain === args.ownDomain) {
store.pushMessage(msg.payload.recipient, msg.payload.payload, msg.payload.sender);
return true;
}
if (!args.domains[msg.domain]) {
return false;
}
const senderParts = msg.payload.sender.split('.');
const isLocalSender = senderParts.length === 1;
let sender = msg.payload.sender;
if (isLocalSender) {
sender = `${args.ownDomain}.${sender}`;
}
args.domains[msg.domain].sendOutbound({
...msg,
payload: {
...msg.payload,
sender,
}
});
return true;
};
return {
handleIncomingMessage,
interfaces,
ownDomain: args.ownDomain,
};
};
exports.createRouter = createRouter;
//# sourceMappingURL=index.js.map

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

{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":""}
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/network/index.ts"],"names":[],"mappings":";;;AAoBO,MAAM,sBAAsB,GAAG,GAAqB,EAAE;IAC3D,MAAM,SAAS,GAAU,EAAE,CAAA;IAC3B,IAAI,aAAa,GAAkC,GAAG,EAAE,GAAG,CAAC,CAAA;IAC5D,OAAO;QACL,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YACjB,aAAa,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC;QACD,YAAY,EAAE,CAAC,GAAG,EAAE,EAAE;YACpB,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBACrB,EAAE,CAAC,GAAG,CAAC,CAAA;YACT,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,2BAA2B,EAAE,CAAC,EAAE,EAAE,EAAE;YAClC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACpB,CAAC;QACD,gBAAgB,EAAE,CAAC,EAAE,EAAE,EAAE;YACvB,aAAa,GAAG,EAAE,CAAA;QACpB,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAnBY,QAAA,sBAAsB,0BAmBlC;AAQM,MAAM,YAAY,GAAG,CAAC,IAAsB,EAAiB,EAAE;IACpE,MAAM,UAAU,GAAuB,EAAE,CAAA;IACzC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;QACtC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;QAC3B,sBAAsB;QACtB,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE;YAChC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;SACnB;IAEH,CAAC,CAAC,CAAA;IACF,MAAM,qBAAqB,GAAG,CAAC,GAAmB,EAAE,KAA4B,EAAW,EAAE;QAC3F,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI,CAAC,SAAS,EAAE;YACjC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;YACjF,OAAO,IAAI,CAAA;SACZ;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE;YAC7B,OAAO,KAAK,CAAC;SACd;QACD,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QACjD,MAAM,aAAa,GAAG,WAAW,CAAC,MAAM,KAAK,CAAC,CAAC;QAC/C,IAAI,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAA;QAC/B,IAAI,aAAa,EAAE;YACjB,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,IAAI,MAAM,EAAE,CAAA;SACvC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,YAAY,CAAC;YACpC,GAAG,GAAG;YACN,OAAO,EAAE;gBACP,GAAG,GAAG,CAAC,OAAO;gBACd,MAAM;aACP;SACF,CAAC,CAAA;QACF,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IAED,OAAO;QACL,qBAAqB;QACrB,UAAU;QACV,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAA;AACH,CAAC,CAAA;AAvCY,QAAA,YAAY,gBAuCxB"}
import { Actor } from './actor';
import { WatchableMessageStore } from './store';
import { NetworkRouter } from '../network';
export interface Director {

@@ -8,4 +9,5 @@ registerActor: (name: string) => Actor;

store: WatchableMessageStore;
routers?: NetworkRouter[];
}
export declare function createDirector(options: CreateDirectorOptions): Director;
export {};
import { createDirector, dispatch, Director, Message, createStore } from './actor';
export { createDirector, dispatch, Director, Message, createStore };
import { createNetworkInterface, createRouter, NetworkInterface, NetworkMessage, NetworkRouter } from './network';
export { createDirector, dispatch, Director, Message, createStore, createNetworkInterface, createRouter, NetworkInterface, NetworkMessage, NetworkRouter };

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

interface NetworkMessage {
import { Message, WatchableMessageStore } from '../actor/store';
export interface NetworkMessage {
domain: string;
payload: Message;
}
interface NetworkInterface {
export interface NetworkInterface {
sendLocal: (msg: NetworkMessage) => void;
sendOutbound: (msg: NetworkMessage) => void;
handleLocalIncomingMessages: (cb: (msg: NetworkMessage) => void) => void;
setLocalCallback: (cb: (msg: NetworkMessage) => void) => void;
}
export interface NetworkRouter {
handleIncomingMessage: (msg: NetworkMessage, store: WatchableMessageStore) => boolean;
interfaces: NetworkInterface[];
ownDomain: string;
}
export declare const createNetworkInterface: () => NetworkInterface;
interface CreateRouterArgs {
ownDomain: string;
domains: Record<string, NetworkInterface>;
}
export declare const createRouter: (args: CreateRouterArgs) => NetworkRouter;
export {};
{
"name": "@actorize/core",
"version": "0.0.1",
"version": "0.0.2",
"description": "",

@@ -5,0 +5,0 @@ "main": "dist/lib/index.js",

import { Actor, createActorFactory } from './actor'
import { WatchableMessageStore, PossibleMessagePayload } from './store'
import { NetworkMessage, NetworkRouter } from '../network'
export interface Director {
registerActor: (name: string) => Actor
registerActor: (name: string) => Actor
}
interface CreateDirectorOptions {
store: WatchableMessageStore,
store: WatchableMessageStore,
routers?: NetworkRouter[]
}

@@ -14,29 +16,48 @@

// TODO: patch those plugins and routers in here
function patchStoreWithPlugins(store: WatchableMessageStore): WatchableMessageStore {
const pushMessage = async (recipient: string, payload: PossibleMessagePayload, sender: string) => {
const recipientParts = recipient.split('.')
const isLocal = recipientParts.length === 1
if (!isLocal) {
return
}
return store.pushMessage(recipient, payload, sender)
function patchStoreWithPlugins(store: WatchableMessageStore, routers: NetworkRouter[]): WatchableMessageStore {
const pushMessage = async (recipient: string, payload: PossibleMessagePayload, sender: string) => {
const recipientParts = recipient.split('.')
const isLocal = recipientParts.length === 1;
if (!isLocal) {
const networkmsg: NetworkMessage = {
domain: recipientParts[0],
payload: {
recipient: recipientParts[recipientParts.length - 1],
payload,
sender,
},
}
const found = routers.find(router => {
const success = router.handleIncomingMessage(networkmsg, store)
return success
})
return
}
return {
...store,
pushMessage,
}
return store.pushMessage(recipient, payload, sender)
}
return {
...store,
pushMessage,
}
}
export function createDirector(options: CreateDirectorOptions): Director {
const { store } = options
const patchedStore = patchStoreWithPlugins(store)
const createActor = createActorFactory({ store: patchedStore })
const { store, routers = [] } = options
const patchedStore = patchStoreWithPlugins(store, routers)
routers.forEach(router => {
router.interfaces.forEach(i => {
i.setLocalCallback((msg: NetworkMessage) => {
patchedStore.pushMessage(msg.payload.recipient, msg.payload.payload, msg.payload.sender)
})
})
})
const createActor = createActorFactory({ store: patchedStore })
const registerActor = (name: string): Actor => {
const actor = createActor(name)
return actor
}
return {
registerActor
}
}
const registerActor = (name: string): Actor => {
const actor = createActor(name)
return actor
}
return {
registerActor
}
}

@@ -6,16 +6,17 @@ import { PossibleMessagePayload, Message } from './store'

export async function dispatch(director: Director, recipient: string, payload: PossibleMessagePayload, waitTillResponse = false) {
const randomActorName = randomstring()
const actor = director.registerActor(randomActorName)
let returnValue: undefined | Promise<Message>
if (waitTillResponse) {
returnValue = new Promise(resolve => {
actor.onMessage((msgs) => {
resolve(msgs[0])
})
})
}
const randomActorName = randomstring()
const actor = director.registerActor(randomActorName)
let returnValue: undefined | Promise<Message>
if (waitTillResponse) {
returnValue = new Promise(resolve => {
actor.onMessage((msgs) => {
resolve(msgs[0])
})
})
}
await actor.sendMessage(recipient, payload)
await actor.sendMessage(recipient, payload)
return returnValue
}
return returnValue
}
export type PossibleMessagePayload = string | number | Record<string, any> | (string | number | Record<string, any>)[]
export interface Message {
recipient: string;
payload: PossibleMessagePayload;
sender: string;
recipient: string;
payload: PossibleMessagePayload;
sender: string;
}
export interface WatchableMessageStore {
popMessages: (recipient: string, keepMessage?: boolean) => Promise<Message[]>
pushMessage: (recipient: string, payload: PossibleMessagePayload, sender: string) => Promise<void>
subscribe: (recipient: string, callback: (msg: Message[]) => void) => () => void
popMessages: (recipient: string, keepMessage?: boolean) => Promise<Message[]>
pushMessage: (recipient: string, payload: PossibleMessagePayload, sender: string) => Promise<void>
subscribe: (recipient: string, callback: (msg: Message[]) => void) => () => void
}
export function createStore() {
let messages: Message[] = []
const callbacks: Record<string, any> = {}
let messages: Message[] = []
const callbacks: Record<string, any> = {}
const popMessages = async (recipient: string, keepMessage = false) => {
const relevantMessages = messages.filter(e => {
return e.recipient === recipient || recipient === '*'
})
if (!keepMessage) {
messages = messages.filter(e => {
return !(e.recipient === recipient || recipient === '*')
})
}
return relevantMessages
const popMessages = async (recipient: string, keepMessage = false) => {
const relevantMessages = messages.filter(e => {
return e.recipient === recipient || recipient === '*'
})
if (!keepMessage) {
messages = messages.filter(e => {
return !(e.recipient === recipient || recipient === '*')
})
}
return relevantMessages
}
const pushMessage = async (recipient: string, payload: PossibleMessagePayload, sender: string) => {
messages.push({
recipient,
payload,
sender,
})
if (callbacks[recipient]) {
setTimeout(callbacks[recipient], 0)
}
const pushMessage = async (recipient: string, payload: PossibleMessagePayload, sender: string) => {
messages.push({
recipient,
payload,
sender,
})
if (callbacks[recipient]) {
setTimeout(callbacks[recipient], 0)
}
}
const subscribe = (recipient: string, callback: (msg: Message[]) => void) => {
let timeout = -1
const cb = async () => {
const msgs = await popMessages(recipient)
if (msgs.length) {
callback(msgs)
}
const subscribe = (recipient: string, callback: (msg: Message[]) => void) => {
let timeout = -1
const cb = async () => {
const msgs = await popMessages(recipient)
if (msgs.length) {
callback(msgs)
}
// timeout = setTimeout(cb, 50)
}
callbacks[recipient] = cb
// timeout = setTimeout(cb, 50)
return () => {
// self.clearTimeout(timeout)
delete callbacks[recipient]
}
// timeout = setTimeout(cb, 50)
}
callbacks[recipient] = cb
// timeout = setTimeout(cb, 50)
return () => {
// self.clearTimeout(timeout)
delete callbacks[recipient]
}
}
return {
pushMessage,
popMessages,
subscribe,
}
}
return {
pushMessage,
popMessages,
subscribe,
}
}
import { createDirector, dispatch, Director, Message, createStore } from './actor'
import { createNetworkInterface, createRouter, NetworkInterface, NetworkMessage, NetworkRouter } from './network'
export { createDirector, dispatch, Director, Message, createStore }
export { createDirector, dispatch, Director, Message, createStore, createNetworkInterface, createRouter, NetworkInterface, NetworkMessage, NetworkRouter }

@@ -1,7 +0,88 @@

interface NetworkMessage {
import { Message, WatchableMessageStore } from '../actor/store'
export interface NetworkMessage {
domain: string;
payload: Message;
}
interface NetworkInterface {
export interface NetworkInterface {
sendLocal: (msg: NetworkMessage) => void;
sendOutbound: (msg: NetworkMessage) => void;
handleLocalIncomingMessages: (cb: (msg: NetworkMessage) => void) => void;
setLocalCallback: (cb: (msg: NetworkMessage) => void) => void;
}
}
export interface NetworkRouter {
handleIncomingMessage: (msg: NetworkMessage, store: WatchableMessageStore) => boolean;
interfaces: NetworkInterface[];
ownDomain: string;
}
export const createNetworkInterface = (): NetworkInterface => {
const callbacks: any[] = []
let localCallback: (msg: NetworkMessage) => void = () => { }
return {
sendLocal: (msg) => {
localCallback(msg)
},
sendOutbound: (msg) => {
callbacks.forEach(cb => {
cb(msg)
})
},
handleLocalIncomingMessages: (cb) => {
callbacks.push(cb)
},
setLocalCallback: (cb) => {
localCallback = cb
}
}
}
interface CreateRouterArgs {
ownDomain: string;
domains: Record<string, NetworkInterface>
}
export const createRouter = (args: CreateRouterArgs): NetworkRouter => {
const interfaces: NetworkInterface[] = []
Object.keys(args.domains).forEach(key => {
const i = args.domains[key]
// prevent duplication
if (interfaces.indexOf(i) === -1) {
interfaces.push(i)
}
})
const handleIncomingMessage = (msg: NetworkMessage, store: WatchableMessageStore): boolean => {
if (msg.domain === args.ownDomain) {
store.pushMessage(msg.payload.recipient, msg.payload.payload, msg.payload.sender)
return true
}
if (!args.domains[msg.domain]) {
return false;
}
const senderParts = msg.payload.sender.split('.')
const isLocalSender = senderParts.length === 1;
let sender = msg.payload.sender
if (isLocalSender) {
sender = `${args.ownDomain}.${sender}`
}
args.domains[msg.domain].sendOutbound({
...msg,
payload: {
...msg.payload,
sender,
}
})
return true
}
return {
handleIncomingMessage,
interfaces,
ownDomain: args.ownDomain,
}
}