@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
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@toa.io/core",
3
- "version": "1.0.0-alpha.32",
3
+ "version": "1.0.0-alpha.320",
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.32",
25
- "@toa.io/generic": "1.0.0-alpha.32",
26
- "@toa.io/yaml": "1.0.0-alpha.32",
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.311",
44
+ "@toa.io/schemas": "1.0.0-alpha.311",
45
+ "openspan": "1.0.0-alpha.305",
46
+ "uuid": "14.0.2"
31
47
  },
32
- "gitHead": "93ceb53797363abb77eb9c550db77e906691d42a"
48
+ "gitHead": "5ef92ab939a596e4ac820965c59c015820eba7b2"
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, streamed?: string);
8
+ invoke(request?: Request, options?: Options): Promise<any>;
9
+ explain(): any;
10
+ }
@@ -0,0 +1,187 @@
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
+ /** the input property a stream is carried in, where what it calls takes one */
20
+ #streamed;
21
+ // eslint-disable-next-line max-params
22
+ constructor(transmitter, contract, target, source, stateful = false, safe = false, streamed) {
23
+ super();
24
+ this.#transmitter = transmitter;
25
+ this.#contract = contract;
26
+ this.#target = target;
27
+ this.#source = source;
28
+ this.#stateful = stateful;
29
+ this.#safe = safe;
30
+ this.#streamed = streamed;
31
+ this.depends(transmitter);
32
+ }
33
+ async invoke(request = {}, options = {}) {
34
+ const invocation = trail.current();
35
+ /*
36
+ * The process a call goes to, which the transmission is handed beside what the call asks, and
37
+ * what the caller said of reading, which is not the answer on its own.
38
+ */
39
+ const { instance, readonly: stated, ...asked } = request;
40
+ /*
41
+ * The disjunction is what makes it a guarantee rather than a convention: a caller under a
42
+ * readonly invocation cannot clear it for a call of its own.
43
+ */
44
+ const readonly = stated === true || invocation?.readonly === true;
45
+ this.#refuse(request, options, readonly);
46
+ /*
47
+ * The envelope is built around what the caller asked for rather than written over it: one
48
+ * request object is handed to several concurrent calls in more than one place, and those are
49
+ * different calls — sharing one identity would have all but the first refused as duplicates
50
+ * of it.
51
+ */
52
+ const envelope = {
53
+ ...asked,
54
+ // avoid validation on the recipient's side
55
+ authentic: true,
56
+ // an operation that takes no input still has to send an explicit null
57
+ input: request.input ?? null,
58
+ id: request.id ?? this.#identity(invocation),
59
+ /*
60
+ * What a receiver has already put on the request wins, and a service with no chain in
61
+ * scope starts one under its own name.
62
+ */
63
+ trail: request.trail ?? invocation?.hops ?? service(this.#source),
64
+ // the caller may have attributed the call itself, as the node bridge does
65
+ source: request.source ?? this.#source
66
+ };
67
+ // nothing carries a key it has no value for onto the wire
68
+ if (envelope.source === undefined)
69
+ delete envelope.source;
70
+ if (envelope.trail === undefined)
71
+ delete envelope.trail;
72
+ if (readonly)
73
+ envelope.readonly = true;
74
+ this.#contract.fit(envelope);
75
+ const context = current();
76
+ if (context !== undefined)
77
+ envelope.telemetry = encode(context);
78
+ const reply = await this.#transmit(envelope, this.#terms(instance, options.timeout, options.signal));
79
+ if (reply === null)
80
+ return null;
81
+ else if (reply instanceof Readable)
82
+ return reply;
83
+ else {
84
+ if (reply.exception !== undefined)
85
+ throw reply.exception;
86
+ if (reply.error !== undefined)
87
+ return new RemoteError(reply.error);
88
+ else
89
+ return reply.output;
90
+ }
91
+ }
92
+ explain() {
93
+ return this.#contract.discovery;
94
+ }
95
+ /**
96
+ * Derived where this process is serving a call, so that the same call served twice makes the
97
+ * same call here twice over and whatever it reaches refuses its own copy; minted where there
98
+ * is nothing to derive from, which is an entry point, or a caller from before identities.
99
+ */
100
+ #identity(invocation) {
101
+ if (invocation?.id === undefined)
102
+ return newid();
103
+ return derive(invocation.id, this.#target, trail.ordinal(invocation, this.#target));
104
+ }
105
+ /** A call whose making contradicts what it calls is refused before anything is sent. */
106
+ #refuse(request, options, readonly) {
107
+ const { instance, task } = request;
108
+ const { timeout, signal } = options;
109
+ if (readonly && !this.#safe)
110
+ throw new SafetyException(`'${this.#target}' may change state, and this call may only read`);
111
+ if (this.#stateful && instance === undefined)
112
+ throw new RequestContractException(`'${this.#target}' is stateful, and a call to it names \`instance\``);
113
+ if (!this.#stateful && instance !== undefined)
114
+ throw new RequestContractException(`'${this.#target}' is stateless, and a call to it names no \`instance\``);
115
+ // a task is taken by whichever process is free, and a stateful operation is served
116
+ // under the name of one
117
+ if (this.#stateful && task === true)
118
+ throw new RequestContractException(`'${this.#target}' is stateful, and a call to it is no task`);
119
+ // nobody waits for a task, and it is made from wherever the queue is consumed
120
+ if (task === true && (timeout !== undefined || signal !== undefined))
121
+ throw new RequestContractException('A task names no `timeout` and no `signal`');
122
+ // an ordinary call is answered eventually, and what nobody could answer is parked with who
123
+ // asked — which only means something to a caller still waiting
124
+ if (!this.#stateful && (timeout !== undefined || signal !== undefined))
125
+ throw new RequestContractException(`'${this.#target}' is stateless, and a call to it names no \`timeout\` and no \`signal\``);
126
+ if (this.#streamed !== undefined) {
127
+ // a task is taken later, by a process whose caller is no longer holding a stream
128
+ if (task === true)
129
+ throw new RequestContractException(`'${this.#target}' takes a stream, and a task carries none`);
130
+ // the contract has the property, and only what is made here can say what is in it
131
+ if (!carries(request.input, this.#streamed))
132
+ throw new RequestContractException(`'${this.#target}' takes a stream at '${this.#streamed}', which this call carries none of`);
133
+ }
134
+ if (timeout !== undefined && !(Number.isFinite(timeout) && timeout > 0))
135
+ throw new RequestContractException('`timeout` is a positive number of milliseconds');
136
+ }
137
+ /**
138
+ * What the transmission is handed beside the envelope. An addressed call always waits for a set
139
+ * time — its caller's, or the context's — because nothing else ends a call to a process that has
140
+ * gone; an ordinary call waits for as long as it takes, and is handed nothing.
141
+ */
142
+ #terms(instance, timeout, signal) {
143
+ if (instance === undefined)
144
+ return undefined;
145
+ const deadline = timeout ?? addressed.timeout();
146
+ const expiry = AbortSignal.timeout(deadline);
147
+ return {
148
+ instance,
149
+ timeout: deadline,
150
+ signal: signal === undefined ? expiry : AbortSignal.any([signal, expiry])
151
+ };
152
+ }
153
+ /** The reply, or *abandoned* once the caller has stopped waiting, however the wait ended. */
154
+ async #transmit(envelope, terms) {
155
+ const signal = terms?.signal;
156
+ // a call its caller stopped waiting for before it was made is handed to no binding
157
+ if (signal?.aborted === true)
158
+ throw abandoned(this.#target, signal);
159
+ return await waiting(this.#transmitter.request(envelope, terms), signal, this.#target);
160
+ }
161
+ }
162
+ /**
163
+ * Whether the input carries a stream where the operation takes one: the property itself where its
164
+ * caller said nothing about it, and the property's `stream` where a route filled one.
165
+ */
166
+ function carries(input, property) {
167
+ if (input === null || typeof input !== 'object')
168
+ return false;
169
+ const carried = input[property];
170
+ if (carried instanceof Readable)
171
+ return true;
172
+ if (carried === null || typeof carried !== 'object')
173
+ return false;
174
+ return carried.stream instanceof Readable;
175
+ }
176
+ /** Where a service calls from no invocation, the chain starts under the service's own name. */
177
+ function service(source) {
178
+ return source !== undefined && 'service' in source ? [source.service] : undefined;
179
+ }
180
+ // the remote error as a value: every property it carries, and nothing else enumerable
181
+ class RemoteError extends Error {
182
+ constructor(error) {
183
+ super();
184
+ Object.assign(this, error);
185
+ }
186
+ }
187
+ //# 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"}