@toa.io/core 1.0.0-alpha.30 → 1.0.0-alpha.300
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +28 -12
- package/transpiled/abandon.d.ts +9 -0
- package/transpiled/abandon.js +37 -0
- package/transpiled/abandon.js.map +1 -0
- package/transpiled/assignment.d.ts +6 -0
- package/transpiled/assignment.js +25 -0
- package/transpiled/assignment.js.map +1 -0
- package/transpiled/call.d.ts +10 -0
- package/transpiled/call.js +146 -0
- package/transpiled/call.js.map +1 -0
- package/transpiled/cascade.d.ts +7 -0
- package/transpiled/cascade.js +28 -0
- package/transpiled/cascade.js.map +1 -0
- package/transpiled/component.d.ts +15 -0
- package/transpiled/component.js +93 -0
- package/transpiled/component.js.map +1 -0
- package/transpiled/composition.d.ts +6 -0
- package/transpiled/composition.js +23 -0
- package/transpiled/composition.js.map +1 -0
- package/transpiled/connector.d.ts +54 -0
- package/transpiled/connector.js +193 -0
- package/transpiled/connector.js.map +1 -0
- package/transpiled/context.d.ts +25 -0
- package/transpiled/context.js +55 -0
- package/transpiled/context.js.map +1 -0
- package/transpiled/contract/contract.d.ts +10 -0
- package/transpiled/contract/contract.js +14 -0
- package/transpiled/contract/contract.js.map +1 -0
- package/transpiled/contract/index.d.ts +2 -0
- package/transpiled/contract/index.js +3 -0
- package/transpiled/contract/index.js.map +1 -0
- package/transpiled/contract/reply.d.ts +7 -0
- package/transpiled/contract/reply.js +48 -0
- package/transpiled/contract/reply.js.map +1 -0
- package/transpiled/contract/request.d.ts +39 -0
- package/transpiled/contract/request.js +111 -0
- package/transpiled/contract/request.js.map +1 -0
- package/transpiled/contract/schemas.d.ts +4 -0
- package/transpiled/contract/schemas.js +36 -0
- package/transpiled/contract/schemas.js.map +1 -0
- package/transpiled/discovery.d.ts +19 -0
- package/transpiled/discovery.js +52 -0
- package/transpiled/discovery.js.map +1 -0
- package/transpiled/effect.d.ts +5 -0
- package/transpiled/effect.js +11 -0
- package/transpiled/effect.js.map +1 -0
- package/transpiled/emission.d.ts +10 -0
- package/transpiled/emission.js +16 -0
- package/transpiled/emission.js.map +1 -0
- package/transpiled/entities/changeset.d.ts +10 -0
- package/transpiled/entities/changeset.js +27 -0
- package/transpiled/entities/changeset.js.map +1 -0
- package/transpiled/entities/entity.d.ts +19 -0
- package/transpiled/entities/entity.js +137 -0
- package/transpiled/entities/entity.js.map +1 -0
- package/transpiled/entities/factory.d.ts +27 -0
- package/transpiled/entities/factory.js +38 -0
- package/transpiled/entities/factory.js.map +1 -0
- package/transpiled/entities/index.d.ts +5 -0
- package/transpiled/entities/index.js +6 -0
- package/transpiled/entities/index.js.map +1 -0
- package/transpiled/entities/newid.d.ts +10 -0
- package/transpiled/entities/newid.js +35 -0
- package/transpiled/entities/newid.js.map +1 -0
- package/transpiled/entities/set.d.ts +10 -0
- package/transpiled/entities/set.js +19 -0
- package/transpiled/entities/set.js.map +1 -0
- package/transpiled/event.d.ts +14 -0
- package/transpiled/event.js +51 -0
- package/transpiled/event.js.map +1 -0
- package/transpiled/exceptions.d.ts +89 -0
- package/transpiled/exceptions.js +180 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/exposition.d.ts +18 -0
- package/transpiled/exposition.js +18 -0
- package/transpiled/exposition.js.map +1 -0
- package/transpiled/guard.d.ts +7 -0
- package/transpiled/guard.js +12 -0
- package/transpiled/guard.js.map +1 -0
- package/transpiled/index.d.ts +37 -0
- package/transpiled/index.js +31 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/instance.d.ts +10 -0
- package/transpiled/instance.js +30 -0
- package/transpiled/instance.js.map +1 -0
- package/transpiled/locator.d.ts +12 -0
- package/transpiled/locator.js +32 -0
- package/transpiled/locator.js.map +1 -0
- package/transpiled/observation.d.ts +5 -0
- package/transpiled/observation.js +12 -0
- package/transpiled/observation.js.map +1 -0
- package/transpiled/operation.d.ts +67 -0
- package/transpiled/operation.js +127 -0
- package/transpiled/operation.js.map +1 -0
- package/transpiled/outbox.d.ts +45 -0
- package/transpiled/outbox.js +430 -0
- package/transpiled/outbox.js.map +1 -0
- package/transpiled/query/criteria.d.ts +6 -0
- package/transpiled/query/criteria.js +74 -0
- package/transpiled/query/criteria.js.map +1 -0
- package/transpiled/query/options.d.ts +3 -0
- package/transpiled/query/options.js +27 -0
- package/transpiled/query/options.js.map +1 -0
- package/transpiled/query.d.ts +9 -0
- package/transpiled/query.js +57 -0
- package/transpiled/query.js.map +1 -0
- package/transpiled/receiver.d.ts +20 -0
- package/transpiled/receiver.js +113 -0
- package/transpiled/receiver.js.map +1 -0
- package/transpiled/reflection.d.ts +9 -0
- package/transpiled/reflection.js +13 -0
- package/transpiled/reflection.js.map +1 -0
- package/transpiled/remote.d.ts +10 -0
- package/transpiled/remote.js +11 -0
- package/transpiled/remote.js.map +1 -0
- package/transpiled/state.d.ts +36 -0
- package/transpiled/state.js +131 -0
- package/transpiled/state.js.map +1 -0
- package/transpiled/trail.d.ts +71 -0
- package/transpiled/trail.js +110 -0
- package/transpiled/trail.js.map +1 -0
- package/transpiled/transition.d.ts +14 -0
- package/transpiled/transition.js +51 -0
- package/transpiled/transition.js.map +1 -0
- package/transpiled/transmission.d.ts +8 -0
- package/transpiled/transmission.js +30 -0
- package/transpiled/transmission.js.map +1 -0
- package/transpiled/types/atomicity.d.ts +56 -0
- package/transpiled/types/atomicity.js +2 -0
- package/transpiled/types/atomicity.js.map +1 -0
- package/transpiled/types/bindings.d.ts +77 -0
- package/transpiled/types/bindings.js +2 -0
- package/transpiled/types/bindings.js.map +1 -0
- package/transpiled/types/bridges.d.ts +38 -0
- package/transpiled/types/bridges.js +2 -0
- package/transpiled/types/bridges.js.map +1 -0
- package/transpiled/types/extensions.d.ts +92 -0
- package/transpiled/types/extensions.js +2 -0
- package/transpiled/types/extensions.js.map +1 -0
- package/transpiled/types/inbox.d.ts +22 -0
- package/transpiled/types/inbox.js +2 -0
- package/transpiled/types/inbox.js.map +1 -0
- package/transpiled/types/index.d.ts +14 -0
- package/transpiled/types/index.js +9 -0
- package/transpiled/types/index.js.map +1 -0
- package/transpiled/types/message.d.ts +16 -0
- package/transpiled/types/message.js +2 -0
- package/transpiled/types/message.js.map +1 -0
- package/transpiled/types/operations.d.ts +15 -0
- package/transpiled/types/operations.js +2 -0
- package/transpiled/types/operations.js.map +1 -0
- package/transpiled/types/outbox.d.ts +54 -0
- package/transpiled/types/outbox.js +2 -0
- package/transpiled/types/outbox.js.map +1 -0
- package/transpiled/types/receiver.d.ts +9 -0
- package/transpiled/types/receiver.js +2 -0
- package/transpiled/types/receiver.js.map +1 -0
- package/transpiled/types/request.d.ts +103 -0
- package/transpiled/types/request.js +2 -0
- package/transpiled/types/request.js.map +1 -0
- package/transpiled/types/state.d.ts +9 -0
- package/transpiled/types/state.js +2 -0
- package/transpiled/types/state.js.map +1 -0
- package/transpiled/types/storages.d.ts +146 -0
- package/transpiled/types/storages.js +2 -0
- package/transpiled/types/storages.js.map +1 -0
- package/transpiled/unmanaged.d.ts +5 -0
- package/transpiled/unmanaged.js +7 -0
- package/transpiled/unmanaged.js.map +1 -0
- package/src/assignment.js +0 -31
- package/src/call.js +0 -42
- package/src/cascade.js +0 -35
- package/src/component.js +0 -41
- package/src/composition.js +0 -25
- package/src/connector.js +0 -183
- package/src/context.js +0 -55
- package/src/contract/conditions.js +0 -21
- package/src/contract/index.js +0 -7
- package/src/contract/reply.js +0 -25
- package/src/contract/request.js +0 -67
- package/src/contract/schemas/error.yaml +0 -9
- package/src/contract/schemas/index.js +0 -7
- package/src/contract/schemas/query.yaml +0 -30
- package/src/discovery.js +0 -44
- package/src/emission.js +0 -23
- package/src/entities/changeset.js +0 -38
- package/src/entities/entity.js +0 -74
- package/src/entities/factory.js +0 -33
- package/src/entities/index.js +0 -5
- package/src/entities/set.js +0 -15
- package/src/event.js +0 -40
- package/src/exceptions.js +0 -100
- package/src/exposition.js +0 -27
- package/src/index.js +0 -47
- package/src/locator.js +0 -54
- package/src/observation.js +0 -20
- package/src/operation.js +0 -69
- package/src/query/criteria.js +0 -41
- package/src/query/options.js +0 -40
- package/src/query.js +0 -41
- package/src/receiver.js +0 -65
- package/src/reflection.js +0 -28
- package/src/remote.js +0 -17
- package/src/state.js +0 -99
- package/src/transition.js +0 -67
- package/src/transmission.js +0 -33
- package/test/call.fixtures.js +0 -27
- package/test/call.test.js +0 -46
- package/test/component.fixtures.js +0 -21
- package/test/component.test.js +0 -40
- package/test/connector.fixtures.js +0 -40
- package/test/connector.test.js +0 -176
- package/test/context.fixtures.js +0 -18
- package/test/context.test.js +0 -29
- package/test/contract/conditions.test.js +0 -26
- package/test/contract/contract.fixtures.js +0 -33
- package/test/contract/request.test.js +0 -112
- package/test/emission.fixtures.js +0 -17
- package/test/emission.test.js +0 -35
- package/test/entities/entity.fixtures.js +0 -29
- package/test/entities/entity.test.js +0 -65
- package/test/entities/factory.fixtures.js +0 -18
- package/test/entities/factory.test.js +0 -48
- package/test/entities/set.fixtures.js +0 -11
- package/test/entities/set.test.js +0 -12
- package/test/event.fixtures.js +0 -29
- package/test/event.test.js +0 -118
- package/test/locator.test.js +0 -113
- package/test/query.fixtures.js +0 -100
- package/test/query.test.js +0 -86
- package/test/receiver.fixtures.js +0 -23
- package/test/receiver.test.js +0 -95
- package/test/reflection.test.js +0 -30
- package/test/state.fixtures.js +0 -47
- package/test/state.test.js +0 -46
- package/test/transmission.fixtures.js +0 -15
- package/test/transmission.test.js +0 -46
- package/types/bindings.d.ts +0 -40
- package/types/bridges.ts +0 -30
- package/types/component.d.ts +0 -9
- package/types/connector.d.ts +0 -18
- package/types/context.d.ts +0 -21
- package/types/entity.d.ts +0 -46
- package/types/event.d.ts +0 -11
- package/types/exception.d.ts +0 -4
- package/types/extensions.d.ts +0 -29
- package/types/index.ts +0 -14
- package/types/locator.d.ts +0 -13
- package/types/message.d.ts +0 -3
- package/types/operations.d.ts +0 -2
- package/types/query.d.ts +0 -15
- package/types/receiver.d.ts +0 -12
- package/types/reflection.d.ts +0 -14
- package/types/request.d.ts +0 -23
- package/types/state.d.ts +0 -35
- package/types/storages.d.ts +0 -71
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/core",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.300",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Toa Core",
|
|
5
6
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
7
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -11,23 +12,38 @@
|
|
|
11
12
|
"bugs": {
|
|
12
13
|
"url": "https://github.com/toa-io/toa/issues"
|
|
13
14
|
},
|
|
14
|
-
"main": "
|
|
15
|
-
"types": "
|
|
15
|
+
"main": "transpiled/index.js",
|
|
16
|
+
"types": "transpiled/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./transpiled/index.d.ts",
|
|
20
|
+
"default": "./transpiled/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./types": {
|
|
23
|
+
"types": "./transpiled/types/index.d.ts",
|
|
24
|
+
"default": "./transpiled/types/index.js"
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
16
28
|
"publishConfig": {
|
|
17
29
|
"access": "public"
|
|
18
30
|
},
|
|
31
|
+
"files": [
|
|
32
|
+
"transpiled",
|
|
33
|
+
"!**/tsconfig.tsbuildinfo",
|
|
34
|
+
"!**/*.test.*",
|
|
35
|
+
"!**/.env*"
|
|
36
|
+
],
|
|
19
37
|
"scripts": {
|
|
38
|
+
"transpile": "tsc",
|
|
20
39
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
21
40
|
},
|
|
22
41
|
"dependencies": {
|
|
23
|
-
"@rsql/parser": "1.
|
|
24
|
-
"@toa.io/
|
|
25
|
-
"@toa.io/
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
},
|
|
29
|
-
"devDependencies": {
|
|
30
|
-
"clone-deep": "4.0.1"
|
|
42
|
+
"@rsql/parser": "1.6.0",
|
|
43
|
+
"@toa.io/generic": "1.0.0-alpha.292",
|
|
44
|
+
"@toa.io/schemas": "1.0.0-alpha.299",
|
|
45
|
+
"openspan": "1.0.0-alpha.293",
|
|
46
|
+
"uuid": "14.0.2"
|
|
31
47
|
},
|
|
32
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "f91131a9aeb29aa271f177c4055ddcf0cda8c75e"
|
|
33
49
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Exception } from './exceptions.js';
|
|
2
|
+
/** What a caller that stopped waiting for `target` is told. */
|
|
3
|
+
export declare function abandoned(target: string, signal: AbortSignal): Exception;
|
|
4
|
+
/**
|
|
5
|
+
* What the promise settles with, or *abandoned* once the signal aborts, whichever comes first — at
|
|
6
|
+
* once where it has aborted already. The promise goes on running, and settles with nobody waiting
|
|
7
|
+
* for it.
|
|
8
|
+
*/
|
|
9
|
+
export declare function waiting<T>(promise: Promise<T>, signal: AbortSignal | undefined, target: string): Promise<T>;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { AbandonedException } from './exceptions.js';
|
|
2
|
+
/** What a caller that stopped waiting for `target` is told. */
|
|
3
|
+
export function abandoned(target, signal) {
|
|
4
|
+
return new AbandonedException(`'${target}' went unanswered`, signal.reason);
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* What the promise settles with, or *abandoned* once the signal aborts, whichever comes first — at
|
|
8
|
+
* once where it has aborted already. The promise goes on running, and settles with nobody waiting
|
|
9
|
+
* for it.
|
|
10
|
+
*/
|
|
11
|
+
export async function waiting(promise, signal, target) {
|
|
12
|
+
if (signal === undefined)
|
|
13
|
+
return await promise;
|
|
14
|
+
if (signal.aborted) {
|
|
15
|
+
promise.catch(noop);
|
|
16
|
+
throw abandoned(target, signal);
|
|
17
|
+
}
|
|
18
|
+
let abort = noop;
|
|
19
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
20
|
+
abort = () => reject(abandoned(target, signal));
|
|
21
|
+
});
|
|
22
|
+
signal.addEventListener('abort', abort, { once: true });
|
|
23
|
+
try {
|
|
24
|
+
return await Promise.race([promise, aborted]);
|
|
25
|
+
}
|
|
26
|
+
catch (exception) {
|
|
27
|
+
// however the wait ended — here, or in whatever was carrying it
|
|
28
|
+
if (signal.aborted)
|
|
29
|
+
throw abandoned(target, signal);
|
|
30
|
+
throw exception;
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
signal.removeEventListener('abort', abort);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function noop() { }
|
|
37
|
+
//# sourceMappingURL=abandon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abandon.js","sourceRoot":"","sources":["../source/abandon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGpD,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,MAAmB;IAC3D,OAAO,IAAI,kBAAkB,CAAC,IAAI,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;AAC7E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAmB,EACnB,MAA+B,EAC/B,MAAc;IAEd,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,OAAO,CAAA;IAE9C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEnB,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,KAAK,GAAe,IAAI,CAAA;IAE5B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QACtD,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAEvD,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/C,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,gEAAgE;QAChE,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAEnD,MAAM,SAAS,CAAA;IACjB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,IAAI,KAAU,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Operation } from './operation.js';
|
|
2
|
+
export class Assignment extends Operation {
|
|
3
|
+
async acquire(store) {
|
|
4
|
+
const changeset = this.scope.changeset(store.request.query);
|
|
5
|
+
store.scope = changeset;
|
|
6
|
+
store.state = changeset.get();
|
|
7
|
+
}
|
|
8
|
+
async commit(store) {
|
|
9
|
+
const { scope, state, reply, request } = store;
|
|
10
|
+
if (reply.error !== undefined)
|
|
11
|
+
return;
|
|
12
|
+
const changeset = scope;
|
|
13
|
+
changeset.set(state);
|
|
14
|
+
/*
|
|
15
|
+
* The call carries the reply as it stands, which is empty where the algorithm named no
|
|
16
|
+
* output — the storage fills it with the post-image it computes, because that is where the
|
|
17
|
+
* post-image is known.
|
|
18
|
+
*/
|
|
19
|
+
const output = await this.scope.apply(changeset, request.input, this.call(store));
|
|
20
|
+
// assignment returns new state by default
|
|
21
|
+
if (store.reply.output === undefined)
|
|
22
|
+
store.reply.output = output;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=assignment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"assignment.js","sourceRoot":"","sources":["../source/assignment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAI1C,MAAM,OAAO,UAAW,SAAQ,SAAS;IACpB,KAAK,CAAC,OAAO,CAAC,KAAY;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,KAAY,CAAC,CAAA;QAElE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAA;QACvB,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,CAAA;IAC/B,CAAC;IAEkB,KAAK,CAAC,MAAM,CAAC,KAAY;QAC1C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;QAE9C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,OAAM;QAErC,MAAM,SAAS,GAAG,KAAkB,CAAA;QAEpC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAEpB;;;;WAIG;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAEjF,0CAA0C;QAC1C,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAA;IACnE,CAAC;CACF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
import type { Transmission } from './transmission.js';
|
|
3
|
+
import type { Request as Contract } from './contract/request.js';
|
|
4
|
+
import type { Options, Request, Source } from './types/request.js';
|
|
5
|
+
export declare class Call extends Connector {
|
|
6
|
+
#private;
|
|
7
|
+
constructor(transmitter: Transmission, contract: Contract, target: string, source?: Source, stateful?: boolean);
|
|
8
|
+
invoke(request?: Request, options?: Options): Promise<any>;
|
|
9
|
+
explain(): any;
|
|
10
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { current, encode } from 'openspan';
|
|
3
|
+
import { Connector } from './connector.js';
|
|
4
|
+
import { derive, newid } from './entities/newid.js';
|
|
5
|
+
import { RequestContractException } from './exceptions.js';
|
|
6
|
+
import { abandoned, waiting } from './abandon.js';
|
|
7
|
+
import * as addressed from './instance.js';
|
|
8
|
+
import * as trail from './trail.js';
|
|
9
|
+
export class Call extends Connector {
|
|
10
|
+
#transmitter;
|
|
11
|
+
#contract;
|
|
12
|
+
/** what this calls, as a hop is named, so that an identity derived here names it too */
|
|
13
|
+
#target;
|
|
14
|
+
#source;
|
|
15
|
+
/** whether a call to it names the process it goes to */
|
|
16
|
+
#stateful;
|
|
17
|
+
// eslint-disable-next-line max-params
|
|
18
|
+
constructor(transmitter, contract, target, source, stateful = false) {
|
|
19
|
+
super();
|
|
20
|
+
this.#transmitter = transmitter;
|
|
21
|
+
this.#contract = contract;
|
|
22
|
+
this.#target = target;
|
|
23
|
+
this.#source = source;
|
|
24
|
+
this.#stateful = stateful;
|
|
25
|
+
this.depends(transmitter);
|
|
26
|
+
}
|
|
27
|
+
async invoke(request = {}, options = {}) {
|
|
28
|
+
const invocation = trail.current();
|
|
29
|
+
this.#refuse(request, options);
|
|
30
|
+
// the process a call goes to, which the transmission is handed beside what the call asks
|
|
31
|
+
const { instance, ...asked } = request;
|
|
32
|
+
/*
|
|
33
|
+
* The envelope is built around what the caller asked for rather than written over it: one
|
|
34
|
+
* request object is handed to several concurrent calls in more than one place, and those are
|
|
35
|
+
* different calls — sharing one identity would have all but the first refused as duplicates
|
|
36
|
+
* of it.
|
|
37
|
+
*/
|
|
38
|
+
const envelope = {
|
|
39
|
+
...asked,
|
|
40
|
+
// avoid validation on the recipient's side
|
|
41
|
+
authentic: true,
|
|
42
|
+
// an operation that takes no input still has to send an explicit null
|
|
43
|
+
input: request.input ?? null,
|
|
44
|
+
id: request.id ?? this.#identity(invocation),
|
|
45
|
+
/*
|
|
46
|
+
* What a receiver has already put on the request wins, and a service with no chain in
|
|
47
|
+
* scope starts one under its own name.
|
|
48
|
+
*/
|
|
49
|
+
trail: request.trail ?? invocation?.hops ?? service(this.#source),
|
|
50
|
+
// the caller may have attributed the call itself, as the node bridge does
|
|
51
|
+
source: request.source ?? this.#source
|
|
52
|
+
};
|
|
53
|
+
// nothing carries a key it has no value for onto the wire
|
|
54
|
+
if (envelope.source === undefined)
|
|
55
|
+
delete envelope.source;
|
|
56
|
+
if (envelope.trail === undefined)
|
|
57
|
+
delete envelope.trail;
|
|
58
|
+
this.#contract.fit(envelope);
|
|
59
|
+
const context = current();
|
|
60
|
+
if (context !== undefined)
|
|
61
|
+
envelope.telemetry = encode(context);
|
|
62
|
+
const reply = await this.#transmit(envelope, this.#terms(instance, options.timeout, options.signal));
|
|
63
|
+
if (reply === null)
|
|
64
|
+
return null;
|
|
65
|
+
else if (reply instanceof Readable)
|
|
66
|
+
return reply;
|
|
67
|
+
else {
|
|
68
|
+
if (reply.exception !== undefined)
|
|
69
|
+
throw reply.exception;
|
|
70
|
+
if (reply.error !== undefined)
|
|
71
|
+
return new RemoteError(reply.error);
|
|
72
|
+
else
|
|
73
|
+
return reply.output;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
explain() {
|
|
77
|
+
return this.#contract.discovery;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Derived where this process is serving a call, so that the same call served twice makes the
|
|
81
|
+
* same call here twice over and whatever it reaches refuses its own copy; minted where there
|
|
82
|
+
* is nothing to derive from, which is an entry point, or a caller from before identities.
|
|
83
|
+
*/
|
|
84
|
+
#identity(invocation) {
|
|
85
|
+
if (invocation?.id === undefined)
|
|
86
|
+
return newid();
|
|
87
|
+
return derive(invocation.id, this.#target, trail.ordinal(invocation, this.#target));
|
|
88
|
+
}
|
|
89
|
+
/** A call whose making contradicts what it calls is refused before anything is sent. */
|
|
90
|
+
#refuse(request, options) {
|
|
91
|
+
const { instance, task } = request;
|
|
92
|
+
const { timeout, signal } = options;
|
|
93
|
+
if (this.#stateful && instance === undefined)
|
|
94
|
+
throw new RequestContractException(`'${this.#target}' is stateful, and a call to it names \`instance\``);
|
|
95
|
+
if (!this.#stateful && instance !== undefined)
|
|
96
|
+
throw new RequestContractException(`'${this.#target}' is stateless, and a call to it names no \`instance\``);
|
|
97
|
+
// nobody waits for a task, and it is made from wherever the queue is consumed
|
|
98
|
+
if (task === true && (timeout !== undefined || signal !== undefined))
|
|
99
|
+
throw new RequestContractException('A task names no `timeout` and no `signal`');
|
|
100
|
+
if (timeout !== undefined && !(Number.isFinite(timeout) && timeout > 0))
|
|
101
|
+
throw new RequestContractException('`timeout` is a positive number of milliseconds');
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* What the transmission is handed beside the envelope. An addressed call always waits for a set
|
|
105
|
+
* time — its caller's, or the context's — because nothing else ends a call to a process that has
|
|
106
|
+
* gone; an ordinary call waits for one only where its caller set it.
|
|
107
|
+
*/
|
|
108
|
+
#terms(instance, timeout, signal) {
|
|
109
|
+
const deadline = timeout ?? (this.#stateful ? addressed.timeout() : undefined);
|
|
110
|
+
if (instance === undefined && deadline === undefined && signal === undefined)
|
|
111
|
+
return undefined;
|
|
112
|
+
const signals = [];
|
|
113
|
+
if (signal !== undefined)
|
|
114
|
+
signals.push(signal);
|
|
115
|
+
if (deadline !== undefined)
|
|
116
|
+
signals.push(AbortSignal.timeout(deadline));
|
|
117
|
+
const terms = {};
|
|
118
|
+
if (instance !== undefined)
|
|
119
|
+
terms.instance = instance;
|
|
120
|
+
if (deadline !== undefined)
|
|
121
|
+
terms.timeout = deadline;
|
|
122
|
+
if (signals.length > 0)
|
|
123
|
+
terms.signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
|
|
124
|
+
return terms;
|
|
125
|
+
}
|
|
126
|
+
/** The reply, or *abandoned* once the caller has stopped waiting, however the wait ended. */
|
|
127
|
+
async #transmit(envelope, terms) {
|
|
128
|
+
const signal = terms?.signal;
|
|
129
|
+
// a call its caller stopped waiting for before it was made is handed to no binding
|
|
130
|
+
if (signal?.aborted === true)
|
|
131
|
+
throw abandoned(this.#target, signal);
|
|
132
|
+
return await waiting(this.#transmitter.request(envelope, terms), signal, this.#target);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/** Where a service calls from no invocation, the chain starts under the service's own name. */
|
|
136
|
+
function service(source) {
|
|
137
|
+
return source !== undefined && 'service' in source ? [source.service] : undefined;
|
|
138
|
+
}
|
|
139
|
+
// the remote error as a value: every property it carries, and nothing else enumerable
|
|
140
|
+
class RemoteError extends Error {
|
|
141
|
+
constructor(error) {
|
|
142
|
+
super();
|
|
143
|
+
Object.assign(this, error);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=call.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call.js","sourceRoot":"","sources":["../source/call.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
import type { Algorithm } from './types/bridges.js';
|
|
3
|
+
export declare class Cascade extends Connector {
|
|
4
|
+
#private;
|
|
5
|
+
constructor(bridges: Algorithm[], preflight?: Connector);
|
|
6
|
+
run(...args: [any, any?]): Promise<any>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
export class Cascade extends Connector {
|
|
3
|
+
#last;
|
|
4
|
+
constructor(bridges, preflight) {
|
|
5
|
+
super();
|
|
6
|
+
// this.#bridges = bridges
|
|
7
|
+
this.#last = bridges[bridges.length - 1];
|
|
8
|
+
if (preflight === undefined)
|
|
9
|
+
this.depends(bridges);
|
|
10
|
+
else
|
|
11
|
+
this.depends(bridges).depends(preflight);
|
|
12
|
+
}
|
|
13
|
+
async run(...args) {
|
|
14
|
+
// const reply = {}
|
|
15
|
+
//
|
|
16
|
+
// for (const bridge of this.#bridges) {
|
|
17
|
+
// const partial = await bridge.execute(...args)
|
|
18
|
+
//
|
|
19
|
+
// if (partial.error) return { error: partial.error }
|
|
20
|
+
//
|
|
21
|
+
// merge(reply, partial)
|
|
22
|
+
// }
|
|
23
|
+
//
|
|
24
|
+
// return reply
|
|
25
|
+
return this.#last.execute(...args);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=cascade.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cascade.js","sourceRoot":"","sources":["../source/cascade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,MAAM,OAAO,OAAQ,SAAQ,SAAS;IAC3B,KAAK,CAAW;IAEzB,YAAmB,OAAoB,EAAE,SAAqB;QAC5D,KAAK,EAAE,CAAA;QAEP,0BAA0B;QAC1B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAExC,IAAI,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;;YAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/C,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAG,IAAiB;QACnC,mBAAmB;QACnB,EAAE;QACF,wCAAwC;QACxC,kDAAkD;QAClD,EAAE;QACF,uDAAuD;QACvD,EAAE;QACF,0BAA0B;QAC1B,IAAI;QACJ,EAAE;QACF,eAAe;QAEf,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;IACpC,CAAC;CACF"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
import type { Locator } from './locator.js';
|
|
3
|
+
import type { Envelope, Options, Request } from './types/request.js';
|
|
4
|
+
/** What a component holds one of per endpoint: an operation, or the call that stands for it. */
|
|
5
|
+
export interface Invocable extends Connector {
|
|
6
|
+
invoke: (request: Envelope, options?: Options) => Promise<any>;
|
|
7
|
+
}
|
|
8
|
+
export declare class Component<O extends Invocable = Invocable> extends Connector {
|
|
9
|
+
#private;
|
|
10
|
+
readonly locator: Locator;
|
|
11
|
+
protected readonly operations: Record<string, O>;
|
|
12
|
+
protected kind: 'server' | 'client';
|
|
13
|
+
constructor(locator: Locator, operations: Record<string, O>);
|
|
14
|
+
invoke<T = any>(endpoint: string, request?: Request, options?: Options): Promise<T>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { console, current, decode, run } from 'openspan';
|
|
2
|
+
import { Connector } from './connector.js';
|
|
3
|
+
import { EndpointException } from './exceptions.js';
|
|
4
|
+
import * as trail from './trail.js';
|
|
5
|
+
export class Component extends Connector {
|
|
6
|
+
locator;
|
|
7
|
+
operations;
|
|
8
|
+
kind = 'server';
|
|
9
|
+
/** span options per endpoint */
|
|
10
|
+
#spans = {};
|
|
11
|
+
/** what refuses a call that has been here already, as the environment states it */
|
|
12
|
+
#limits = trail.limits();
|
|
13
|
+
constructor(locator, operations) {
|
|
14
|
+
super();
|
|
15
|
+
this.locator = locator;
|
|
16
|
+
this.operations = operations;
|
|
17
|
+
Object.values(operations).forEach((operation) => this.depends(operation));
|
|
18
|
+
}
|
|
19
|
+
async invoke(endpoint, request, options) {
|
|
20
|
+
if (!(endpoint in this.operations))
|
|
21
|
+
throw new EndpointException(`'${endpoint}' is not provided by '${this.locator.id}'`);
|
|
22
|
+
// if the request carries no telemetry, the trace starts here
|
|
23
|
+
const remote = request?.telemetry === undefined ? null : decode(request.telemetry);
|
|
24
|
+
const invocation = async () => this.#process(endpoint, request, options);
|
|
25
|
+
let task = invocation;
|
|
26
|
+
/*
|
|
27
|
+
* The hop is the server's alone. A `Remote` is a component too and names the very endpoint
|
|
28
|
+
* this one does, so counting it there as well would make the threshold depend on how many
|
|
29
|
+
* clients a call happened to cross — a different number for a local call, an HTTP one and a
|
|
30
|
+
* delayed one. An endpoint beginning with `.` is the runtime's own and is no hop at all.
|
|
31
|
+
*/
|
|
32
|
+
if (this.kind === 'server' && endpoint[0] !== '.') {
|
|
33
|
+
let hops;
|
|
34
|
+
try {
|
|
35
|
+
// the span's name is the hop's, and it is already built once per endpoint
|
|
36
|
+
hops = trail.extend(request?.trail, this.#span(endpoint).name, this.#limits);
|
|
37
|
+
}
|
|
38
|
+
catch (exception) {
|
|
39
|
+
console.error('Call chain refused', {
|
|
40
|
+
endpoint: `${this.locator.id}.${endpoint}`,
|
|
41
|
+
exception
|
|
42
|
+
});
|
|
43
|
+
// answered, not thrown: thrown, this would run into the broker library on the event
|
|
44
|
+
// path, and on the call path its code would survive only by `Exception` not being an
|
|
45
|
+
// `Error`. Answered, `Call` throws it into the caller as it does any other.
|
|
46
|
+
return { exception };
|
|
47
|
+
}
|
|
48
|
+
/*
|
|
49
|
+
* The identity is put in scope with the chain: an operation reaches neither, and the
|
|
50
|
+
* calls it makes derive their own from what it is serving.
|
|
51
|
+
*/
|
|
52
|
+
const scope = { hops, id: request?.id, calls: new Map() };
|
|
53
|
+
task = async () => trail.follow(scope, invocation);
|
|
54
|
+
}
|
|
55
|
+
if (remote === null)
|
|
56
|
+
return task();
|
|
57
|
+
else
|
|
58
|
+
return run(remote, task);
|
|
59
|
+
}
|
|
60
|
+
async #process(endpoint, request, options) {
|
|
61
|
+
return console.span(this.#span(endpoint), async () => {
|
|
62
|
+
const reply = await this.operations[endpoint].invoke(request, options);
|
|
63
|
+
if (reply?.exception !== undefined) {
|
|
64
|
+
const span = current();
|
|
65
|
+
if (span !== undefined)
|
|
66
|
+
span.status = 'error';
|
|
67
|
+
console.error('Failed to execute operation', {
|
|
68
|
+
endpoint: `${this.locator.id}.${endpoint}`,
|
|
69
|
+
exception: reply.exception
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
return reply;
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The span of an endpoint never changes, so it is built once. Not in the constructor:
|
|
77
|
+
* `kind` is a field of the subclass, and those are assigned after this one is built.
|
|
78
|
+
*
|
|
79
|
+
*/
|
|
80
|
+
#span(endpoint) {
|
|
81
|
+
let options = this.#spans[endpoint];
|
|
82
|
+
if (options === undefined) {
|
|
83
|
+
options = { name: `${this.locator.id}.${endpoint}`, kind: this.kind };
|
|
84
|
+
// the server span is emitted by the component itself, while the client span
|
|
85
|
+
// belongs to the calling service and inherits it from the context
|
|
86
|
+
if (this.kind === 'server')
|
|
87
|
+
options.service = this.locator.id;
|
|
88
|
+
this.#spans[endpoint] = options;
|
|
89
|
+
}
|
|
90
|
+
return options;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=component.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../source/component.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
export declare class Composition extends Connector {
|
|
3
|
+
constructor(expositions: Connector[], producers: Connector[], receivers: Connector[], tenants: Connector[]);
|
|
4
|
+
protected open(): Promise<void>;
|
|
5
|
+
protected dispose(): Promise<void>;
|
|
6
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { console } from 'openspan';
|
|
2
|
+
import { Connector } from './connector.js';
|
|
3
|
+
export class Composition extends Connector {
|
|
4
|
+
// eslint-disable-next-line max-params
|
|
5
|
+
constructor(expositions, producers, receivers, tenants) {
|
|
6
|
+
super();
|
|
7
|
+
if (expositions.length > 0)
|
|
8
|
+
this.depends(expositions);
|
|
9
|
+
if (producers.length > 0)
|
|
10
|
+
this.depends(producers);
|
|
11
|
+
if (receivers.length > 0)
|
|
12
|
+
this.depends(receivers);
|
|
13
|
+
if (tenants.length > 0)
|
|
14
|
+
this.depends(tenants);
|
|
15
|
+
}
|
|
16
|
+
async open() {
|
|
17
|
+
console.info('Composition complete');
|
|
18
|
+
}
|
|
19
|
+
async dispose() {
|
|
20
|
+
console.info('Composition shutdown complete');
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=composition.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"composition.js","sourceRoot":"","sources":["../source/composition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,OAAO,WAAY,SAAQ,SAAS;IACxC,sCAAsC;IACtC,YACE,WAAwB,EACxB,SAAsB,EACtB,SAAsB,EACtB,OAAoB;QAEpB,KAAK,EAAE,CAAA;QAEP,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;QACrD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAEkB,KAAK,CAAC,IAAI;QAC3B,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;IACtC,CAAC;IAEkB,KAAK,CAAC,OAAO;QAC9B,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;IAC/C,CAAC;CACF"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Abstract connections hierarchy */
|
|
2
|
+
export declare class Connector {
|
|
3
|
+
#private;
|
|
4
|
+
readonly id: string;
|
|
5
|
+
connected: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Whether this has been taken down. What is disposed of is never connected again: a
|
|
8
|
+
* communication it held is sealed, an announcement it made has stopped, an algorithm it ran
|
|
9
|
+
* is unmounted. Whoever remembers one for the life of the process — an extension factory
|
|
10
|
+
* caching what it hands to components — replaces it rather than handing it out twice.
|
|
11
|
+
*/
|
|
12
|
+
disposed: boolean;
|
|
13
|
+
constructor();
|
|
14
|
+
/**
|
|
15
|
+
* Creates a dependency and backlink with another Connector or a set of Connectors
|
|
16
|
+
*
|
|
17
|
+
* See .connect() and .disconnect()
|
|
18
|
+
*
|
|
19
|
+
*/
|
|
20
|
+
depends(connector: Connector | Connector[]): Connector;
|
|
21
|
+
/**
|
|
22
|
+
* Creates a backlink to another Connector
|
|
23
|
+
*
|
|
24
|
+
* See .connect() and .disconnect()
|
|
25
|
+
*
|
|
26
|
+
*/
|
|
27
|
+
link(connector: Connector): void;
|
|
28
|
+
/**
|
|
29
|
+
* Connects dependants then self
|
|
30
|
+
*
|
|
31
|
+
* In case of exception disconnects with current connection interruption
|
|
32
|
+
*
|
|
33
|
+
* Method is idempotent
|
|
34
|
+
*
|
|
35
|
+
*/
|
|
36
|
+
connect(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Disconnects self then dependants
|
|
39
|
+
*
|
|
40
|
+
* Does nothing if there are connected linked Connectors
|
|
41
|
+
*
|
|
42
|
+
* Method is idempotent
|
|
43
|
+
*
|
|
44
|
+
*/
|
|
45
|
+
disconnect(interrupt?: boolean): Promise<void>;
|
|
46
|
+
reconnect(): Promise<void>;
|
|
47
|
+
debug(node?: Record<string, any>): Record<string, any>;
|
|
48
|
+
/** Called on connection */
|
|
49
|
+
protected open(): Promise<void> | void;
|
|
50
|
+
/** Called on disconnection */
|
|
51
|
+
protected close(): Promise<void> | void;
|
|
52
|
+
/** Called after self and dependants disconnection is complete */
|
|
53
|
+
protected dispose(): Promise<void> | void;
|
|
54
|
+
}
|