@toa.io/core 1.0.0-alpha.3 → 1.0.0-alpha.300

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/package.json +28 -12
  2. package/transpiled/abandon.d.ts +9 -0
  3. package/transpiled/abandon.js +37 -0
  4. package/transpiled/abandon.js.map +1 -0
  5. package/transpiled/assignment.d.ts +6 -0
  6. package/transpiled/assignment.js +25 -0
  7. package/transpiled/assignment.js.map +1 -0
  8. package/transpiled/call.d.ts +10 -0
  9. package/transpiled/call.js +146 -0
  10. package/transpiled/call.js.map +1 -0
  11. package/transpiled/cascade.d.ts +7 -0
  12. package/transpiled/cascade.js +28 -0
  13. package/transpiled/cascade.js.map +1 -0
  14. package/transpiled/component.d.ts +15 -0
  15. package/transpiled/component.js +93 -0
  16. package/transpiled/component.js.map +1 -0
  17. package/transpiled/composition.d.ts +6 -0
  18. package/transpiled/composition.js +23 -0
  19. package/transpiled/composition.js.map +1 -0
  20. package/transpiled/connector.d.ts +54 -0
  21. package/transpiled/connector.js +193 -0
  22. package/transpiled/connector.js.map +1 -0
  23. package/transpiled/context.d.ts +25 -0
  24. package/transpiled/context.js +55 -0
  25. package/transpiled/context.js.map +1 -0
  26. package/transpiled/contract/contract.d.ts +10 -0
  27. package/transpiled/contract/contract.js +14 -0
  28. package/transpiled/contract/contract.js.map +1 -0
  29. package/transpiled/contract/index.d.ts +2 -0
  30. package/transpiled/contract/index.js +3 -0
  31. package/transpiled/contract/index.js.map +1 -0
  32. package/transpiled/contract/reply.d.ts +7 -0
  33. package/transpiled/contract/reply.js +48 -0
  34. package/transpiled/contract/reply.js.map +1 -0
  35. package/transpiled/contract/request.d.ts +39 -0
  36. package/transpiled/contract/request.js +111 -0
  37. package/transpiled/contract/request.js.map +1 -0
  38. package/transpiled/contract/schemas.d.ts +4 -0
  39. package/transpiled/contract/schemas.js +36 -0
  40. package/transpiled/contract/schemas.js.map +1 -0
  41. package/transpiled/discovery.d.ts +19 -0
  42. package/transpiled/discovery.js +52 -0
  43. package/transpiled/discovery.js.map +1 -0
  44. package/transpiled/effect.d.ts +5 -0
  45. package/transpiled/effect.js +11 -0
  46. package/transpiled/effect.js.map +1 -0
  47. package/transpiled/emission.d.ts +10 -0
  48. package/transpiled/emission.js +16 -0
  49. package/transpiled/emission.js.map +1 -0
  50. package/transpiled/entities/changeset.d.ts +10 -0
  51. package/transpiled/entities/changeset.js +27 -0
  52. package/transpiled/entities/changeset.js.map +1 -0
  53. package/transpiled/entities/entity.d.ts +19 -0
  54. package/transpiled/entities/entity.js +137 -0
  55. package/transpiled/entities/entity.js.map +1 -0
  56. package/transpiled/entities/factory.d.ts +27 -0
  57. package/transpiled/entities/factory.js +38 -0
  58. package/transpiled/entities/factory.js.map +1 -0
  59. package/transpiled/entities/index.d.ts +5 -0
  60. package/transpiled/entities/index.js +6 -0
  61. package/transpiled/entities/index.js.map +1 -0
  62. package/transpiled/entities/newid.d.ts +10 -0
  63. package/transpiled/entities/newid.js +35 -0
  64. package/transpiled/entities/newid.js.map +1 -0
  65. package/transpiled/entities/set.d.ts +10 -0
  66. package/transpiled/entities/set.js +19 -0
  67. package/transpiled/entities/set.js.map +1 -0
  68. package/transpiled/event.d.ts +14 -0
  69. package/transpiled/event.js +51 -0
  70. package/transpiled/event.js.map +1 -0
  71. package/transpiled/exceptions.d.ts +89 -0
  72. package/transpiled/exceptions.js +180 -0
  73. package/transpiled/exceptions.js.map +1 -0
  74. package/transpiled/exposition.d.ts +18 -0
  75. package/transpiled/exposition.js +18 -0
  76. package/transpiled/exposition.js.map +1 -0
  77. package/transpiled/guard.d.ts +7 -0
  78. package/transpiled/guard.js +12 -0
  79. package/transpiled/guard.js.map +1 -0
  80. package/transpiled/index.d.ts +37 -0
  81. package/transpiled/index.js +31 -0
  82. package/transpiled/index.js.map +1 -0
  83. package/transpiled/instance.d.ts +10 -0
  84. package/transpiled/instance.js +30 -0
  85. package/transpiled/instance.js.map +1 -0
  86. package/transpiled/locator.d.ts +12 -0
  87. package/transpiled/locator.js +32 -0
  88. package/transpiled/locator.js.map +1 -0
  89. package/transpiled/observation.d.ts +5 -0
  90. package/transpiled/observation.js +12 -0
  91. package/transpiled/observation.js.map +1 -0
  92. package/transpiled/operation.d.ts +67 -0
  93. package/transpiled/operation.js +127 -0
  94. package/transpiled/operation.js.map +1 -0
  95. package/transpiled/outbox.d.ts +45 -0
  96. package/transpiled/outbox.js +430 -0
  97. package/transpiled/outbox.js.map +1 -0
  98. package/transpiled/query/criteria.d.ts +6 -0
  99. package/transpiled/query/criteria.js +74 -0
  100. package/transpiled/query/criteria.js.map +1 -0
  101. package/transpiled/query/options.d.ts +3 -0
  102. package/transpiled/query/options.js +27 -0
  103. package/transpiled/query/options.js.map +1 -0
  104. package/transpiled/query.d.ts +9 -0
  105. package/transpiled/query.js +57 -0
  106. package/transpiled/query.js.map +1 -0
  107. package/transpiled/receiver.d.ts +20 -0
  108. package/transpiled/receiver.js +113 -0
  109. package/transpiled/receiver.js.map +1 -0
  110. package/transpiled/reflection.d.ts +9 -0
  111. package/transpiled/reflection.js +13 -0
  112. package/transpiled/reflection.js.map +1 -0
  113. package/transpiled/remote.d.ts +10 -0
  114. package/transpiled/remote.js +11 -0
  115. package/transpiled/remote.js.map +1 -0
  116. package/transpiled/state.d.ts +36 -0
  117. package/transpiled/state.js +131 -0
  118. package/transpiled/state.js.map +1 -0
  119. package/transpiled/trail.d.ts +71 -0
  120. package/transpiled/trail.js +110 -0
  121. package/transpiled/trail.js.map +1 -0
  122. package/transpiled/transition.d.ts +14 -0
  123. package/transpiled/transition.js +51 -0
  124. package/transpiled/transition.js.map +1 -0
  125. package/transpiled/transmission.d.ts +8 -0
  126. package/transpiled/transmission.js +30 -0
  127. package/transpiled/transmission.js.map +1 -0
  128. package/transpiled/types/atomicity.d.ts +56 -0
  129. package/transpiled/types/atomicity.js +2 -0
  130. package/transpiled/types/atomicity.js.map +1 -0
  131. package/transpiled/types/bindings.d.ts +77 -0
  132. package/transpiled/types/bindings.js +2 -0
  133. package/transpiled/types/bindings.js.map +1 -0
  134. package/transpiled/types/bridges.d.ts +38 -0
  135. package/transpiled/types/bridges.js +2 -0
  136. package/transpiled/types/bridges.js.map +1 -0
  137. package/transpiled/types/extensions.d.ts +92 -0
  138. package/transpiled/types/extensions.js +2 -0
  139. package/transpiled/types/extensions.js.map +1 -0
  140. package/transpiled/types/inbox.d.ts +22 -0
  141. package/transpiled/types/inbox.js +2 -0
  142. package/transpiled/types/inbox.js.map +1 -0
  143. package/transpiled/types/index.d.ts +14 -0
  144. package/transpiled/types/index.js +9 -0
  145. package/transpiled/types/index.js.map +1 -0
  146. package/transpiled/types/message.d.ts +16 -0
  147. package/transpiled/types/message.js +2 -0
  148. package/transpiled/types/message.js.map +1 -0
  149. package/transpiled/types/operations.d.ts +15 -0
  150. package/transpiled/types/operations.js +2 -0
  151. package/transpiled/types/operations.js.map +1 -0
  152. package/transpiled/types/outbox.d.ts +54 -0
  153. package/transpiled/types/outbox.js +2 -0
  154. package/transpiled/types/outbox.js.map +1 -0
  155. package/transpiled/types/receiver.d.ts +9 -0
  156. package/transpiled/types/receiver.js +2 -0
  157. package/transpiled/types/receiver.js.map +1 -0
  158. package/transpiled/types/request.d.ts +103 -0
  159. package/transpiled/types/request.js +2 -0
  160. package/transpiled/types/request.js.map +1 -0
  161. package/transpiled/types/state.d.ts +9 -0
  162. package/transpiled/types/state.js +2 -0
  163. package/transpiled/types/state.js.map +1 -0
  164. package/transpiled/types/storages.d.ts +146 -0
  165. package/transpiled/types/storages.js +2 -0
  166. package/transpiled/types/storages.js.map +1 -0
  167. package/transpiled/unmanaged.d.ts +5 -0
  168. package/transpiled/unmanaged.js +7 -0
  169. package/transpiled/unmanaged.js.map +1 -0
  170. package/src/assignment.js +0 -22
  171. package/src/call.js +0 -42
  172. package/src/cascade.js +0 -36
  173. package/src/component.js +0 -41
  174. package/src/composition.js +0 -25
  175. package/src/connector.js +0 -183
  176. package/src/context.js +0 -55
  177. package/src/contract/conditions.js +0 -21
  178. package/src/contract/index.js +0 -7
  179. package/src/contract/reply.js +0 -25
  180. package/src/contract/request.js +0 -67
  181. package/src/contract/schemas/error.yaml +0 -9
  182. package/src/contract/schemas/index.js +0 -7
  183. package/src/contract/schemas/query.yaml +0 -31
  184. package/src/discovery.js +0 -44
  185. package/src/emission.js +0 -23
  186. package/src/entities/changeset.js +0 -47
  187. package/src/entities/entity.js +0 -58
  188. package/src/entities/factory.js +0 -33
  189. package/src/entities/index.js +0 -5
  190. package/src/entities/set.js +0 -15
  191. package/src/event.js +0 -40
  192. package/src/exceptions.js +0 -99
  193. package/src/exposition.js +0 -27
  194. package/src/index.js +0 -47
  195. package/src/locator.js +0 -49
  196. package/src/observation.js +0 -20
  197. package/src/operation.js +0 -69
  198. package/src/query/criteria.js +0 -41
  199. package/src/query/options.js +0 -40
  200. package/src/query.js +0 -41
  201. package/src/receiver.js +0 -65
  202. package/src/reflection.js +0 -28
  203. package/src/remote.js +0 -17
  204. package/src/state.js +0 -98
  205. package/src/transition.js +0 -60
  206. package/src/transmission.js +0 -33
  207. package/test/call.fixtures.js +0 -27
  208. package/test/call.test.js +0 -46
  209. package/test/component.fixtures.js +0 -21
  210. package/test/component.test.js +0 -40
  211. package/test/connector.fixtures.js +0 -40
  212. package/test/connector.test.js +0 -176
  213. package/test/context.fixtures.js +0 -18
  214. package/test/context.test.js +0 -29
  215. package/test/contract/conditions.test.js +0 -26
  216. package/test/contract/contract.fixtures.js +0 -33
  217. package/test/contract/request.test.js +0 -112
  218. package/test/emission.fixtures.js +0 -17
  219. package/test/emission.test.js +0 -35
  220. package/test/entities/entity.fixtures.js +0 -26
  221. package/test/entities/entity.test.js +0 -76
  222. package/test/entities/factory.fixtures.js +0 -18
  223. package/test/entities/factory.test.js +0 -48
  224. package/test/entities/set.fixtures.js +0 -11
  225. package/test/entities/set.test.js +0 -12
  226. package/test/event.fixtures.js +0 -29
  227. package/test/event.test.js +0 -118
  228. package/test/locator.test.js +0 -113
  229. package/test/query.fixtures.js +0 -100
  230. package/test/query.test.js +0 -86
  231. package/test/receiver.fixtures.js +0 -23
  232. package/test/receiver.test.js +0 -95
  233. package/test/reflection.test.js +0 -30
  234. package/test/state.fixtures.js +0 -47
  235. package/test/state.test.js +0 -46
  236. package/test/transmission.fixtures.js +0 -15
  237. package/test/transmission.test.js +0 -46
  238. package/types/bindings.d.ts +0 -40
  239. package/types/bridges.ts +0 -30
  240. package/types/component.d.ts +0 -9
  241. package/types/connector.d.ts +0 -18
  242. package/types/context.d.ts +0 -21
  243. package/types/entity.d.ts +0 -46
  244. package/types/event.d.ts +0 -11
  245. package/types/exception.d.ts +0 -4
  246. package/types/extensions.d.ts +0 -29
  247. package/types/index.ts +0 -14
  248. package/types/locator.d.ts +0 -12
  249. package/types/message.d.ts +0 -3
  250. package/types/operations.d.ts +0 -2
  251. package/types/query.d.ts +0 -15
  252. package/types/receiver.d.ts +0 -12
  253. package/types/reflection.d.ts +0 -14
  254. package/types/request.d.ts +0 -23
  255. package/types/state.d.ts +0 -35
  256. package/types/storages.d.ts +0 -71
