@toa.io/core 1.0.0-alpha.32 → 1.0.0-alpha.320

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 (283) 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 +187 -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 +148 -0
  16. package/transpiled/component.js.map +1 -0
  17. package/transpiled/composition.d.ts +6 -0
  18. package/transpiled/composition.js +20 -0
  19. package/transpiled/composition.js.map +1 -0
  20. package/transpiled/connector.d.ts +71 -0
  21. package/transpiled/connector.js +248 -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/component.d.ts +37 -0
  27. package/transpiled/contract/component.js +94 -0
  28. package/transpiled/contract/component.js.map +1 -0
  29. package/transpiled/contract/contract.d.ts +10 -0
  30. package/transpiled/contract/contract.js +14 -0
  31. package/transpiled/contract/contract.js.map +1 -0
  32. package/transpiled/contract/index.d.ts +4 -0
  33. package/transpiled/contract/index.js +5 -0
  34. package/transpiled/contract/index.js.map +1 -0
  35. package/transpiled/contract/reply.d.ts +7 -0
  36. package/transpiled/contract/reply.js +48 -0
  37. package/transpiled/contract/reply.js.map +1 -0
  38. package/transpiled/contract/request.d.ts +49 -0
  39. package/transpiled/contract/request.js +152 -0
  40. package/transpiled/contract/request.js.map +1 -0
  41. package/transpiled/contract/schemas.d.ts +4 -0
  42. package/transpiled/contract/schemas.js +38 -0
  43. package/transpiled/contract/schemas.js.map +1 -0
  44. package/transpiled/contract/system.d.ts +33 -0
  45. package/transpiled/contract/system.js +76 -0
  46. package/transpiled/contract/system.js.map +1 -0
  47. package/transpiled/deliveries.d.ts +22 -0
  48. package/transpiled/deliveries.js +31 -0
  49. package/transpiled/deliveries.js.map +1 -0
  50. package/transpiled/effect.d.ts +7 -0
  51. package/transpiled/effect.js +13 -0
  52. package/transpiled/effect.js.map +1 -0
  53. package/transpiled/emission.d.ts +10 -0
  54. package/transpiled/emission.js +16 -0
  55. package/transpiled/emission.js.map +1 -0
  56. package/transpiled/encoded.d.ts +16 -0
  57. package/transpiled/encoded.js +25 -0
  58. package/transpiled/encoded.js.map +1 -0
  59. package/transpiled/entities/changeset.d.ts +10 -0
  60. package/transpiled/entities/changeset.js +27 -0
  61. package/transpiled/entities/changeset.js.map +1 -0
  62. package/transpiled/entities/entity.d.ts +19 -0
  63. package/transpiled/entities/entity.js +137 -0
  64. package/transpiled/entities/entity.js.map +1 -0
  65. package/transpiled/entities/factory.d.ts +27 -0
  66. package/transpiled/entities/factory.js +38 -0
  67. package/transpiled/entities/factory.js.map +1 -0
  68. package/transpiled/entities/index.d.ts +5 -0
  69. package/transpiled/entities/index.js +6 -0
  70. package/transpiled/entities/index.js.map +1 -0
  71. package/transpiled/entities/newid.d.ts +11 -0
  72. package/transpiled/entities/newid.js +41 -0
  73. package/transpiled/entities/newid.js.map +1 -0
  74. package/transpiled/entities/set.d.ts +10 -0
  75. package/transpiled/entities/set.js +19 -0
  76. package/transpiled/entities/set.js.map +1 -0
  77. package/transpiled/event.d.ts +20 -0
  78. package/transpiled/event.js +65 -0
  79. package/transpiled/event.js.map +1 -0
  80. package/transpiled/exceptions.d.ts +110 -0
  81. package/transpiled/exceptions.js +215 -0
  82. package/transpiled/exceptions.js.map +1 -0
  83. package/transpiled/gate.d.ts +40 -0
  84. package/transpiled/gate.js +84 -0
  85. package/transpiled/gate.js.map +1 -0
  86. package/transpiled/guard.d.ts +7 -0
  87. package/transpiled/guard.js +12 -0
  88. package/transpiled/guard.js.map +1 -0
  89. package/transpiled/halting.d.ts +16 -0
  90. package/transpiled/halting.js +25 -0
  91. package/transpiled/halting.js.map +1 -0
  92. package/transpiled/index.d.ts +44 -0
  93. package/transpiled/index.js +36 -0
  94. package/transpiled/index.js.map +1 -0
  95. package/transpiled/instance.d.ts +10 -0
  96. package/transpiled/instance.js +30 -0
  97. package/transpiled/instance.js.map +1 -0
  98. package/transpiled/locator.d.ts +12 -0
  99. package/transpiled/locator.js +32 -0
  100. package/transpiled/locator.js.map +1 -0
  101. package/transpiled/measurements.d.ts +20 -0
  102. package/transpiled/measurements.js +40 -0
  103. package/transpiled/measurements.js.map +1 -0
  104. package/transpiled/observation.d.ts +7 -0
  105. package/transpiled/observation.js +14 -0
  106. package/transpiled/observation.js.map +1 -0
  107. package/transpiled/operation.d.ts +73 -0
  108. package/transpiled/operation.js +213 -0
  109. package/transpiled/operation.js.map +1 -0
  110. package/transpiled/outbox.d.ts +45 -0
  111. package/transpiled/outbox.js +448 -0
  112. package/transpiled/outbox.js.map +1 -0
  113. package/transpiled/outbox.measurements.d.ts +4 -0
  114. package/transpiled/outbox.measurements.js +38 -0
  115. package/transpiled/outbox.measurements.js.map +1 -0
  116. package/transpiled/parts.d.ts +20 -0
  117. package/transpiled/parts.js +23 -0
  118. package/transpiled/parts.js.map +1 -0
  119. package/transpiled/query/criteria.d.ts +6 -0
  120. package/transpiled/query/criteria.js +177 -0
  121. package/transpiled/query/criteria.js.map +1 -0
  122. package/transpiled/query/options.d.ts +3 -0
  123. package/transpiled/query/options.js +34 -0
  124. package/transpiled/query/options.js.map +1 -0
  125. package/transpiled/query.d.ts +9 -0
  126. package/transpiled/query.js +57 -0
  127. package/transpiled/query.js.map +1 -0
  128. package/transpiled/receiver.d.ts +20 -0
  129. package/transpiled/receiver.js +113 -0
  130. package/transpiled/receiver.js.map +1 -0
  131. package/transpiled/reflection.d.ts +9 -0
  132. package/transpiled/reflection.js +13 -0
  133. package/transpiled/reflection.js.map +1 -0
  134. package/transpiled/remote.d.ts +10 -0
  135. package/transpiled/remote.js +11 -0
  136. package/transpiled/remote.js.map +1 -0
  137. package/transpiled/rendering.d.ts +13 -0
  138. package/transpiled/rendering.js +21 -0
  139. package/transpiled/rendering.js.map +1 -0
  140. package/transpiled/safety.d.ts +5 -0
  141. package/transpiled/safety.js +26 -0
  142. package/transpiled/safety.js.map +1 -0
  143. package/transpiled/state.d.ts +36 -0
  144. package/transpiled/state.js +131 -0
  145. package/transpiled/state.js.map +1 -0
  146. package/transpiled/trail.d.ts +78 -0
  147. package/transpiled/trail.js +112 -0
  148. package/transpiled/trail.js.map +1 -0
  149. package/transpiled/transition.d.ts +14 -0
  150. package/transpiled/transition.js +51 -0
  151. package/transpiled/transition.js.map +1 -0
  152. package/transpiled/transmission.d.ts +8 -0
  153. package/transpiled/transmission.js +30 -0
  154. package/transpiled/transmission.js.map +1 -0
  155. package/transpiled/types/atomicity.d.ts +58 -0
  156. package/transpiled/types/atomicity.js +2 -0
  157. package/transpiled/types/atomicity.js.map +1 -0
  158. package/transpiled/types/bindings.d.ts +82 -0
  159. package/transpiled/types/bindings.js +2 -0
  160. package/transpiled/types/bindings.js.map +1 -0
  161. package/transpiled/types/bridges.d.ts +41 -0
  162. package/transpiled/types/bridges.js +2 -0
  163. package/transpiled/types/bridges.js.map +1 -0
  164. package/transpiled/types/extensions.d.ts +121 -0
  165. package/transpiled/types/extensions.js +2 -0
  166. package/transpiled/types/extensions.js.map +1 -0
  167. package/transpiled/types/inbox.d.ts +27 -0
  168. package/transpiled/types/inbox.js +2 -0
  169. package/transpiled/types/inbox.js.map +1 -0
  170. package/transpiled/types/index.d.ts +14 -0
  171. package/transpiled/types/index.js +9 -0
  172. package/transpiled/types/index.js.map +1 -0
  173. package/transpiled/types/message.d.ts +16 -0
  174. package/transpiled/types/message.js +2 -0
  175. package/transpiled/types/message.js.map +1 -0
  176. package/transpiled/types/operations.d.ts +15 -0
  177. package/transpiled/types/operations.js +2 -0
  178. package/transpiled/types/operations.js.map +1 -0
  179. package/transpiled/types/outbox.d.ts +68 -0
  180. package/transpiled/types/outbox.js +2 -0
  181. package/transpiled/types/outbox.js.map +1 -0
  182. package/transpiled/types/receiver.d.ts +9 -0
  183. package/transpiled/types/receiver.js +2 -0
  184. package/transpiled/types/receiver.js.map +1 -0
  185. package/transpiled/types/request.d.ts +119 -0
  186. package/transpiled/types/request.js +2 -0
  187. package/transpiled/types/request.js.map +1 -0
  188. package/transpiled/types/state.d.ts +9 -0
  189. package/transpiled/types/state.js +2 -0
  190. package/transpiled/types/state.js.map +1 -0
  191. package/transpiled/types/storages.d.ts +154 -0
  192. package/transpiled/types/storages.js +2 -0
  193. package/transpiled/types/storages.js.map +1 -0
  194. package/transpiled/unmanaged.d.ts +5 -0
  195. package/transpiled/unmanaged.js +7 -0
  196. package/transpiled/unmanaged.js.map +1 -0
  197. package/src/assignment.js +0 -31
  198. package/src/call.js +0 -42
  199. package/src/cascade.js +0 -35
  200. package/src/component.js +0 -41
  201. package/src/composition.js +0 -25
  202. package/src/connector.js +0 -183
  203. package/src/context.js +0 -55
  204. package/src/contract/conditions.js +0 -21
  205. package/src/contract/index.js +0 -7
  206. package/src/contract/reply.js +0 -25
  207. package/src/contract/request.js +0 -67
  208. package/src/contract/schemas/error.yaml +0 -9
  209. package/src/contract/schemas/index.js +0 -7
  210. package/src/contract/schemas/query.yaml +0 -30
  211. package/src/discovery.js +0 -44
  212. package/src/emission.js +0 -23
  213. package/src/entities/changeset.js +0 -38
  214. package/src/entities/entity.js +0 -74
  215. package/src/entities/factory.js +0 -33
  216. package/src/entities/index.js +0 -5
  217. package/src/entities/set.js +0 -15
  218. package/src/event.js +0 -40
  219. package/src/exceptions.js +0 -100
  220. package/src/exposition.js +0 -27
  221. package/src/index.js +0 -47
  222. package/src/locator.js +0 -54
  223. package/src/observation.js +0 -20
  224. package/src/operation.js +0 -69
  225. package/src/query/criteria.js +0 -41
  226. package/src/query/options.js +0 -40
  227. package/src/query.js +0 -41
  228. package/src/receiver.js +0 -61
  229. package/src/reflection.js +0 -28
  230. package/src/remote.js +0 -17
  231. package/src/state.js +0 -99
  232. package/src/transition.js +0 -67
  233. package/src/transmission.js +0 -33
  234. package/test/call.fixtures.js +0 -27
  235. package/test/call.test.js +0 -46
  236. package/test/component.fixtures.js +0 -21
  237. package/test/component.test.js +0 -40
  238. package/test/connector.fixtures.js +0 -40
  239. package/test/connector.test.js +0 -176
  240. package/test/context.fixtures.js +0 -18
  241. package/test/context.test.js +0 -29
  242. package/test/contract/conditions.test.js +0 -26
  243. package/test/contract/contract.fixtures.js +0 -33
  244. package/test/contract/request.test.js +0 -112
  245. package/test/emission.fixtures.js +0 -17
  246. package/test/emission.test.js +0 -35
  247. package/test/entities/entity.fixtures.js +0 -29
  248. package/test/entities/entity.test.js +0 -65
  249. package/test/entities/factory.fixtures.js +0 -18
  250. package/test/entities/factory.test.js +0 -48
  251. package/test/entities/set.fixtures.js +0 -11
  252. package/test/entities/set.test.js +0 -12
  253. package/test/event.fixtures.js +0 -29
  254. package/test/event.test.js +0 -118
  255. package/test/locator.test.js +0 -113
  256. package/test/query.fixtures.js +0 -100
  257. package/test/query.test.js +0 -86
  258. package/test/receiver.fixtures.js +0 -23
  259. package/test/receiver.test.js +0 -95
  260. package/test/reflection.test.js +0 -30
  261. package/test/state.fixtures.js +0 -47
  262. package/test/state.test.js +0 -46
  263. package/test/transmission.fixtures.js +0 -15
  264. package/test/transmission.test.js +0 -46
  265. package/types/bindings.d.ts +0 -40
  266. package/types/bridges.ts +0 -30
  267. package/types/component.d.ts +0 -9
  268. package/types/connector.d.ts +0 -18
  269. package/types/context.d.ts +0 -21
  270. package/types/entity.d.ts +0 -46
  271. package/types/event.d.ts +0 -11
  272. package/types/exception.d.ts +0 -4
  273. package/types/extensions.d.ts +0 -29
  274. package/types/index.ts +0 -14
  275. package/types/locator.d.ts +0 -13
  276. package/types/message.d.ts +0 -3
  277. package/types/operations.d.ts +0 -2
  278. package/types/query.d.ts +0 -15
  279. package/types/receiver.d.ts +0 -12
  280. package/types/reflection.d.ts +0 -14
  281. package/types/request.d.ts +0 -23
  282. package/types/state.d.ts +0 -35
  283. package/types/storages.d.ts +0 -71
