@toa.io/core 1.0.0-alpha.284 → 1.0.0-alpha.287

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 (290) hide show
  1. package/CHANGELOG.md +1 -185
  2. package/package.json +19 -7
  3. package/source/assignment.ts +27 -0
  4. package/{src/call.js → source/call.ts} +16 -21
  5. package/{src/cascade.js → source/cascade.ts} +6 -8
  6. package/{src/component.js → source/component.ts} +27 -25
  7. package/{src/composition.js → source/composition.ts} +9 -3
  8. package/{src/connector.js → source/connector.ts} +36 -55
  9. package/source/context.ts +67 -0
  10. package/source/contract/contract.ts +23 -0
  11. package/{src/contract/reply.js → source/contract/reply.ts} +26 -19
  12. package/source/contract/request.ts +85 -0
  13. package/source/contract/schemas.ts +39 -0
  14. package/{src/discovery.js → source/discovery.ts} +15 -8
  15. package/source/effect.ts +14 -0
  16. package/{src/emission.js → source/emission.ts} +5 -3
  17. package/source/entities/changeset.ts +37 -0
  18. package/source/entities/entity.ts +137 -0
  19. package/source/entities/factory.ts +52 -0
  20. package/source/entities/index.ts +4 -0
  21. package/{src/entities/newid.js → source/entities/newid.ts} +1 -1
  22. package/{src/entities/set.js → source/entities/set.ts} +8 -5
  23. package/source/event.ts +57 -0
  24. package/{src/exceptions.js → source/exceptions.ts} +52 -33
  25. package/source/exposition.ts +33 -0
  26. package/source/guard.ts +16 -0
  27. package/{src/index.js → source/index.ts} +8 -0
  28. package/{src/locator.js → source/locator.ts} +17 -30
  29. package/source/observation.ts +16 -0
  30. package/source/operation.ts +138 -0
  31. package/{src/outbox/outbox.js → source/outbox/outbox.ts} +87 -53
  32. package/source/query/criteria.ts +90 -0
  33. package/source/query/options.ts +35 -0
  34. package/{src/query.js → source/query.ts} +14 -17
  35. package/source/receiver.ts +120 -0
  36. package/source/reflection.ts +20 -0
  37. package/source/remote.ts +20 -0
  38. package/source/state.ts +179 -0
  39. package/source/transition.ts +79 -0
  40. package/{src/transmission.js → source/transmission.ts} +8 -8
  41. package/source/types/atomicity.ts +63 -0
  42. package/source/types/bindings.ts +59 -0
  43. package/source/types/bridges.ts +54 -0
  44. package/source/types/extensions.ts +89 -0
  45. package/{types → source/types}/index.ts +9 -16
  46. package/{types/message.d.ts → source/types/message.ts} +2 -1
  47. package/source/types/operations.ts +31 -0
  48. package/source/types/outbox.ts +35 -0
  49. package/source/types/receiver.ts +10 -0
  50. package/{types/request.d.ts → source/types/request.ts} +8 -9
  51. package/source/types/state.ts +9 -0
  52. package/source/types/storages.ts +129 -0
  53. package/source/unmanaged.ts +8 -0
  54. package/test/call.fixtures.js +3 -1
  55. package/test/call.test.js +28 -7
  56. package/test/component.test.js +10 -5
  57. package/test/connector.fixtures.js +7 -7
  58. package/test/connector.test.js +15 -2
  59. package/test/context.fixtures.js +1 -1
  60. package/test/context.test.js +4 -4
  61. package/test/contract/conditions.test.js +6 -2
  62. package/test/contract/contract.fixtures.js +3 -4
  63. package/test/contract/request.test.js +68 -34
  64. package/test/discovery.test.js +10 -3
  65. package/test/emission.test.js +16 -8
  66. package/test/entities/entity.fixtures.js +5 -6
  67. package/test/entities/entity.test.js +54 -20
  68. package/test/entities/factory.fixtures.js +11 -10
  69. package/test/entities/factory.test.js +47 -10
  70. package/test/entities/set.test.js +1 -1
  71. package/test/event.test.js +29 -11
  72. package/test/locator.test.js +10 -4
  73. package/test/outbox.test.js +49 -15
  74. package/test/query.test.js +69 -7
  75. package/test/receiver.fixtures.js +2 -2
  76. package/test/receiver.test.js +53 -27
  77. package/test/reflection.test.js +3 -3
  78. package/test/state.fixtures.js +10 -3
  79. package/test/state.test.js +77 -14
  80. package/test/transmission.test.js +25 -12
  81. package/transpiled/assignment.d.ts +6 -0
  82. package/transpiled/assignment.js +20 -0
  83. package/transpiled/assignment.js.map +1 -0
  84. package/transpiled/call.d.ts +10 -0
  85. package/transpiled/call.js +52 -0
  86. package/transpiled/call.js.map +1 -0
  87. package/transpiled/cascade.d.ts +7 -0
  88. package/transpiled/cascade.js +28 -0
  89. package/transpiled/cascade.js.map +1 -0
  90. package/transpiled/component.d.ts +15 -0
  91. package/transpiled/component.js +61 -0
  92. package/transpiled/component.js.map +1 -0
  93. package/transpiled/composition.d.ts +6 -0
  94. package/transpiled/composition.js +23 -0
  95. package/transpiled/composition.js.map +1 -0
  96. package/transpiled/connector.d.ts +47 -0
  97. package/transpiled/connector.js +143 -0
  98. package/transpiled/connector.js.map +1 -0
  99. package/transpiled/context.d.ts +18 -0
  100. package/transpiled/context.js +41 -0
  101. package/transpiled/context.js.map +1 -0
  102. package/transpiled/contract/contract.d.ts +10 -0
  103. package/transpiled/contract/contract.js +14 -0
  104. package/transpiled/contract/contract.js.map +1 -0
  105. package/transpiled/contract/index.d.ts +2 -0
  106. package/transpiled/contract/index.js +3 -0
  107. package/transpiled/contract/index.js.map +1 -0
  108. package/transpiled/contract/reply.d.ts +7 -0
  109. package/transpiled/contract/reply.js +48 -0
  110. package/transpiled/contract/reply.js.map +1 -0
  111. package/transpiled/contract/request.d.ts +24 -0
  112. package/transpiled/contract/request.js +59 -0
  113. package/transpiled/contract/request.js.map +1 -0
  114. package/transpiled/contract/schemas.d.ts +4 -0
  115. package/transpiled/contract/schemas.js +36 -0
  116. package/transpiled/contract/schemas.js.map +1 -0
  117. package/transpiled/discovery.d.ts +12 -0
  118. package/transpiled/discovery.js +34 -0
  119. package/transpiled/discovery.js.map +1 -0
  120. package/transpiled/effect.d.ts +5 -0
  121. package/transpiled/effect.js +11 -0
  122. package/transpiled/effect.js.map +1 -0
  123. package/transpiled/emission.d.ts +8 -0
  124. package/transpiled/emission.js +14 -0
  125. package/transpiled/emission.js.map +1 -0
  126. package/transpiled/entities/changeset.d.ts +10 -0
  127. package/transpiled/entities/changeset.js +27 -0
  128. package/transpiled/entities/changeset.js.map +1 -0
  129. package/transpiled/entities/entity.d.ts +19 -0
  130. package/transpiled/entities/entity.js +109 -0
  131. package/transpiled/entities/entity.js.map +1 -0
  132. package/transpiled/entities/factory.d.ts +22 -0
  133. package/transpiled/entities/factory.js +34 -0
  134. package/transpiled/entities/factory.js.map +1 -0
  135. package/transpiled/entities/index.d.ts +4 -0
  136. package/transpiled/entities/index.js +5 -0
  137. package/transpiled/entities/index.js.map +1 -0
  138. package/transpiled/entities/newid.d.ts +1 -0
  139. package/transpiled/entities/newid.js +7 -0
  140. package/transpiled/entities/newid.js.map +1 -0
  141. package/transpiled/entities/set.d.ts +10 -0
  142. package/transpiled/entities/set.js +19 -0
  143. package/transpiled/entities/set.js.map +1 -0
  144. package/transpiled/event.d.ts +14 -0
  145. package/transpiled/event.js +38 -0
  146. package/transpiled/event.js.map +1 -0
  147. package/transpiled/exceptions.d.ts +61 -0
  148. package/transpiled/exceptions.js +93 -0
  149. package/transpiled/exceptions.js.map +1 -0
  150. package/transpiled/exposition.d.ts +18 -0
  151. package/transpiled/exposition.js +18 -0
  152. package/transpiled/exposition.js.map +1 -0
  153. package/transpiled/guard.d.ts +7 -0
  154. package/transpiled/guard.js +12 -0
  155. package/transpiled/guard.js.map +1 -0
  156. package/transpiled/index.d.ts +35 -0
  157. package/transpiled/index.js +29 -0
  158. package/transpiled/index.js.map +1 -0
  159. package/transpiled/locator.d.ts +12 -0
  160. package/transpiled/locator.js +32 -0
  161. package/transpiled/locator.js.map +1 -0
  162. package/transpiled/observation.d.ts +5 -0
  163. package/transpiled/observation.js +12 -0
  164. package/transpiled/observation.js.map +1 -0
  165. package/transpiled/operation.d.ts +49 -0
  166. package/transpiled/operation.js +77 -0
  167. package/transpiled/operation.js.map +1 -0
  168. package/transpiled/outbox/index.d.ts +1 -0
  169. package/transpiled/outbox/index.js +2 -0
  170. package/transpiled/outbox/index.js.map +1 -0
  171. package/transpiled/outbox/outbox.d.ts +46 -0
  172. package/transpiled/outbox/outbox.js +267 -0
  173. package/transpiled/outbox/outbox.js.map +1 -0
  174. package/transpiled/query/criteria.d.ts +6 -0
  175. package/transpiled/query/criteria.js +74 -0
  176. package/transpiled/query/criteria.js.map +1 -0
  177. package/transpiled/query/options.d.ts +3 -0
  178. package/transpiled/query/options.js +27 -0
  179. package/transpiled/query/options.js.map +1 -0
  180. package/transpiled/query.d.ts +9 -0
  181. package/transpiled/query.js +57 -0
  182. package/transpiled/query.js.map +1 -0
  183. package/transpiled/receiver.d.ts +20 -0
  184. package/transpiled/receiver.js +92 -0
  185. package/transpiled/receiver.js.map +1 -0
  186. package/transpiled/reflection.d.ts +9 -0
  187. package/transpiled/reflection.js +13 -0
  188. package/transpiled/reflection.js.map +1 -0
  189. package/transpiled/remote.d.ts +10 -0
  190. package/transpiled/remote.js +12 -0
  191. package/transpiled/remote.js.map +1 -0
  192. package/transpiled/state.d.ts +33 -0
  193. package/transpiled/state.js +126 -0
  194. package/transpiled/state.js.map +1 -0
  195. package/transpiled/transition.d.ts +14 -0
  196. package/transpiled/transition.js +51 -0
  197. package/transpiled/transition.js.map +1 -0
  198. package/transpiled/transmission.d.ts +8 -0
  199. package/transpiled/transmission.js +30 -0
  200. package/transpiled/transmission.js.map +1 -0
  201. package/transpiled/types/atomicity.d.ts +56 -0
  202. package/transpiled/types/atomicity.js +2 -0
  203. package/transpiled/types/atomicity.js.map +1 -0
  204. package/transpiled/types/bindings.d.ts +42 -0
  205. package/transpiled/types/bindings.js +2 -0
  206. package/transpiled/types/bindings.js.map +1 -0
  207. package/transpiled/types/bridges.d.ts +38 -0
  208. package/transpiled/types/bridges.js +2 -0
  209. package/transpiled/types/bridges.js.map +1 -0
  210. package/transpiled/types/extensions.d.ts +62 -0
  211. package/transpiled/types/extensions.js +2 -0
  212. package/transpiled/types/extensions.js.map +1 -0
  213. package/transpiled/types/index.d.ts +13 -0
  214. package/transpiled/types/index.js +8 -0
  215. package/transpiled/types/index.js.map +1 -0
  216. package/transpiled/types/message.d.ts +5 -0
  217. package/transpiled/types/message.js +2 -0
  218. package/transpiled/types/message.js.map +1 -0
  219. package/transpiled/types/operations.d.ts +15 -0
  220. package/transpiled/types/operations.js +2 -0
  221. package/transpiled/types/operations.js.map +1 -0
  222. package/transpiled/types/outbox.d.ts +28 -0
  223. package/transpiled/types/outbox.js +2 -0
  224. package/transpiled/types/outbox.js.map +1 -0
  225. package/transpiled/types/receiver.d.ts +9 -0
  226. package/transpiled/types/receiver.js +2 -0
  227. package/transpiled/types/receiver.js.map +1 -0
  228. package/transpiled/types/request.d.ts +55 -0
  229. package/transpiled/types/request.js +2 -0
  230. package/transpiled/types/request.js.map +1 -0
  231. package/transpiled/types/state.d.ts +9 -0
  232. package/transpiled/types/state.js +2 -0
  233. package/transpiled/types/state.js.map +1 -0
  234. package/transpiled/types/storages.d.ts +106 -0
  235. package/transpiled/types/storages.js +2 -0
  236. package/transpiled/types/storages.js.map +1 -0
  237. package/transpiled/unmanaged.d.ts +5 -0
  238. package/transpiled/unmanaged.js +7 -0
  239. package/transpiled/unmanaged.js.map +1 -0
  240. package/tsconfig.json +10 -0
  241. package/tsconfig.tsbuildinfo +1 -0
  242. package/src/assignment.js +0 -28
  243. package/src/context.js +0 -57
  244. package/src/contract/contract.js +0 -18
  245. package/src/contract/request.js +0 -77
  246. package/src/contract/schemas/error.yaml +0 -9
  247. package/src/contract/schemas/index.js +0 -11
  248. package/src/contract/schemas/query.yaml +0 -43
  249. package/src/contract/schemas/source.yaml +0 -23
  250. package/src/effect.js +0 -15
  251. package/src/entities/changeset.js +0 -36
  252. package/src/entities/entity.js +0 -119
  253. package/src/entities/factory.js +0 -40
  254. package/src/entities/index.js +0 -1
  255. package/src/event.js +0 -54
  256. package/src/exposition.js +0 -24
  257. package/src/guard.js +0 -13
  258. package/src/observation.js +0 -8
  259. package/src/operation.js +0 -95
  260. package/src/query/criteria.js +0 -44
  261. package/src/query/options.js +0 -37
  262. package/src/receiver.js +0 -123
  263. package/src/reflection.js +0 -24
  264. package/src/remote.js +0 -14
  265. package/src/state.js +0 -138
  266. package/src/transition.js +0 -61
  267. package/src/unmanaged.js +0 -7
  268. package/types/atomicity.d.ts +0 -79
  269. package/types/bindings.d.ts +0 -42
  270. package/types/bridges.ts +0 -33
  271. package/types/call.d.ts +0 -13
  272. package/types/component.d.ts +0 -12
  273. package/types/connector.d.ts +0 -18
  274. package/types/context.d.ts +0 -24
  275. package/types/entity.d.ts +0 -46
  276. package/types/event.d.ts +0 -11
  277. package/types/exception.d.ts +0 -4
  278. package/types/extensions.d.ts +0 -73
  279. package/types/guard.d.ts +0 -5
  280. package/types/locator.d.ts +0 -13
  281. package/types/operations.d.ts +0 -8
  282. package/types/outbox.d.ts +0 -53
  283. package/types/query.d.ts +0 -17
  284. package/types/receiver.d.ts +0 -12
  285. package/types/reflection.d.ts +0 -14
  286. package/types/remote.d.ts +0 -19
  287. package/types/state.d.ts +0 -38
  288. package/types/storages.d.ts +0 -96
  289. /package/{src/contract/index.js → source/contract/index.ts} +0 -0
  290. /package/{src/outbox/index.js → source/outbox/index.ts} +0 -0