@@ -0,0 +1,110 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ import { environment } from '@toa.io/generic';
3
+ import { LoopException } from './exceptions.js';
4
+ /**
5
+ * What the invocation running now came by: the chain of hops it passed through and the rule that
6
+ * refuses one that has come back to where it had been, and the identity of the call it is
7
+ * serving, from which the identity of every call it makes is derived.
8
+ *
9
+ * Ambient, like the trace context and for the same reason: an algorithm's `context` is built
10
+ * once per operation at boot and shared by every invocation of it, so nothing per-invocation
11
+ * can be handed to it. It is not the trace context's own store, which `console.span` replaces
12
+ * on every span and does not enter at all when the trace is unsampled — a chain that
13
+ * disappears under sampling is a breaker that stops breaking in production.
14
+ *
15
+ * One writer, `Component.invoke`, where the hop is appended and the identity is put in scope;
16
+ * two readers, `Call.invoke`, which puts both on the request it is about to send, and
17
+ * `Outbox.row`, which writes the chain onto the row so it outlives the operation that caused it.
18
+ */
19
+ // as openspan holds its own: a process may carry two copies of this module, and a chain that
20
+ // is empty because the writer sat in the other one is a breaker that never fires. The name says
21
+ // what is stored, so a copy carrying the chain alone does not answer where the whole is expected
22
+ const KEY = Symbol.for('toa.core.invocation');
23
+ const storage = (globalThis[KEY] ??= new AsyncLocalStorage());
24
+ /**
25
+ * What the environment says, read where a component is built rather than once for the process,
26
+ * as the outbox reads its own — so a composition booted after a variable was set sees it.
27
+ *
28
+ * `TOA_TRAIL_REPEATS=0` refuses nothing: the chain is still stamped, carried and bounded. It is
29
+ * the off switch, and it exists because this refuses calls an application may be making today —
30
+ * a handshake written as `a > b > a > b > a` is three occurrences of one hop. A breaker with no
31
+ * way to open it is itself the outage.
32
+ */
33
+ export function limits() {
34
+ return {
35
+ repeats: number('TOA_TRAIL_REPEATS', 3),
36
+ depth: number('TOA_TRAIL_DEPTH', 32)
37
+ };
38
+ }
39
+ /** The invocation running now, where there is one. */
40
+ export function current() {
41
+ return storage.getStore();
42
+ }
43
+ /** Runs `task` as the invocation the chain now ends with. */
44
+ export async function follow(invocation, task) {
45
+ return storage.run(invocation, task);
46
+ }
47
+ /**
48
+ * The ordinal of the call `invocation` is about to make to `endpoint`, counting from zero, and
49
+ * counts it. Read once per call, on the caller's own path, which is where the order is the order
50
+ * the algorithm made them in.
51
+ */
52
+ export function ordinal(invocation, endpoint) {
53
+ const made = invocation.calls.get(endpoint) ?? 0;
54
+ invocation.calls.set(endpoint, made + 1);
55
+ return made;
56
+ }
57
+ /**
58
+ * The chain this hop makes, or a raise where it is one hop too many: a hop already taken
59
+ * `repeats` times is a cycle, and a chain past `depth` is one nothing meant to make. Both are
60
+ * permanent, so what hits one is set aside rather than tried again into the same loop.
61
+ *
62
+ * The chain is copied rather than appended to, which is what makes it a path down the call
63
+ * tree rather than a log of everything that happened — an operation calling one endpoint fifty
64
+ * times makes fifty chains of one hop, not one chain of fifty.
65
+ */
66
+ export function extend(inbound, hop, limits) {
67
+ const hops = clip(received(inbound), limits.depth);
68
+ const trail = [...hops, hop];
69
+ if (limits.repeats === 0)
70
+ return trail;
71
+ if (trail.length > limits.depth)
72
+ throw new LoopException(`Call chain is ${trail.length} hops deep`, trail);
73
+ let seen = 0;
74
+ for (const passed of hops)
75
+ if (passed === hop)
76
+ seen++;
77
+ if (seen + 1 >= limits.repeats)
78
+ throw new LoopException(`'${hop}' is hop ${seen + 1} of this chain`, trail);
79
+ return trail;
80
+ }
81
+ /**
82
+ * How an event is named in a chain. The sigil is what tells it from an operation: the two are
83
+ * the same shape, a component may declare one of each under a single name, and `sync` is both
84
+ * the event every component inherits and an ordinary name for an operation.
85
+ *
86
+ * What an operator rewires to break a cycle is the subscription rather than the operation, so a
87
+ * chain that named only operations would not say how a component was re-entered.
88
+ */
89
+ export function event(destination) {
90
+ return '~' + destination;
91
+ }
92
+ /**
93
+ * What came off the wire, as a chain and nothing else. Neither the request contract nor a
94
+ * message validates this — a request is not validated at all once it is `authentic` — so a
95
+ * malformed one would otherwise become a `TypeError` where a named exception was contracted
96
+ * for. Bounding it is `extend`'s, one hop later, which is the only place the limits are known.
97
+ */
98
+ export function received(value) {
99
+ return Array.isArray(value) ? value.filter((hop) => typeof hop === 'string') : [];
100
+ }
101
+ // with the hop being appended that is one past the cap, which is enough to be refused; the
102
+ // rest is a message buying memory, and where the rule is off it is what bounds the chain
103
+ function clip(hops, depth) {
104
+ return hops.length > depth ? hops.slice(0, depth) : hops;
105
+ }
106
+ function number(variable, fallback) {
107
+ const declared = Number(environment.get(variable));
108
+ return Number.isNaN(declared) || declared < 0 ? fallback : declared;
109
+ }
110
+ //# sourceMappingURL=trail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trail.js","sourceRoot":"","sources":["../source/trail.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Operation } from './operation.js';
2
+ import type { Contracts, Definition, Store } from './operation.js';
3
+ import type { Cascade } from './cascade.js';
4
+ import type { State } from './state.js';
5
+ import type { Query as Translator } from './query.js';
6
+ export declare class Transition extends Operation {
7
+ #private;
8
+ /** a transition is the only operation that commits */
9
+ protected mutable: boolean;
10
+ constructor(cascade: Cascade, scope: State, contract: Contracts, query: Translator, definition: Definition);
11
+ protected process(store: Store): Promise<any>;
12
+ protected acquire(store: Store): Promise<void>;
13
+ protected commit(store: Store): Promise<void>;
14
+ }
@@ -0,0 +1,51 @@
1
+ import { retry } from '@toa.io/generic';
2
+ import { Operation } from './operation.js';
3
+ import { StateConcurrencyException, StateNotFoundException } from './exceptions.js';
4
+ export class Transition extends Operation {
5
+ /** a transition is the only operation that commits */
6
+ mutable = true;
7
+ #concurrency;
8
+ // eslint-disable-next-line max-params
9
+ constructor(cascade, scope, contract, query, definition) {
10
+ super(cascade, scope, contract, query, definition);
11
+ this.#concurrency = definition.concurrency;
12
+ }
13
+ async process(store) {
14
+ return retry(async (retry) => this.#retry(store, retry), RETRY);
15
+ }
16
+ async acquire(store) {
17
+ const { request } = store;
18
+ store.scope =
19
+ request.query === undefined ? this.scope.init() : await this.query(request.query);
20
+ const entity = store.scope;
21
+ if (entity === null ||
22
+ (entity.deleted && request.query?.options?.deleted !== true))
23
+ throw new StateNotFoundException();
24
+ store.state = entity.get();
25
+ }
26
+ async commit(store) {
27
+ const { scope, state, reply, retry } = store;
28
+ if (reply.error !== undefined)
29
+ return;
30
+ const entity = scope;
31
+ entity.set(state);
32
+ const result = await this.scope.commit(entity, store.request.input, this.call(store));
33
+ if (result !== false)
34
+ return;
35
+ if (this.#concurrency === 'retry')
36
+ await retry?.();
37
+ else
38
+ throw new StateConcurrencyException();
39
+ }
40
+ async #retry(store, retry) {
41
+ store.retry = retry;
42
+ return super.process(store);
43
+ }
44
+ }
45
+ const RETRY = {
46
+ base: 10,
47
+ max: 5000,
48
+ dispersion: 1,
49
+ retries: 32
50
+ };
51
+ //# sourceMappingURL=transition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transition.js","sourceRoot":"","sources":["../source/transition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,yBAAyB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AAOnF,MAAM,OAAO,UAAW,SAAQ,SAAS;IACvC,sDAAsD;IACnC,OAAO,GAAG,IAAI,CAAA;IAExB,YAAY,CAAoB;IAEzC,sCAAsC;IACtC,YACE,OAAgB,EAChB,KAAY,EACZ,QAAmB,EACnB,KAAiB,EACjB,UAAsB;QAEtB,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,CAAA;QAElD,IAAI,CAAC,YAAY,GAAG,UAAU,CAAC,WAAW,CAAA;IAC5C,CAAC;IAEkB,KAAK,CAAC,OAAO,CAAC,KAAY;QAC3C,OAAO,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,KAAK,CAAC,CAAA;IACjE,CAAC;IAEkB,KAAK,CAAC,OAAO,CAAC,KAAY;QAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;QAEzB,KAAK,CAAC,KAAK;YACT,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAEnF,MAAM,MAAM,GAAG,KAAK,CAAC,KAAsB,CAAA;QAE3C,IACE,MAAM,KAAK,IAAI;YACf,CAAC,MAAM,CAAC,OAAO,IAAK,OAAO,CAAC,KAAa,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;YAErE,MAAM,IAAI,sBAAsB,EAAE,CAAA;QAEpC,KAAK,CAAC,KAAK,GAAG,MAAM,CAAC,GAAG,EAAE,CAAA;IAC5B,CAAC;IAEkB,KAAK,CAAC,MAAM,CAAC,KAAY;QAC1C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAA;QAE5C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,OAAM;QAErC,MAAM,MAAM,GAAG,KAAe,CAAA;QAE9B,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAEjB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAErF,IAAI,MAAM,KAAK,KAAK;YAAE,OAAM;QAE5B,IAAI,IAAI,CAAC,YAAY,KAAK,OAAO;YAAE,MAAM,KAAK,EAAE,EAAE,CAAA;;YAC7C,MAAM,IAAI,yBAAyB,EAAE,CAAA;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAY,EAAE,KAAyB;QAClD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAA;QAEnB,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC7B,CAAC;CACF;AAED,MAAM,KAAK,GAAG;IACZ,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,IAAI;IACT,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,EAAE;CACZ,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { Connector } from './connector.js';
2
+ import type { Consumer, Terms } from './types/bindings.js';
3
+ import type { Request } from './types/request.js';
4
+ export declare class Transmission extends Connector {
5
+ #private;
6
+ constructor(bindings: Consumer[]);
7
+ request(request: Request, terms?: Terms): Promise<any>;
8
+ }
@@ -0,0 +1,30 @@
1
+ import { Connector } from './connector.js';
2
+ import { TransmissionException } from './exceptions.js';
3
+ export class Transmission extends Connector {
4
+ #bindings;
5
+ constructor(bindings) {
6
+ super();
7
+ this.#bindings = bindings;
8
+ this.depends(bindings);
9
+ }
10
+ async request(request, terms) {
11
+ let reply = false;
12
+ let i = 0;
13
+ while (reply === false && i < this.#bindings.length) {
14
+ const binding = this.#bindings[i];
15
+ i++;
16
+ if (request?.task === true) {
17
+ if (binding.task === undefined)
18
+ continue;
19
+ await binding.task(request);
20
+ reply = null;
21
+ }
22
+ else
23
+ reply = await binding.request(request, terms);
24
+ }
25
+ if (reply === false)
26
+ throw new TransmissionException(`All (${this.#bindings.length}) bindings rejected.`);
27
+ return reply;
28
+ }
29
+ }
30
+ //# sourceMappingURL=transmission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transmission.js","sourceRoot":"","sources":["../source/transmission.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AAIvD,MAAM,OAAO,YAAa,SAAQ,SAAS;IAChC,SAAS,CAAY;IAE9B,YAAmB,QAAoB;QACrC,KAAK,EAAE,CAAA;QAEP,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAA;QACzB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxB,CAAC;IAEM,KAAK,CAAC,OAAO,CAAC,OAAgB,EAAE,KAAa;QAClD,IAAI,KAAK,GAAQ,KAAK,CAAA;QACtB,IAAI,CAAC,GAAG,CAAC,CAAA;QAET,OAAO,KAAK,KAAK,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YACpD,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAA;YAEjC,CAAC,EAAE,CAAA;YAEH,IAAI,OAAO,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC;gBAC3B,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS;oBAAE,SAAQ;gBAExC,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;gBAC3B,KAAK,GAAG,IAAI,CAAA;YACd,CAAC;;gBAAM,KAAK,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;QACtD,CAAC;QAED,IAAI,KAAK,KAAK,KAAK;YACjB,MAAM,IAAI,qBAAqB,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,sBAAsB,CAAC,CAAA;QAEtF,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
@@ -0,0 +1,56 @@
1
+ import type { Connector } from '../connector.js';
2
+ /** Which of the group this replica is, and how many of them there are. */
3
+ export interface Assignment {
4
+ i: number;
5
+ n: number;
6
+ }
7
+ /**
8
+ * What one group of replicas decides together, in one place. The decisions here are the ones
9
+ * processes cannot arrange by talking to each other: they need a single arbiter and a step
10
+ * indivisible from its point of view.
11
+ */
12
+ export interface Atom extends Connector {
13
+ /**
14
+ * An exclusive claim on slots of `0..total`: while this replica holds one, no other
15
+ * replica of the group does. Answered from memory, so it costs nothing to ask.
16
+ *
17
+ * `null` while this replica owns nothing — after a restart, during a rollout, or while
18
+ * coordination is unreachable. Whoever asks must be able to stand down: acting on a claim
19
+ * that cannot be supported is a different guarantee, not a degraded one.
20
+ */
21
+ slots(total: number): number[] | null;
22
+ /**
23
+ * Calls `listener` with the assignment this replica holds, and again whenever it changes —
24
+ * one arrived, was lost, or the group resized. Answers with what removes the listener
25
+ * again.
26
+ *
27
+ * A change and not a heartbeat: a group that stays as it is never calls back. It is called
28
+ * once as it is added, with the claim as it stands.
29
+ */
30
+ onassigned(listener: (assignment: Assignment | null) => void): () => void;
31
+ /**
32
+ * Debt the group has run up under each key, in milliseconds. Every call adds its own deltas
33
+ * and reads back where the group stands, so a replica reports what it alone has spent and
34
+ * still decides on what all of them have.
35
+ *
36
+ * Rejects where there is nothing to arbitrate through.
37
+ */
38
+ meter(keys: string[], deltas: number[]): Promise<number[]>;
39
+ /**
40
+ * Runs `routine` holding `keys`, and while it holds them no other replica of the group
41
+ * does. Waits for as long as it takes to acquire them.
42
+ *
43
+ * The lease is extended for as long as the routine runs. An extension that fails aborts the
44
+ * signal the routine is given, which is the only way it learns it no longer holds what it
45
+ * is working under.
46
+ *
47
+ * Rejects where there is nothing to arbitrate through.
48
+ */
49
+ lock<T>(keys: string | string[], routine: (signal: AbortSignal, context: unknown) => Promise<T>): Promise<T>;
50
+ }
51
+ export interface Factory {
52
+ /** @param group what the replicas deciding together have in common */
53
+ atom(group: string, options?: {
54
+ interval?: number;
55
+ }): Atom;
56
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=atomicity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atomicity.js","sourceRoot":"","sources":["../../source/types/atomicity.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { Connector } from '../connector.js';
3
+ import type { Locator } from '../locator.js';
4
+ import type { Component } from '../component.js';
5
+ import type { Receiver } from './receiver.js';
6
+ import type { Message } from './message.js';
7
+ import type { Reply, Request } from './request.js';
8
+ /** What a binding module exports beside its factory. */
9
+ export interface Properties {
10
+ /** delivers asynchronously; an event's binding must */
11
+ async?: boolean;
12
+ /** in-process: its producers are connected first and torn down last */
13
+ local?: boolean;
14
+ }
15
+ /**
16
+ * How a call is carried, as its caller settled it. None of it is part of the request, and none of
17
+ * it is sent as part of one.
18
+ */
19
+ export interface Terms {
20
+ /** the process an addressed call goes to */
21
+ instance?: string;
22
+ /** milliseconds the caller waits, where it waits for a set time */
23
+ timeout?: number;
24
+ /** aborts when the caller stops waiting */
25
+ signal?: AbortSignal;
26
+ }
27
+ export interface Consumer extends Connector {
28
+ /**
29
+ * `false` says this binding does not carry the endpoint, and the transmission tries the
30
+ * next one. A `Readable` is a streamed reply.
31
+ */
32
+ request(request: Request, terms?: Terms): Promise<Reply | Readable | false>;
33
+ /**
34
+ * Absent where the binding cannot enqueue — a transmission skips a binding that offers
35
+ * no `task` rather than failing over it.
36
+ */
37
+ task?(request: Request): Promise<void>;
38
+ }
39
+ export interface Emitter extends Connector {
40
+ emit(message: Message): Promise<void>;
41
+ }
42
+ export interface Broadcast<L extends string = string> extends Connector {
43
+ transmit<T>(label: L, payload: T): Promise<void>;
44
+ receive<T>(label: L, callback: (payload: T) => void | Promise<void>): Promise<void>;
45
+ }
46
+ export interface Factory {
47
+ /** `stateful` are the endpoints among `endpoints` that take addressed calls only */
48
+ producer(locator: Locator, endpoints: string[], component: Component, stateful?: string[]): Connector;
49
+ consumer(locator: Locator, endpoint: string): Consumer;
50
+ /** only the binding an event declares is asked for one */
51
+ emitter?(locator: Locator, label: string): Emitter;
52
+ /** `group` is absent for an exclusive subscription */
53
+ receiver?(locator: Locator, label: string, group: string | undefined, receiver: Receiver): Connector;
54
+ broadcast?(name: string, group?: string): Broadcast;
55
+ /**
56
+ * A channel is a name the caller picks, from which the binding derives whatever its
57
+ * transport needs, and `uris` are the brokers to carry it over — so a second broker set
58
+ * costs the binding no configuration and no variable of its own.
59
+ */
60
+ outbound?(channel: string, uris: string[]): Outbound;
61
+ /** what arrives on `channel` under `label` */
62
+ inbound?(channel: string, uris: string[], label: string, sink: Inbound): Connector;
63
+ }
64
+ /**
65
+ * Publishes to a channel, addressed by label. It forwards messages and nothing else: what
66
+ * `send` is handed is what is published, with no envelope, no field and no header of the
67
+ * binding's own, and none stripped — because a message shape is often somebody else's
68
+ * contract, and an extension shipping changes into another system must be able to send
69
+ * exactly what that system accepts.
70
+ */
71
+ export interface Outbound extends Connector {
72
+ send(label: string, message: object): Promise<void>;
73
+ }
74
+ /** What a binding hands a message to. */
75
+ export interface Inbound {
76
+ accept(message: object): Promise<void>;
77
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bindings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bindings.js","sourceRoot":"","sources":["../../source/types/bindings.ts"],"names":[],"mappings":""}
@@ -0,0 +1,38 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { Connector } from '../connector.js';
3
+ import type { Context } from '../context.js';
4
+ import type { Event as StateEvent } from './state.js';
5
+ import type { Reply, Request } from './request.js';
6
+ /**
7
+ * What runs one endpoint. `mount` and `unmount` are the component author's, called by the
8
+ * bridge as it opens and closes; core only ever asks for `execute`.
9
+ */
10
+ export interface Algorithm extends Connector {
11
+ execute(input: any, scope?: object | object[]): Promise<Reply | Readable>;
12
+ }
13
+ export interface Event extends Connector {
14
+ condition(event: StateEvent): Promise<boolean>;
15
+ payload(event: StateEvent): Promise<object>;
16
+ }
17
+ export interface Receiver extends Connector {
18
+ condition(payload: object): Promise<boolean>;
19
+ /** the trailing arguments are what the receiver declaration named */
20
+ request(payload: object, ...args: unknown[]): Promise<Request>;
21
+ }
22
+ /** Runs on every change to an entity's state, before the contract is applied. */
23
+ export interface Guard {
24
+ fit(state: object, origin: object | null): boolean;
25
+ }
26
+ /** Connectors whose lifecycle moments are the component's. */
27
+ export interface RunCommands {
28
+ preflight?: Connector;
29
+ settle?: Connector;
30
+ dispose?: Connector;
31
+ }
32
+ export interface Factory {
33
+ algorithm(path: string, endpoint: string, context: Context): Algorithm | Promise<Algorithm>;
34
+ event?(path: string, label: string, context: Context): Event | Promise<Event>;
35
+ receiver?(path: string, label: string): Receiver | Promise<Receiver>;
36
+ guard?(path: string, name: string, context: Context): Guard | Promise<Guard>;
37
+ rc?(path: string, context: Context): Promise<RunCommands | undefined>;
38
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=bridges.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridges.js","sourceRoot":"","sources":["../../source/types/bridges.ts"],"names":[],"mappings":""}
@@ -0,0 +1,92 @@
1
+ import type { Connector } from '../connector.js';
2
+ import type { Locator } from '../locator.js';
3
+ import type { Component } from '../component.js';
4
+ import type { Remote } from '../remote.js';
5
+ import type { Receiver } from './receiver.js';
6
+ import type { Context } from '../context.js';
7
+ import type { Storage } from './storages.js';
8
+ import type { Broadcast, Emitter, Inbound, Outbound } from './bindings.js';
9
+ import type { Atom } from './atomicity.js';
10
+ import type { Source } from './request.js';
11
+ import type { Destination } from './outbox.js';
12
+ /**
13
+ * What the process hosting an extension provides to it: the counterpart of a component's
14
+ * context. What is returned is a connector the extension depends on.
15
+ */
16
+ export interface Host {
17
+ /** a component of the context, by locator */
18
+ remote(locator: Locator, source?: Source): Promise<Remote>;
19
+ /** a channel of the messaging binding */
20
+ broadcast<L extends string = string>(channel: string, group?: string): Promise<Broadcast<L>>;
21
+ /** components to run inside the extension's own process */
22
+ composition(paths: string[]): Promise<Connector>;
23
+ /** a consumer of an event of the context, `namespace.component.event` */
24
+ receive(label: string, receiver: Receiver): Promise<Connector>;
25
+ /** what the replicas of one group decide together */
26
+ atom(group: string): Atom;
27
+ /** where this deployment publishes a channel, over the brokers named */
28
+ outbound(binding: string, channel: string, uris: string[]): Promise<Outbound>;
29
+ /** what arrives on a channel under one label */
30
+ inbound(binding: string, channel: string, uris: string[], label: string, sink: Inbound): Promise<Connector>;
31
+ }
32
+ /**
33
+ * `Manifest` is a type parameter rather than an import: `@toa.io/norm` depends on core, so
34
+ * core cannot name its types.
35
+ */
36
+ export interface Factory<Manifest = unknown> {
37
+ tenant?(locator: Locator, declaration: any, manifest: Manifest): Connector | Promise<Connector>;
38
+ aspect?(locator: Locator, declaration: any): Aspect | Aspect[];
39
+ /**
40
+ * Where a committed state change of this component goes, beside its own events. Read before
41
+ * the storage is made, because one of these is what gives a component an outbox when it
42
+ * declares no event at all.
43
+ */
44
+ destination?(locator: Locator, declaration: any, manifest: Manifest): Destination | Promise<Destination> | undefined;
45
+ /** what the extension runs as a process of its own; `null` where it is off here */
46
+ service?(): Connector | null | Promise<Connector | null>;
47
+ /**
48
+ * What the extension keeps in every process, whatever that process runs — the counterpart of
49
+ * `tenant` for a process rather than a component. Asked of every extension the process has
50
+ * loaded, and the predefined ones are loaded by every process for this.
51
+ *
52
+ * `null` where the extension keeps nothing here.
53
+ */
54
+ resident?(host: Host): Resident | null | Promise<Resident | null>;
55
+ component?(component: Component): Component;
56
+ context?(context: Context): Context;
57
+ manage?(composition: Connector): Connector;
58
+ storage?(storage: Storage, locator: Locator): Storage;
59
+ emitter?(emitter: Emitter, label: string, locator: Locator): Emitter;
60
+ receiver?(receiver: Receiver, locator: Locator): Receiver;
61
+ }
62
+ /**
63
+ * A connector that lives as long as the process, whatever the process runs.
64
+ *
65
+ * It connects before what the process was built with and goes after it, which is what makes it
66
+ * the place for something that answers for the process rather than for anything in it — the
67
+ * readiness probe is the one this was written for.
68
+ */
69
+ export interface Resident extends Connector {
70
+ /** Everything the process was built with has connected. */
71
+ complete?: () => Promise<void>;
72
+ }
73
+ export interface Aspect extends Connector {
74
+ /** the key it takes on the context; a duplicate is a boot error */
75
+ readonly name: string;
76
+ invoke(...args: any[]): any;
77
+ }
78
+ /**
79
+ * What an extension puts on a component's context, as the extension states it. How it is
80
+ * presented there is the bridge's — a bash bridge has no context to put anything on — and
81
+ * what is declared here is the key and what it holds.
82
+ */
83
+ export interface Contribution {
84
+ /** the key on the context */
85
+ name: string;
86
+ /** what the key holds, as TypeScript */
87
+ type?: string;
88
+ /** what `type` names, by the module it comes from */
89
+ imports?: Record<string, string[]>;
90
+ /** a JSON Schema to read the type from instead, where a component states one */
91
+ schema?: object;
92
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../source/types/extensions.ts"],"names":[],"mappings":""}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * What a call was, kept so that the same call arriving again is refused rather than made twice.
3
+ *
4
+ * Everything about it is core's, as the outbox row is: core builds it and hands it to the write,
5
+ * and the storage commits it in the transaction the entity is committed in. Written only for a
6
+ * call that changed something — an operation that refused, or that raised, leaves nothing, and a
7
+ * call that arrives again after one of those is made again and refuses again.
8
+ */
9
+ export interface Call {
10
+ /** the identity of the request, which is the key it is refused on */
11
+ id: string;
12
+ /** what the call answered, so that a duplicate of it is answered rather than refused */
13
+ reply: object;
14
+ }
15
+ /**
16
+ * The read side of an inbox. What writes a record is the storage's own: it happens inside the
17
+ * transaction the storage opened, which core never reaches into.
18
+ */
19
+ export interface Inbox {
20
+ /** what the call under this identity answered, or `null` where it was never made */
21
+ recall(id: string): Promise<object | null>;
22
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../source/types/inbox.ts"],"names":[],"mappings":""}
@@ -0,0 +1,14 @@
1
+ export * as atomicity from './atomicity.js';
2
+ export * as bindings from './bindings.js';
3
+ export * as bridges from './bridges.js';
4
+ export * as extensions from './extensions.js';
5
+ export * as operations from './operations.js';
6
+ export * as inbox from './inbox.js';
7
+ export * as outbox from './outbox.js';
8
+ export * as storages from './storages.js';
9
+ export type { Contribution } from './extensions.js';
10
+ export type { Event } from './state.js';
11
+ export type { Message } from './message.js';
12
+ export type { Receiver } from './receiver.js';
13
+ export type { Call, Guard, Observation, Transition } from './operations.js';
14
+ export type { Envelope, Maybe, Options, Query, Reply, RemoteError, Request, Source } from './request.js';
@@ -0,0 +1,9 @@
1
+ export * as atomicity from './atomicity.js';
2
+ export * as bindings from './bindings.js';
3
+ export * as bridges from './bridges.js';
4
+ export * as extensions from './extensions.js';
5
+ export * as operations from './operations.js';
6
+ export * as inbox from './inbox.js';
7
+ export * as outbox from './outbox.js';
8
+ export * as storages from './storages.js';
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../source/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AACzC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,UAAU,MAAM,iBAAiB,CAAA;AAC7C,OAAO,KAAK,KAAK,MAAM,YAAY,CAAA;AACnC,OAAO,KAAK,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA"}
@@ -0,0 +1,16 @@
1
+ export interface Message<T = any> {
2
+ payload: T;
3
+ /**
4
+ * What this message is, so that a receiver's state change happens once however many times it
5
+ * arrives. Derived from the outbox row it was published from, which is committed once, so the
6
+ * immediate path, the pump and a redelivery all carry the one identity.
7
+ */
8
+ id?: string;
9
+ /** W3C traceparent */
10
+ telemetry?: string;
11
+ /**
12
+ * The hops that led to the state change this is about, so a receiver of it continues the
13
+ * chain rather than starting one. See `core/source/trail.ts`.
14
+ */
15
+ trail?: string[];
16
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message.js","sourceRoot":"","sources":["../../source/types/message.ts"],"names":[],"mappings":""}
@@ -0,0 +1,15 @@
1
+ import type { Request } from './request.js';
2
+ export type type = 'transition' | 'observation' | 'assignment' | 'computation' | 'effect' | 'unmanaged';
3
+ export type scope = 'object' | 'objects' | 'changeset' | 'stream' | 'none';
4
+ /**
5
+ * How an endpoint is called. What it resolves to is what the operation declares — `toa types`
6
+ * writes that per operation, and these are what a hand-written context says instead.
7
+ */
8
+ export type Call<Output = any, Input = any> = (request: Request<Input>) => Promise<Output>;
9
+ export type Observation<Output = any, Input = never, Entity = unknown> = (request: Request<Input, Entity>) => Promise<Output extends unknown[] ? Output : Output | null>;
10
+ export type Transition<Output = any, Input = never, Entity = unknown> = (request: Request<Input, Entity>) => Promise<Output | null>;
11
+ /**
12
+ * Runs on every change to an entity's state, before the contract is applied. `false` refuses
13
+ * the change as `EntityGuard`.
14
+ */
15
+ export type Guard<T, C = unknown> = (state: T, origin: T | null, context: C) => boolean;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operations.js","sourceRoot":"","sources":["../../source/types/operations.ts"],"names":[],"mappings":""}