@toa.io/core 1.0.0-alpha.31 → 1.0.0-alpha.310

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