@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
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/core",
3
- "version": "1.0.0-alpha.31",
3
+ "version": "1.0.0-alpha.310",
4
+ "type": "module",
4
5
  "description": "Toa Core",
5
6
  "author": "temich <tema.gurtovoy@gmail.com>",
6
7
  "homepage": "https://github.com/toa-io/toa#readme",
@@ -11,23 +12,38 @@
11
12
  "bugs": {
12
13
  "url": "https://github.com/toa-io/toa/issues"
13
14
  },
14
- "main": "src/index.js",
15
- "types": "types/index.ts",
15
+ "main": "transpiled/index.js",
16
+ "types": "transpiled/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./transpiled/index.d.ts",
20
+ "default": "./transpiled/index.js"
21
+ },
22
+ "./types": {
23
+ "types": "./transpiled/types/index.d.ts",
24
+ "default": "./transpiled/types/index.js"
25
+ },
26
+ "./package.json": "./package.json"
27
+ },
16
28
  "publishConfig": {
17
29
  "access": "public"
18
30
  },
31
+ "files": [
32
+ "transpiled",
33
+ "!**/tsconfig.tsbuildinfo",
34
+ "!**/*.test.*",
35
+ "!**/.env*"
36
+ ],
19
37
  "scripts": {
38
+ "transpile": "tsc",
20
39
  "test": "echo \"Error: run tests from root\" && exit 1"
21
40
  },
22
41
  "dependencies": {
23
- "@rsql/parser": "1.2.4",
24
- "@toa.io/console": "1.0.0-alpha.31",
25
- "@toa.io/generic": "1.0.0-alpha.31",
26
- "@toa.io/yaml": "1.0.0-alpha.31",
27
- "error-value": "0.3.0"
28
- },
29
- "devDependencies": {
30
- "clone-deep": "4.0.1"
42
+ "@rsql/parser": "1.6.0",
43
+ "@toa.io/generic": "1.0.0-alpha.310",
44
+ "@toa.io/schemas": "1.0.0-alpha.310",
45
+ "openspan": "1.0.0-alpha.305",
46
+ "uuid": "14.0.2"
31
47
  },
32
- "gitHead": "91839a488176853a0731f49abc70dc7103ed7cca"
48
+ "gitHead": "d952c57f77279729e26d52d50c6df47138ad0a4f"
33
49
  }
