@toa.io/core 1.0.0-alpha.31 → 1.0.0-alpha.310
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 +165 -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 +148 -0
- package/transpiled/component.js.map +1 -0
- package/transpiled/composition.d.ts +6 -0
- package/transpiled/composition.js +20 -0
- package/transpiled/composition.js.map +1 -0
- package/transpiled/connector.d.ts +71 -0
- package/transpiled/connector.js +248 -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/component.d.ts +24 -0
- package/transpiled/contract/component.js +48 -0
- package/transpiled/contract/component.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 +3 -0
- package/transpiled/contract/index.js +4 -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 +115 -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/deliveries.d.ts +22 -0
- package/transpiled/deliveries.js +31 -0
- package/transpiled/deliveries.js.map +1 -0
- package/transpiled/effect.d.ts +7 -0
- package/transpiled/effect.js +13 -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/encoded.d.ts +16 -0
- package/transpiled/encoded.js +25 -0
- package/transpiled/encoded.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 +11 -0
- package/transpiled/entities/newid.js +41 -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 +53 -0
- package/transpiled/event.js.map +1 -0
- package/transpiled/exceptions.d.ts +104 -0
- package/transpiled/exceptions.js +205 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/gate.d.ts +40 -0
- package/transpiled/gate.js +84 -0
- package/transpiled/gate.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/halting.d.ts +16 -0
- package/transpiled/halting.js +25 -0
- package/transpiled/halting.js.map +1 -0
- package/transpiled/index.d.ts +41 -0
- package/transpiled/index.js +34 -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/measurements.d.ts +20 -0
- package/transpiled/measurements.js +40 -0
- package/transpiled/measurements.js.map +1 -0
- package/transpiled/observation.d.ts +7 -0
- package/transpiled/observation.js +14 -0
- package/transpiled/observation.js.map +1 -0
- package/transpiled/operation.d.ts +69 -0
- package/transpiled/operation.js +174 -0
- package/transpiled/operation.js.map +1 -0
- package/transpiled/outbox.d.ts +45 -0
- package/transpiled/outbox.js +448 -0
- package/transpiled/outbox.js.map +1 -0
- package/transpiled/outbox.measurements.d.ts +4 -0
- package/transpiled/outbox.measurements.js +38 -0
- package/transpiled/outbox.measurements.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 +34 -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/safety.d.ts +5 -0
- package/transpiled/safety.js +26 -0
- package/transpiled/safety.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 +78 -0
- package/transpiled/trail.js +112 -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 +58 -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 +41 -0
- package/transpiled/types/bridges.js +2 -0
- package/transpiled/types/bridges.js.map +1 -0
- package/transpiled/types/extensions.d.ts +116 -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 +119 -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 -61
- 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
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function newid(): string;
|
|
2
|
+
/**
|
|
3
|
+
* An id that is a function of what it is made of, in the shape `newid` produces, so that an `_id`
|
|
4
|
+
* is one kind of thing wherever it came from.
|
|
5
|
+
*
|
|
6
|
+
* What it is for is a call whose identity must be the same on every run that makes it: the same
|
|
7
|
+
* duplicate then produces the same identity, and whatever it reaches refuses its own copy. A
|
|
8
|
+
* name-based uuid is exactly that function: version 5 of RFC 9562, the bytes `uuid.v5` produces,
|
|
9
|
+
* hashed here with the namespace already parsed, since a call derives one on every call it makes.
|
|
10
|
+
*/
|
|
11
|
+
export declare function derive(...parts: Array<string | number>): string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import * as uuid from 'uuid';
|
|
3
|
+
export function newid() {
|
|
4
|
+
const buf = Buffer.alloc(16);
|
|
5
|
+
uuid.v7(undefined, buf);
|
|
6
|
+
return buf.toString('hex');
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* An id that is a function of what it is made of, in the shape `newid` produces, so that an `_id`
|
|
10
|
+
* is one kind of thing wherever it came from.
|
|
11
|
+
*
|
|
12
|
+
* What it is for is a call whose identity must be the same on every run that makes it: the same
|
|
13
|
+
* duplicate then produces the same identity, and whatever it reaches refuses its own copy. A
|
|
14
|
+
* name-based uuid is exactly that function: version 5 of RFC 9562, the bytes `uuid.v5` produces,
|
|
15
|
+
* hashed here with the namespace already parsed, since a call derives one on every call it makes.
|
|
16
|
+
*/
|
|
17
|
+
export function derive(...parts) {
|
|
18
|
+
const hash = createHash('sha1').update(NAMESPACE).update(name(parts), 'utf8').digest();
|
|
19
|
+
hash[6] = (hash[6] & 0x0f) | 0x50;
|
|
20
|
+
hash[8] = (hash[8] & 0x3f) | 0x80;
|
|
21
|
+
return hash.toString('hex', 0, 16);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Each part behind its own length, so that no two different sets of parts read as one name
|
|
25
|
+
* whatever a part happens to contain — a separator alone would have `a` and `b:c` name what
|
|
26
|
+
* `a:b` and `c` do, and this decides whether two calls are one call.
|
|
27
|
+
*/
|
|
28
|
+
function name(parts) {
|
|
29
|
+
let name = '';
|
|
30
|
+
for (const part of parts) {
|
|
31
|
+
const value = String(part);
|
|
32
|
+
name += value.length + ':' + value;
|
|
33
|
+
}
|
|
34
|
+
return name;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Toa's own, `26bd9bc6-675c-4465-9b42-9e008b20befe`, so that a name derived here collides with
|
|
38
|
+
* nothing derived elsewhere.
|
|
39
|
+
*/
|
|
40
|
+
const NAMESPACE = Buffer.from('26bd9bc6675c44659b429e008b20befe', 'hex');
|
|
41
|
+
//# sourceMappingURL=newid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"newid.js","sourceRoot":"","sources":["../../source/entities/newid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAA;AAE5B,MAAM,UAAU,KAAK;IACnB,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IAE5B,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,CAAC,CAAA;IAEvB,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,MAAM,CAAC,GAAG,KAA6B;IACrD,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,EAAE,CAAA;IAEtF,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IACjC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAEjC,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AACpC,CAAC;AAED;;;;GAIG;AACH,SAAS,IAAI,CAAC,KAA6B;IACzC,IAAI,IAAI,GAAG,EAAE,CAAA;IAEb,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAA;QAE1B,IAAI,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,GAAG,KAAK,CAAA;IACpC,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Entity } from './entity.ts';
|
|
2
|
+
import type { Record } from '../types/storages.ts';
|
|
3
|
+
import type { Event } from '../types/state.ts';
|
|
4
|
+
export declare class EntitySet {
|
|
5
|
+
#private;
|
|
6
|
+
constructor(set: Entity[]);
|
|
7
|
+
get(): Record[];
|
|
8
|
+
set(values: Record[]): void;
|
|
9
|
+
events(input?: object): Event[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { SystemException } from '../exceptions.js';
|
|
2
|
+
export class EntitySet {
|
|
3
|
+
#set;
|
|
4
|
+
constructor(set) {
|
|
5
|
+
this.#set = set;
|
|
6
|
+
}
|
|
7
|
+
get() {
|
|
8
|
+
return this.#set.map((entity) => entity.get());
|
|
9
|
+
}
|
|
10
|
+
set(values) {
|
|
11
|
+
if (values.length !== this.#set.length)
|
|
12
|
+
throw new SystemException('Objects array must not be modified');
|
|
13
|
+
values.forEach((value, index) => this.#set[index].set(value));
|
|
14
|
+
}
|
|
15
|
+
events(input) {
|
|
16
|
+
return this.#set.map((entity) => entity.event(input));
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=set.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"set.js","sourceRoot":"","sources":["../../source/entities/set.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAKlD,MAAM,OAAO,SAAS;IACX,IAAI,CAAU;IAEvB,YAAmB,GAAa;QAC9B,IAAI,CAAC,IAAI,GAAG,GAAG,CAAA;IACjB,CAAC;IAEM,GAAG;QACR,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;IAChD,CAAC;IAEM,GAAG,CAAC,MAAgB;QACzB,IAAI,MAAM,CAAC,MAAM,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM;YACpC,MAAM,IAAI,eAAe,CAAC,oCAAoC,CAAC,CAAA;QAEjE,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;IAC/D,CAAC;IAEM,MAAM,CAAC,KAAc;QAC1B,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IACvD,CAAC;CACF"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
import type { Emitter } from './types/bindings.ts';
|
|
3
|
+
import type { Event as Bridge } from './types/bridges.ts';
|
|
4
|
+
import type { Row } from './types/outbox.ts';
|
|
5
|
+
export interface Definition {
|
|
6
|
+
conditioned?: boolean;
|
|
7
|
+
subjective?: boolean;
|
|
8
|
+
label?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class Event extends Connector {
|
|
11
|
+
#private;
|
|
12
|
+
constructor(definition: Definition, emitter: Emitter, bridge?: Bridge);
|
|
13
|
+
emit(row: Row): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { console, current, encode } from 'openspan';
|
|
2
|
+
import { Connector } from './connector.js';
|
|
3
|
+
import { derive } from './entities/newid.js';
|
|
4
|
+
import * as measure from './measurements.js';
|
|
5
|
+
export class Event extends Connector {
|
|
6
|
+
#emitter;
|
|
7
|
+
#bridge;
|
|
8
|
+
#conditioned;
|
|
9
|
+
#subjective;
|
|
10
|
+
#label;
|
|
11
|
+
constructor(definition, emitter, bridge) {
|
|
12
|
+
super();
|
|
13
|
+
this.#conditioned = definition.conditioned;
|
|
14
|
+
this.#subjective = definition.subjective;
|
|
15
|
+
this.#label = definition.label ?? 'event';
|
|
16
|
+
this.#emitter = emitter;
|
|
17
|
+
this.#bridge = bridge;
|
|
18
|
+
this.depends(emitter);
|
|
19
|
+
if (bridge !== undefined)
|
|
20
|
+
this.depends(bridge);
|
|
21
|
+
}
|
|
22
|
+
async emit(row) {
|
|
23
|
+
const event = row.event;
|
|
24
|
+
if (this.#conditioned === false || (await this.#bridge?.condition(event)) === true) {
|
|
25
|
+
const payload = this.#subjective === true ? await this.#bridge?.payload(event) : event.state;
|
|
26
|
+
/*
|
|
27
|
+
* The row is committed once, so its id is what makes every publication of it one message:
|
|
28
|
+
* the immediate path, the pump that may run an hour later in another replica, and a
|
|
29
|
+
* redelivery of what either sent. Derived with the label rather than the row id itself,
|
|
30
|
+
* because one row is published as several events and a component may consume two of them —
|
|
31
|
+
* one identity across both would have the second refused as a duplicate of the first.
|
|
32
|
+
*/
|
|
33
|
+
const message = { payload, id: derive(row.id, this.#label) };
|
|
34
|
+
// the chain the change was made by, so a receiver of this continues it rather than
|
|
35
|
+
// starting one; read off the row, because the pump publishes off the operation's path
|
|
36
|
+
if (row.trail !== undefined)
|
|
37
|
+
message.trail = row.trail;
|
|
38
|
+
const options = {
|
|
39
|
+
name: `${this.#label} publish`,
|
|
40
|
+
kind: 'producer',
|
|
41
|
+
attributes: { 'messaging.destination.name': this.#label },
|
|
42
|
+
measure: { histogram: measure.event.publish, labels: { event: this.#label } }
|
|
43
|
+
};
|
|
44
|
+
await console.span(options, async () => {
|
|
45
|
+
const context = current();
|
|
46
|
+
if (context !== undefined)
|
|
47
|
+
message.telemetry = encode(context);
|
|
48
|
+
await this.#emitter.emit(message);
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../source/event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAoB,MAAM,UAAU,CAAA;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAC5C,OAAO,KAAK,OAAO,MAAM,mBAAmB,CAAA;AAY5C,MAAM,OAAO,KAAM,SAAQ,SAAS;IACzB,QAAQ,CAAS;IACjB,OAAO,CAAoB;IAC3B,YAAY,CAAqB;IACjC,WAAW,CAAqB;IAChC,MAAM,CAAQ;IAEvB,YAAmB,UAAsB,EAAE,OAAgB,EAAE,MAAe;QAC1E,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,WAAW,CAAA;QAC1C,IAAI,CAAC,WAAW,GAAG,UAAU,CAAC,UAAU,CAAA;QACxC,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,KAAK,IAAI,OAAO,CAAA;QACzC,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAA;QACvB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;QAErB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QAErB,IAAI,MAAM,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAChD,CAAC;IAEM,KAAK,CAAC,IAAI,CAAC,GAAQ;QACxB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAA;QAEvB,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnF,MAAM,OAAO,GACX,IAAI,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAA;YAE9E;;;;;;eAMG;YACH,MAAM,OAAO,GAAY,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;YAErE,mFAAmF;YACnF,sFAAsF;YACtF,IAAI,GAAG,CAAC,KAAK,KAAK,SAAS;gBAAE,OAAO,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAA;YAEtD,MAAM,OAAO,GAAgB;gBAC3B,IAAI,EAAE,GAAG,IAAI,CAAC,MAAM,UAAU;gBAC9B,IAAI,EAAE,UAAU;gBAChB,UAAU,EAAE,EAAE,4BAA4B,EAAE,IAAI,CAAC,MAAM,EAAE;gBACzD,OAAO,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,EAAE;aAC9E,CAAA;YAED,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBACrC,MAAM,OAAO,GAAG,OAAO,EAAE,CAAA;gBAEzB,IAAI,OAAO,KAAK,SAAS;oBAAE,OAAO,CAAC,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAA;gBAE9D,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnC,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import type { SchemaError } from '@toa.io/schemas';
|
|
2
|
+
export declare const codes: {
|
|
3
|
+
System: number;
|
|
4
|
+
Contract: number;
|
|
5
|
+
RequestSyntax: number;
|
|
6
|
+
RequestContract: number;
|
|
7
|
+
RequestConflict: number;
|
|
8
|
+
ResponseContract: number;
|
|
9
|
+
EntityContract: number;
|
|
10
|
+
EntityGuard: number;
|
|
11
|
+
QuerySyntax: number;
|
|
12
|
+
State: number;
|
|
13
|
+
StateNotFound: number;
|
|
14
|
+
StatePrecondition: number;
|
|
15
|
+
StateConcurrency: number;
|
|
16
|
+
StateInitialization: number;
|
|
17
|
+
Duplicate: number;
|
|
18
|
+
/** this call has been made, and what it changed is changed */
|
|
19
|
+
DuplicateCall: number;
|
|
20
|
+
Communication: number;
|
|
21
|
+
Transmission: number;
|
|
22
|
+
Endpoint: number;
|
|
23
|
+
/** nothing held the name an addressed call named */
|
|
24
|
+
Addressee: number;
|
|
25
|
+
/** the caller stopped waiting, and what it called may still run */
|
|
26
|
+
Abandoned: number;
|
|
27
|
+
/** the tree the call was made through has been taken down, and is not coming back */
|
|
28
|
+
Disposed: number;
|
|
29
|
+
/** a call to an operation that may change state, made under a request that may only read */
|
|
30
|
+
Safety: number;
|
|
31
|
+
/** a chain that came back to where it had been, or went further than a chain goes */
|
|
32
|
+
Loop: number;
|
|
33
|
+
/** a component asked for something its manifest does not declare */
|
|
34
|
+
Misuse: number;
|
|
35
|
+
/** a run command pauses what nothing takes again: `pause` with no `resume` */
|
|
36
|
+
Irresumable: number;
|
|
37
|
+
/** a call to a component nothing this process was given states */
|
|
38
|
+
Unstated: number;
|
|
39
|
+
};
|
|
40
|
+
export declare class Exception {
|
|
41
|
+
readonly code: number;
|
|
42
|
+
readonly message: string;
|
|
43
|
+
cause?: unknown;
|
|
44
|
+
/** what a contract exception copies off the schema error it refused with */
|
|
45
|
+
[key: string]: unknown;
|
|
46
|
+
constructor(code: number, message: string, cause?: unknown);
|
|
47
|
+
}
|
|
48
|
+
export declare class SystemException extends Exception {
|
|
49
|
+
readonly stack?: string;
|
|
50
|
+
constructor(error: Error | string);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* A call refused for where it has been rather than for what it says. Named, and so permanent:
|
|
54
|
+
* the chain is deterministic, and another attempt reproduces it hop for hop.
|
|
55
|
+
*/
|
|
56
|
+
export declare class LoopException extends Exception {
|
|
57
|
+
/** the whole chain, so what is set aside can be read without guessing */
|
|
58
|
+
readonly trail: string[];
|
|
59
|
+
constructor(message: string, trail: string[]);
|
|
60
|
+
}
|
|
61
|
+
export declare class ContractException extends Exception {
|
|
62
|
+
constructor(code: number | undefined, error: SchemaError | string | null, cause?: unknown);
|
|
63
|
+
}
|
|
64
|
+
export declare class RequestContractException extends ContractException {
|
|
65
|
+
constructor(error: SchemaError | string, cause?: unknown);
|
|
66
|
+
}
|
|
67
|
+
export declare class ResponseContractException extends ContractException {
|
|
68
|
+
constructor(error: SchemaError | string, cause?: unknown);
|
|
69
|
+
}
|
|
70
|
+
export declare class EntityContractException extends ContractException {
|
|
71
|
+
constructor(error: SchemaError | string, cause?: unknown);
|
|
72
|
+
}
|
|
73
|
+
export declare class EntityGuardException extends ContractException {
|
|
74
|
+
constructor(name: string, cause?: unknown);
|
|
75
|
+
}
|
|
76
|
+
type Derived = new (message?: string, cause?: unknown) => Exception;
|
|
77
|
+
export declare const RequestSyntaxException: Derived;
|
|
78
|
+
export declare const RequestConflictException: Derived;
|
|
79
|
+
export declare const QuerySyntaxException: Derived;
|
|
80
|
+
export declare const StateException: Derived;
|
|
81
|
+
export declare const StateNotFoundException: Derived;
|
|
82
|
+
export declare const StatePreconditionException: Derived;
|
|
83
|
+
export declare const StateConcurrencyException: Derived;
|
|
84
|
+
export declare const StateInitializationException: Derived;
|
|
85
|
+
export declare const DuplicateException: Derived;
|
|
86
|
+
export declare const DuplicateCallException: Derived;
|
|
87
|
+
export declare const CommunicationException: Derived;
|
|
88
|
+
export declare const TransmissionException: Derived;
|
|
89
|
+
export declare const EndpointException: Derived;
|
|
90
|
+
export declare const AddresseeException: Derived;
|
|
91
|
+
export declare const AbandonedException: Derived;
|
|
92
|
+
export declare const DisposedException: Derived;
|
|
93
|
+
export declare const SafetyException: Derived;
|
|
94
|
+
export declare const MisuseException: Derived;
|
|
95
|
+
export declare const IrresumableException: Derived;
|
|
96
|
+
export declare const UnstatedException: Derived;
|
|
97
|
+
export declare const names: Record<string, string>;
|
|
98
|
+
/**
|
|
99
|
+
* Takes `unknown` because a caller has caught something rather than been handed an `Exception`.
|
|
100
|
+
* Anything core did not raise — an error from a driver, a rejection with no code at all — is not
|
|
101
|
+
* on the list, and is therefore worth trying again.
|
|
102
|
+
*/
|
|
103
|
+
export declare function permanent(exception: unknown): boolean;
|
|
104
|
+
export {};
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import { swap } from '@toa.io/generic';
|
|
2
|
+
export const codes = {
|
|
3
|
+
System: 0,
|
|
4
|
+
Contract: 200,
|
|
5
|
+
RequestSyntax: 201,
|
|
6
|
+
RequestContract: 202,
|
|
7
|
+
RequestConflict: 203,
|
|
8
|
+
ResponseContract: 211,
|
|
9
|
+
EntityContract: 212,
|
|
10
|
+
EntityGuard: 213,
|
|
11
|
+
QuerySyntax: 221,
|
|
12
|
+
State: 300,
|
|
13
|
+
StateNotFound: 302,
|
|
14
|
+
StatePrecondition: 303,
|
|
15
|
+
StateConcurrency: 304,
|
|
16
|
+
StateInitialization: 305,
|
|
17
|
+
Duplicate: 306,
|
|
18
|
+
/** this call has been made, and what it changed is changed */
|
|
19
|
+
DuplicateCall: 307,
|
|
20
|
+
Communication: 400,
|
|
21
|
+
Transmission: 401,
|
|
22
|
+
Endpoint: 402,
|
|
23
|
+
/** nothing held the name an addressed call named */
|
|
24
|
+
Addressee: 403,
|
|
25
|
+
/** the caller stopped waiting, and what it called may still run */
|
|
26
|
+
Abandoned: 404,
|
|
27
|
+
/** the tree the call was made through has been taken down, and is not coming back */
|
|
28
|
+
Disposed: 405,
|
|
29
|
+
/** a call to an operation that may change state, made under a request that may only read */
|
|
30
|
+
Safety: 406,
|
|
31
|
+
/** a chain that came back to where it had been, or went further than a chain goes */
|
|
32
|
+
Loop: 500,
|
|
33
|
+
/** a component asked for something its manifest does not declare */
|
|
34
|
+
Misuse: 600,
|
|
35
|
+
/** a run command pauses what nothing takes again: `pause` with no `resume` */
|
|
36
|
+
Irresumable: 601,
|
|
37
|
+
/** a call to a component nothing this process was given states */
|
|
38
|
+
Unstated: 602
|
|
39
|
+
};
|
|
40
|
+
export class Exception {
|
|
41
|
+
code;
|
|
42
|
+
message;
|
|
43
|
+
cause;
|
|
44
|
+
constructor(code, message, cause) {
|
|
45
|
+
this.code = code;
|
|
46
|
+
this.message = message;
|
|
47
|
+
if (cause !== undefined)
|
|
48
|
+
this.cause = cause;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export class SystemException extends Exception {
|
|
52
|
+
stack;
|
|
53
|
+
constructor(error) {
|
|
54
|
+
super(codes.System, typeof error === 'string' ? error : error.message);
|
|
55
|
+
if (typeof error !== 'string' && error.stack !== undefined)
|
|
56
|
+
this.stack = error.stack;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A call refused for where it has been rather than for what it says. Named, and so permanent:
|
|
61
|
+
* the chain is deterministic, and another attempt reproduces it hop for hop.
|
|
62
|
+
*/
|
|
63
|
+
export class LoopException extends Exception {
|
|
64
|
+
/** the whole chain, so what is set aside can be read without guessing */
|
|
65
|
+
trail;
|
|
66
|
+
constructor(message, trail) {
|
|
67
|
+
super(codes.Loop, message);
|
|
68
|
+
this.trail = trail;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
export class ContractException extends Exception {
|
|
72
|
+
constructor(code, error, cause) {
|
|
73
|
+
super(code ?? codes.Contract, typeof error === 'string' ? error : (error?.message ?? ''), cause);
|
|
74
|
+
if (typeof error === 'object' && error !== null)
|
|
75
|
+
for (const k of [
|
|
76
|
+
'keyword',
|
|
77
|
+
'instancePath',
|
|
78
|
+
'schemaPath',
|
|
79
|
+
'params',
|
|
80
|
+
'propertyName'
|
|
81
|
+
])
|
|
82
|
+
if (k in error)
|
|
83
|
+
this[k] = error[k];
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export class RequestContractException extends ContractException {
|
|
87
|
+
constructor(error, cause) {
|
|
88
|
+
super(codes.RequestContract, error, cause);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
export class ResponseContractException extends ContractException {
|
|
92
|
+
constructor(error, cause) {
|
|
93
|
+
super(codes.ResponseContract, error, cause);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export class EntityContractException extends ContractException {
|
|
97
|
+
constructor(error, cause) {
|
|
98
|
+
super(codes.EntityContract, error, cause);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export class EntityGuardException extends ContractException {
|
|
102
|
+
constructor(name, cause) {
|
|
103
|
+
super(codes.EntityGuard, name, cause);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function derive(name) {
|
|
107
|
+
const classname = name + 'Exception';
|
|
108
|
+
const derived = class extends Exception {
|
|
109
|
+
constructor(message, cause) {
|
|
110
|
+
super(codes[name], message === undefined ? classname : `${classname}: ${message}`, cause);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
// the name is the class's own, and a class expression has none worth reporting
|
|
114
|
+
Object.defineProperty(derived, 'name', { value: classname });
|
|
115
|
+
return derived;
|
|
116
|
+
}
|
|
117
|
+
export const RequestSyntaxException = derive('RequestSyntax');
|
|
118
|
+
export const RequestConflictException = derive('RequestConflict');
|
|
119
|
+
export const QuerySyntaxException = derive('QuerySyntax');
|
|
120
|
+
export const StateException = derive('State');
|
|
121
|
+
export const StateNotFoundException = derive('StateNotFound');
|
|
122
|
+
export const StatePreconditionException = derive('StatePrecondition');
|
|
123
|
+
export const StateConcurrencyException = derive('StateConcurrency');
|
|
124
|
+
export const StateInitializationException = derive('StateInitialization');
|
|
125
|
+
export const DuplicateException = derive('Duplicate');
|
|
126
|
+
export const DuplicateCallException = derive('DuplicateCall');
|
|
127
|
+
export const CommunicationException = derive('Communication');
|
|
128
|
+
export const TransmissionException = derive('Transmission');
|
|
129
|
+
export const EndpointException = derive('Endpoint');
|
|
130
|
+
export const AddresseeException = derive('Addressee');
|
|
131
|
+
export const AbandonedException = derive('Abandoned');
|
|
132
|
+
export const DisposedException = derive('Disposed');
|
|
133
|
+
export const SafetyException = derive('Safety');
|
|
134
|
+
export const MisuseException = derive('Misuse');
|
|
135
|
+
export const IrresumableException = derive('Irresumable');
|
|
136
|
+
export const UnstatedException = derive('Unstated');
|
|
137
|
+
export const names = swap(codes);
|
|
138
|
+
// #endregion
|
|
139
|
+
/**
|
|
140
|
+
* Whether a failure means the same thing on a later attempt.
|
|
141
|
+
*
|
|
142
|
+
* Every code answers, and the answer is here rather than inferred: `Record<keyof typeof codes>`
|
|
143
|
+
* refuses to compile until a code added later says which it is. What core names, core raised on
|
|
144
|
+
* purpose — a contract does not start fitting, a version that has passed does not come back.
|
|
145
|
+
* `System` is the exception that proves it: it is a code like any other, and what it wraps is
|
|
146
|
+
* whatever reached core from below, which is the kind that passes.
|
|
147
|
+
*/
|
|
148
|
+
const OUTCOME = {
|
|
149
|
+
// whatever the algorithm or a connector threw: core neither chose it nor can read it
|
|
150
|
+
System: 'transient',
|
|
151
|
+
Contract: 'permanent',
|
|
152
|
+
RequestSyntax: 'permanent',
|
|
153
|
+
RequestContract: 'permanent',
|
|
154
|
+
RequestConflict: 'permanent',
|
|
155
|
+
ResponseContract: 'permanent',
|
|
156
|
+
EntityContract: 'permanent',
|
|
157
|
+
EntityGuard: 'permanent',
|
|
158
|
+
QuerySyntax: 'permanent',
|
|
159
|
+
State: 'permanent',
|
|
160
|
+
// an event about an entity can outrun the one that creates it; nothing promises order
|
|
161
|
+
StateNotFound: 'transient',
|
|
162
|
+
// an entity's version only grows, so one that has passed does not start matching
|
|
163
|
+
StatePrecondition: 'permanent',
|
|
164
|
+
// the compare-and-swap lost, which is the case a later attempt exists for
|
|
165
|
+
StateConcurrency: 'transient',
|
|
166
|
+
StateInitialization: 'permanent',
|
|
167
|
+
Duplicate: 'permanent',
|
|
168
|
+
// a call that has been made stays made: another attempt is refused by the same record
|
|
169
|
+
DuplicateCall: 'permanent',
|
|
170
|
+
Communication: 'transient',
|
|
171
|
+
// nothing is listening on that queue yet — a deployment in progress, most of the time
|
|
172
|
+
Transmission: 'transient',
|
|
173
|
+
// its sibling, and the other way round: nothing carried the call is a moment,
|
|
174
|
+
// there is nothing to carry it to is a fact
|
|
175
|
+
Endpoint: 'permanent',
|
|
176
|
+
// a process that lost its broker connection claims its name again once it is restored
|
|
177
|
+
Addressee: 'transient',
|
|
178
|
+
// what the caller gave up on may have run, and may run yet
|
|
179
|
+
Abandoned: 'transient',
|
|
180
|
+
// the tree is gone and a resume builds another, so the same context never works again
|
|
181
|
+
Disposed: 'permanent',
|
|
182
|
+
// a transition does not become an observation, and the request goes on saying it only reads
|
|
183
|
+
Safety: 'permanent',
|
|
184
|
+
// the chain is deterministic, so another attempt walks it again: a retry is another cycle
|
|
185
|
+
Loop: 'permanent',
|
|
186
|
+
// what a component did not declare, it does not declare on the next attempt either
|
|
187
|
+
Misuse: 'permanent',
|
|
188
|
+
// the component is refused at start, so nothing reaches it to be attempted twice
|
|
189
|
+
Irresumable: 'permanent',
|
|
190
|
+
// a remote is built once and held, so what this process was not given, it is not given later
|
|
191
|
+
Unstated: 'permanent'
|
|
192
|
+
};
|
|
193
|
+
const PERMANENT = new Set(Object.entries(OUTCOME)
|
|
194
|
+
.filter(([, outcome]) => outcome === 'permanent')
|
|
195
|
+
.map(([name]) => codes[name]));
|
|
196
|
+
/**
|
|
197
|
+
* Takes `unknown` because a caller has caught something rather than been handed an `Exception`.
|
|
198
|
+
* Anything core did not raise — an error from a driver, a rejection with no code at all — is not
|
|
199
|
+
* on the list, and is therefore worth trying again.
|
|
200
|
+
*/
|
|
201
|
+
export function permanent(exception) {
|
|
202
|
+
const code = exception?.code;
|
|
203
|
+
return code !== undefined && PERMANENT.has(code);
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=exceptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exceptions.js","sourceRoot":"","sources":["../source/exceptions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
/**
|
|
3
|
+
* A part of a tree that a halt takes down and builds again.
|
|
4
|
+
*
|
|
5
|
+
* What it holds it *owns*, rather than depends on: a connector with a live dependant refuses to
|
|
6
|
+
* disconnect, and the one way past that refusal skips `close()` with it. A subtree nobody links
|
|
7
|
+
* has neither problem, so the teardown here is the one a shutdown performs.
|
|
8
|
+
*
|
|
9
|
+
* And the subtree is discarded rather than kept, because what comes back is built anew: a sealed
|
|
10
|
+
* communication, a receiver that has stopped announcing, an algorithm that has been unmounted —
|
|
11
|
+
* none of them are asked to work a second time. Nothing outlives a halt but what is above it.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Gate extends Connector {
|
|
14
|
+
private readonly build;
|
|
15
|
+
private live;
|
|
16
|
+
/** While halted, when what this holds comes back; `0` where it is not halted. */
|
|
17
|
+
private resumesAt;
|
|
18
|
+
constructor(build: () => Promise<Connector>);
|
|
19
|
+
/** Whether what this holds is up. */
|
|
20
|
+
holding(): boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Seconds until what this holds is back, and `0` where it is up or is not coming back.
|
|
23
|
+
*
|
|
24
|
+
* What sits above a gate answers for it while it is down — the gateway keeps its port and
|
|
25
|
+
* replies `503` rather than closing it — and this is what such a reply says to come back
|
|
26
|
+
* after.
|
|
27
|
+
*/
|
|
28
|
+
remaining(): number;
|
|
29
|
+
/**
|
|
30
|
+
* @param seconds how long it stays down, where it is coming back
|
|
31
|
+
*/
|
|
32
|
+
down(seconds?: number): Promise<void>;
|
|
33
|
+
up(): Promise<void>;
|
|
34
|
+
/** What a gate holds is not a dependency, so the walks that stop a tree are led into it. */
|
|
35
|
+
halt(visited?: Set<Connector>): Promise<void>;
|
|
36
|
+
restore(visited?: Set<Connector>): Promise<void>;
|
|
37
|
+
debug(node?: Record<string, any>): Record<string, any>;
|
|
38
|
+
protected open(): Promise<void>;
|
|
39
|
+
protected close(): Promise<void>;
|
|
40
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { Connector } from './connector.js';
|
|
2
|
+
/**
|
|
3
|
+
* A part of a tree that a halt takes down and builds again.
|
|
4
|
+
*
|
|
5
|
+
* What it holds it *owns*, rather than depends on: a connector with a live dependant refuses to
|
|
6
|
+
* disconnect, and the one way past that refusal skips `close()` with it. A subtree nobody links
|
|
7
|
+
* has neither problem, so the teardown here is the one a shutdown performs.
|
|
8
|
+
*
|
|
9
|
+
* And the subtree is discarded rather than kept, because what comes back is built anew: a sealed
|
|
10
|
+
* communication, a receiver that has stopped announcing, an algorithm that has been unmounted —
|
|
11
|
+
* none of them are asked to work a second time. Nothing outlives a halt but what is above it.
|
|
12
|
+
*/
|
|
13
|
+
export class Gate extends Connector {
|
|
14
|
+
build;
|
|
15
|
+
live = null;
|
|
16
|
+
/** While halted, when what this holds comes back; `0` where it is not halted. */
|
|
17
|
+
resumesAt = 0;
|
|
18
|
+
constructor(build) {
|
|
19
|
+
super();
|
|
20
|
+
this.build = build;
|
|
21
|
+
}
|
|
22
|
+
/** Whether what this holds is up. */
|
|
23
|
+
holding() {
|
|
24
|
+
return this.live !== null;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Seconds until what this holds is back, and `0` where it is up or is not coming back.
|
|
28
|
+
*
|
|
29
|
+
* What sits above a gate answers for it while it is down — the gateway keeps its port and
|
|
30
|
+
* replies `503` rather than closing it — and this is what such a reply says to come back
|
|
31
|
+
* after.
|
|
32
|
+
*/
|
|
33
|
+
remaining() {
|
|
34
|
+
if (this.resumesAt === 0)
|
|
35
|
+
return 0;
|
|
36
|
+
return Math.max(0, Math.ceil((this.resumesAt - Date.now()) / 1000));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @param seconds how long it stays down, where it is coming back
|
|
40
|
+
*/
|
|
41
|
+
async down(seconds = 0) {
|
|
42
|
+
const live = this.live;
|
|
43
|
+
if (live === null)
|
|
44
|
+
return;
|
|
45
|
+
this.live = null;
|
|
46
|
+
this.resumesAt = seconds === 0 ? 0 : Date.now() + seconds * 1000;
|
|
47
|
+
await live.disconnect();
|
|
48
|
+
}
|
|
49
|
+
async up() {
|
|
50
|
+
this.resumesAt = 0;
|
|
51
|
+
if (this.live !== null)
|
|
52
|
+
return;
|
|
53
|
+
const live = await this.build();
|
|
54
|
+
// held only once it is up: a build that throws leaves nothing to take down
|
|
55
|
+
await live.connect();
|
|
56
|
+
this.live = live;
|
|
57
|
+
}
|
|
58
|
+
/** What a gate holds is not a dependency, so the walks that stop a tree are led into it. */
|
|
59
|
+
async halt(visited = new Set()) {
|
|
60
|
+
if (visited.has(this))
|
|
61
|
+
return;
|
|
62
|
+
await super.halt(visited);
|
|
63
|
+
await this.live?.halt(visited);
|
|
64
|
+
}
|
|
65
|
+
async restore(visited = new Set()) {
|
|
66
|
+
if (visited.has(this))
|
|
67
|
+
return;
|
|
68
|
+
await this.live?.restore(visited);
|
|
69
|
+
await super.restore(visited);
|
|
70
|
+
}
|
|
71
|
+
debug(node = {}) {
|
|
72
|
+
super.debug(node);
|
|
73
|
+
// what a gate holds is not a dependency, so the walk does not reach it on its own
|
|
74
|
+
this.live?.debug(node[this.id]);
|
|
75
|
+
return node;
|
|
76
|
+
}
|
|
77
|
+
async open() {
|
|
78
|
+
await this.up();
|
|
79
|
+
}
|
|
80
|
+
async close() {
|
|
81
|
+
await this.down();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../source/gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C;;;;;;;;;;GAUG;AACH,MAAM,OAAO,IAAK,SAAQ,SAAS;IAChB,KAAK,CAA0B;IACxC,IAAI,GAAqB,IAAI,CAAA;IAErC,iFAAiF;IACzE,SAAS,GAAG,CAAC,CAAA;IAErB,YAAmB,KAA+B;QAChD,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,qCAAqC;IAC9B,OAAO;QACZ,OAAO,IAAI,CAAC,IAAI,KAAK,IAAI,CAAA;IAC3B,CAAC;IAED;;;;;;OAMG;IACI,SAAS;QACd,IAAI,IAAI,CAAC,SAAS,KAAK,CAAC;YAAE,OAAO,CAAC,CAAA;QAElC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,CAAA;IACrE,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC;QAC3B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QAEtB,IAAI,IAAI,KAAK,IAAI;YAAE,OAAM;QAEzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,SAAS,GAAG,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,IAAI,CAAA;QAEhE,MAAM,IAAI,CAAC,UAAU,EAAE,CAAA;IACzB,CAAC;IAEM,KAAK,CAAC,EAAE;QACb,IAAI,CAAC,SAAS,GAAG,CAAC,CAAA;QAElB,IAAI,IAAI,CAAC,IAAI,KAAK,IAAI;YAAE,OAAM;QAE9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,EAAE,CAAA;QAE/B,2EAA2E;QAC3E,MAAM,IAAI,CAAC,OAAO,EAAE,CAAA;QAEpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;IAClB,CAAC;IAED,4FAA4F;IAC5E,KAAK,CAAC,IAAI,CAAC,OAAO,GAAmB,IAAI,GAAG,EAAE;QAC5D,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAM;QAE7B,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACzB,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;IAChC,CAAC;IAEe,KAAK,CAAC,OAAO,CAAC,OAAO,GAAmB,IAAI,GAAG,EAAE;QAC/D,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAM;QAE7B,MAAM,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAA;QACjC,MAAM,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC9B,CAAC;IAEe,KAAK,CAAC,IAAI,GAAwB,EAAE;QAClD,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEjB,kFAAkF;QAClF,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;QAE/B,OAAO,IAAI,CAAA;IACb,CAAC;IAEkB,KAAK,CAAC,IAAI;QAC3B,MAAM,IAAI,CAAC,EAAE,EAAE,CAAA;IACjB,CAAC;IAEkB,KAAK,CAAC,KAAK;QAC5B,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../source/guard.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,KAAK;IACA,IAAI,CAAQ;IAEnB,OAAO,CAAQ;IAExB,YAAmB,IAAY,EAAE,MAAc;QAC7C,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,OAAO,GAAG,MAAM,CAAA;IACvB,CAAC;IAEM,GAAG,CAAC,KAAa,EAAE,MAAqB;QAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACxC,CAAC;CACF"}
|