@actorize/core
Advanced tools
| 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) | ||
| }) | ||
| }) |
@@ -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 +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 {}; |
+1
-1
| { | ||
| "name": "@actorize/core", | ||
| "version": "0.0.1", | ||
| "version": "0.0.2", | ||
| "description": "", | ||
@@ -5,0 +5,0 @@ "main": "dist/lib/index.js", |
+46
-25
| 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 | ||
| } | ||
| } |
+14
-13
@@ -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 | ||
| } |
+48
-48
| 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, | ||
| } | ||
| } |
+2
-1
| 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 } |
+84
-3
@@ -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, | ||
| } | ||
| } | ||
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
38312
55.52%41
5.13%835
70.41%1
Infinity%