@@ -0,0 +1,9 @@
1
+ import type { Exception } from './exceptions.ts';
2
+ /** What a caller that stopped waiting for `target` is told. */
3
+ export declare function abandoned(target: string, signal: AbortSignal): Exception;
4
+ /**
5
+ * What the promise settles with, or *abandoned* once the signal aborts, whichever comes first — at
6
+ * once where it has aborted already. The promise goes on running, and settles with nobody waiting
7
+ * for it.
8
+ */
9
+ export declare function waiting<T>(promise: Promise<T>, signal: AbortSignal | undefined, target: string): Promise<T>;
@@ -0,0 +1,37 @@
1
+ import { AbandonedException } from './exceptions.js';
2
+ /** What a caller that stopped waiting for `target` is told. */
3
+ export function abandoned(target, signal) {
4
+ return new AbandonedException(`'${target}' went unanswered`, signal.reason);
5
+ }
6
+ /**
7
+ * What the promise settles with, or *abandoned* once the signal aborts, whichever comes first — at
8
+ * once where it has aborted already. The promise goes on running, and settles with nobody waiting
9
+ * for it.
10
+ */
11
+ export async function waiting(promise, signal, target) {
12
+ if (signal === undefined)
13
+ return await promise;
14
+ if (signal.aborted) {
15
+ promise.catch(noop);
16
+ throw abandoned(target, signal);
17
+ }
18
+ let abort = noop;
19
+ const aborted = new Promise((_resolve, reject) => {
20
+ abort = () => reject(abandoned(target, signal));
21
+ });
22
+ signal.addEventListener('abort', abort, { once: true });
23
+ try {
24
+ return await Promise.race([promise, aborted]);
25
+ }
26
+ catch (exception) {
27
+ // however the wait ended — here, or in whatever was carrying it
28
+ if (signal.aborted)
29
+ throw abandoned(target, signal);
30
+ throw exception;
31
+ }
32
+ finally {
33
+ signal.removeEventListener('abort', abort);
34
+ }
35
+ }
36
+ function noop() { }
37
+ //# sourceMappingURL=abandon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abandon.js","sourceRoot":"","sources":["../source/abandon.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAGpD,+DAA+D;AAC/D,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,MAAmB;IAC3D,OAAO,IAAI,kBAAkB,CAAC,IAAI,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;AAC7E,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,OAAmB,EACnB,MAA+B,EAC/B,MAAc;IAEd,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,MAAM,OAAO,CAAA;IAE9C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAEnB,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC;IAED,IAAI,KAAK,GAAe,IAAI,CAAA;IAE5B,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;QACtD,KAAK,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;IAEF,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IAEvD,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAC/C,CAAC;IAAC,OAAO,SAAS,EAAE,CAAC;QACnB,gEAAgE;QAChE,IAAI,MAAM,CAAC,OAAO;YAAE,MAAM,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;QAEnD,MAAM,SAAS,CAAA;IACjB,CAAC;YAAS,CAAC;QACT,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,IAAI,KAAU,CAAC"}
@@ -0,0 +1,6 @@
1
+ import { Operation } from './operation.ts';
2
+ import type { Store } from './operation.ts';
3
+ export declare class Assignment extends Operation {
4
+ protected acquire(store: Store): Promise<void>;
5
+ protected commit(store: Store): Promise<void>;
6
+ }
@@ -0,0 +1,25 @@
1
+ import { Operation } from './operation.js';
2
+ export class Assignment extends Operation {
3
+ async acquire(store) {
4
+ const changeset = this.scope.changeset(store.request.query);
5
+ store.scope = changeset;
6
+ store.state = changeset.get();
7
+ }
8
+ async commit(store) {
9
+ const { scope, state, reply, request } = store;
10
+ if (reply.error !== undefined)
11
+ return;
12
+ const changeset = scope;
13
+ changeset.set(state);
14
+ /*
15
+ * The call carries the reply as it stands, which is empty where the algorithm named no
16
+ * output — the storage fills it with the post-image it computes, because that is where the
17
+ * post-image is known.
18
+ */
19
+ const output = await this.scope.apply(changeset, request.input, this.call(store));
20
+ // assignment returns new state by default
21
+ if (store.reply.output === undefined)
22
+ store.reply.output = output;
23
+ }
24
+ }
25
+ //# sourceMappingURL=assignment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assignment.js","sourceRoot":"","sources":["../source/assignment.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAI1C,MAAM,OAAO,UAAW,SAAQ,SAAS;IACpB,KAAK,CAAC,OAAO,CAAC,KAAY;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,KAAY,CAAC,CAAA;QAElE,KAAK,CAAC,KAAK,GAAG,SAAS,CAAA;QACvB,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,EAAE,CAAA;IAC/B,CAAC;IAEkB,KAAK,CAAC,MAAM,CAAC,KAAY;QAC1C,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,KAAK,CAAA;QAE9C,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS;YAAE,OAAM;QAErC,MAAM,SAAS,GAAG,KAAkB,CAAA;QAEpC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAEpB;;;;WAIG;QACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;QAEjF,0CAA0C;QAC1C,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS;YAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM,CAAA;IACnE,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import { Connector } from './connector.ts';
2
+ import type { Transmission } from './transmission.ts';
3
+ import type { Request as Contract } from './contract/request.ts';
4
+ import type { Options, Request, Source } from './types/request.ts';
5
+ export declare class Call extends Connector {
6
+ #private;
7
+ constructor(transmitter: Transmission, contract: Contract, target: string, source?: Source, stateful?: boolean, safe?: boolean);
8
+ invoke(request?: Request, options?: Options): Promise<any>;
9
+ explain(): any;
10
+ }
@@ -0,0 +1,165 @@
1
+ import { Readable } from 'node:stream';
2
+ import { current, encode } from 'openspan';
3
+ import { Connector } from './connector.js';
4
+ import { derive, newid } from './entities/newid.js';
5
+ import { RequestContractException, SafetyException } from './exceptions.js';
6
+ import { abandoned, waiting } from './abandon.js';
7
+ import * as addressed from './instance.js';
8
+ import * as trail from './trail.js';
9
+ export class Call extends Connector {
10
+ #transmitter;
11
+ #contract;
12
+ /** what this calls, as a hop is named, so that an identity derived here names it too */
13
+ #target;
14
+ #source;
15
+ /** whether a call to it names the process it goes to */
16
+ #stateful;
17
+ /** whether what it calls is incapable of changing the State; see `safety.ts` */
18
+ #safe;
19
+ // eslint-disable-next-line max-params
20
+ constructor(transmitter, contract, target, source, stateful = false, safe = false) {
21
+ super();
22
+ this.#transmitter = transmitter;
23
+ this.#contract = contract;
24
+ this.#target = target;
25
+ this.#source = source;
26
+ this.#stateful = stateful;
27
+ this.#safe = safe;
28
+ this.depends(transmitter);
29
+ }
30
+ async invoke(request = {}, options = {}) {
31
+ const invocation = trail.current();
32
+ /*
33
+ * The process a call goes to, which the transmission is handed beside what the call asks, and
34
+ * what the caller said of reading, which is not the answer on its own.
35
+ */
36
+ const { instance, readonly: stated, ...asked } = request;
37
+ /*
38
+ * The disjunction is what makes it a guarantee rather than a convention: a caller under a
39
+ * readonly invocation cannot clear it for a call of its own.
40
+ */
41
+ const readonly = stated === true || invocation?.readonly === true;
42
+ this.#refuse(request, options, readonly);
43
+ /*
44
+ * The envelope is built around what the caller asked for rather than written over it: one
45
+ * request object is handed to several concurrent calls in more than one place, and those are
46
+ * different calls — sharing one identity would have all but the first refused as duplicates
47
+ * of it.
48
+ */
49
+ const envelope = {
50
+ ...asked,
51
+ // avoid validation on the recipient's side
52
+ authentic: true,
53
+ // an operation that takes no input still has to send an explicit null
54
+ input: request.input ?? null,
55
+ id: request.id ?? this.#identity(invocation),
56
+ /*
57
+ * What a receiver has already put on the request wins, and a service with no chain in
58
+ * scope starts one under its own name.
59
+ */
60
+ trail: request.trail ?? invocation?.hops ?? service(this.#source),
61
+ // the caller may have attributed the call itself, as the node bridge does
62
+ source: request.source ?? this.#source
63
+ };
64
+ // nothing carries a key it has no value for onto the wire
65
+ if (envelope.source === undefined)
66
+ delete envelope.source;
67
+ if (envelope.trail === undefined)
68
+ delete envelope.trail;
69
+ if (readonly)
70
+ envelope.readonly = true;
71
+ this.#contract.fit(envelope);
72
+ const context = current();
73
+ if (context !== undefined)
74
+ envelope.telemetry = encode(context);
75
+ const reply = await this.#transmit(envelope, this.#terms(instance, options.timeout, options.signal));
76
+ if (reply === null)
77
+ return null;
78
+ else if (reply instanceof Readable)
79
+ return reply;
80
+ else {
81
+ if (reply.exception !== undefined)
82
+ throw reply.exception;
83
+ if (reply.error !== undefined)
84
+ return new RemoteError(reply.error);
85
+ else
86
+ return reply.output;
87
+ }
88
+ }
89
+ explain() {
90
+ return this.#contract.discovery;
91
+ }
92
+ /**
93
+ * Derived where this process is serving a call, so that the same call served twice makes the
94
+ * same call here twice over and whatever it reaches refuses its own copy; minted where there
95
+ * is nothing to derive from, which is an entry point, or a caller from before identities.
96
+ */
97
+ #identity(invocation) {
98
+ if (invocation?.id === undefined)
99
+ return newid();
100
+ return derive(invocation.id, this.#target, trail.ordinal(invocation, this.#target));
101
+ }
102
+ /** A call whose making contradicts what it calls is refused before anything is sent. */
103
+ #refuse(request, options, readonly) {
104
+ const { instance, task } = request;
105
+ const { timeout, signal } = options;
106
+ if (readonly && !this.#safe)
107
+ throw new SafetyException(`'${this.#target}' may change state, and this call may only read`);
108
+ if (this.#stateful && instance === undefined)
109
+ throw new RequestContractException(`'${this.#target}' is stateful, and a call to it names \`instance\``);
110
+ if (!this.#stateful && instance !== undefined)
111
+ throw new RequestContractException(`'${this.#target}' is stateless, and a call to it names no \`instance\``);
112
+ // a task is taken by whichever process is free, and a stateful operation is served
113
+ // under the name of one
114
+ if (this.#stateful && task === true)
115
+ throw new RequestContractException(`'${this.#target}' is stateful, and a call to it is no task`);
116
+ // nobody waits for a task, and it is made from wherever the queue is consumed
117
+ if (task === true && (timeout !== undefined || signal !== undefined))
118
+ throw new RequestContractException('A task names no `timeout` and no `signal`');
119
+ if (timeout !== undefined && !(Number.isFinite(timeout) && timeout > 0))
120
+ throw new RequestContractException('`timeout` is a positive number of milliseconds');
121
+ }
122
+ /**
123
+ * What the transmission is handed beside the envelope. An addressed call always waits for a set
124
+ * time — its caller's, or the context's — because nothing else ends a call to a process that has
125
+ * gone; an ordinary call waits for one only where its caller set it.
126
+ */
127
+ #terms(instance, timeout, signal) {
128
+ const deadline = timeout ?? (this.#stateful ? addressed.timeout() : undefined);
129
+ if (instance === undefined && deadline === undefined && signal === undefined)
130
+ return undefined;
131
+ const signals = [];
132
+ if (signal !== undefined)
133
+ signals.push(signal);
134
+ if (deadline !== undefined)
135
+ signals.push(AbortSignal.timeout(deadline));
136
+ const terms = {};
137
+ if (instance !== undefined)
138
+ terms.instance = instance;
139
+ if (deadline !== undefined)
140
+ terms.timeout = deadline;
141
+ if (signals.length > 0)
142
+ terms.signal = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
143
+ return terms;
144
+ }
145
+ /** The reply, or *abandoned* once the caller has stopped waiting, however the wait ended. */
146
+ async #transmit(envelope, terms) {
147
+ const signal = terms?.signal;
148
+ // a call its caller stopped waiting for before it was made is handed to no binding
149
+ if (signal?.aborted === true)
150
+ throw abandoned(this.#target, signal);
151
+ return await waiting(this.#transmitter.request(envelope, terms), signal, this.#target);
152
+ }
153
+ }
154
+ /** Where a service calls from no invocation, the chain starts under the service's own name. */
155
+ function service(source) {
156
+ return source !== undefined && 'service' in source ? [source.service] : undefined;
157
+ }
158
+ // the remote error as a value: every property it carries, and nothing else enumerable
159
+ class RemoteError extends Error {
160
+ constructor(error) {
161
+ super();
162
+ Object.assign(this, error);
163
+ }
164
+ }
165
+ //# sourceMappingURL=call.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.js","sourceRoot":"","sources":["../source/call.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { Connector } from './connector.ts';
2
+ import type { Algorithm } from './types/bridges.ts';
3
+ export declare class Cascade extends Connector {
4
+ #private;
5
+ constructor(bridges: Algorithm[], preflight?: Connector);
6
+ run(...args: [any, any?]): Promise<any>;
7
+ }
@@ -0,0 +1,28 @@
1
+ import { Connector } from './connector.js';
2
+ export class Cascade extends Connector {
3
+ #last;
4
+ constructor(bridges, preflight) {
5
+ super();
6
+ // this.#bridges = bridges
7
+ this.#last = bridges[bridges.length - 1];
8
+ if (preflight === undefined)
9
+ this.depends(bridges);
10
+ else
11
+ this.depends(bridges).depends(preflight);
12
+ }
13
+ async run(...args) {
14
+ // const reply = {}
15
+ //
16
+ // for (const bridge of this.#bridges) {
17
+ // const partial = await bridge.execute(...args)
18
+ //
19
+ // if (partial.error) return { error: partial.error }
20
+ //
21
+ // merge(reply, partial)
22
+ // }
23
+ //
24
+ // return reply
25
+ return this.#last.execute(...args);
26
+ }
27
+ }
28
+ //# sourceMappingURL=cascade.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cascade.js","sourceRoot":"","sources":["../source/cascade.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAG1C,MAAM,OAAO,OAAQ,SAAQ,SAAS;IAC3B,KAAK,CAAW;IAEzB,YAAmB,OAAoB,EAAE,SAAqB;QAC5D,KAAK,EAAE,CAAA;QAEP,0BAA0B;QAC1B,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;QAExC,IAAI,SAAS,KAAK,SAAS;YAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;;YAC7C,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/C,CAAC;IAEM,KAAK,CAAC,GAAG,CAAC,GAAG,IAAiB;QACnC,mBAAmB;QACnB,EAAE;QACF,wCAAwC;QACxC,kDAAkD;QAClD,EAAE;QACF,uDAAuD;QACvD,EAAE;QACF,0BAA0B;QAC1B,IAAI;QACJ,EAAE;QACF,eAAe;QAEf,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,IAAI,CAAC,CAAA;IACpC,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ import { Connector } from './connector.ts';
2
+ import type { Locator } from './locator.ts';
3
+ import type { Envelope, Options, Request } from './types/request.ts';
4
+ /** What a component holds one of per endpoint: an operation, or the call that stands for it. */
5
+ export interface Invocable extends Connector {
6
+ invoke: (request: Envelope, options?: Options) => Promise<any>;
7
+ }
8
+ export declare class Component<O extends Invocable = Invocable> extends Connector {
9
+ #private;
10
+ readonly locator: Locator;
11
+ protected readonly operations: Record<string, O>;
12
+ protected kind: 'server' | 'client';
13
+ constructor(locator: Locator, operations: Record<string, O>);
14
+ invoke<T = any>(endpoint: string, request?: Request, options?: Options): Promise<T>;
15
+ }
@@ -0,0 +1,148 @@
1
+ import { console, current, decode, run } from 'openspan';
2
+ import { Connector } from './connector.js';
3
+ import { DisposedException, EndpointException, names, permanent } from './exceptions.js';
4
+ import * as measure from './measurements.js';
5
+ import * as trail from './trail.js';
6
+ /** The code a declared error refuses with, which its manifest bounds. */
7
+ function code(error) {
8
+ return String(error.code ?? 'UNDECLARED');
9
+ }
10
+ export class Component extends Connector {
11
+ locator;
12
+ operations;
13
+ kind = 'server';
14
+ /** span options per endpoint */
15
+ #spans = {};
16
+ /** what refuses a call that has been here already, as the environment states it */
17
+ #limits = trail.limits();
18
+ constructor(locator, operations) {
19
+ super();
20
+ this.locator = locator;
21
+ this.operations = operations;
22
+ Object.values(operations).forEach((operation) => this.depends(operation));
23
+ }
24
+ async invoke(endpoint, request, options) {
25
+ /*
26
+ * A component that has been taken down refuses to work. What reaches it here is something
27
+ * the component started and did not stop — an interval, a watcher, a promise nobody
28
+ * awaited — calling through a context whose tree is gone, and a resume builds another tree
29
+ * rather than reviving this one, so it is never coming back.
30
+ *
31
+ * The client side is left alone deliberately: a `Remote` is a client to a queue rather than
32
+ * to an instance of anything, so its being taken down says nothing about whether what it
33
+ * calls is there.
34
+ */
35
+ if (this.disposed && this.kind === 'server')
36
+ throw new DisposedException(`'${this.locator.id}' has been taken down, and what reached it here was started by ` +
37
+ 'something that outlived it');
38
+ if (!(endpoint in this.operations))
39
+ throw new EndpointException(`'${endpoint}' is not provided by '${this.locator.id}'`);
40
+ // if the request carries no telemetry, the trace starts here
41
+ const remote = request?.telemetry === undefined ? null : decode(request.telemetry);
42
+ const invocation = async () => this.#process(endpoint, request, options);
43
+ let task = invocation;
44
+ /*
45
+ * The hop is the server's alone. A `Remote` is a component too and names the very endpoint
46
+ * this one does, so counting it there as well would make the threshold depend on how many
47
+ * clients a call happened to cross — a different number for a local call, an HTTP one and a
48
+ * delayed one. An endpoint beginning with `.` is the runtime's own and is no hop at all.
49
+ */
50
+ if (this.kind === 'server' && endpoint[0] !== '.') {
51
+ let hops;
52
+ try {
53
+ // the span's name is the hop's, and it is already built once per endpoint
54
+ hops = trail.extend(request?.trail, this.#span(endpoint).name, this.#limits);
55
+ }
56
+ catch (exception) {
57
+ console.error('Call chain refused', {
58
+ endpoint: `${this.locator.id}.${endpoint}`,
59
+ exception
60
+ });
61
+ // answered, not thrown: thrown, this would run into the broker library on the event
62
+ // path, and on the call path its code would survive only by `Exception` not being an
63
+ // `Error`. Answered, `Call` throws it into the caller as it does any other.
64
+ return { exception };
65
+ }
66
+ /*
67
+ * The identity is put in scope with the chain: an operation reaches neither, and the
68
+ * calls it makes derive their own from what it is serving. So is whether this request may
69
+ * only read, which is what every call the operation makes is then held to.
70
+ */
71
+ const scope = { hops, id: request?.id };
72
+ if (request?.readonly === true)
73
+ scope.readonly = true;
74
+ task = async () => trail.follow(scope, invocation);
75
+ }
76
+ if (remote === null)
77
+ return task();
78
+ else
79
+ return run(remote, task);
80
+ }
81
+ async #process(endpoint, request, options) {
82
+ const measurements = this.kind === 'server' ? measure.operation : measure.call;
83
+ const labels = { component: this.locator.id, operation: endpoint };
84
+ measurements.inflight.add(1, labels);
85
+ try {
86
+ return await console.span(this.#span(endpoint), async () => {
87
+ const reply = await this.operations[endpoint].invoke(request, options);
88
+ if (reply?.error !== undefined && this.kind === 'server')
89
+ measure.operation.errors.add(1, { ...labels, code: code(reply.error) });
90
+ if (reply?.exception !== undefined) {
91
+ const span = current();
92
+ if (span !== undefined)
93
+ span.status = 'error';
94
+ this.#failed(labels, reply.exception);
95
+ console.error('Failed to execute operation', {
96
+ endpoint: `${this.locator.id}.${endpoint}`,
97
+ exception: reply.exception
98
+ });
99
+ }
100
+ return reply;
101
+ });
102
+ }
103
+ finally {
104
+ measurements.inflight.add(-1, labels);
105
+ }
106
+ }
107
+ /**
108
+ * A refusal the caller sees is one the callee already counted, so only the server side counts
109
+ * an exception. `outcome` is what a receiver reads to choose between another attempt and the
110
+ * parking queue, which makes it two different incidents rather than one rate.
111
+ */
112
+ #failed(labels, exception) {
113
+ if (this.kind !== 'server')
114
+ return;
115
+ const { code = 0 } = exception;
116
+ measure.operation.exceptions.add(1, {
117
+ ...labels,
118
+ code: names[code] ?? String(code),
119
+ outcome: permanent(exception) ? 'permanent' : 'transient'
120
+ });
121
+ }
122
+ /**
123
+ * The span of an endpoint never changes, so it is built once. Not in the constructor:
124
+ * `kind` is a field of the subclass, and those are assigned after this one is built.
125
+ *
126
+ */
127
+ #span(endpoint) {
128
+ let options = this.#spans[endpoint];
129
+ if (options === undefined) {
130
+ const measurements = this.kind === 'server' ? measure.operation : measure.call;
131
+ options = {
132
+ name: `${this.locator.id}.${endpoint}`,
133
+ kind: this.kind,
134
+ measure: {
135
+ histogram: measurements.duration,
136
+ labels: { component: this.locator.id, operation: endpoint }
137
+ }
138
+ };
139
+ // the server span is emitted by the component itself, while the client span
140
+ // belongs to the calling service and inherits it from the context
141
+ if (this.kind === 'server')
142
+ options.service = this.locator.id;
143
+ this.#spans[endpoint] = options;
144
+ }
145
+ return options;
146
+ }
147
+ }
148
+ //# sourceMappingURL=component.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"component.js","sourceRoot":"","sources":["../source/component.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Connector } from './connector.ts';
2
+ export declare class Composition extends Connector {
3
+ constructor(producers: Connector[], receivers: Connector[], tenants: Connector[]);
4
+ protected open(): Promise<void>;
5
+ protected dispose(): Promise<void>;
6
+ }
@@ -0,0 +1,20 @@
1
+ import { console } from 'openspan';
2
+ import { Connector } from './connector.js';
3
+ export class Composition extends Connector {
4
+ constructor(producers, receivers, tenants) {
5
+ super();
6
+ if (producers.length > 0)
7
+ this.depends(producers);
8
+ if (receivers.length > 0)
9
+ this.depends(receivers);
10
+ if (tenants.length > 0)
11
+ this.depends(tenants);
12
+ }
13
+ async open() {
14
+ console.info('Composition complete');
15
+ }
16
+ async dispose() {
17
+ console.info('Composition shutdown complete');
18
+ }
19
+ }
20
+ //# sourceMappingURL=composition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composition.js","sourceRoot":"","sources":["../source/composition.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AAClC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,MAAM,OAAO,WAAY,SAAQ,SAAS;IACxC,YACE,SAAsB,EACtB,SAAsB,EACtB,OAAoB;QAEpB,KAAK,EAAE,CAAA;QAEP,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACjD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC/C,CAAC;IAEkB,KAAK,CAAC,IAAI;QAC3B,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;IACtC,CAAC;IAEkB,KAAK,CAAC,OAAO;QAC9B,OAAO,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAA;IAC/C,CAAC;CACF"}