@toa.io/core 1.0.0-alpha.31 → 1.0.0-alpha.311
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,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this process is halting.
|
|
3
|
+
*
|
|
4
|
+
* A halt is the one teardown that is not a shutdown: the process stays, and what it held is
|
|
5
|
+
* built again. Two things read this and act differently because of it — a connection gives up
|
|
6
|
+
* the replies it is waiting for rather than holding the teardown open for a peer that is
|
|
7
|
+
* halting too, and a rejection from a tree that has been taken down is reported rather than
|
|
8
|
+
* fatal, because the process is in exactly the state the runtime put it in.
|
|
9
|
+
*
|
|
10
|
+
* Ambient, like the instance name and the invocation chain, and for the same reason: a process
|
|
11
|
+
* may carry two copies of this module, and an answer from one of them answers for half a
|
|
12
|
+
* process.
|
|
13
|
+
*/
|
|
14
|
+
export declare function begin(): void;
|
|
15
|
+
export declare function end(): void;
|
|
16
|
+
export declare function underway(): boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether this process is halting.
|
|
3
|
+
*
|
|
4
|
+
* A halt is the one teardown that is not a shutdown: the process stays, and what it held is
|
|
5
|
+
* built again. Two things read this and act differently because of it — a connection gives up
|
|
6
|
+
* the replies it is waiting for rather than holding the teardown open for a peer that is
|
|
7
|
+
* halting too, and a rejection from a tree that has been taken down is reported rather than
|
|
8
|
+
* fatal, because the process is in exactly the state the runtime put it in.
|
|
9
|
+
*
|
|
10
|
+
* Ambient, like the instance name and the invocation chain, and for the same reason: a process
|
|
11
|
+
* may carry two copies of this module, and an answer from one of them answers for half a
|
|
12
|
+
* process.
|
|
13
|
+
*/
|
|
14
|
+
const KEY = Symbol.for('toa.core.halting');
|
|
15
|
+
const store = (globalThis[KEY] ??= { underway: false });
|
|
16
|
+
export function begin() {
|
|
17
|
+
store.underway = true;
|
|
18
|
+
}
|
|
19
|
+
export function end() {
|
|
20
|
+
store.underway = false;
|
|
21
|
+
}
|
|
22
|
+
export function underway() {
|
|
23
|
+
return store.underway;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=halting.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"halting.js","sourceRoot":"","sources":["../source/halting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAA;AAI1C,MAAM,KAAK,GAAG,CAAE,UAAoB,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAA;AAElE,MAAM,UAAU,KAAK;IACnB,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAA;AACvB,CAAC;AAED,MAAM,UAAU,GAAG;IACjB,KAAK,CAAC,QAAQ,GAAG,KAAK,CAAA;AACxB,CAAC;AAED,MAAM,UAAU,QAAQ;IACtB,OAAO,KAAK,CAAC,QAAQ,CAAA;AACvB,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export { Assignment } from './assignment.ts';
|
|
2
|
+
export { Call } from './call.ts';
|
|
3
|
+
export { Cascade } from './cascade.ts';
|
|
4
|
+
export { Component } from './component.ts';
|
|
5
|
+
export { Composition } from './composition.ts';
|
|
6
|
+
export { Connector } from './connector.ts';
|
|
7
|
+
export { Context } from './context.ts';
|
|
8
|
+
export { Encoded } from './encoded.ts';
|
|
9
|
+
export { Effect } from './effect.ts';
|
|
10
|
+
export { Emission } from './emission.ts';
|
|
11
|
+
export { Event } from './event.ts';
|
|
12
|
+
export { Gate } from './gate.ts';
|
|
13
|
+
export { Locator } from './locator.ts';
|
|
14
|
+
export { Observation } from './observation.ts';
|
|
15
|
+
export { Outbox } from './outbox.ts';
|
|
16
|
+
export { Operation } from './operation.ts';
|
|
17
|
+
export { Query } from './query.ts';
|
|
18
|
+
export { Receiver } from './receiver.ts';
|
|
19
|
+
export { Reflection } from './reflection.ts';
|
|
20
|
+
export { Remote } from './remote.ts';
|
|
21
|
+
export { State } from './state.ts';
|
|
22
|
+
export { Transition } from './transition.ts';
|
|
23
|
+
export { Transmission } from './transmission.ts';
|
|
24
|
+
export { Unmanaged } from './unmanaged.ts';
|
|
25
|
+
export { Guard } from './guard.ts';
|
|
26
|
+
export { instance } from './instance.ts';
|
|
27
|
+
export { safe } from './safety.ts';
|
|
28
|
+
export * as deliveries from './deliveries.ts';
|
|
29
|
+
export * as entities from './entities/index.ts';
|
|
30
|
+
export * as halting from './halting.ts';
|
|
31
|
+
export * as exceptions from './exceptions.ts';
|
|
32
|
+
export * as trail from './trail.ts';
|
|
33
|
+
export * as contract from './contract/index.ts';
|
|
34
|
+
export type { Exception } from './exceptions.ts';
|
|
35
|
+
export type { Invocable } from './component.ts';
|
|
36
|
+
export type { Explicable } from './remote.ts';
|
|
37
|
+
export type { Scoped, Store } from './operation.ts';
|
|
38
|
+
export type { Source as ReflectionSource } from './reflection.ts';
|
|
39
|
+
export type { Explanation } from './contract/request.ts';
|
|
40
|
+
export type { Contract } from './contract/component.ts';
|
|
41
|
+
export type { JSONSchema } from './contract/schemas.ts';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export { Assignment } from './assignment.js';
|
|
2
|
+
export { Call } from './call.js';
|
|
3
|
+
export { Cascade } from './cascade.js';
|
|
4
|
+
export { Component } from './component.js';
|
|
5
|
+
export { Composition } from './composition.js';
|
|
6
|
+
export { Connector } from './connector.js';
|
|
7
|
+
export { Context } from './context.js';
|
|
8
|
+
export { Encoded } from './encoded.js';
|
|
9
|
+
export { Effect } from './effect.js';
|
|
10
|
+
export { Emission } from './emission.js';
|
|
11
|
+
export { Event } from './event.js';
|
|
12
|
+
export { Gate } from './gate.js';
|
|
13
|
+
export { Locator } from './locator.js';
|
|
14
|
+
export { Observation } from './observation.js';
|
|
15
|
+
export { Outbox } from './outbox.js';
|
|
16
|
+
export { Operation } from './operation.js';
|
|
17
|
+
export { Query } from './query.js';
|
|
18
|
+
export { Receiver } from './receiver.js';
|
|
19
|
+
export { Reflection } from './reflection.js';
|
|
20
|
+
export { Remote } from './remote.js';
|
|
21
|
+
export { State } from './state.js';
|
|
22
|
+
export { Transition } from './transition.js';
|
|
23
|
+
export { Transmission } from './transmission.js';
|
|
24
|
+
export { Unmanaged } from './unmanaged.js';
|
|
25
|
+
export { Guard } from './guard.js';
|
|
26
|
+
export { instance } from './instance.js';
|
|
27
|
+
export { safe } from './safety.js';
|
|
28
|
+
export * as deliveries from './deliveries.js';
|
|
29
|
+
export * as entities from './entities/index.js';
|
|
30
|
+
export * as halting from './halting.js';
|
|
31
|
+
export * as exceptions from './exceptions.js';
|
|
32
|
+
export * as trail from './trail.js';
|
|
33
|
+
export * as contract from './contract/index.js';
|
|
34
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../source/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA;AAC/C,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The name this process answers addressed calls under, and what a call to one of its stateful
|
|
3
|
+
* operations names: given by `TOA_INSTANCE`, or generated once.
|
|
4
|
+
*
|
|
5
|
+
* It is kept where every copy of this package reads it, because a binding and a component loaded
|
|
6
|
+
* against two copies must agree on whose name a call carries.
|
|
7
|
+
*/
|
|
8
|
+
export declare function instance(): string;
|
|
9
|
+
/** How long an addressed call waits where it names no timeout of its own, in milliseconds. */
|
|
10
|
+
export declare function timeout(): number;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { environment } from '@toa.io/generic';
|
|
2
|
+
import { newid } from './entities/newid.js';
|
|
3
|
+
const KEY = Symbol.for('toa.core.instance');
|
|
4
|
+
// what a queue name may carry, short enough that one made of it stays within a broker's limit
|
|
5
|
+
const NAME = /^[\w.:-]{1,64}$/;
|
|
6
|
+
const TIMEOUT = 5000;
|
|
7
|
+
/**
|
|
8
|
+
* The name this process answers addressed calls under, and what a call to one of its stateful
|
|
9
|
+
* operations names: given by `TOA_INSTANCE`, or generated once.
|
|
10
|
+
*
|
|
11
|
+
* It is kept where every copy of this package reads it, because a binding and a component loaded
|
|
12
|
+
* against two copies must agree on whose name a call carries.
|
|
13
|
+
*/
|
|
14
|
+
export function instance() {
|
|
15
|
+
return (globalThis[KEY] ??= named());
|
|
16
|
+
}
|
|
17
|
+
/** How long an addressed call waits where it names no timeout of its own, in milliseconds. */
|
|
18
|
+
export function timeout() {
|
|
19
|
+
const value = Number(environment.get('TOA_ADDRESSED_TIMEOUT'));
|
|
20
|
+
return Number.isInteger(value) && value > 0 ? value : TIMEOUT;
|
|
21
|
+
}
|
|
22
|
+
function named() {
|
|
23
|
+
const given = environment.get('TOA_INSTANCE');
|
|
24
|
+
if (given === undefined)
|
|
25
|
+
return newid();
|
|
26
|
+
if (!NAME.test(given))
|
|
27
|
+
throw new Error(`TOA_INSTANCE '${given}' must be 1 to 64 letters, digits, '_', '-', '.' or ':'`);
|
|
28
|
+
return given;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=instance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance.js","sourceRoot":"","sources":["../source/instance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAC7C,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAE3C,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;AAI3C,8FAA8F;AAC9F,MAAM,IAAI,GAAG,iBAAiB,CAAA;AAE9B,MAAM,OAAO,GAAG,IAAI,CAAA;AAEpB;;;;;;GAMG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,CAAE,UAAoB,CAAC,GAAG,CAAC,KAAK,KAAK,EAAE,CAAC,CAAA;AACjD,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,OAAO;IACrB,MAAM,KAAK,GAAG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAA;IAE9D,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAA;AAC/D,CAAC;AAED,SAAS,KAAK;IACZ,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,CAAA;IAE7C,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,EAAE,CAAA;IAEvC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QACnB,MAAM,IAAI,KAAK,CACb,iBAAiB,KAAK,yDAAyD,CAChF,CAAA;IAEH,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Where a component is, as every name derived from it. */
|
|
2
|
+
export declare class Locator {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
readonly namespace: string | undefined;
|
|
5
|
+
readonly id: string;
|
|
6
|
+
readonly label: string;
|
|
7
|
+
readonly uppercase: string;
|
|
8
|
+
readonly lowercase: string;
|
|
9
|
+
constructor(name: string, namespace?: string);
|
|
10
|
+
static parse(string: string): Locator;
|
|
11
|
+
hostname(prefix?: string): string;
|
|
12
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { concat } from '@toa.io/generic';
|
|
2
|
+
/** Where a component is, as every name derived from it. */
|
|
3
|
+
export class Locator {
|
|
4
|
+
name;
|
|
5
|
+
namespace;
|
|
6
|
+
id;
|
|
7
|
+
label;
|
|
8
|
+
uppercase;
|
|
9
|
+
lowercase;
|
|
10
|
+
constructor(name, namespace) {
|
|
11
|
+
if (name === undefined)
|
|
12
|
+
throw new TypeError('Locator name must be defined');
|
|
13
|
+
this.name = name;
|
|
14
|
+
this.namespace = namespace;
|
|
15
|
+
this.id = concat(namespace, '.') + name;
|
|
16
|
+
this.label = (concat(namespace, '-') + name).toLowerCase();
|
|
17
|
+
this.uppercase = (concat(namespace, '_') + name).toUpperCase();
|
|
18
|
+
this.lowercase = (concat(namespace, '_') + name).toLowerCase();
|
|
19
|
+
}
|
|
20
|
+
static parse(string) {
|
|
21
|
+
const [namespace, name] = string.split(DOT);
|
|
22
|
+
if (name === undefined)
|
|
23
|
+
return new Locator(namespace);
|
|
24
|
+
else
|
|
25
|
+
return new Locator(name, namespace);
|
|
26
|
+
}
|
|
27
|
+
hostname(prefix) {
|
|
28
|
+
return concat(prefix?.toLowerCase(), '-') + this.label;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
const DOT = '.';
|
|
32
|
+
//# sourceMappingURL=locator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locator.js","sourceRoot":"","sources":["../source/locator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAExC,2DAA2D;AAC3D,MAAM,OAAO,OAAO;IACF,IAAI,CAAQ;IACZ,SAAS,CAAoB;IAE7B,EAAE,CAAQ;IACV,KAAK,CAAQ;IACb,SAAS,CAAQ;IACjB,SAAS,CAAQ;IAEjC,YAAmB,IAAY,EAAE,SAAkB;QACjD,IAAI,IAAI,KAAK,SAAS;YAAE,MAAM,IAAI,SAAS,CAAC,8BAA8B,CAAC,CAAA;QAE3E,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAE1B,IAAI,CAAC,EAAE,GAAG,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,IAAI,CAAA;QACvC,IAAI,CAAC,KAAK,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;QAC1D,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;QAC9D,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE,CAAA;IAChE,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,MAAc;QAChC,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAE3C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC,CAAA;;YAChD,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;IAC1C,CAAC;IAEM,QAAQ,CAAC,MAAe;QAC7B,OAAO,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAA;IACxD,CAAC;CACF;AAED,MAAM,GAAG,GAAG,GAAG,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Prometheus' own ladder, in seconds: from five milliseconds to ten seconds. */
|
|
2
|
+
export declare const DURATIONS: number[];
|
|
3
|
+
export declare const operation: {
|
|
4
|
+
duration: import("openspan").Histogram;
|
|
5
|
+
/** a refusal the operation chose: the operation working */
|
|
6
|
+
errors: import("openspan").Counter;
|
|
7
|
+
/** a failure nobody chose; `outcome` says whether another attempt could pass */
|
|
8
|
+
exceptions: import("openspan").Counter;
|
|
9
|
+
inflight: import("openspan").Gauge;
|
|
10
|
+
};
|
|
11
|
+
export declare const call: {
|
|
12
|
+
duration: import("openspan").Histogram;
|
|
13
|
+
/** only what the transmission raised: what the callee sent back is counted where it happened */
|
|
14
|
+
exceptions: import("openspan").Counter;
|
|
15
|
+
/** callers waiting, which is held for the whole round trip and not only while one runs */
|
|
16
|
+
inflight: import("openspan").Gauge;
|
|
17
|
+
};
|
|
18
|
+
export declare const event: {
|
|
19
|
+
publish: import("openspan").Histogram;
|
|
20
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { registry } from 'openspan';
|
|
2
|
+
/**
|
|
3
|
+
* What core measures, declared once for the process.
|
|
4
|
+
*
|
|
5
|
+
* An invocation and a call are two metrics rather than one with a `kind` label: a `Remote` is a
|
|
6
|
+
* `Component` too and names the very endpoint the callee does, so a single name would hold two
|
|
7
|
+
* quantities — the callee's own work, and the caller's round trip with the transport in it — and
|
|
8
|
+
* would count every remote call twice, once in each process.
|
|
9
|
+
*/
|
|
10
|
+
const meters = registry();
|
|
11
|
+
const COMPONENT = { component: null };
|
|
12
|
+
const ENDPOINT = { component: null, operation: null };
|
|
13
|
+
/** Prometheus' own ladder, in seconds: from five milliseconds to ten seconds. */
|
|
14
|
+
export const DURATIONS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10];
|
|
15
|
+
export const operation = {
|
|
16
|
+
duration: meters.histogram('toa.operation.duration', { buckets: DURATIONS, unit: 's' }, ENDPOINT),
|
|
17
|
+
/** a refusal the operation chose: the operation working */
|
|
18
|
+
errors: meters.counter('toa.operation.errors', {
|
|
19
|
+
...ENDPOINT,
|
|
20
|
+
code: null
|
|
21
|
+
}),
|
|
22
|
+
/** a failure nobody chose; `outcome` says whether another attempt could pass */
|
|
23
|
+
exceptions: meters.counter('toa.operation.exceptions', {
|
|
24
|
+
...ENDPOINT,
|
|
25
|
+
code: null,
|
|
26
|
+
outcome: null
|
|
27
|
+
}),
|
|
28
|
+
inflight: meters.gauge('toa.operation.inflight', COMPONENT)
|
|
29
|
+
};
|
|
30
|
+
export const call = {
|
|
31
|
+
duration: meters.histogram('toa.call.duration', { buckets: DURATIONS, unit: 's' }, ENDPOINT),
|
|
32
|
+
/** only what the transmission raised: what the callee sent back is counted where it happened */
|
|
33
|
+
exceptions: meters.counter('toa.call.exceptions', { ...ENDPOINT, code: null }),
|
|
34
|
+
/** callers waiting, which is held for the whole round trip and not only while one runs */
|
|
35
|
+
inflight: meters.gauge('toa.call.inflight', COMPONENT)
|
|
36
|
+
};
|
|
37
|
+
export const event = {
|
|
38
|
+
publish: meters.histogram('toa.event.publish.duration', { buckets: DURATIONS, unit: 's' }, { event: null })
|
|
39
|
+
};
|
|
40
|
+
//# sourceMappingURL=measurements.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"measurements.js","sourceRoot":"","sources":["../source/measurements.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAEnC;;;;;;;GAOG;AACH,MAAM,MAAM,GAAG,QAAQ,EAAE,CAAA;AAEzB,MAAM,SAAS,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AACrC,MAAM,QAAQ,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAA;AAErD,iFAAiF;AACjF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AAElF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAC,SAAS,CACxB,wBAAwB,EACxB,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EACjC,QAAQ,CACT;IAED,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC,OAAO,CAAC,sBAAsB,EAAE;QAC7C,GAAG,QAAQ;QACX,IAAI,EAAE,IAAI;KACX,CAAC;IAEF,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,0BAA0B,EAAE;QACrD,GAAG,QAAQ;QACX,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,IAAI;KACd,CAAC;IAEF,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,wBAAwB,EAAE,SAAS,CAAC;CAC5D,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,QAAQ,EAAE,MAAM,CAAC,SAAS,CACxB,mBAAmB,EACnB,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EACjC,QAAQ,CACT;IAED,gGAAgG;IAChG,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAE9E,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,SAAS,CAAC;CACvD,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,OAAO,EAAE,MAAM,CAAC,SAAS,CACvB,4BAA4B,EAC5B,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,EAAE,EACjC,EAAE,KAAK,EAAE,IAAI,EAAE,CAChB;CACF,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Operation } from './operation.ts';
|
|
2
|
+
import type { Store } from './operation.ts';
|
|
3
|
+
export declare class Observation extends Operation {
|
|
4
|
+
/** an observation answers what it read, and writes none of it back */
|
|
5
|
+
protected projects: boolean;
|
|
6
|
+
protected run(store: Store): Promise<void>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Operation } from './operation.js';
|
|
2
|
+
export class Observation extends Operation {
|
|
3
|
+
/** an observation answers what it read, and writes none of it back */
|
|
4
|
+
projects = true;
|
|
5
|
+
async run(store) {
|
|
6
|
+
const scope = store.scope;
|
|
7
|
+
if (scope === null ||
|
|
8
|
+
(scope?.deleted === true && store.request.query?.options?.deleted !== true))
|
|
9
|
+
store.reply = null;
|
|
10
|
+
else
|
|
11
|
+
await super.run(store);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=observation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation.js","sourceRoot":"","sources":["../source/observation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAI1C,MAAM,OAAO,WAAY,SAAQ,SAAS;IACxC,sEAAsE;IACnD,QAAQ,GAAY,IAAI,CAAA;IAExB,KAAK,CAAC,GAAG,CAAC,KAAY;QACvC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAsB,CAAA;QAE1C,IACE,KAAK,KAAK,IAAI;YACd,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,IAAK,KAAK,CAAC,OAAO,CAAC,KAAa,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;YAEpF,KAAK,CAAC,KAAK,GAAG,IAAI,CAAA;;YACf,MAAM,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { Connector } from './connector.ts';
|
|
3
|
+
import type { Cascade } from './cascade.ts';
|
|
4
|
+
import type { State } from './state.ts';
|
|
5
|
+
import type { Query as Translator } from './query.ts';
|
|
6
|
+
import type { Contract } from './contract/contract.ts';
|
|
7
|
+
import type { Entity } from './entities/entity.ts';
|
|
8
|
+
import type { EntitySet } from './entities/set.ts';
|
|
9
|
+
import type { Changeset } from './entities/changeset.ts';
|
|
10
|
+
import type { scope as Scope } from './types/operations.ts';
|
|
11
|
+
import type { Call } from './types/inbox.ts';
|
|
12
|
+
import type { Envelope, Query } from './types/request.ts';
|
|
13
|
+
/** What an operation acquires for the algorithm to run against. */
|
|
14
|
+
export type Scoped = Entity | EntitySet | Changeset | Readable | null;
|
|
15
|
+
/** What one invocation carries from step to step. */
|
|
16
|
+
export interface Store {
|
|
17
|
+
request: Envelope;
|
|
18
|
+
scope?: Scoped;
|
|
19
|
+
state?: any;
|
|
20
|
+
reply?: any;
|
|
21
|
+
/** set by a transition, which is the only operation that runs its steps again */
|
|
22
|
+
retry?: () => Promise<any>;
|
|
23
|
+
}
|
|
24
|
+
export interface Contracts {
|
|
25
|
+
request: Contract;
|
|
26
|
+
reply: Contract;
|
|
27
|
+
}
|
|
28
|
+
export interface Definition {
|
|
29
|
+
scope: Scope;
|
|
30
|
+
concurrency?: string;
|
|
31
|
+
/** whether the same call arriving twice changes state once; see `documentation/inbox.md` */
|
|
32
|
+
once?: boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare class Operation extends Connector {
|
|
35
|
+
#private;
|
|
36
|
+
scope: State;
|
|
37
|
+
/**
|
|
38
|
+
* Whether what this operation acquires may be modified and committed. Only a
|
|
39
|
+
* transition commits, and only a commit needs the pre-image an entity keeps
|
|
40
|
+
* to diff the new state against.
|
|
41
|
+
*
|
|
42
|
+
* @protected
|
|
43
|
+
*/
|
|
44
|
+
protected mutable: boolean;
|
|
45
|
+
/** whether a query of this operation may name the properties its storage reads */
|
|
46
|
+
protected projects: boolean;
|
|
47
|
+
constructor(cascade: Cascade, scope: State, contracts: Contracts, query: Translator, definition: Definition);
|
|
48
|
+
invoke(request: Envelope): Promise<any>;
|
|
49
|
+
/**
|
|
50
|
+
* The call, once. What it answered is recorded with what it changed, in one transaction, so a
|
|
51
|
+
* second arrival of the same identity finds the key taken, changes nothing, and is answered
|
|
52
|
+
* with what the first one answered.
|
|
53
|
+
*
|
|
54
|
+
* The read in front of it is not what makes that true — the key is — but it is what keeps the
|
|
55
|
+
* ordinary duplicate from running the algorithm at all, and the ordinary duplicate is a
|
|
56
|
+
* retransmission that arrives after the first call has finished.
|
|
57
|
+
*/
|
|
58
|
+
protected once(store: Store): Promise<any>;
|
|
59
|
+
/**
|
|
60
|
+
* What is recorded with the write. Read where the write is made, which is after the algorithm
|
|
61
|
+
* has run, because the reply is what a duplicate is answered with.
|
|
62
|
+
*/
|
|
63
|
+
protected call(store: Store): Call | undefined;
|
|
64
|
+
protected process(store: Store): Promise<any>;
|
|
65
|
+
protected acquire(store: Store): Promise<void>;
|
|
66
|
+
protected run(store: Store): Promise<void>;
|
|
67
|
+
protected commit(_store: Store): Promise<void>;
|
|
68
|
+
protected query(query?: Query): Promise<Scoped>;
|
|
69
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { Readable } from 'node:stream';
|
|
2
|
+
import { Connector } from './connector.js';
|
|
3
|
+
import { codes, SystemException, RequestContractException } from './exceptions.js';
|
|
4
|
+
import { environment } from '@toa.io/generic';
|
|
5
|
+
export class Operation extends Connector {
|
|
6
|
+
scope;
|
|
7
|
+
/**
|
|
8
|
+
* Whether what this operation acquires may be modified and committed. Only a
|
|
9
|
+
* transition commits, and only a commit needs the pre-image an entity keeps
|
|
10
|
+
* to diff the new state against.
|
|
11
|
+
*
|
|
12
|
+
* @protected
|
|
13
|
+
*/
|
|
14
|
+
mutable = false;
|
|
15
|
+
/** whether a query of this operation may name the properties its storage reads */
|
|
16
|
+
projects = false;
|
|
17
|
+
#cascade;
|
|
18
|
+
#contracts;
|
|
19
|
+
#query;
|
|
20
|
+
#scope;
|
|
21
|
+
#once;
|
|
22
|
+
/** a reply is validated only on local environments, which are set before an operation is built */
|
|
23
|
+
#local;
|
|
24
|
+
// eslint-disable-next-line max-params
|
|
25
|
+
constructor(cascade, scope, contracts, query, definition) {
|
|
26
|
+
super();
|
|
27
|
+
this.scope = scope;
|
|
28
|
+
this.#cascade = cascade;
|
|
29
|
+
this.#contracts = contracts;
|
|
30
|
+
this.#query = query;
|
|
31
|
+
this.#scope = definition.scope;
|
|
32
|
+
this.#once = definition.once === true;
|
|
33
|
+
this.#local = environment.get('TOA_ENV') === 'local';
|
|
34
|
+
this.depends(cascade);
|
|
35
|
+
}
|
|
36
|
+
async invoke(request) {
|
|
37
|
+
try {
|
|
38
|
+
/*
|
|
39
|
+
* A projection is what a storage reads, and only an observation's read is never written
|
|
40
|
+
* back: a transition replaces the record it read, an assignment's event carries the record
|
|
41
|
+
* it changed, and an effect reads for what it does next. Refused here rather than by the
|
|
42
|
+
* contract alone, because an authentic request skips the contract.
|
|
43
|
+
*/
|
|
44
|
+
if (!this.projects && request.query?.projection !== undefined)
|
|
45
|
+
throw new RequestContractException('`projection` is read by an observation alone');
|
|
46
|
+
if (request.authentic !== true)
|
|
47
|
+
this.#contracts.request.fit(request);
|
|
48
|
+
// the request carries the query onward in its parsed form: what a storage is given,
|
|
49
|
+
// not what the caller sent
|
|
50
|
+
if ('query' in request)
|
|
51
|
+
request.query = this.#query.parse(request.query);
|
|
52
|
+
// validate entity
|
|
53
|
+
if ('entity' in request)
|
|
54
|
+
this.scope.fit(request.entity);
|
|
55
|
+
const store = { request };
|
|
56
|
+
const reply = this.#once ? await this.once(store) : await this.process(store);
|
|
57
|
+
return restrict(reply, request.output);
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
const exception = e instanceof Error ? new SystemException(e) : e;
|
|
61
|
+
return { exception };
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The call, once. What it answered is recorded with what it changed, in one transaction, so a
|
|
66
|
+
* second arrival of the same identity finds the key taken, changes nothing, and is answered
|
|
67
|
+
* with what the first one answered.
|
|
68
|
+
*
|
|
69
|
+
* The read in front of it is not what makes that true — the key is — but it is what keeps the
|
|
70
|
+
* ordinary duplicate from running the algorithm at all, and the ordinary duplicate is a
|
|
71
|
+
* retransmission that arrives after the first call has finished.
|
|
72
|
+
*/
|
|
73
|
+
async once(store) {
|
|
74
|
+
const { id } = store.request;
|
|
75
|
+
if (id === undefined)
|
|
76
|
+
throw new RequestContractException('a request to an operation declared `once` carries no id');
|
|
77
|
+
const recalled = await this.scope.recall(id);
|
|
78
|
+
if (recalled !== null)
|
|
79
|
+
return recalled;
|
|
80
|
+
try {
|
|
81
|
+
return await this.process(store);
|
|
82
|
+
}
|
|
83
|
+
catch (exception) {
|
|
84
|
+
if (exception?.code !== codes.DuplicateCall)
|
|
85
|
+
throw exception;
|
|
86
|
+
/*
|
|
87
|
+
* It was made between the read and the write — a duplicate that arrived while the first
|
|
88
|
+
* was still running, and lost. Nothing of this one was committed, so what is answered is
|
|
89
|
+
* the other one's reply. Absent only if the record expired in between, which is the
|
|
90
|
+
* window closing on a call nobody is waiting on any more.
|
|
91
|
+
*/
|
|
92
|
+
return (await this.scope.recall(id)) ?? { exception };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* What is recorded with the write. Read where the write is made, which is after the algorithm
|
|
97
|
+
* has run, because the reply is what a duplicate is answered with.
|
|
98
|
+
*/
|
|
99
|
+
call(store) {
|
|
100
|
+
if (!this.#once)
|
|
101
|
+
return undefined;
|
|
102
|
+
/*
|
|
103
|
+
* A copy: an assignment fills its output in after the write it is recorded by returns, and
|
|
104
|
+
* what is recorded must be what was known when the record was made rather than whatever the
|
|
105
|
+
* reply became afterwards.
|
|
106
|
+
*/
|
|
107
|
+
return { id: store.request.id, reply: { ...store.reply } };
|
|
108
|
+
}
|
|
109
|
+
async process(store) {
|
|
110
|
+
await this.acquire(store);
|
|
111
|
+
await this.run(store);
|
|
112
|
+
await this.commit(store);
|
|
113
|
+
return store.reply;
|
|
114
|
+
}
|
|
115
|
+
async acquire(store) {
|
|
116
|
+
if (this.#scope === 'none')
|
|
117
|
+
return;
|
|
118
|
+
const scope = await this.query(store.request.query);
|
|
119
|
+
const raw = scope === null || scope instanceof Readable;
|
|
120
|
+
store.scope = scope;
|
|
121
|
+
store.state = raw ? scope : scope.get();
|
|
122
|
+
}
|
|
123
|
+
async run(store) {
|
|
124
|
+
const { request, state } = store;
|
|
125
|
+
const reply = await this.#cascade.run(request.input, state);
|
|
126
|
+
if (this.#local && !(reply instanceof Readable))
|
|
127
|
+
this.#contracts.reply.fit(reply);
|
|
128
|
+
store.reply = reply;
|
|
129
|
+
}
|
|
130
|
+
async commit(_store) { }
|
|
131
|
+
async query(query) {
|
|
132
|
+
if (query === undefined)
|
|
133
|
+
throw new RequestContractException('Request query is required');
|
|
134
|
+
const acquire = this.scope[this.#scope];
|
|
135
|
+
return acquire.call(this.scope, query, this.mutable);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* What a caller receives of the output it asked for: each object of it keeps the properties the
|
|
140
|
+
* request named, in the order the object holds them, and an empty list leaves no output at all.
|
|
141
|
+
* A system property is one of them: a caller that reads `VERSION` asks for it. A stream, an error,
|
|
142
|
+
* an exception and a value that is not an object are answered as they are.
|
|
143
|
+
*/
|
|
144
|
+
function restrict(reply, output) {
|
|
145
|
+
if (output === undefined || reply === null || typeof reply !== 'object')
|
|
146
|
+
return reply;
|
|
147
|
+
const answered = reply.output;
|
|
148
|
+
if (answered === undefined || answered === null || answered instanceof Readable)
|
|
149
|
+
return reply;
|
|
150
|
+
if (typeof answered !== 'object') {
|
|
151
|
+
if (output.length === 0)
|
|
152
|
+
delete reply.output;
|
|
153
|
+
return reply;
|
|
154
|
+
}
|
|
155
|
+
if (output.length === 0) {
|
|
156
|
+
delete reply.output;
|
|
157
|
+
return reply;
|
|
158
|
+
}
|
|
159
|
+
const allowed = new Set(output);
|
|
160
|
+
reply.output = Array.isArray(answered)
|
|
161
|
+
? answered.map((entity) => entity !== null && typeof entity === 'object' ? fit(entity, allowed) : entity)
|
|
162
|
+
: fit(answered, allowed);
|
|
163
|
+
return reply;
|
|
164
|
+
}
|
|
165
|
+
/** Runs per entity of a collection, hence the set and the absence of intermediates. */
|
|
166
|
+
function fit(entity, allowed) {
|
|
167
|
+
const output = {};
|
|
168
|
+
// the entity's own keys, so that what is answered keeps the order it was built in
|
|
169
|
+
for (const key of Object.keys(entity))
|
|
170
|
+
if (allowed.has(key))
|
|
171
|
+
output[key] = entity[key];
|
|
172
|
+
return output;
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=operation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operation.js","sourceRoot":"","sources":["../source/operation.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Connector } from './connector.ts';
|
|
2
|
+
import type { Atom } from './types/atomicity.ts';
|
|
3
|
+
import type { Storage } from './types/storages.ts';
|
|
4
|
+
import type { Destination, Row } from './types/outbox.ts';
|
|
5
|
+
import type { Event } from './types/state.ts';
|
|
6
|
+
export interface Options {
|
|
7
|
+
interval?: number;
|
|
8
|
+
batch?: number;
|
|
9
|
+
gap?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Owns the intent to publish. A row is built before the write so that the storage can commit
|
|
13
|
+
* it in the same transaction as the entity; publication then happens off the operation's path,
|
|
14
|
+
* and anything that fails to publish is recovered from the row.
|
|
15
|
+
*
|
|
16
|
+
* The mechanism is a safety net: in a healthy system the row is written, published within
|
|
17
|
+
* milliseconds by the same process, and marked published on that process's next tick.
|
|
18
|
+
*
|
|
19
|
+
* A storage that cannot commit a row atomically has no outbox, and this degrades to the
|
|
20
|
+
* inline emission it replaces.
|
|
21
|
+
*/
|
|
22
|
+
export declare class Outbox extends Connector {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(destinations: Destination[], storage: Storage | undefined, atom: Atom, options?: Options);
|
|
25
|
+
/** whether the storage can commit a row atomically with the entity */
|
|
26
|
+
get durable(): boolean;
|
|
27
|
+
/**
|
|
28
|
+
* An assignment's images are the write's own, so it hands over an event with neither, and
|
|
29
|
+
* the storage fills them in.
|
|
30
|
+
*/
|
|
31
|
+
row(event: Partial<Event>): Row;
|
|
32
|
+
/**
|
|
33
|
+
* Hands a committed row over. Awaited by the caller only on the legacy path — with an
|
|
34
|
+
* outbox this returns at once and the broker leaves the operation's path.
|
|
35
|
+
*/
|
|
36
|
+
publish(row: Row): Promise<void> | void;
|
|
37
|
+
protected open(): Promise<void>;
|
|
38
|
+
protected close(): Promise<void>;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Constant, never configuration: rows carry their lane, so lowering this would leave rows in
|
|
42
|
+
* lanes nobody reads any more. It is also the ceiling on replicas of one component, and a
|
|
43
|
+
* power of two so that the common replica counts divide evenly.
|
|
44
|
+
*/
|
|
45
|
+
export declare const LANES = 128;
|