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

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/package.json +19 -7
  2. package/source/assignment.ts +27 -0
  3. package/{src/call.js → source/call.ts} +16 -21
  4. package/{src/cascade.js → source/cascade.ts} +6 -8
  5. package/{src/component.js → source/component.ts} +27 -25
  6. package/{src/composition.js → source/composition.ts} +9 -3
  7. package/{src/connector.js → source/connector.ts} +36 -55
  8. package/source/context.ts +67 -0
  9. package/source/contract/contract.ts +23 -0
  10. package/{src/contract/reply.js → source/contract/reply.ts} +26 -19
  11. package/source/contract/request.ts +85 -0
  12. package/source/contract/schemas.ts +39 -0
  13. package/{src/discovery.js → source/discovery.ts} +15 -8
  14. package/source/effect.ts +14 -0
  15. package/{src/emission.js → source/emission.ts} +5 -3
  16. package/source/entities/changeset.ts +37 -0
  17. package/source/entities/entity.ts +137 -0
  18. package/source/entities/factory.ts +52 -0
  19. package/source/entities/index.ts +4 -0
  20. package/{src/entities/newid.js → source/entities/newid.ts} +1 -1
  21. package/{src/entities/set.js → source/entities/set.ts} +8 -5
  22. package/source/event.ts +57 -0
  23. package/{src/exceptions.js → source/exceptions.ts} +52 -33
  24. package/source/exposition.ts +33 -0
  25. package/source/guard.ts +16 -0
  26. package/{src/index.js → source/index.ts} +8 -0
  27. package/{src/locator.js → source/locator.ts} +17 -30
  28. package/source/observation.ts +16 -0
  29. package/source/operation.ts +138 -0
  30. package/{src/outbox/outbox.js → source/outbox/outbox.ts} +87 -53
  31. package/source/query/criteria.ts +90 -0
  32. package/source/query/options.ts +35 -0
  33. package/{src/query.js → source/query.ts} +14 -17
  34. package/source/receiver.ts +120 -0
  35. package/source/reflection.ts +20 -0
  36. package/source/remote.ts +20 -0
  37. package/source/state.ts +179 -0
  38. package/source/transition.ts +79 -0
  39. package/{src/transmission.js → source/transmission.ts} +8 -8
  40. package/source/types/atomicity.ts +63 -0
  41. package/source/types/bindings.ts +59 -0
  42. package/source/types/bridges.ts +54 -0
  43. package/source/types/extensions.ts +89 -0
  44. package/{types → source/types}/index.ts +9 -16
  45. package/{types/message.d.ts → source/types/message.ts} +2 -1
  46. package/source/types/operations.ts +31 -0
  47. package/source/types/outbox.ts +35 -0
  48. package/source/types/receiver.ts +10 -0
  49. package/{types/request.d.ts → source/types/request.ts} +8 -9
  50. package/source/types/state.ts +9 -0
  51. package/source/types/storages.ts +129 -0
  52. package/source/unmanaged.ts +8 -0
  53. package/test/call.fixtures.js +3 -1
  54. package/test/call.test.js +28 -7
  55. package/test/component.test.js +10 -5
  56. package/test/connector.fixtures.js +7 -7
  57. package/test/connector.test.js +15 -2
  58. package/test/context.fixtures.js +1 -1
  59. package/test/context.test.js +4 -4
  60. package/test/contract/conditions.test.js +6 -2
  61. package/test/contract/contract.fixtures.js +3 -4
  62. package/test/contract/request.test.js +68 -34
  63. package/test/discovery.test.js +10 -3
  64. package/test/emission.test.js +16 -8
  65. package/test/entities/entity.fixtures.js +5 -6
  66. package/test/entities/entity.test.js +54 -20
  67. package/test/entities/factory.fixtures.js +11 -10
  68. package/test/entities/factory.test.js +47 -10
  69. package/test/entities/set.test.js +1 -1
  70. package/test/event.test.js +29 -11
  71. package/test/locator.test.js +10 -4
  72. package/test/outbox.test.js +49 -15
  73. package/test/query.test.js +69 -7
  74. package/test/receiver.fixtures.js +2 -2
  75. package/test/receiver.test.js +53 -27
  76. package/test/reflection.test.js +3 -3
  77. package/test/state.fixtures.js +10 -3
  78. package/test/state.test.js +77 -14
  79. package/test/transmission.test.js +25 -12
  80. package/transpiled/assignment.d.ts +6 -0
  81. package/transpiled/assignment.js +20 -0
  82. package/transpiled/assignment.js.map +1 -0
  83. package/transpiled/call.d.ts +10 -0
  84. package/transpiled/call.js +52 -0
  85. package/transpiled/call.js.map +1 -0
  86. package/transpiled/cascade.d.ts +7 -0
  87. package/transpiled/cascade.js +28 -0
  88. package/transpiled/cascade.js.map +1 -0
  89. package/transpiled/component.d.ts +15 -0
  90. package/transpiled/component.js +61 -0
  91. package/transpiled/component.js.map +1 -0
  92. package/transpiled/composition.d.ts +6 -0
  93. package/transpiled/composition.js +23 -0
  94. package/transpiled/composition.js.map +1 -0
  95. package/transpiled/connector.d.ts +47 -0
  96. package/transpiled/connector.js +143 -0
  97. package/transpiled/connector.js.map +1 -0
  98. package/transpiled/context.d.ts +18 -0
  99. package/transpiled/context.js +41 -0
  100. package/transpiled/context.js.map +1 -0
  101. package/transpiled/contract/contract.d.ts +10 -0
  102. package/transpiled/contract/contract.js +14 -0
  103. package/transpiled/contract/contract.js.map +1 -0
  104. package/transpiled/contract/index.d.ts +2 -0
  105. package/transpiled/contract/index.js +3 -0
  106. package/transpiled/contract/index.js.map +1 -0
  107. package/transpiled/contract/reply.d.ts +7 -0
  108. package/transpiled/contract/reply.js +48 -0
  109. package/transpiled/contract/reply.js.map +1 -0
  110. package/transpiled/contract/request.d.ts +24 -0
  111. package/transpiled/contract/request.js +59 -0
  112. package/transpiled/contract/request.js.map +1 -0
  113. package/transpiled/contract/schemas.d.ts +4 -0
  114. package/transpiled/contract/schemas.js +36 -0
  115. package/transpiled/contract/schemas.js.map +1 -0
  116. package/transpiled/discovery.d.ts +12 -0
  117. package/transpiled/discovery.js +34 -0
  118. package/transpiled/discovery.js.map +1 -0
  119. package/transpiled/effect.d.ts +5 -0
  120. package/transpiled/effect.js +11 -0
  121. package/transpiled/effect.js.map +1 -0
  122. package/transpiled/emission.d.ts +8 -0
  123. package/transpiled/emission.js +14 -0
  124. package/transpiled/emission.js.map +1 -0
  125. package/transpiled/entities/changeset.d.ts +10 -0
  126. package/transpiled/entities/changeset.js +27 -0
  127. package/transpiled/entities/changeset.js.map +1 -0
  128. package/transpiled/entities/entity.d.ts +19 -0
  129. package/transpiled/entities/entity.js +109 -0
  130. package/transpiled/entities/entity.js.map +1 -0
  131. package/transpiled/entities/factory.d.ts +22 -0
  132. package/transpiled/entities/factory.js +34 -0
  133. package/transpiled/entities/factory.js.map +1 -0
  134. package/transpiled/entities/index.d.ts +4 -0
  135. package/transpiled/entities/index.js +5 -0
  136. package/transpiled/entities/index.js.map +1 -0
  137. package/transpiled/entities/newid.d.ts +1 -0
  138. package/transpiled/entities/newid.js +7 -0
  139. package/transpiled/entities/newid.js.map +1 -0
  140. package/transpiled/entities/set.d.ts +10 -0
  141. package/transpiled/entities/set.js +19 -0
  142. package/transpiled/entities/set.js.map +1 -0
  143. package/transpiled/event.d.ts +14 -0
  144. package/transpiled/event.js +38 -0
  145. package/transpiled/event.js.map +1 -0
  146. package/transpiled/exceptions.d.ts +61 -0
  147. package/transpiled/exceptions.js +93 -0
  148. package/transpiled/exceptions.js.map +1 -0
  149. package/transpiled/exposition.d.ts +18 -0
  150. package/transpiled/exposition.js +18 -0
  151. package/transpiled/exposition.js.map +1 -0
  152. package/transpiled/guard.d.ts +7 -0
  153. package/transpiled/guard.js +12 -0
  154. package/transpiled/guard.js.map +1 -0
  155. package/transpiled/index.d.ts +35 -0
  156. package/transpiled/index.js +29 -0
  157. package/transpiled/index.js.map +1 -0
  158. package/transpiled/locator.d.ts +12 -0
  159. package/transpiled/locator.js +32 -0
  160. package/transpiled/locator.js.map +1 -0
  161. package/transpiled/observation.d.ts +5 -0
  162. package/transpiled/observation.js +12 -0
  163. package/transpiled/observation.js.map +1 -0
  164. package/transpiled/operation.d.ts +49 -0
  165. package/transpiled/operation.js +77 -0
  166. package/transpiled/operation.js.map +1 -0
  167. package/transpiled/outbox/index.d.ts +1 -0
  168. package/transpiled/outbox/index.js +2 -0
  169. package/transpiled/outbox/index.js.map +1 -0
  170. package/transpiled/outbox/outbox.d.ts +46 -0
  171. package/transpiled/outbox/outbox.js +267 -0
  172. package/transpiled/outbox/outbox.js.map +1 -0
  173. package/transpiled/query/criteria.d.ts +6 -0
  174. package/transpiled/query/criteria.js +74 -0
  175. package/transpiled/query/criteria.js.map +1 -0
  176. package/transpiled/query/options.d.ts +3 -0
  177. package/transpiled/query/options.js +27 -0
  178. package/transpiled/query/options.js.map +1 -0
  179. package/transpiled/query.d.ts +9 -0
  180. package/transpiled/query.js +57 -0
  181. package/transpiled/query.js.map +1 -0
  182. package/transpiled/receiver.d.ts +20 -0
  183. package/transpiled/receiver.js +92 -0
  184. package/transpiled/receiver.js.map +1 -0
  185. package/transpiled/reflection.d.ts +9 -0
  186. package/transpiled/reflection.js +13 -0
  187. package/transpiled/reflection.js.map +1 -0
  188. package/transpiled/remote.d.ts +10 -0
  189. package/transpiled/remote.js +12 -0
  190. package/transpiled/remote.js.map +1 -0
  191. package/transpiled/state.d.ts +33 -0
  192. package/transpiled/state.js +126 -0
  193. package/transpiled/state.js.map +1 -0
  194. package/transpiled/transition.d.ts +14 -0
  195. package/transpiled/transition.js +51 -0
  196. package/transpiled/transition.js.map +1 -0
  197. package/transpiled/transmission.d.ts +8 -0
  198. package/transpiled/transmission.js +30 -0
  199. package/transpiled/transmission.js.map +1 -0
  200. package/transpiled/types/atomicity.d.ts +56 -0
  201. package/transpiled/types/atomicity.js +2 -0
  202. package/transpiled/types/atomicity.js.map +1 -0
  203. package/transpiled/types/bindings.d.ts +42 -0
  204. package/transpiled/types/bindings.js +2 -0
  205. package/transpiled/types/bindings.js.map +1 -0
  206. package/transpiled/types/bridges.d.ts +38 -0
  207. package/transpiled/types/bridges.js +2 -0
  208. package/transpiled/types/bridges.js.map +1 -0
  209. package/transpiled/types/extensions.d.ts +62 -0
  210. package/transpiled/types/extensions.js +2 -0
  211. package/transpiled/types/extensions.js.map +1 -0
  212. package/transpiled/types/index.d.ts +13 -0
  213. package/transpiled/types/index.js +8 -0
  214. package/transpiled/types/index.js.map +1 -0
  215. package/transpiled/types/message.d.ts +5 -0
  216. package/transpiled/types/message.js +2 -0
  217. package/transpiled/types/message.js.map +1 -0
  218. package/transpiled/types/operations.d.ts +15 -0
  219. package/transpiled/types/operations.js +2 -0
  220. package/transpiled/types/operations.js.map +1 -0
  221. package/transpiled/types/outbox.d.ts +28 -0
  222. package/transpiled/types/outbox.js +2 -0
  223. package/transpiled/types/outbox.js.map +1 -0
  224. package/transpiled/types/receiver.d.ts +9 -0
  225. package/transpiled/types/receiver.js +2 -0
  226. package/transpiled/types/receiver.js.map +1 -0
  227. package/transpiled/types/request.d.ts +55 -0
  228. package/transpiled/types/request.js +2 -0
  229. package/transpiled/types/request.js.map +1 -0
  230. package/transpiled/types/state.d.ts +9 -0
  231. package/transpiled/types/state.js +2 -0
  232. package/transpiled/types/state.js.map +1 -0
  233. package/transpiled/types/storages.d.ts +106 -0
  234. package/transpiled/types/storages.js +2 -0
  235. package/transpiled/types/storages.js.map +1 -0
  236. package/transpiled/unmanaged.d.ts +5 -0
  237. package/transpiled/unmanaged.js +7 -0
  238. package/transpiled/unmanaged.js.map +1 -0
  239. package/tsconfig.json +10 -0
  240. package/tsconfig.tsbuildinfo +1 -0
  241. package/CHANGELOG.md +0 -192
  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/src/receiver.js DELETED