package/CHANGELOG.md CHANGED
@@ -3,190 +3,6 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
- # [1.0.0-alpha.284](https://github.com/toa-io/toa/compare/v1.0.0-alpha.283...v1.0.0-alpha.284) (2026-09-05)
7
-
8
- ### Bug Fixes
9
-
10
- * **core:** a criteria list coerces every value in it ([37f57ee](https://github.com/toa-io/toa/commit/37f57ee8b50907a13722b7a558b881cccf105442))
11
-
12
- ### Features
13
-
14
- * an operation states what it is ([b5e2f66](https://github.com/toa-io/toa/commit/b5e2f66c8bf67924e2eaaaa11f283dfb4d810981))
15
- * **atomicity:** a replica can be told what it owns, not only ask ([f7b56b9](https://github.com/toa-io/toa/commit/f7b56b99cc43313f3f855df658a80fdc0659689e))
16
-
17
-
18
- # [1.0.0-alpha.283](https://github.com/toa-io/toa/compare/v1.0.0-alpha.282...v1.0.0-alpha.283) (2026-09-04)
19
-
20
- ### Bug Fixes
21
-
22
- * **core:** an operation returns the errors it declares, and nothing else ([1c2b819](https://github.com/toa-io/toa/commit/1c2b8193ae7fbe86bc1a25053a6044ee4dd16a4a))
23
- * **storages:** take `Maybe` from core, not from the deprecated package ([bcaeeb3](https://github.com/toa-io/toa/commit/bcaeeb3c76c89af34e94ff569a210d21b7e87f64))
24
-
25
- ### Features
26
-
27
- * **extensions:** an extension declares what it puts on a component's context ([133bc2a](https://github.com/toa-io/toa/commit/133bc2aad1e45a2d4aa68a08a5e44ca48d3b7414))
28
-
29
-
30
- # [1.0.0-alpha.282](https://github.com/toa-io/toa/compare/v1.0.0-alpha.281...v1.0.0-alpha.282) (2026-09-03)
31
-
32
- ### Features
33
-
34
- * **core:** a Host for extensions ([6315eac](https://github.com/toa-io/toa/commit/6315eac1e9fb05be472272de06385c54ad5934ce))
35
-
36
-
37
- # [1.0.0-alpha.278](https://github.com/toa-io/toa/compare/v1.0.0-alpha.277...v1.0.0-alpha.278) (2026-09-03)
38
-
39
- **Note:** Version bump only for package @toa.io/core
40
-
41
-
42
-
43
-
44
-
45
- # [1.0.0-alpha.277](https://github.com/toa-io/toa/compare/v1.0.0-alpha.276...v1.0.0-alpha.277) (2026-09-03)
46
-
47
- ### Bug Fixes
48
-
49
- * read a manifest the way js-yaml read one before ([fcea1b2](https://github.com/toa-io/toa/commit/fcea1b21996d6efa6c3198acbfc9f70f1ce0c35c))
50
- * settle what the module loader made asynchronous ([d4ab9df](https://github.com/toa-io/toa/commit/d4ab9dfb09e382da311dba08f52214e7645f4a6c))
51
-
52
-
53
- # [1.0.0-alpha.273](https://github.com/toa-io/toa/compare/v1.0.0-alpha.272...v1.0.0-alpha.273) (2026-09-02)
6
+ # [1.0.0-alpha.287](https://github.com/toa-io/toa/compare/v1.0.0-alpha.286...v1.0.0-alpha.287) (2026-09-06)
54
7
 
55
8
  **Note:** Version bump only for package @toa.io/core
56
-
57
-
58
-
59
-
60
-
61
- # [1.0.0-alpha.272](https://github.com/toa-io/toa/compare/v1.0.0-alpha.271...v1.0.0-alpha.272) (2026-09-01)
62
-
63
-
64
- ### Bug Fixes
65
-
66
- * **core:** stop the reply contract from relaxing the declaration ([6222893](https://github.com/toa-io/toa/commit/622289326630b94deff93499d6a851bfaa57c69a))
67
-
68
-
69
- * feat(atomicity)!: take a quorum of independent servers ([862562f](https://github.com/toa-io/toa/commit/862562f24d77ec00127dbbd88d43802b208c643b))
70
- * refactor(atomicity)!: take the lock manager from the stash ([4fd91eb](https://github.com/toa-io/toa/commit/4fd91eb2fdb68f7b87aaf16d182794bbc567ba57))
71
- * refactor(core)!: pump the outbox in one cycle ([bf590fe](https://github.com/toa-io/toa/commit/bf590fe8ed59c701b5fd1a91ba4874685b79242f))
72
- * refactor(atomicity)!: make the connector a family, not a partitioner ([06fd63a](https://github.com/toa-io/toa/commit/06fd63ad6296b724ef83afccf4e4e25d0bcaf080))
73
- * refactor(atomicity)!: rename the connector and free it of the outbox ([21f1a41](https://github.com/toa-io/toa/commit/21f1a41aceafcfd35c7620014062fe46b54afa95))
74
- * feat(core)!: commit events with the state that produced them ([1eb68cc](https://github.com/toa-io/toa/commit/1eb68cc435dbfa03faa16009fceb866693d22e1a)), closes [#20](https://github.com/toa-io/toa/issues/20)
75
-
76
-
77
- ### Features
78
-
79
- * **atomicity:** meter what the group has spent ([bb1118a](https://github.com/toa-io/toa/commit/bb1118aa60bfeb43d3212f2495b7797445f003c3))
80
- * **core:** give every component an atom aspect ([b501b9c](https://github.com/toa-io/toa/commit/b501b9cd3d5f5408d9faa71213e953fe2792cf9f))
81
-
82
-
83
- ### BREAKING CHANGES
84
-
85
- * `atomicity.redis` accepts a list again, of independent servers rather
86
- than cluster nodes, and refuses an even number of them.
87
-
88
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
89
- * `context.stash.lock` is gone; lock through `context.atom` instead.
90
- A stash pointer resolving to several addresses now uses the first.
91
-
92
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
93
- * `Storage.outbox.pending` takes a fourth argument, the id to
94
- continue from.
95
-
96
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
97
- * `Factory.partition(group)` is `Factory.atom(group)`, and the
98
- `Partition` it returned is an `Atom`. `slots(total)` is unchanged.
99
-
100
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
101
- * `@toa.io/partitions.redis` is now `@toa.io/atomicity`, and its
102
- `lanes(total)` is `slots(total)`. Redis is declared as `atomicity` in the context
103
- rather than `outbox.redis`, and read from `TOA_ATOMICITY_REDIS`.
104
- `TOA_OUTBOX_PARTITION_INTERVAL` is `TOA_ATOMICITY_INTERVAL`.
105
-
106
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
107
- * `event.changeset` is removed; use `origin` and `state`. `State`
108
- takes an `Outbox` in place of an `Emission`. `difference` is dropped from
109
- `@toa.io/generic` along with its last caller.
110
-
111
- Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
112
-
113
-
114
-
115
-
116
-
117
- # [1.0.0-alpha.270](https://github.com/toa-io/toa/compare/v1.0.0-alpha.269...v1.0.0-alpha.270) (2026-08-31)
118
-
119
-
120
- ### Bug Fixes
121
-
122
- * **core:** apply the input default on a remote call ([341699b](https://github.com/toa-io/toa/commit/341699b26c9299963a898368671633a9b3fb97ed))
123
-
124
-
125
- ### Performance Improvements
126
-
127
- * **core:** do not snapshot a record an operation cannot commit ([a5e695b](https://github.com/toa-io/toa/commit/a5e695b0b1d4b00a91e40336deecd476c9646c89))
128
- * **core:** keep the parsed criteria of a query ([7efc694](https://github.com/toa-io/toa/commit/7efc694814c2a071ae7e48dbf1c6014db6025a9f))
129
- * stop rebuilding per-call values that never change ([4202504](https://github.com/toa-io/toa/commit/4202504c33fb9ef9694f9995f3d0397d3a186438))
130
-
131
-
132
-
133
-
134
-
135
- # [1.0.0-alpha.266](https://github.com/toa-io/toa/compare/v1.0.0-alpha.265...v1.0.0-alpha.266) (2026-08-29)
136
-
137
-
138
- ### Bug Fixes
139
-
140
- * **core:** say a connector is disconnected once it has closed, not before ([d67b48e](https://github.com/toa-io/toa/commit/d67b48eaafaacd5c635d8b066413f84b8e6a3771))
141
-
142
-
143
-
144
-
145
-
146
- # [1.0.0-alpha.265](https://github.com/toa-io/toa/compare/v1.0.0-alpha.264...v1.0.0-alpha.265) (2026-08-29)
147
-
148
-
149
- ### Features
150
-
151
- * **bridges.node:** add the dispose run command phase ([00df715](https://github.com/toa-io/toa/commit/00df7158f638b976ab09d4007102a4ead3c696c3))
152
-
153
-
154
-
155
-
156
-
157
- # [1.0.0-alpha.264](https://github.com/toa-io/toa/compare/v1.0.0-alpha.263...v1.0.0-alpha.264) (2026-08-29)
158
-
159
- **Note:** Version bump only for package @toa.io/core
160
-
161
-
162
-
163
-
164
-
165
- # [1.0.0-alpha.262](https://github.com/toa-io/toa/compare/v1.0.0-alpha.261...v1.0.0-alpha.262) (2026-08-28)
166
-
167
-
168
- ### Features
169
-
170
- * **core:** identify the origin of a call with `request.source` ([9da6b66](https://github.com/toa-io/toa/commit/9da6b66df852690351a1e82c7b8cc176fd89774a))
171
-
172
-
173
-
174
-
175
-
176
- # [1.0.0-alpha.259](https://github.com/toa-io/toa/compare/v1.0.0-alpha.258...v1.0.0-alpha.259) (2026-08-24)
177
-
178
-
179
- ### Features
180
-
181
- * **runtime:** split component RC into preflight and settle ([0d648b3](https://github.com/toa-io/toa/commit/0d648b314e4aac226c254bf01a86affa04b59b34))
182
-
183
-
184
-
185
-
186
-
187
- # [1.0.0-alpha.257](https://github.com/toa-io/toa/compare/v1.0.0-alpha.256...v1.0.0-alpha.257) (2026-08-24)
188
-
189
-
190
- ### Bug Fixes
191
-
192
- * **core:** lift tombstone on commit when transition leaves it untouched ([38c0d15](https://github.com/toa-io/toa/commit/38c0d15e946c3e2d559d4b18aecc33e0fda2471a))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toa.io/core",
3
- "version": "1.0.0-alpha.284",
3
+ "version": "1.0.0-alpha.287",
4
4
  "type": "module",
5
5
  "description": "Toa Core",
6
6
  "author": "temich <tema.gurtovoy@gmail.com>",
@@ -12,20 +12,32 @@
12
12
  "bugs": {
13
13
  "url": "https://github.com/toa-io/toa/issues"
14
14
  },
15
- "main": "src/index.js",
16
- "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
+ },
17
28
  "publishConfig": {
18
29
  "access": "public"
19
30
  },
20
31
  "scripts": {
32
+ "transpile": "tsc",
21
33
  "test": "echo \"Error: run tests from root\" && exit 1"
22
34
  },
23
35
  "dependencies": {
24
36
  "@rsql/parser": "1.6.0",
25
- "@toa.io/generic": "1.0.0-alpha.283",
26
- "js-yaml": "5.4.1",
27
- "openspan": "1.0.0-alpha.277",
37
+ "@toa.io/generic": "1.0.0-alpha.286",
38
+ "@toa.io/schemas": "1.0.0-alpha.287",
39
+ "openspan": "1.0.0-alpha.286",
28
40
  "uuid": "14.0.2"
29
41
  },
30
- "gitHead": "006755556879e91e8d68fa86753aa3b475bdf4bf"
42
+ "gitHead": "5c7944a70c16065ab6372072385cc1f02f5db77c"
31
43
  }
@@ -0,0 +1,27 @@
1
+ import { Operation } from './operation.js'
2
+ import type { Store } from './operation.js'
3
+ import type { Changeset } from './entities/changeset.js'
4
+
5
+ export class Assignment extends Operation {
6
+ protected override async acquire(store: Store): Promise<void> {
7
+ const changeset = this.scope.changeset(store.request.query as any)
8
+
9
+ store.scope = changeset
10
+ store.state = changeset.get()
11
+ }
12
+
13
+ protected override async commit(store: Store): Promise<void> {
14
+ const { scope, state, reply, request } = store
15
+
16
+ if (reply.error !== undefined) return
17
+
18
+ const changeset = scope as Changeset
19
+
20
+ changeset.set(state)
21
+
22
+ const output = await this.scope.apply(changeset, request.input)
23
+
24
+ // assignment returns new state by default
25
+ if (store.reply.output === undefined) store.reply.output = output
26
+ }
27
+ }
@@ -1,13 +1,16 @@
1
1
  import { Readable } from 'node:stream'
2
2
  import { current, encode } from 'openspan'
3
3
  import { Connector } from './connector.js'
4
+ import type { Transmission } from './transmission.js'
5
+ import type { Request as Contract } from './contract/request.js'
6
+ import type { Request, Source } from './types/request.js'
4
7
 
5
8
  export class Call extends Connector {
6
- #transmitter
7
- #contract
8
- #source
9
+ readonly #transmitter: Transmission
10
+ readonly #contract: Contract
11
+ readonly #source: Source | undefined
9
12
 
10
- constructor (transmitter, contract, source) {
13
+ public constructor(transmitter: Transmission, contract: Contract, source?: Source) {
11
14
  super()
12
15
 
13
16
  this.#transmitter = transmitter
@@ -17,15 +20,13 @@ export class Call extends Connector {
17
20
  this.depends(transmitter)
18
21
  }
19
22
 
20
- async invoke (request = {}) {
23
+ public async invoke(request: Request = {}): Promise<any> {
21
24
  // the caller may have attributed the call itself, as the node bridge does
22
- if (this.#source !== undefined)
23
- request.source ??= this.#source
25
+ if (this.#source !== undefined) request.source ??= this.#source
24
26
 
25
- // fitting first lets the input schema supply its default;
26
- // an operation that takes no input still has to send an explicit null
27
27
  this.#contract.fit(request)
28
28
 
29
+ // an operation that takes no input still has to send an explicit null
29
30
  request.input ??= null
30
31
 
31
32
  // avoid validation on the recipient's side
@@ -33,34 +34,28 @@ export class Call extends Connector {
33
34
 
34
35
  const context = current()
35
36
 
36
- if (context !== undefined)
37
- request.telemetry = encode(context)
37
+ if (context !== undefined) request.telemetry = encode(context)
38
38
 
39
39
  const reply = await this.#transmitter.request(request)
40
40
 
41
41
  if (reply === null) return null
42
42
  else if (reply instanceof Readable) return reply
43
43
  else {
44
- if (reply.exception !== undefined)
45
- throw reply.exception
44
+ if (reply.exception !== undefined) throw reply.exception
46
45
 
47
- if (reply.error !== undefined)
48
- return new RemoteError(reply.error)
49
- else
50
- return reply.output
46
+ if (reply.error !== undefined) return new RemoteError(reply.error)
47
+ else return reply.output
51
48
  }
52
49
  }
53
50
 
54
- explain () {
51
+ public explain(): any {
55
52
  return this.#contract.discovery
56
53
  }
57
54
  }
58
55
 
59
-
60
-
61
56
  // the remote error as a value: every property it carries, and nothing else enumerable
62
57
  class RemoteError extends Error {
63
- constructor (error) {
58
+ public constructor(error: object) {
64
59
  super()
65
60
 
66
61
  Object.assign(this, error)
@@ -1,22 +1,20 @@
1
1
  import { Connector } from './connector.js'
2
+ import type { Algorithm } from './types/bridges.js'
2
3
 
3
4
  export class Cascade extends Connector {
4
- // #bridges
5
- #last
5
+ readonly #last: Algorithm
6
6
 
7
- constructor (bridges, preflight) {
7
+ public constructor(bridges: Algorithm[], preflight?: Connector) {
8
8
  super()
9
9
 
10
10
  // this.#bridges = bridges
11
11
  this.#last = bridges[bridges.length - 1]
12
12
 
13
- if (preflight === undefined)
14
- this.depends(bridges)
15
- else
16
- this.depends(bridges).depends(preflight)
13
+ if (preflight === undefined) this.depends(bridges)
14
+ else this.depends(bridges).depends(preflight)
17
15
  }
18
16
 
19
- async run (...args) {
17
+ public async run(...args: [any, any?]): Promise<any> {
20
18
  // const reply = {}
21
19
  //
22
20
  // for (const bridge of this.#bridges) {
@@ -1,20 +1,25 @@
1
1
  import assert from 'node:assert'
2
- import { console, current, decode, run } from 'openspan'
2
+ import { console, current, decode, run, type SpanOptions } from 'openspan'
3
3
  import { Connector } from './connector.js'
4
+ import type { Locator } from './locator.js'
5
+ import type { Request } from './types/request.js'
4
6
 
5
- export class Component extends Connector {
6
- locator
7
+ /** What a component holds one of per endpoint: an operation, or the call that stands for it. */
8
+ export interface Invocable extends Connector {
9
+ invoke: (request: Request) => Promise<any>
10
+ }
11
+
12
+ export class Component<O extends Invocable = Invocable> extends Connector {
13
+ public readonly locator: Locator
7
14
 
8
- /** @protected */
9
- operations
15
+ protected readonly operations: Record<string, O>
10
16
 
11
- /** @protected */
12
- kind = 'server'
17
+ protected kind: 'server' | 'client' = 'server'
13
18
 
14
- /** @type {Record<string, object>} span options per endpoint */
15
- #spans = {}
19
+ /** span options per endpoint */
20
+ readonly #spans: Record<string, SpanOptions> = {}
16
21
 
17
- constructor (locator, operations) {
22
+ public constructor(locator: Locator, operations: Record<string, O>) {
18
23
  super()
19
24
 
20
25
  this.locator = locator
@@ -23,28 +28,27 @@ export class Component extends Connector {
23
28
  Object.values(operations).forEach((operation) => this.depends(operation))
24
29
  }
25
30
 
26
- async invoke (endpoint, request) {
31
+ public async invoke<T = any>(endpoint: string, request?: Request): Promise<T> {
27
32
  if (!(endpoint in this.operations))
28
33
  // `assert.fail`, not `assert.ok`: the message is built only when it is needed
29
34
  assert.fail(`Endpoint '${endpoint}' is not provided by '${this.locator.id}'`)
30
35
 
31
36
  // if the request carries no telemetry, the trace starts here
32
37
  const remote = request?.telemetry === undefined ? null : decode(request.telemetry)
33
- const task = () => this.process(endpoint, request)
38
+ const task = async (): Promise<any> => this.#process(endpoint, request)
34
39
 
35
- if (remote === null)
36
- return task()
37
- else
38
- return run(remote, task)
40
+ if (remote === null) return task()
41
+ else return run(remote, task)
39
42
  }
40
43
 
41
- /** @private */
42
- async process (endpoint, request) {
43
- return console.span(this.span(endpoint), async () => {
44
- const reply = await this.operations[endpoint].invoke(request)
44
+ async #process(endpoint: string, request?: Request): Promise<any> {
45
+ return console.span(this.#span(endpoint), async () => {
46
+ const reply = await this.operations[endpoint].invoke(request as Request)
45
47
 
46
48
  if (reply?.exception !== undefined) {
47
- current().status = 'error'
49
+ const span = current()
50
+
51
+ if (span !== undefined) span.status = 'error'
48
52
 
49
53
  console.error('Failed to execute operation', {
50
54
  endpoint: `${this.locator.id}.${endpoint}`,
@@ -60,9 +64,8 @@ export class Component extends Connector {
60
64
  * The span of an endpoint never changes, so it is built once. Not in the constructor:
61
65
  * `kind` is a field of the subclass, and those are assigned after this one is built.
62
66
  *
63
- * @private
64
67
  */
65
- span (endpoint) {
68
+ #span(endpoint: string): SpanOptions {
66
69
  let options = this.#spans[endpoint]
67
70
 
68
71
  if (options === undefined) {
@@ -70,8 +73,7 @@ export class Component extends Connector {
70
73
 
71
74
  // the server span is emitted by the component itself, while the client span
72
75
  // belongs to the calling service and inherits it from the context
73
- if (this.kind === 'server')
74
- options.service = this.locator.id
76
+ if (this.kind === 'server') options.service = this.locator.id
75
77
 
76
78
  this.#spans[endpoint] = options
77
79
  }
@@ -2,7 +2,13 @@ import { console } from 'openspan'
2
2
  import { Connector } from './connector.js'
3
3
 
4
4
  export class Composition extends Connector {
5
- constructor (expositions, producers, receivers, tenants) {
5
+ // eslint-disable-next-line max-params
6
+ public constructor(
7
+ expositions: Connector[],
8
+ producers: Connector[],
9
+ receivers: Connector[],
10
+ tenants: Connector[]
11
+ ) {
6
12
  super()
7
13
 
8
14
  if (expositions.length > 0) this.depends(expositions)
@@ -11,11 +17,11 @@ export class Composition extends Connector {
11
17
  if (tenants.length > 0) this.depends(tenants)
12
18
  }
13
19
 
14
- async open () {
20
+ protected override async open(): Promise<void> {
15
21
  console.info('Composition complete')
16
22
  }
17
23
 
18
- async dispose () {
24
+ protected override async dispose(): Promise<void> {
19
25
  console.info('Composition shutdown complete')
20
26
  }
21
27
  }
@@ -1,28 +1,17 @@
1
1
  import { console } from 'openspan'
2
+ import type { Locator } from './locator.js'
2
3
 
3
- /**
4
- * Abstract connections hierarchy
5
- * @implements {toa.core.Connector}
6
- */
4
+ /** Abstract connections hierarchy */
7
5
  export class Connector {
8
- /** @type {Array<Connector>} */
9
- #dependencies = []
6
+ #dependencies: Connector[] = []
7
+ #links: Connector[] = []
8
+ #connecting: Promise<void> | undefined
9
+ #disconnecting: Promise<void> | undefined
10
10
 
11
- /** @type {Array<Connector>} */
12
- #links = []
11
+ public readonly id: string
12
+ public connected: boolean = false
13
13
 
14
- /** @type {Promise} */
15
- #connecting
16
-
17
- /** @type {Promise} */
18
- #disconnecting
19
-
20
- /** @type {string} */
21
- id
22
- /** @type {boolean} */
23
- connected = false
24
-
25
- constructor () {
14
+ public constructor() {
26
15
  this.id = this.constructor.name + '#' + Math.random().toString(36).substring(2, 8)
27
16
  }
28
17
 
@@ -31,12 +20,9 @@ export class Connector {
31
20
  *
32
21
  * See .connect() and .disconnect()
33
22
  *
34
- * @param connector {Connector | any | Array<Connector | any>}
35
- * @returns {Connector}
36
23
  */
37
- depends (connector) {
38
- /** @type {Connector} */
39
- let next
24
+ public depends(connector: Connector | Connector[]): Connector {
25
+ let next: Connector
40
26
 
41
27
  if (connector instanceof Array) {
42
28
  if (connector.length === 0) throw new Error('Connectors array must not be empty')
@@ -62,10 +48,8 @@ export class Connector {
62
48
  *
63
49
  * See .connect() and .disconnect()
64
50
  *
65
- * @param connector {Connector}
66
- * @returns {void}
67
51
  */
68
- link (connector) {
52
+ public link(connector: Connector): void {
69
53
  this.#links.push(connector)
70
54
  }
71
55
 
@@ -76,9 +60,8 @@ export class Connector {
76
60
  *
77
61
  * Method is idempotent
78
62
  *
79
- * @returns {Promise<void>}
80
63
  */
81
- async connect () {
64
+ public async connect(): Promise<void> {
82
65
  if (this.#connecting) return this.#connecting
83
66
 
84
67
  this.#disconnecting = undefined
@@ -89,12 +72,17 @@ export class Connector {
89
72
  }
90
73
 
91
74
  // anonymous grouping nodes are not worth a span
92
- this.#connecting = TRACE_BOOT && this.constructor.name !== 'Connector'
93
- ? console.span({
94
- name: `connect ${this.constructor.name}`,
95
- attributes: { id: this.locator?.id ?? this.id }
96
- }, work)
97
- : work()
75
+ this.#connecting =
76
+ TRACE_BOOT && this.constructor.name !== 'Connector'
77
+ ? console.span(
78
+ {
79
+ name: `connect ${this.constructor.name}`,
80
+ // a connector that has a locator is named by it; a grouping node has none
81
+ attributes: { id: (this as { locator?: Locator }).locator?.id ?? this.id }
82
+ },
83
+ work
84
+ )
85
+ : work()
98
86
 
99
87
  try {
100
88
  await this.#connecting
@@ -112,10 +100,8 @@ export class Connector {
112
100
  *
113
101
  * Method is idempotent
114
102
  *
115
- * @param [interrupt] {boolean}
116
- * @returns {Promise<void>}
117
103
  */
118
- async disconnect (interrupt) {
104
+ public async disconnect(interrupt?: boolean): Promise<void> {
119
105
  // a connector that has not finished connecting has nothing to close, and
120
106
  // awaiting a connection that may never settle outlives any grace period
121
107
  const pending = interrupt === true || this.connected === false
@@ -149,7 +135,7 @@ export class Connector {
149
135
 
150
136
  clearInterval(interval)
151
137
 
152
- await Promise.all(this.#dependencies.map(connector => connector.disconnect()))
138
+ await Promise.all(this.#dependencies.map((connector) => connector.disconnect()))
153
139
 
154
140
  await this.dispose()
155
141
  })()
@@ -157,33 +143,28 @@ export class Connector {
157
143
  await this.#disconnecting
158
144
  }
159
145
 
160
- async reconnect () {
146
+ public async reconnect(): Promise<void> {
161
147
  await this.disconnect()
162
148
  await this.connect()
163
149
  }
164
150
 
165
- debug (node = {}) {
151
+ public debug(node: Record<string, any> = {}): Record<string, any> {
166
152
  node[this.id] = { connected: this.connected }
167
153
 
168
- if (this.#dependencies.length > 0) for (const connector of this.#dependencies) connector.debug?.(node[this.id])
154
+ if (this.#dependencies.length > 0)
155
+ for (const connector of this.#dependencies) connector.debug?.(node[this.id])
169
156
 
170
157
  return node
171
158
  }
172
159
 
173
- /**
174
- * Called on connection
175
- */
176
- async open () {}
160
+ /** Called on connection */
161
+ protected open(): Promise<void> | void {}
177
162
 
178
- /**
179
- * Called on disconnection
180
- */
181
- async close () {}
163
+ /** Called on disconnection */
164
+ protected close(): Promise<void> | void {}
182
165
 
183
- /**
184
- * Called after self and dependants disconnection is complete
185
- */
186
- async dispose () {}
166
+ /** Called after self and dependants disconnection is complete */
167
+ protected dispose(): Promise<void> | void {}
187
168
  }
188
169
 
189
170
  const DELAY = 5000