@toa.io/core 1.0.0-alpha.29 → 1.0.0-alpha.291

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 (304) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/package.json +22 -12
  3. package/source/assignment.ts +27 -0
  4. package/source/call.ts +63 -0
  5. package/source/cascade.ts +32 -0
  6. package/source/component.ts +83 -0
  7. package/source/composition.ts +27 -0
  8. package/source/connector.ts +217 -0
  9. package/source/context.ts +68 -0
  10. package/source/contract/contract.ts +23 -0
  11. package/source/contract/index.ts +2 -0
  12. package/source/contract/reply.ts +56 -0
  13. package/source/contract/request.ts +140 -0
  14. package/source/contract/schemas.ts +39 -0
  15. package/source/discovery.ts +53 -0
  16. package/source/effect.ts +14 -0
  17. package/source/emission.ts +21 -0
  18. package/source/entities/changeset.ts +37 -0
  19. package/source/entities/entity.ts +137 -0
  20. package/source/entities/factory.ts +52 -0
  21. package/source/entities/index.ts +4 -0
  22. package/source/entities/newid.ts +9 -0
  23. package/source/entities/set.ts +27 -0
  24. package/source/event.ts +57 -0
  25. package/source/exceptions.ts +133 -0
  26. package/source/exposition.ts +33 -0
  27. package/source/guard.ts +16 -0
  28. package/source/index.ts +36 -0
  29. package/source/locator.ts +37 -0
  30. package/source/observation.ts +16 -0
  31. package/source/operation.ts +139 -0
  32. package/source/outbox/index.ts +1 -0
  33. package/source/outbox/outbox.ts +341 -0
  34. package/source/query/criteria.ts +90 -0
  35. package/source/query/options.ts +35 -0
  36. package/source/query.ts +67 -0
  37. package/source/receiver.ts +120 -0
  38. package/source/reflection.ts +20 -0
  39. package/source/remote.ts +20 -0
  40. package/source/state.ts +179 -0
  41. package/source/transition.ts +79 -0
  42. package/source/transmission.ts +38 -0
  43. package/source/types/atomicity.ts +63 -0
  44. package/source/types/bindings.ts +59 -0
  45. package/source/types/bridges.ts +54 -0
  46. package/source/types/extensions.ts +89 -0
  47. package/source/types/index.ts +14 -0
  48. package/{types/message.d.ts → source/types/message.ts} +2 -0
  49. package/source/types/operations.ts +31 -0
  50. package/source/types/outbox.ts +35 -0
  51. package/source/types/receiver.ts +10 -0
  52. package/source/types/request.ts +54 -0
  53. package/source/types/state.ts +9 -0
  54. package/source/types/storages.ts +134 -0
  55. package/source/unmanaged.ts +8 -0
  56. package/test/call.fixtures.js +10 -12
  57. package/test/call.test.js +42 -9
  58. package/test/component.fixtures.js +5 -8
  59. package/test/component.test.js +27 -10
  60. package/test/connector.fixtures.js +29 -13
  61. package/test/connector.test.js +128 -38
  62. package/test/context.fixtures.js +8 -12
  63. package/test/context.test.js +19 -8
  64. package/test/contract/conditions.test.js +15 -9
  65. package/test/contract/contract.fixtures.js +11 -16
  66. package/test/contract/request.test.js +130 -46
  67. package/test/discovery.test.js +71 -0
  68. package/test/emission.fixtures.js +6 -10
  69. package/test/emission.test.js +37 -12
  70. package/test/entities/entity.fixtures.js +11 -16
  71. package/test/entities/entity.test.js +105 -50
  72. package/test/entities/factory.fixtures.js +26 -13
  73. package/test/entities/factory.test.js +68 -17
  74. package/test/entities/set.fixtures.js +6 -8
  75. package/test/entities/set.test.js +6 -5
  76. package/test/event.fixtures.js +9 -14
  77. package/test/event.test.js +78 -34
  78. package/test/locator.test.js +32 -25
  79. package/test/outbox.test.js +202 -0
  80. package/test/query.fixtures.js +1 -5
  81. package/test/query.test.js +111 -14
  82. package/test/receiver.fixtures.js +9 -12
  83. package/test/receiver.test.js +80 -31
  84. package/test/reflection.test.js +9 -8
  85. package/test/state.fixtures.js +33 -31
  86. package/test/state.test.js +135 -19
  87. package/test/transmission.fixtures.js +4 -6
  88. package/test/transmission.test.js +47 -16
  89. package/transpiled/assignment.d.ts +6 -0
  90. package/transpiled/assignment.js +20 -0
  91. package/transpiled/assignment.js.map +1 -0
  92. package/transpiled/call.d.ts +10 -0
  93. package/transpiled/call.js +52 -0
  94. package/transpiled/call.js.map +1 -0
  95. package/transpiled/cascade.d.ts +7 -0
  96. package/transpiled/cascade.js +28 -0
  97. package/transpiled/cascade.js.map +1 -0
  98. package/transpiled/component.d.ts +15 -0
  99. package/transpiled/component.js +61 -0
  100. package/transpiled/component.js.map +1 -0
  101. package/transpiled/composition.d.ts +6 -0
  102. package/transpiled/composition.js +23 -0
  103. package/transpiled/composition.js.map +1 -0
  104. package/transpiled/connector.d.ts +47 -0
  105. package/transpiled/connector.js +185 -0
  106. package/transpiled/connector.js.map +1 -0
  107. package/transpiled/context.d.ts +18 -0
  108. package/transpiled/context.js +42 -0
  109. package/transpiled/context.js.map +1 -0
  110. package/transpiled/contract/contract.d.ts +10 -0
  111. package/transpiled/contract/contract.js +14 -0
  112. package/transpiled/contract/contract.js.map +1 -0
  113. package/transpiled/contract/index.d.ts +2 -0
  114. package/transpiled/contract/index.js +3 -0
  115. package/transpiled/contract/index.js.map +1 -0
  116. package/transpiled/contract/reply.d.ts +7 -0
  117. package/transpiled/contract/reply.js +48 -0
  118. package/transpiled/contract/reply.js.map +1 -0
  119. package/transpiled/contract/request.d.ts +29 -0
  120. package/transpiled/contract/request.js +103 -0
  121. package/transpiled/contract/request.js.map +1 -0
  122. package/transpiled/contract/schemas.d.ts +4 -0
  123. package/transpiled/contract/schemas.js +36 -0
  124. package/transpiled/contract/schemas.js.map +1 -0
  125. package/transpiled/discovery.d.ts +12 -0
  126. package/transpiled/discovery.js +34 -0
  127. package/transpiled/discovery.js.map +1 -0
  128. package/transpiled/effect.d.ts +5 -0
  129. package/transpiled/effect.js +11 -0
  130. package/transpiled/effect.js.map +1 -0
  131. package/transpiled/emission.d.ts +8 -0
  132. package/transpiled/emission.js +14 -0
  133. package/transpiled/emission.js.map +1 -0
  134. package/transpiled/entities/changeset.d.ts +10 -0
  135. package/transpiled/entities/changeset.js +27 -0
  136. package/transpiled/entities/changeset.js.map +1 -0
  137. package/transpiled/entities/entity.d.ts +19 -0
  138. package/transpiled/entities/entity.js +109 -0
  139. package/transpiled/entities/entity.js.map +1 -0
  140. package/transpiled/entities/factory.d.ts +22 -0
  141. package/transpiled/entities/factory.js +34 -0
  142. package/transpiled/entities/factory.js.map +1 -0
  143. package/transpiled/entities/index.d.ts +4 -0
  144. package/transpiled/entities/index.js +5 -0
  145. package/transpiled/entities/index.js.map +1 -0
  146. package/transpiled/entities/newid.d.ts +1 -0
  147. package/transpiled/entities/newid.js +7 -0
  148. package/transpiled/entities/newid.js.map +1 -0
  149. package/transpiled/entities/set.d.ts +10 -0
  150. package/transpiled/entities/set.js +19 -0
  151. package/transpiled/entities/set.js.map +1 -0
  152. package/transpiled/event.d.ts +14 -0
  153. package/transpiled/event.js +38 -0
  154. package/transpiled/event.js.map +1 -0
  155. package/transpiled/exceptions.d.ts +61 -0
  156. package/transpiled/exceptions.js +93 -0
  157. package/transpiled/exceptions.js.map +1 -0
  158. package/transpiled/exposition.d.ts +18 -0
  159. package/transpiled/exposition.js +18 -0
  160. package/transpiled/exposition.js.map +1 -0
  161. package/transpiled/guard.d.ts +7 -0
  162. package/transpiled/guard.js +12 -0
  163. package/transpiled/guard.js.map +1 -0
  164. package/transpiled/index.d.ts +35 -0
  165. package/transpiled/index.js +29 -0
  166. package/transpiled/index.js.map +1 -0
  167. package/transpiled/locator.d.ts +12 -0
  168. package/transpiled/locator.js +32 -0
  169. package/transpiled/locator.js.map +1 -0
  170. package/transpiled/observation.d.ts +5 -0
  171. package/transpiled/observation.js +12 -0
  172. package/transpiled/observation.js.map +1 -0
  173. package/transpiled/operation.d.ts +49 -0
  174. package/transpiled/operation.js +78 -0
  175. package/transpiled/operation.js.map +1 -0
  176. package/transpiled/outbox/index.d.ts +1 -0
  177. package/transpiled/outbox/index.js +2 -0
  178. package/transpiled/outbox/index.js.map +1 -0
  179. package/transpiled/outbox/outbox.d.ts +46 -0
  180. package/transpiled/outbox/outbox.js +268 -0
  181. package/transpiled/outbox/outbox.js.map +1 -0
  182. package/transpiled/query/criteria.d.ts +6 -0
  183. package/transpiled/query/criteria.js +74 -0
  184. package/transpiled/query/criteria.js.map +1 -0
  185. package/transpiled/query/options.d.ts +3 -0
  186. package/transpiled/query/options.js +27 -0
  187. package/transpiled/query/options.js.map +1 -0
  188. package/transpiled/query.d.ts +9 -0
  189. package/transpiled/query.js +57 -0
  190. package/transpiled/query.js.map +1 -0
  191. package/transpiled/receiver.d.ts +20 -0
  192. package/transpiled/receiver.js +92 -0
  193. package/transpiled/receiver.js.map +1 -0
  194. package/transpiled/reflection.d.ts +9 -0
  195. package/transpiled/reflection.js +13 -0
  196. package/transpiled/reflection.js.map +1 -0
  197. package/transpiled/remote.d.ts +10 -0
  198. package/transpiled/remote.js +12 -0
  199. package/transpiled/remote.js.map +1 -0
  200. package/transpiled/state.d.ts +33 -0
  201. package/transpiled/state.js +126 -0
  202. package/transpiled/state.js.map +1 -0
  203. package/transpiled/transition.d.ts +14 -0
  204. package/transpiled/transition.js +51 -0
  205. package/transpiled/transition.js.map +1 -0
  206. package/transpiled/transmission.d.ts +8 -0
  207. package/transpiled/transmission.js +30 -0
  208. package/transpiled/transmission.js.map +1 -0
  209. package/transpiled/types/atomicity.d.ts +56 -0
  210. package/transpiled/types/atomicity.js +2 -0
  211. package/transpiled/types/atomicity.js.map +1 -0
  212. package/transpiled/types/bindings.d.ts +42 -0
  213. package/transpiled/types/bindings.js +2 -0
  214. package/transpiled/types/bindings.js.map +1 -0
  215. package/transpiled/types/bridges.d.ts +38 -0
  216. package/transpiled/types/bridges.js +2 -0
  217. package/transpiled/types/bridges.js.map +1 -0
  218. package/transpiled/types/extensions.d.ts +62 -0
  219. package/transpiled/types/extensions.js +2 -0
  220. package/transpiled/types/extensions.js.map +1 -0
  221. package/transpiled/types/index.d.ts +13 -0
  222. package/transpiled/types/index.js +8 -0
  223. package/transpiled/types/index.js.map +1 -0
  224. package/transpiled/types/message.d.ts +5 -0
  225. package/transpiled/types/message.js +2 -0
  226. package/transpiled/types/message.js.map +1 -0
  227. package/transpiled/types/operations.d.ts +15 -0
  228. package/transpiled/types/operations.js +2 -0
  229. package/transpiled/types/operations.js.map +1 -0
  230. package/transpiled/types/outbox.d.ts +28 -0
  231. package/transpiled/types/outbox.js +2 -0
  232. package/transpiled/types/outbox.js.map +1 -0
  233. package/transpiled/types/receiver.d.ts +9 -0
  234. package/transpiled/types/receiver.js +2 -0
  235. package/transpiled/types/receiver.js.map +1 -0
  236. package/transpiled/types/request.d.ts +55 -0
  237. package/transpiled/types/request.js +2 -0
  238. package/transpiled/types/request.js.map +1 -0
  239. package/transpiled/types/state.d.ts +9 -0
  240. package/transpiled/types/state.js +2 -0
  241. package/transpiled/types/state.js.map +1 -0
  242. package/transpiled/types/storages.d.ts +111 -0
  243. package/transpiled/types/storages.js +2 -0
  244. package/transpiled/types/storages.js.map +1 -0
  245. package/transpiled/unmanaged.d.ts +5 -0
  246. package/transpiled/unmanaged.js +7 -0
  247. package/transpiled/unmanaged.js.map +1 -0
  248. package/tsconfig.json +10 -0
  249. package/tsconfig.tsbuildinfo +1 -0
  250. package/src/assignment.js +0 -31
  251. package/src/call.js +0 -42
  252. package/src/cascade.js +0 -36
  253. package/src/component.js +0 -41
  254. package/src/composition.js +0 -25
  255. package/src/connector.js +0 -183
  256. package/src/context.js +0 -55
  257. package/src/contract/conditions.js +0 -21
  258. package/src/contract/index.js +0 -7
  259. package/src/contract/reply.js +0 -25
  260. package/src/contract/request.js +0 -67
  261. package/src/contract/schemas/error.yaml +0 -9
  262. package/src/contract/schemas/index.js +0 -7
  263. package/src/contract/schemas/query.yaml +0 -30
  264. package/src/discovery.js +0 -44
  265. package/src/emission.js +0 -23
  266. package/src/entities/changeset.js +0 -43
  267. package/src/entities/entity.js +0 -73
  268. package/src/entities/factory.js +0 -33
  269. package/src/entities/index.js +0 -5
  270. package/src/entities/set.js +0 -15
  271. package/src/event.js +0 -40
  272. package/src/exceptions.js +0 -100
  273. package/src/exposition.js +0 -27
  274. package/src/index.js +0 -47
  275. package/src/locator.js +0 -54
  276. package/src/observation.js +0 -20
  277. package/src/operation.js +0 -69
  278. package/src/query/criteria.js +0 -41
  279. package/src/query/options.js +0 -40
  280. package/src/query.js +0 -41
  281. package/src/receiver.js +0 -65
  282. package/src/reflection.js +0 -28
  283. package/src/remote.js +0 -17
  284. package/src/state.js +0 -99
  285. package/src/transition.js +0 -73
  286. package/src/transmission.js +0 -33
  287. package/types/bindings.d.ts +0 -40
  288. package/types/bridges.ts +0 -30
  289. package/types/component.d.ts +0 -9
  290. package/types/connector.d.ts +0 -18
  291. package/types/context.d.ts +0 -21
  292. package/types/entity.d.ts +0 -46
  293. package/types/event.d.ts +0 -11
  294. package/types/exception.d.ts +0 -4
  295. package/types/extensions.d.ts +0 -29
  296. package/types/index.ts +0 -14
  297. package/types/locator.d.ts +0 -13
  298. package/types/operations.d.ts +0 -2
  299. package/types/query.d.ts +0 -15
  300. package/types/receiver.d.ts +0 -12
  301. package/types/reflection.d.ts +0 -14
  302. package/types/request.d.ts +0 -23
  303. package/types/state.d.ts +0 -35
  304. package/types/storages.d.ts +0 -71