@@ -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,73 @@
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
+ /**
32
+ * Whether the same call arriving twice changes state once; see `documentation/inbox.md`. A
33
+ * number is how many seconds a call is remembered, where the deployment's window is not the
34
+ * one its callers retry within.
35
+ */
36
+ once?: boolean | number;
37
+ }
38
+ export declare class Operation extends Connector {
39
+ #private;
40
+ scope: State;
41
+ /**
42
+ * Whether what this operation acquires may be modified and committed. Only a
43
+ * transition commits, and only a commit needs the pre-image an entity keeps
44
+ * to diff the new state against.
45
+ *
46
+ * @protected
47
+ */
48
+ protected mutable: boolean;
49
+ /** whether a query of this operation may name the properties its storage reads */
50
+ protected projects: boolean;
51
+ constructor(cascade: Cascade, scope: State, contracts: Contracts, query: Translator, definition: Definition);
52
+ invoke(request: Envelope): Promise<any>;
53
+ /**
54
+ * The call, once. What it answered is recorded with what it changed, in one transaction, so a
55
+ * second arrival of the same identity finds the key taken, changes nothing, and is answered
56
+ * with what the first one answered.
57
+ *
58
+ * The read in front of it is not what makes that true — the key is — but it is what keeps the
59
+ * ordinary duplicate from running the algorithm at all, and the ordinary duplicate is a
60
+ * retransmission that arrives after the first call has finished.
61
+ */
62
+ protected once(store: Store): Promise<any>;
63
+ /**
64
+ * What is recorded with the write. Read where the write is made, which is after the algorithm
65
+ * has run, because the reply is what a duplicate is answered with.
66
+ */
67
+ protected call(store: Store): Call | undefined;
68
+ protected process(store: Store): Promise<any>;
69
+ protected acquire(store: Store): Promise<void>;
70
+ protected run(store: Store): Promise<void>;
71
+ protected commit(_store: Store): Promise<void>;
72
+ protected query(query?: Query): Promise<Scoped>;
73
+ }
@@ -0,0 +1,213 @@
1
+ import { Readable, Transform, pipeline } from 'node:stream';
2
+ import { Connector } from './connector.js';
3
+ import { codes, SystemException, RequestContractException } from './exceptions.js';
4
+ import * as parts from './parts.js';
5
+ import { environment } from '@toa.io/generic';
6
+ export class Operation extends Connector {
7
+ scope;
8
+ /**
9
+ * Whether what this operation acquires may be modified and committed. Only a
10
+ * transition commits, and only a commit needs the pre-image an entity keeps
11
+ * to diff the new state against.
12
+ *
13
+ * @protected
14
+ */
15
+ mutable = false;
16
+ /** whether a query of this operation may name the properties its storage reads */
17
+ projects = false;
18
+ #cascade;
19
+ #contracts;
20
+ #query;
21
+ #scope;
22
+ #once;
23
+ /** what this operation states of how long a call is remembered; the deployment's where absent */
24
+ #retention;
25
+ /** a reply is validated only on local environments, which are set before an operation is built */
26
+ #local;
27
+ // eslint-disable-next-line max-params
28
+ constructor(cascade, scope, contracts, query, definition) {
29
+ super();
30
+ this.scope = scope;
31
+ this.#cascade = cascade;
32
+ this.#contracts = contracts;
33
+ this.#query = query;
34
+ this.#scope = definition.scope;
35
+ this.#once = definition.once === true || typeof definition.once === 'number';
36
+ this.#retention = typeof definition.once === 'number' ? definition.once : undefined;
37
+ this.#local = environment.get('TOA_ENV') === 'local';
38
+ this.depends(cascade);
39
+ }
40
+ async invoke(request) {
41
+ try {
42
+ /*
43
+ * A projection is what a storage reads, and only an observation's read is never written
44
+ * back: a transition replaces the record it read, an assignment's event carries the record
45
+ * it changed, and an effect reads for what it does next. Refused here rather than by the
46
+ * contract alone, because an authentic request skips the contract.
47
+ */
48
+ if (!this.projects && request.query?.projection !== undefined)
49
+ throw new RequestContractException('`projection` is read by an observation alone');
50
+ if (request.authentic !== true)
51
+ this.#contracts.request.fit(request);
52
+ // the request carries the query onward in its parsed form: what a storage is given,
53
+ // not what the caller sent
54
+ if ('query' in request)
55
+ request.query = this.#query.parse(request.query);
56
+ // validate entity
57
+ if ('entity' in request)
58
+ this.scope.fit(request.entity);
59
+ const store = { request };
60
+ const reply = this.#once ? await this.once(store) : await this.process(store);
61
+ return restrict(reply, request.output);
62
+ }
63
+ catch (e) {
64
+ const exception = e instanceof Error ? new SystemException(e) : e;
65
+ return { exception };
66
+ }
67
+ }
68
+ /**
69
+ * The call, once. What it answered is recorded with what it changed, in one transaction, so a
70
+ * second arrival of the same identity finds the key taken, changes nothing, and is answered
71
+ * with what the first one answered.
72
+ *
73
+ * The read in front of it is not what makes that true — the key is — but it is what keeps the
74
+ * ordinary duplicate from running the algorithm at all, and the ordinary duplicate is a
75
+ * retransmission that arrives after the first call has finished.
76
+ */
77
+ async once(store) {
78
+ const { id } = store.request;
79
+ if (id === undefined)
80
+ throw new RequestContractException('a request to an operation declared `once` carries no id');
81
+ const recalled = await this.scope.recall(id);
82
+ if (recalled !== null)
83
+ return recalled;
84
+ try {
85
+ return await this.process(store);
86
+ }
87
+ catch (exception) {
88
+ if (exception?.code !== codes.DuplicateCall)
89
+ throw exception;
90
+ /*
91
+ * It was made between the read and the write — a duplicate that arrived while the first
92
+ * was still running, and lost. Nothing of this one was committed, so what is answered is
93
+ * the other one's reply. Absent only if the record expired in between, which is the
94
+ * window closing on a call nobody is waiting on any more.
95
+ */
96
+ return (await this.scope.recall(id)) ?? { exception };
97
+ }
98
+ }
99
+ /**
100
+ * What is recorded with the write. Read where the write is made, which is after the algorithm
101
+ * has run, because the reply is what a duplicate is answered with.
102
+ */
103
+ call(store) {
104
+ if (!this.#once)
105
+ return undefined;
106
+ /*
107
+ * A copy: an assignment fills its output in after the write it is recorded by returns, and
108
+ * what is recorded must be what was known when the record was made rather than whatever the
109
+ * reply became afterwards.
110
+ */
111
+ const call = { id: store.request.id, reply: { ...store.reply } };
112
+ if (this.#retention !== undefined)
113
+ call.retention = this.#retention;
114
+ return call;
115
+ }
116
+ async process(store) {
117
+ await this.acquire(store);
118
+ await this.run(store);
119
+ await this.commit(store);
120
+ return store.reply;
121
+ }
122
+ async acquire(store) {
123
+ if (this.#scope === 'none')
124
+ return;
125
+ const scope = await this.query(store.request.query);
126
+ const raw = scope === null || scope instanceof Readable;
127
+ store.scope = scope;
128
+ store.state = raw ? scope : scope.get();
129
+ }
130
+ async run(store) {
131
+ const { request, state } = store;
132
+ const reply = await this.#cascade.run(request.input, state);
133
+ if (this.#local && !(reply instanceof Readable))
134
+ this.#contracts.reply.fit(reply);
135
+ store.reply = reply;
136
+ }
137
+ async commit(_store) { }
138
+ async query(query) {
139
+ if (query === undefined)
140
+ throw new RequestContractException('Request query is required');
141
+ const acquire = this.scope[this.#scope];
142
+ return acquire.call(this.scope, query, this.mutable);
143
+ }
144
+ }
145
+ /**
146
+ * What a caller receives of the output it asked for: each object of it keeps the properties the
147
+ * request named, in the order the object holds them, and an empty list leaves no output at all.
148
+ * A system property is one of them: a caller that reads `VERSION` asks for it. An object is one
149
+ * the output is, one of an array it is, or one a stream it is yields. An error, an exception and
150
+ * a value that is not an object are answered as they are.
151
+ */
152
+ function restrict(reply, output) {
153
+ if (output === undefined || reply === null || typeof reply !== 'object')
154
+ return reply;
155
+ // a stream is answered bare, where anything else is answered in `output`
156
+ if (reply instanceof Readable)
157
+ return restrict({ output: reply }, output).output ?? {};
158
+ const answered = reply.output;
159
+ if (answered === undefined || answered === null)
160
+ return reply;
161
+ if (output.length === 0) {
162
+ // nobody reads it, and what it holds open — a cursor, a reply pipe — is let go now
163
+ if (answered instanceof Readable)
164
+ answered.destroy();
165
+ delete reply.output;
166
+ return reply;
167
+ }
168
+ if (typeof answered !== 'object')
169
+ return reply;
170
+ const allowed = new Set(output);
171
+ // a stream of bytes is a value, as a primitive is: there is no property of it to leave out
172
+ if (answered instanceof Readable)
173
+ reply.output = answered.readableObjectMode ? restricted(answered, allowed) : answered;
174
+ else if (Array.isArray(answered))
175
+ reply.output = answered.map((value) => fitted(value, allowed));
176
+ else
177
+ reply.output = fit(answered, allowed);
178
+ return reply;
179
+ }
180
+ /**
181
+ * A stream of what `fitted` makes of each value. Joined by `pipeline`, so that a failure of
182
+ * either side reaches the other: the source's error is the reader's, and a reader that stops
183
+ * reading closes the source.
184
+ */
185
+ function restricted(source, allowed) {
186
+ const transform = new Transform({
187
+ objectMode: true,
188
+ transform(value, _, callback) {
189
+ callback(null, fitted(value, allowed));
190
+ }
191
+ });
192
+ return pipeline(source, transform, noop);
193
+ }
194
+ function fitted(value, allowed) {
195
+ // what a part carries of the set is its entry; a removal and a token are not the entity's
196
+ if (parts.is(value))
197
+ return 'entry' in value ? { entry: fit(value.entry, allowed) } : value;
198
+ return value !== null && typeof value === 'object' && !ArrayBuffer.isView(value)
199
+ ? fit(value, allowed)
200
+ : value;
201
+ }
202
+ // what `pipeline` reports is what each stream already carries to its reader
203
+ function noop() { }
204
+ /** Runs per entity of a collection, hence the set and the absence of intermediates. */
205
+ function fit(entity, allowed) {
206
+ const output = {};
207
+ // the entity's own keys, so that what is answered keeps the order it was built in
208
+ for (const key of Object.keys(entity))
209
+ if (allowed.has(key))
210
+ output[key] = entity[key];
211
+ return output;
212
+ }
213
+ //# 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;