@@ -1,123 +0,0 @@
1
- import { console, decode, run } from 'openspan'
2
- import { add } from '@toa.io/generic'
3
- import { Connector } from './connector.js'
4
-
5
- /**
6
- * @implements {toa.core.Receiver}
7
- */
8
- export class Receiver extends Connector {
9
- /** @type {boolean} */
10
- #conditioned
11
-
12
- /** @type {boolean} */
13
- #adaptive
14
-
15
- /** @type {string} */
16
- #endpoint
17
-
18
- /** @type {string} */
19
- #label
20
-
21
- /** @type {string} */
22
- #destination
23
-
24
- /** @type {unknown[]} */
25
- #arguments
26
-
27
- /** @type {toa.core.Source} */
28
- #origin
29
-
30
- #local
31
-
32
- #bridge
33
-
34
- /** @type {object} */
35
- #delivery
36
-
37
- /** @type {object} */
38
- #processing
39
-
40
- constructor (definition, local, bridge) {
41
- super()
42
-
43
- const { conditioned, adaptive, operation } = definition
44
-
45
- this.#conditioned = conditioned
46
- this.#adaptive = adaptive
47
- this.#endpoint = operation
48
- this.#label = definition.label ?? operation
49
- this.#destination = definition.destination ?? this.#label
50
- this.#arguments = definition.arguments
51
- this.#origin = definition.origin
52
-
53
- this.#local = local
54
- this.#bridge = bridge
55
-
56
- this.depends(local)
57
- if (bridge !== undefined) this.depends(bridge)
58
-
59
- /*
60
- * The delivery span is created on behalf of the messaging destination, so that
61
- * each consumer forms its own complete producer/consumer pair, and service graphs
62
- * display fan-out correctly: producer -> destination -> each consumer
63
- * (Tempo pairs spans one-to-one, thus multiple consumers can not pair
64
- * with a single producer span, see grafana/tempo#5408)
65
- */
66
- this.#delivery = {
67
- name: `${this.#label} deliver`,
68
- kind: 'producer',
69
- service: this.#destination,
70
- attributes: { 'messaging.destination.name': this.#destination }
71
- }
72
-
73
- this.#processing = {
74
- name: `${this.#label} process`,
75
- kind: 'consumer',
76
- service: local.locator.id,
77
- attributes: { 'messaging.destination.name': this.#destination }
78
- }
79
- }
80
-
81
- /** @hot */
82
- async receive (message) {
83
- const { payload, telemetry, ...extensions } = message
84
-
85
- if (this.#conditioned && await this.#bridge.condition(payload) === false) return
86
-
87
- const request = await this.#request(payload)
88
-
89
- add(request, extensions)
90
-
91
- // set after `add`, so that a message field can not spoof the origin
92
- if (this.#origin !== undefined) request.source = this.#origin
93
-
94
- // continue the trace from the producer span
95
- const remote = telemetry === undefined ? null : decode(telemetry)
96
- const task = () => this.#process(request)
97
-
98
- if (remote === null)
99
- await task()
100
- else
101
- await run(remote, task)
102
- }
103
-
104
- async #process (request) {
105
- return console.span(this.#delivery, async () => console.span(this.#processing, async () => {
106
- try {
107
- await this.#local.invoke(this.#endpoint, request)
108
- } catch (error) {
109
- console.error('Receiver error', {
110
- component: this.#local.locator.id,
111
- endpoint: this.#endpoint,
112
- error
113
- })
114
-
115
- throw error
116
- }
117
- }))
118
- }
119
-
120
- async #request (payload) {
121
- return this.#adaptive ? await this.#bridge.request(payload, ...(this.#arguments ?? [])) : { input: payload }
122
- }
123
- }
package/src/reflection.js DELETED
@@ -1,24 +0,0 @@
1
- import { Connector } from './connector.js'
2
-
3
- /**
4
- * @implements {toa.core.Reflection}
5
- */
6
- export class Reflection extends Connector {
7
- /** @type {toa.core.reflection.Source} */
8
- #source
9
-
10
- value
11
-
12
- /**
13
- * @param {toa.core.reflection.Source} source
14
- */
15
- constructor (source) {
16
- super()
17
-
18
- this.#source = source
19
- }
20
-
21
- async open () {
22
- this.value = await this.#source()
23
- }
24
- }
package/src/remote.js DELETED
@@ -1,14 +0,0 @@
1
- import assert from 'node:assert'
2
- import { Component } from './component.js'
3
-
4
- export class Remote extends Component {
5
- kind = 'client'
6
-
7
- explain (endpoint) {
8
- if (!(endpoint in this.operations))
9
- // `assert.fail`, not `assert.ok`: the message is built only when it is needed
10
- assert.fail(`Endpoint '${endpoint}' is not provided by '${this.locator.id}'`)
11
-
12
- return this.operations[endpoint].explain()
13
- }
14
- }
package/src/state.js DELETED
@@ -1,138 +0,0 @@
1
- import { StatePreconditionException, StateNotFoundException } from './exceptions.js'
2
-
3
- export class State {
4
- storage
5
-
6
- #associated
7
- #entities
8
- #outbox
9
-
10
- constructor (storage, entity, outbox, associated) {
11
- this.storage = storage
12
- this.#entities = entity
13
- this.#outbox = outbox
14
- this.#associated = associated === true
15
- }
16
-
17
- init (id) {
18
- return this.#entities.init(id)
19
- }
20
-
21
- fit (values) {
22
- return this.#entities.fit(values)
23
- }
24
-
25
- async object (query, mutable = true) {
26
- const record = await this.storage.get(query)
27
-
28
- if (record === null) {
29
- if (this.#associated && query.id !== undefined && query.criteria === undefined && query.version === undefined)
30
- return this.init(query.id)
31
- else if (query.version !== undefined)
32
- throw new StatePreconditionException()
33
-
34
- return null
35
- } else
36
- return this.#entities.object(record, mutable)
37
- }
38
-
39
- async objects (query, mutable = true) {
40
- const recordset = await this.storage.find(query)
41
- const missing = this.#associated && query.ids !== undefined && recordset.length < query.ids.length
42
- const init = missing ? query.ids.filter((id) => !recordset.some((record) => record.id === id)) : undefined
43
-
44
- return this.#entities.objects(recordset, init, mutable)
45
- }
46
-
47
- async stream (query) {
48
- return this.storage.stream(query)
49
- }
50
-
51
- changeset (query) {
52
- return this.#entities.changeset(query)
53
- }
54
-
55
- none () {
56
- return null
57
- }
58
-
59
- async ensure (query, properties, input) {
60
- const object = this.#entities.init()
61
- const blank = object.get()
62
-
63
- Object.assign(blank, properties)
64
-
65
- object.set(blank)
66
-
67
- const row = this.#outbox?.row(object.event(input))
68
- const record = await this.storage.ensure(query, properties, object.get(), row)
69
-
70
- if (record.id !== blank.id) // exists
71
- return this.#entities.object(record, NOT_MUTABLE)
72
-
73
- if (row !== undefined)
74
- await this.#outbox.publish(row)
75
-
76
- return object
77
- }
78
-
79
- async commit (state, input) {
80
- if (state.constructor.name === 'EntitySet')
81
- return this.massCommit(state, input)
82
-
83
- const data = state.get()
84
-
85
- // the row is built before the write so that the storage can commit it in the same
86
- // transaction, closing the window this used to have
87
- const row = this.#outbox?.row(state.event(input))
88
- const ok = await this.storage.store(data, row)
89
-
90
- if (ok === true && row !== undefined)
91
- await this.#outbox.publish(row)
92
-
93
- return ok
94
- }
95
-
96
- async massCommit (state, input) {
97
- const data = state.get()
98
- const rows = this.#outbox === undefined
99
- ? undefined
100
- : state.events(input).map((event) => this.#outbox.row(event))
101
-
102
- const ok = await this.storage.massStore(data, rows)
103
-
104
- if (ok === true && rows !== undefined)
105
- await Promise.all(rows.map((row) => this.#outbox.publish(row)))
106
-
107
- return ok
108
- }
109
-
110
- async apply (state, input) {
111
- const changeset = state.export()
112
-
113
- // an assignment's event is the write's own images, so the storage fills them in;
114
- // see `apply` in the outbox design
115
- const row = this.#outbox?.row({ input })
116
- const result = await this.storage.upsert(state.query, changeset, row)
117
-
118
- if (result === null) {
119
- if (state.query.version !== undefined) {
120
- throw new StatePreconditionException()
121
- } else {
122
- throw new StateNotFoundException()
123
- }
124
- } else if (row !== undefined) {
125
- // the storage fills `origin` and `state` from its own write; a storage that does not
126
- // know how leaves the event with what it was given
127
- row.event.state ??= result
128
- row.event.origin ??= null
129
-
130
- await this.#outbox.publish(row)
131
- }
132
-
133
- return result
134
- }
135
- }
136
-
137
- /** an effect never commits what `ensure` hands it, see `Effect` */
138
- const NOT_MUTABLE = false
package/src/transition.js DELETED
@@ -1,61 +0,0 @@
1
- import { retry } from '@toa.io/generic'
2
- import { Operation } from './operation.js'
3
- import { StateConcurrencyException, StateNotFoundException } from './exceptions.js'
4
-
5
- export class Transition extends Operation {
6
- /** a transition is the only operation that commits */
7
- mutable = true
8
-
9
- #concurrency
10
-
11
- constructor (cascade, scope, contract, query, definition) {
12
- super(cascade, scope, contract, query, definition)
13
-
14
- this.#concurrency = definition.concurrency
15
- }
16
-
17
- async process (store) {
18
- return retry((retry) => this.#retry(store, retry), RETRY)
19
- }
20
-
21
- async acquire (store) {
22
- const { request } = store
23
-
24
- store.scope = request.query ? await this.query(request.query) : this.scope.init()
25
-
26
- if (store.scope === null || (store.scope.deleted === true && request.query?.options?.deleted !== true))
27
- throw new StateNotFoundException()
28
-
29
- store.state = store.scope.get()
30
- }
31
-
32
- async commit (store) {
33
- const { scope, state, reply, retry } = store
34
-
35
- if (reply.error !== undefined) return
36
-
37
- scope.set(state)
38
-
39
- const result = await this.scope.commit(scope, store.request.input)
40
-
41
- if (result === false) {
42
- if (this.#concurrency === 'retry')
43
- return retry()
44
- else
45
- throw new StateConcurrencyException()
46
- }
47
- }
48
-
49
- async #retry (store, retry) {
50
- store.retry = retry
51
-
52
- return super.process(store)
53
- }
54
- }
55
-
56
- const RETRY = {
57
- base: 10,
58
- max: 5000,
59
- dispersion: 1,
60
- retries: 32
61
- }
package/src/unmanaged.js DELETED
@@ -1,7 +0,0 @@
1
- import { Operation } from './operation.js'
2
-
3
- export class Unmanaged extends Operation {
4
- acquire (context) {
5
- context.state = this.scope.storage.raw
6
- }
7
- }
@@ -1,79 +0,0 @@
1
- // noinspection ES6UnusedImports
2
-
3
- import { Connector } from './connector.js'
4
-
5
- declare namespace toa.core {
6
-
7
- namespace atomicity {
8
-
9
- /**
10
- * What one group of replicas decides together, in one place. The decisions here are the
11
- * ones processes cannot arrange by talking to each other: they need a single arbiter and a
12
- * step indivisible from its point of view.
13
- */
14
- interface Atom extends Connector {
15
- /**
16
- * An exclusive claim on slots of `0..total`: while this replica holds one, no other
17
- * replica of the group does. Answered from memory, so it costs nothing to ask.
18
- *
19
- * `null` while this replica owns nothing — after a restart, during a rollout, or while
20
- * coordination is unreachable. Whoever asks must be able to stand down: acting on a
21
- * claim that cannot be supported is a different guarantee, not a degraded one.
22
- */
23
- slots (total: number): number[] | null
24
-
25
- /**
26
- * Calls `listener` with the assignment this replica holds, and again whenever it
27
- * changes — one arrived, was lost, or the group resized. Answers with what removes the
28
- * listener again.
29
- *
30
- * A change and not a heartbeat: a group that stays as it is never calls back. It is
31
- * called once as it is added, with the claim as it stands.
32
- *
33
- * What `slots` cannot say. Reading serves a consumer that asks often, where a stale
34
- * answer costs it one cycle; a consumer that asks rarely has to be told, or it samples
35
- * the one moment a rollout was passing through and stands down for a whole cycle.
36
- */
37
- onassigned (listener: (assignment: Assignment | null) => void): () => void
38
-
39
- /**
40
- * Debt the group has run up under each key, in milliseconds. Every call adds its own
41
- * deltas and reads back where the group stands, so a replica reports what it alone has
42
- * spent and still decides on what all of them have.
43
- *
44
- * Rejects where there is nothing to arbitrate through.
45
- */
46
- meter (keys: string[], deltas: number[]): Promise<number[]>
47
-
48
- /**
49
- * Runs `routine` holding `keys`, and while it holds them no other replica of the group
50
- * does. Waits for as long as it takes to acquire them.
51
- *
52
- * The lease is extended for as long as the routine runs. An extension that fails aborts
53
- * the signal the routine is given, which is the only way it learns it no longer holds
54
- * what it is working under.
55
- *
56
- * Rejects where there is nothing to arbitrate through.
57
- */
58
- lock<T> (keys: string | string[],
59
- routine: (signal: AbortSignal, context: unknown) => Promise<T>): Promise<T>
60
- }
61
-
62
- /** Which of the group this replica is, and how many of them there are. */
63
- interface Assignment {
64
- i: number
65
- n: number
66
- }
67
-
68
- interface Factory {
69
- /** @param group what the replicas deciding together have in common */
70
- atom (group: string, options?: object): Atom
71
- }
72
-
73
- }
74
-
75
- }
76
-
77
- export type Atom = toa.core.atomicity.Atom
78
- export type Assignment = toa.core.atomicity.Assignment
79
- export type Factory = toa.core.atomicity.Factory
@@ -1,42 +0,0 @@
1
- import * as _core from './index.js'
2
-
3
- declare namespace toa.core.bindings {
4
-
5
- type Properties = {
6
- async?: boolean
7
- }
8
-
9
- interface Consumer extends _core.Connector {
10
- request (request: Request): Promise<_core.Reply>
11
-
12
- task (request: Request): Promise<void>
13
- }
14
-
15
- interface Emitter extends _core.Connector {
16
- emit (message: _core.Message): Promise<void>
17
- }
18
-
19
- interface Broadcast<L> extends _core.Connector {
20
- transmit<T> (label: L, payload: T): Promise<void>
21
-
22
- receive<T> (label: L, callback: (payload: T) => void | Promise<void>): Promise<void>
23
- }
24
-
25
- interface Factory {
26
- producer? (locator: _core.Locator, endpoints: Array<string>, producer: _core.Component): _core.Connector
27
-
28
- consumer? (locator: _core.Locator, endpoint: string): Consumer
29
-
30
- emitter? (locator: _core.Locator, label: string): Emitter
31
-
32
- receiver? (locator: _core.Locator, label: string, group: string, receiver: _core.Receiver): _core.Connector
33
-
34
- broadcast? (name: string, group?: string): Broadcast
35
- }
36
-
37
- }
38
-
39
- export type Emitter = toa.core.bindings.Emitter
40
- export type Factory = toa.core.bindings.Factory
41
- export type Properties = toa.core.bindings.Properties
42
- export type Broadcast<L = any> = toa.core.bindings.Broadcast<L>
package/types/bridges.ts DELETED
@@ -1,33 +0,0 @@
1
- import type { Request, Reply } from './request.js'
2
- import type { Context } from './context.js'
3
- import type { Connector } from './connector.js'
4
-
5
- export interface Algorithm {
6
- mount: (context?: Context) => Promise<void>
7
-
8
- execute: ((input: any, scope: object | object[]) => Promise<Reply>) |
9
- ((input: any) => Promise<Reply>) |
10
- (() => Promise<Reply>)
11
- }
12
-
13
- export interface Event {
14
- condition: (object: object) => Promise<boolean>
15
-
16
- payload: (object: object) => Promise<object>
17
- }
18
-
19
- export interface Receiver {
20
- condition: (object: object) => Promise<boolean>
21
-
22
- request: (object: object) => Promise<Request>
23
- }
24
-
25
- export interface Factory {
26
- algorithm?: (path: string, name: string, context: Context) => Algorithm
27
-
28
- event?: (path: string, label: string) => Event
29
-
30
- receiver?: (path: string, label: string) => Receiver
31
-
32
- rc?: (path: string, context: Context) => Promise<{ preflight?: Connector, settle?: Connector, dispose?: Connector } | undefined>
33
- }
package/types/call.d.ts DELETED
@@ -1,13 +0,0 @@
1
- import type { Request } from './request.js'
2
-
3
- /**
4
- * How an endpoint is called. What it resolves to is what the operation declares — `toa types`
5
- * writes that per operation, and these are what a hand-written context says instead.
6
- */
7
- export type Call<Output = any, Input = any> = (request: Request<Input>) => Promise<Output>
8
-
9
- export type Observation<Output = any, Input = never, Entity = unknown> =
10
- (request: Request<Input, Entity>) => Promise<Output extends unknown[] ? Output : Output | null>
11
-
12
- export type Transition<Output = any, Input = never, Entity = unknown> =
13
- (request: Request<Input, Entity>) => Promise<Output | null>
@@ -1,12 +0,0 @@
1
- import { Connector } from './connector.js'
2
- import { Locator } from './locator.js'
3
- import { Request } from './request.js'
4
- import { Operation } from './operations.js'
5
-
6
- export class Component extends Connector {
7
- locator: Locator
8
-
9
- constructor (locator: Locator, operations: Record<string, Operation>)
10
-
11
- invoke<T = any> (endpoint: string, request: Request): Promise<T>
12
- }
@@ -1,18 +0,0 @@
1
- export class Connector {
2
- public id: string
3
- public connected: boolean
4
-
5
- public connect (): Promise<void>
6
-
7
- public disconnect (interrupt?: boolean): Promise<void>
8
-
9
- public depends (connector: Connector | Connector[]): Connector
10
-
11
- link (connector: Connector): void
12
-
13
- protected open (): Promise<void> | void
14
-
15
- protected close (): Promise<void> | void
16
-
17
- protected dispose (): Promise<void> | void
18
- }
@@ -1,24 +0,0 @@
1
- import * as _request from './request.js'
2
- import { Locator } from './locator.js'
3
- import * as _reply from './reply'
4
- import * as _extensions from './extensions.js'
5
- import * as _connector from './connector.js'
6
-
7
- export interface Context extends _connector.Connector{
8
- aspects: _extensions.Aspect[]
9
-
10
- locator: Locator
11
-
12
- /**
13
- * Calls local endpoint
14
- */
15
- apply (endpoint: string, request: _request.Request): Promise<_reply.Reply>
16
-
17
- /**
18
- * Calls remote endpoint
19
- */
20
- call (namespace: string, name: string, endpoint: string, request: _request.Request): Promise<_reply.Reply>
21
-
22
- // shortcuts
23
- [key: string]: any
24
- }
package/types/entity.d.ts DELETED
@@ -1,46 +0,0 @@
1
- import * as _event from './event.js'
2
- import * as _storages from './storages.js'
3
-
4
- declare namespace toa.core {
5
-
6
- namespace entity {
7
-
8
- interface Factory {
9
- init(id: string): Entity
10
-
11
- object(record: Object, mutable?: boolean): Entity
12
-
13
- objects(recordset: Object[], init?: string[], mutable?: boolean): Entity[]
14
-
15
- changeset(query: _storages.Query): Changeset
16
- }
17
-
18
- }
19
-
20
- interface Entity {
21
- get(): _storages.Record
22
-
23
- set(value: _storages.Record): void
24
-
25
- event(): _event.Event
26
- }
27
-
28
- type Upsert = {
29
- changeset: Object
30
- insert: Object
31
- }
32
-
33
- interface Changeset {
34
- query: _storages.Query
35
-
36
- get(): Object
37
-
38
- set(value: Object): void
39
-
40
- export(): Upsert
41
- }
42
-
43
- }
44
-
45
- export type Entity = toa.core.Entity
46
- export type Changeset = toa.core.Changeset
package/types/event.d.ts DELETED
@@ -1,11 +0,0 @@
1
- import * as _state from './state.js'
2
-
3
- declare namespace toa.core {
4
-
5
- interface Event {
6
- emit(event: _state.Event): Promise<void>
7
- }
8
-
9
- }
10
-
11
- export type Event = toa.core.Event
@@ -1,4 +0,0 @@
1
- export interface Exception {
2
- code: number
3
- message: string
4
- }