@@ -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) {
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);
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;QACnC,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,CAAC,CAAA;QAC/C,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,42 @@
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
+ export interface Consumer extends Connector {
16
+ /**
17
+ * `false` says this binding does not carry the endpoint, and the transmission tries the
18
+ * next one. A `Readable` is a streamed reply.
19
+ */
20
+ request(request: Request): Promise<Reply | Readable | false>;
21
+ /**
22
+ * Absent where the binding cannot enqueue — a transmission skips a binding that offers
23
+ * no `task` rather than failing over it.
24
+ */
25
+ task?(request: Request): Promise<void>;
26
+ }
27
+ export interface Emitter extends Connector {
28
+ emit(message: Message): Promise<void>;
29
+ }
30
+ export interface Broadcast<L extends string = string> extends Connector {
31
+ transmit<T>(label: L, payload: T): Promise<void>;
32
+ receive<T>(label: L, callback: (payload: T) => void | Promise<void>): Promise<void>;
33
+ }
34
+ export interface Factory {
35
+ producer(locator: Locator, endpoints: string[], component: Component): Connector;
36
+ consumer(locator: Locator, endpoint: string): Consumer;
37
+ /** only the binding an event declares is asked for one */
38
+ emitter?(locator: Locator, label: string): Emitter;
39
+ /** `group` is absent for an exclusive subscription */
40
+ receiver?(locator: Locator, label: string, group: string | undefined, receiver: Receiver): Connector;
41
+ broadcast?(name: string, group?: string): Broadcast;
42
+ }
@@ -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,62 @@
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 } from './bindings.js';
9
+ import type { Atom } from './atomicity.js';
10
+ import type { Source } from './request.js';
11
+ /**
12
+ * What the process hosting an extension provides to it: the counterpart of a component's
13
+ * context. What is returned is a connector the extension depends on.
14
+ */
15
+ export interface Host {
16
+ /** a component of the context, by locator */
17
+ remote(locator: Locator, source?: Source): Promise<Remote>;
18
+ /** a channel of the messaging binding */
19
+ broadcast<L extends string = string>(channel: string, group?: string): Promise<Broadcast<L>>;
20
+ /** components to run inside the extension's own process */
21
+ composition(paths: string[]): Promise<Connector>;
22
+ /** a consumer of an event of the context, `namespace.component.event` */
23
+ receive(label: string, receiver: Receiver): Promise<Connector>;
24
+ /** what the replicas of one group decide together */
25
+ atom(group: string): Atom;
26
+ }
27
+ /**
28
+ * `Manifest` is a type parameter rather than an import: `@toa.io/norm` depends on core, so
29
+ * core cannot name its types.
30
+ */
31
+ export interface Factory<Manifest = unknown> {
32
+ tenant?(locator: Locator, declaration: any, manifest: Manifest): Connector | Promise<Connector>;
33
+ aspect?(locator: Locator, declaration: any): Aspect | Aspect[];
34
+ /** what the extension runs as a process of its own; `null` where it is off here */
35
+ service?(): Connector | null | Promise<Connector | null>;
36
+ component?(component: Component): Component;
37
+ context?(context: Context): Context;
38
+ manage?(composition: Connector): Connector;
39
+ storage?(storage: Storage): Storage;
40
+ emitter?(emitter: Emitter, label: string, locator: Locator): Emitter;
41
+ receiver?(receiver: Receiver, locator: Locator): Receiver;
42
+ }
43
+ export interface Aspect extends Connector {
44
+ /** the key it takes on the context; a duplicate is a boot error */
45
+ readonly name: string;
46
+ invoke(...args: any[]): any;
47
+ }
48
+ /**
49
+ * What an extension puts on a component's context, as the extension states it. How it is
50
+ * presented there is the bridge's — a bash bridge has no context to put anything on — and
51
+ * what is declared here is the key and what it holds.
52
+ */
53
+ export interface Contribution {
54
+ /** the key on the context */
55
+ name: string;
56
+ /** what the key holds, as TypeScript */
57
+ type?: string;
58
+ /** what `type` names, by the module it comes from */
59
+ imports?: Record<string, string[]>;
60
+ /** a JSON Schema to read the type from instead, where a component states one */
61
+ schema?: object;
62
+ }
@@ -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,13 @@
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 outbox from './outbox.js';
7
+ export * as storages from './storages.js';
8
+ export type { Contribution } from './extensions.js';
9
+ export type { Event } from './state.js';
10
+ export type { Message } from './message.js';
11
+ export type { Receiver } from './receiver.js';
12
+ export type { Call, Guard, Observation, Transition } from './operations.js';
13
+ export type { Maybe, Query, Reply, RemoteError, Request, Source } from './request.js';
@@ -0,0 +1,8 @@
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 outbox from './outbox.js';
7
+ export * as storages from './storages.js';
8
+ //# 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,MAAM,MAAM,aAAa,CAAA;AACrC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA"}
@@ -0,0 +1,5 @@
1
+ export interface Message<T = any> {
2
+ payload: T;
3
+ /** W3C traceparent */
4
+ telemetry?: string;
5
+ }
@@ -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":""}
@@ -0,0 +1,28 @@
1
+ import type { Event } from './state.js';
2
+ /**
3
+ * The intent to publish, committed with the state change it belongs to. Everything about it
4
+ * is core's: the storage writes it and, where the images are the write's own, fills
5
+ * `event.origin` and `event.state` in.
6
+ */
7
+ export interface Row {
8
+ id: string;
9
+ /** which replica pumps this row; carries no other meaning, and no ordering */
10
+ lane: number;
11
+ published: boolean;
12
+ /** not before this */
13
+ pending: number;
14
+ /** an assignment's images are absent until the storage fills them in */
15
+ event: Event;
16
+ }
17
+ /**
18
+ * The read side of an outbox. What writes a row is the storage's own: it happens inside the
19
+ * transaction the storage opened, which core never reaches into.
20
+ */
21
+ export interface Storage {
22
+ /**
23
+ * One page of what is due, still unpublished, and in one of the given lanes, in the order
24
+ * the rows were written. `after` continues from the last id of the page before.
25
+ */
26
+ pending(lanes: number[], now: number, limit: number, after?: string): Promise<Row[]>;
27
+ settle(ids: string[]): Promise<void>;
28
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=outbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../../source/types/outbox.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { Connector } from '../connector.js';
2
+ import type { Message } from './message.js';
3
+ /**
4
+ * What consumes an event of the context. Core ships one, and an extension may put its own
5
+ * in its place, so what a binding is handed is this rather than core's class.
6
+ */
7
+ export interface Receiver extends Connector {
8
+ receive(message: Message): Promise<void>;
9
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=receiver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiver.js","sourceRoot":"","sources":["../../source/types/receiver.ts"],"names":[],"mappings":""}
@@ -0,0 +1,55 @@
1
+ import type { Exception } from '../exceptions.js';
2
+ /**
3
+ * What a call asks for. `Entity` is the record it is about, which narrows the projection;
4
+ * left out, any name is accepted.
5
+ */
6
+ export interface Query<Entity = any> {
7
+ id?: string;
8
+ ids?: string[];
9
+ criteria?: string;
10
+ search?: string;
11
+ sample?: number;
12
+ omit?: number;
13
+ limit?: number;
14
+ sort?: string[];
15
+ projection?: Array<string & keyof Entity>;
16
+ version?: number;
17
+ deleted?: boolean;
18
+ }
19
+ /** Origin of a call. Stamped by the framework; whoever reads it takes the keys it knows. */
20
+ export type Source = {
21
+ namespace: string;
22
+ component: string;
23
+ operation: string;
24
+ } | {
25
+ namespace: string;
26
+ component: string;
27
+ event: string;
28
+ } | {
29
+ service: string;
30
+ };
31
+ export interface Request<Input = any, Entity = any> {
32
+ input?: Input;
33
+ query?: Query<Entity>;
34
+ /** What the operation acquires, where the caller supplies it rather than the storage. */
35
+ entity?: Entity;
36
+ authentic?: boolean;
37
+ task?: boolean;
38
+ /** W3C traceparent */
39
+ telemetry?: string;
40
+ source?: Source;
41
+ }
42
+ /**
43
+ * An error an operation declares and returns. A call resolves to it rather than throwing:
44
+ * only an exception is thrown.
45
+ */
46
+ export interface RemoteError<Code extends string = string> extends Error {
47
+ code: Code;
48
+ }
49
+ /** What an operation returns where it may refuse: the value, or the error it refused with. */
50
+ export type Maybe<T> = T | Error;
51
+ export interface Reply {
52
+ output?: any;
53
+ error?: object;
54
+ exception?: Exception;
55
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=request.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.js","sourceRoot":"","sources":["../../source/types/request.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ /** What a commit publishes: the images of one state change. */
2
+ export interface Event<State = object, Trailers = object> {
3
+ /** the pre-image; null when the entity did not exist before */
4
+ origin: State | null;
5
+ state: State;
6
+ /** out-of-band values an algorithm wrote into `state._trailers`; must be serializable */
7
+ trailers?: Trailers;
8
+ input?: object;
9
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../source/types/state.ts"],"names":[],"mappings":""}
@@ -0,0 +1,111 @@
1
+ import type { Readable } from 'node:stream';
2
+ import type { Connector } from '../connector.js';
3
+ import type { Locator } from '../locator.js';
4
+ import type { Row, Storage as Outbox } from './outbox.js';
5
+ /** the RSQL tree `@rsql/parser` produces; a storage translates it into its own dialect */
6
+ export interface Node {
7
+ type: 'LOGIC' | 'COMPARISON' | 'SELECTOR' | 'VALUE';
8
+ left?: Node;
9
+ right?: Node;
10
+ operator?: string;
11
+ selector?: string;
12
+ value?: unknown;
13
+ }
14
+ /** What a storage stores. `id` is the key; the upper-cased names are core's. */
15
+ export interface Record {
16
+ id: string;
17
+ VERSION: number;
18
+ CREATED?: number;
19
+ UPDATED?: number;
20
+ /** a tombstone's timestamp; `null` on a live record */
21
+ DELETED?: number | null;
22
+ [key: string]: any;
23
+ }
24
+ /** Everything a request query carried that was not a selector. */
25
+ export interface Options {
26
+ omit?: number;
27
+ limit?: number;
28
+ /** normalised by `query/options.ts` from `'name:asc'` into pairs */
29
+ sort?: Array<[property: string, direction: string]>;
30
+ /** always includes `VERSION`, `CREATED`, `UPDATED`, `DELETED` */
31
+ projection?: string[];
32
+ sample?: number;
33
+ /** include tombstones; without it an observation answers `null` over one */
34
+ deleted?: boolean;
35
+ }
36
+ /** What core hands a storage, written by `Query.parse`. */
37
+ export interface Query {
38
+ id?: string;
39
+ /** many identities at once; `State.objects` inits whichever of them are missing */
40
+ ids?: string[];
41
+ version?: number;
42
+ criteria?: Node;
43
+ search?: string;
44
+ options?: Options;
45
+ }
46
+ /**
47
+ * What core requires of a storage. Every member but `outbox` is called unguarded, so a
48
+ * storage that leaves one out throws where an operation needs it — a storage may serve
49
+ * only some scopes, and says so by failing rather than by declaring less.
50
+ */
51
+ export interface Storage extends Connector {
52
+ /** scope `object` */
53
+ get(query: Query): Promise<Record | null>;
54
+ /** scope `objects` */
55
+ find(query: Query): Promise<Record[]>;
56
+ /** scope `stream` */
57
+ stream(query?: Query): Promise<Readable>;
58
+ /**
59
+ * A transition's commit. `false` is a lost compare-and-swap, not an error. Where `row` is
60
+ * given, it is committed in the same transaction as the record or not at all.
61
+ */
62
+ store(record: Record, row?: Row): Promise<boolean>;
63
+ /** a transition over `objects` */
64
+ massStore(records: Record[], rows?: Row[]): Promise<boolean>;
65
+ /** an assignment; `null` where the query matched nothing */
66
+ upsert(query: Query, changeset: object, row?: Row): Promise<Record | null>;
67
+ /** get-or-create, in one indivisible step */
68
+ ensure(query: Query | undefined, properties: object, record: Record, row?: Row): Promise<Record>;
69
+ /** the driver's own handle, which an unmanaged operation is given as its state */
70
+ readonly raw: unknown;
71
+ /**
72
+ * Present only where a row can be committed atomically with the entity. Its absence is
73
+ * what makes the runtime publish inline, so a storage that cannot do this must not offer
74
+ * it: a row written outside the transaction would be a second write with a crash window
75
+ * in front of it, which is the defect the outbox exists to close.
76
+ */
77
+ readonly outbox?: Outbox;
78
+ /**
79
+ * Whether this storage applies `entity.migrations`. Absent is what a storage that does not
80
+ * says, and a component declaring migrations against one is refused at boot rather than
81
+ * starting with a structure nothing has made.
82
+ */
83
+ readonly migrates?: boolean;
84
+ }
85
+ /**
86
+ * The subset of a component's entity declaration a storage reads. Structural, so that core
87
+ * names no type of `@toa.io/norm`, which depends on core.
88
+ */
89
+ export interface Entity {
90
+ associated?: boolean;
91
+ custom?: boolean;
92
+ /** in the order they are applied; what a step is belongs to the storage that reads it */
93
+ migrations?: Migration[];
94
+ }
95
+ /**
96
+ * One file of a `migrations` directory, named after it — the component's own, or a prototype's,
97
+ * which every descendant applies to its collection ahead of its own.
98
+ */
99
+ export interface Migration {
100
+ id: string;
101
+ steps: unknown[];
102
+ /** the prototype it is inherited from; absent on the component's own */
103
+ prototype?: string;
104
+ }
105
+ export interface StorageOptions {
106
+ /** whether the component publishes anything, and so needs a place to commit a row */
107
+ outbox?: boolean;
108
+ }
109
+ export interface Factory {
110
+ storage(locator: Locator, entity: Entity, options?: StorageOptions): Storage;
111
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=storages.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storages.js","sourceRoot":"","sources":["../../source/types/storages.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { Operation } from './operation.js';
2
+ import type { Store } from './operation.js';
3
+ export declare class Unmanaged extends Operation {
4
+ protected acquire(store: Store): Promise<void>;
5
+ }
@@ -0,0 +1,7 @@
1
+ import { Operation } from './operation.js';
2
+ export class Unmanaged extends Operation {
3
+ async acquire(store) {
4
+ store.state = this.scope.storage.raw;
5
+ }
6
+ }
7
+ //# sourceMappingURL=unmanaged.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unmanaged.js","sourceRoot":"","sources":["../source/unmanaged.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,MAAM,OAAO,SAAU,SAAQ,SAAS;IACnB,KAAK,CAAC,OAAO,CAAC,KAAY;QAC3C,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAA;IACtC,CAAC;CACF"}
package/tsconfig.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "outDir": "./transpiled",
5
+ "rootDir": "./source"
6
+ },
7
+ "include": [
8
+ "source"
9
+ ]
10
+ }