@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
@@ -1,9 +0,0 @@
1
- type: object
2
- properties:
3
- code:
4
- anyOf:
5
- - type: integer
6
- - type: string
7
- message:
8
- type: string
9
- required: [code]
@@ -1,11 +0,0 @@
1
- import { resolve } from 'path'
2
- import { readFileSync } from 'node:fs'
3
- import { yaml } from '@toa.io/generic'
4
-
5
- export const query = read(resolve(import.meta.dirname, './query.yaml'))
6
- export const error = read(resolve(import.meta.dirname, './error.yaml'))
7
- export const source = read(resolve(import.meta.dirname, './source.yaml'))
8
-
9
- function read (path) {
10
- return yaml.load(readFileSync(path, 'utf8'))
11
- }
@@ -1,43 +0,0 @@
1
- type: object
2
- properties:
3
- id:
4
- type: string
5
- ids:
6
- type: array
7
- uniqueItems: true
8
- minItems: 1
9
- items:
10
- type: string
11
- version:
12
- type: integer
13
- minimum: 0
14
- criteria:
15
- type: string
16
- search:
17
- type: string
18
- sample:
19
- type: number
20
- omit:
21
- type: integer
22
- minimum: 0
23
- limit:
24
- type: integer
25
- minimum: 0
26
- sort:
27
- type: array
28
- uniqueItems: true
29
- minItems: 1
30
- items:
31
- type: string
32
- pattern: ^\w{1,32}(?::(?:asc|desc))?$
33
- projection:
34
- type: array
35
- uniqueItems: true
36
- minItems: 1
37
- items:
38
- type: string
39
- not:
40
- const: id
41
- deleted:
42
- type: boolean
43
- additionalProperties: false
@@ -1,23 +0,0 @@
1
- # Origin of a call, see toa.core.Source.
2
- # Deliberately permissive on required properties: the contract throws on a mismatch,
3
- # and a strict union would turn a partially stamped source into a failed business call.
4
- # `additionalProperties: false` combined with `removeAdditional` is what matters here —
5
- # it strips whatever a peer puts in, bounding the cardinality of the resulting map.
6
- type: object
7
- properties:
8
- namespace:
9
- type: string
10
- maxLength: 64
11
- component:
12
- type: string
13
- maxLength: 64
14
- operation:
15
- type: string
16
- maxLength: 64
17
- event:
18
- type: string
19
- maxLength: 64
20
- service:
21
- type: string
22
- maxLength: 64
23
- additionalProperties: false
package/src/effect.js DELETED
@@ -1,15 +0,0 @@
1
- import { Observation } from './observation.js'
2
-
3
- export class Effect extends Observation {
4
-
5
- async acquire (store) {
6
- const { query, entity, input } = store.request
7
-
8
- if (entity === undefined)
9
- return super.acquire(store)
10
-
11
- store.scope = await this.scope.ensure(query, entity, input)
12
- store.state = store.scope.get()
13
- }
14
-
15
- }
@@ -1,36 +0,0 @@
1
- import { EntityContractException } from '../exceptions.js'
2
-
3
- export class Changeset {
4
- /** @type {toa.core.Query} */
5
- query
6
-
7
- #schema
8
- #state
9
-
10
- constructor (schema, query) {
11
- this.query = query
12
-
13
- this.#schema = schema
14
- this.#state = {}
15
- }
16
-
17
- get () {
18
- return this.#state
19
- }
20
-
21
- set (value) {
22
- const error = this.#schema.match(value)
23
-
24
- if (error !== null)
25
- throw new EntityContractException(error, value)
26
-
27
- delete value._version
28
- value._updated = Date.now()
29
-
30
- this.#state = value
31
- }
32
-
33
- export () {
34
- return this.#state
35
- }
36
- }
@@ -1,119 +0,0 @@
1
- import { EntityContractException, EntityGuardException } from '../exceptions.js'
2
- import { newid } from './newid.js'
3
-
4
- export class Entity {
5
- deleted = false
6
- #schema
7
- #guards
8
- #origin = null
9
- #state
10
- #mutable = true
11
-
12
- /**
13
- * @param {boolean} [mutable] whether the entity may be modified and committed
14
- */
15
- constructor (schema, argument, guards, mutable = true) {
16
- this.#schema = schema
17
- this.#guards = guards
18
-
19
- if (typeof argument === 'object') {
20
- /*
21
- * The origin is the pre-image a commit diffs the new state against. An operation
22
- * that cannot commit has nothing to diff, so it takes the record as it came from
23
- * the storage instead of paying for a deep copy of every record it read.
24
- */
25
- this.#mutable = mutable
26
-
27
- if (mutable) {
28
- this.#set(structuredClone(argument))
29
- this.#origin = argument
30
- } else
31
- this.#set(argument)
32
- } else {
33
- const id = argument === undefined ? newid() : argument
34
- this.#init(id)
35
- }
36
- }
37
-
38
- get () {
39
- return this.#state
40
- }
41
-
42
- set (value, optional = false) {
43
- if (!this.#mutable)
44
- throw new Error('Entity acquired by a read-only operation cannot be modified')
45
-
46
- if (!optional)
47
- this.#guard(value)
48
-
49
- const error = optional ? this.#schema.fitOptional(value) : this.#schema.fit(value)
50
-
51
- if (error !== null)
52
- throw new EntityContractException(error, value)
53
-
54
- this.#revive(value)
55
- this.#set(value)
56
- }
57
-
58
- event (input = undefined) {
59
- return {
60
- origin: this.#origin,
61
- state: this.#state,
62
- trailers: this.#state._trailers,
63
- input
64
- }
65
- }
66
-
67
- #init (id) {
68
- const value = { id, _version: 0 }
69
-
70
- this.set(value, true)
71
- }
72
-
73
- #guard (value) {
74
- if (this.#guards === undefined)
75
- return
76
-
77
- for (const guard of this.#guards) {
78
- const ok = guard.fit(value, this.#origin)
79
-
80
- if (ok === false)
81
- throw new EntityGuardException(guard.name, value)
82
- }
83
- }
84
-
85
- // deletion is only expressed as a new _deleted timestamp,
86
- // so committing over a tombstone without touching it means revival
87
- #revive (value) {
88
- if (this.#origin?._deleted == null || value._deleted !== this.#origin._deleted)
89
- return
90
-
91
- value._deleted = null
92
- this.deleted = false
93
- }
94
-
95
- #set (value) {
96
- if (!('_trailers' in value))
97
- Object.defineProperty(value, '_trailers', {
98
- writable: false,
99
- configurable: false,
100
- enumerable: false,
101
- value: {}
102
- })
103
-
104
- if (!('_created' in value)) {
105
- value._created = Date.now()
106
- value._updated ??= value._created
107
- }
108
-
109
- if ('_deleted' in value && value._deleted !== null)
110
- this.deleted = true
111
-
112
- if (this.#state !== undefined) {
113
- value._updated = Date.now()
114
- value._version++
115
- }
116
-
117
- this.#state = value
118
- }
119
- }
@@ -1,40 +0,0 @@
1
- import { newid } from './newid.js'
2
- import { Entity } from './entity.js'
3
- import { EntitySet } from './set.js'
4
- import { Changeset } from './changeset.js'
5
-
6
- export class Factory {
7
- #schema
8
- #guards
9
-
10
- constructor (schema, guards) {
11
- this.#schema = schema
12
- this.#guards = guards
13
- }
14
-
15
- fit (values) {
16
- this.#schema.validate({ id: newid(), ...values }, 'Entity')
17
- }
18
-
19
- init (id) {
20
- return new Entity(this.#schema, id, this.#guards)
21
- }
22
-
23
- object (record, mutable = true) {
24
- return new Entity(this.#schema, record, this.#guards, mutable)
25
- }
26
-
27
- objects (recordset, init, mutable = true) {
28
- const set = recordset.map((record) => this.object(record, mutable))
29
-
30
- if (init !== undefined)
31
- for (const id of init)
32
- set.unshift(this.init(id))
33
-
34
- return new EntitySet(set)
35
- }
36
-
37
- changeset (query) {
38
- return new Changeset(this.#schema, query)
39
- }
40
- }
@@ -1 +0,0 @@
1
- export { Factory } from './factory.js'
package/src/event.js DELETED
@@ -1,54 +0,0 @@
1
- import { console, current, encode } from 'openspan'
2
- import { Connector } from './connector.js'
3
-
4
- /**
5
- * @implements {toa.core.Event}
6
- */
7
- export class Event extends Connector {
8
- /** @type {toa.core.bindings.Emitter} */
9
- #emitter
10
- #bridge
11
- #conditioned
12
- #subjective
13
-
14
- /** @type {string} */
15
- #label
16
-
17
- constructor (definition, emitter, bridge = undefined) {
18
- super()
19
-
20
- this.#conditioned = definition.conditioned
21
- this.#subjective = definition.subjective
22
- this.#label = definition.label ?? 'event'
23
- this.#emitter = emitter
24
- this.#bridge = bridge
25
-
26
- this.depends(emitter)
27
-
28
- if (bridge !== undefined) this.depends(bridge)
29
- }
30
-
31
- async emit (event) {
32
- if (this.#conditioned === false || await this.#bridge.condition(event) === true) {
33
- const payload = this.#subjective ? await this.#bridge.payload(event) : event.state
34
-
35
- /** @type {toa.core.Message} */
36
- const message = { payload }
37
-
38
- const options = {
39
- name: `${this.#label} publish`,
40
- kind: 'producer',
41
- attributes: { 'messaging.destination.name': this.#label }
42
- }
43
-
44
- await console.span(options, async () => {
45
- const context = current()
46
-
47
- if (context !== undefined)
48
- message.telemetry = encode(context)
49
-
50
- await this.#emitter.emit(message)
51
- })
52
- }
53
- }
54
- }
package/src/exposition.js DELETED
@@ -1,24 +0,0 @@
1
- import { Connector } from './connector.js'
2
-
3
- export class Exposition extends Connector {
4
- locator
5
-
6
- #exposition
7
-
8
- constructor (locator, manifest) {
9
- super()
10
-
11
- this.locator = locator
12
- this.#exposition = expose(manifest)
13
- }
14
-
15
- async invoke () {
16
- return { output: this.#exposition }
17
- }
18
- }
19
-
20
- const expose = (manifest) => {
21
- const { namespace, name, entity, operations, events } = manifest
22
-
23
- return { namespace, name, entity, operations, events }
24
- }
package/src/guard.js DELETED
@@ -1,13 +0,0 @@
1
- export class Guard {
2
- name
3
- #bridge
4
-
5
- constructor (name, bridge) {
6
- this.name = name
7
- this.#bridge = bridge
8
- }
9
-
10
- fit (state, origin) {
11
- return this.#bridge.fit(state, origin)
12
- }
13
- }
@@ -1,8 +0,0 @@
1
- import { Operation } from './operation.js'
2
-
3
- export class Observation extends Operation {
4
- async run (store) {
5
- if (store.scope === null || (store.scope?.deleted === true && store.request.query?.options?.deleted !== true)) store.reply = null
6
- else await super.run(store)
7
- }
8
- }
package/src/operation.js DELETED
@@ -1,95 +0,0 @@
1
- import { Connector } from './connector.js'
2
- import { SystemException, RequestContractException } from './exceptions.js'
3
- import { Readable } from 'node:stream'
4
-
5
- export class Operation extends Connector {
6
- scope
7
-
8
- /**
9
- * Whether what this operation acquires may be modified and committed. Only a
10
- * transition commits, and only a commit needs the pre-image an entity keeps
11
- * to diff the new state against.
12
- *
13
- * @protected
14
- */
15
- mutable = false
16
-
17
- #cascade
18
- #contracts
19
- #query
20
- #scope
21
-
22
- constructor (cascade, scope, contracts, query, definition) {
23
- super()
24
-
25
- this.scope = scope
26
-
27
- this.#cascade = cascade
28
- this.#contracts = contracts
29
- this.#query = query
30
- this.#scope = definition.scope
31
-
32
- this.depends(cascade)
33
- }
34
-
35
- async invoke (request) {
36
- try {
37
- if (request.authentic !== true)
38
- this.#contracts.request.fit(request)
39
-
40
- if ('query' in request)
41
- request.query = this.#query.parse(request.query)
42
-
43
- // validate entity
44
- if ('entity' in request)
45
- this.scope.fit(request.entity)
46
-
47
- const store = { request }
48
-
49
- return await this.process(store)
50
- } catch (e) {
51
- const exception = e instanceof Error ? new SystemException(e) : e
52
-
53
- return { exception }
54
- }
55
- }
56
-
57
- async process (store) {
58
- await this.acquire(store)
59
- await this.run(store)
60
- await this.commit(store)
61
-
62
- return store.reply
63
- }
64
-
65
- async acquire (store) {
66
- if (this.#scope === 'none')
67
- return
68
-
69
- const scope = await this.query(store.request.query)
70
- const raw = scope === null || scope instanceof Readable
71
-
72
- store.scope = scope
73
- store.state = raw ? scope : scope.get()
74
- }
75
-
76
- async run (store) {
77
- const { request, state } = store
78
- const reply = await this.#cascade.run(request.input, state)
79
-
80
- // validate reply only on local environments
81
- if (process.env.TOA_ENV === 'local' && !(reply instanceof Readable))
82
- this.#contracts.reply.fit(reply)
83
-
84
- store.reply = reply
85
- }
86
-
87
- async commit () {}
88
-
89
- async query (query) {
90
- if (query === undefined)
91
- throw new RequestContractException('Request query is required')
92
-
93
- return this.scope[this.#scope](query, this.mutable)
94
- }
95
- }
@@ -1,44 +0,0 @@
1
- import { parse } from '@rsql/parser'
2
- import { QuerySyntaxException } from '../exceptions.js'
3
-
4
- export const criteria = (criteria, properties) => {
5
- let ast
6
-
7
- try {
8
- ast = parse(criteria)
9
- } catch (e) {
10
- throw new QuerySyntaxException(e.message)
11
- }
12
-
13
- if (properties !== undefined) coerce(ast, properties)
14
-
15
- return ast
16
- }
17
-
18
- const coerce = (node, properties) => {
19
- if (node.type === 'COMPARISON' && node.left?.type === 'SELECTOR' && node.right?.type === 'VALUE') {
20
- const property = properties[node.left.selector]
21
-
22
- if (property === undefined) {
23
- throw new QuerySyntaxException(`Criteria selector '${node.left.selector}' is not defined`)
24
- }
25
-
26
- const coerce = COERCE[property.type]
27
-
28
- // `=in=` and `=out=` carry a list, and coercing that as one value gives whatever
29
- // `parseInt` makes of a comma-separated string
30
- if (coerce !== undefined)
31
- node.right.value = Array.isArray(node.right.value)
32
- ? node.right.value.map((value) => coerce(value))
33
- : coerce(node.right.value)
34
- } else {
35
- if (node.left !== undefined) coerce(node.left, properties)
36
- if (node.right !== undefined) coerce(node.right, properties)
37
- }
38
- }
39
-
40
- const COERCE = {
41
- number: Number.parseFloat,
42
- integer: Number.parseInt,
43
- boolean: (value) => value === 'true'
44
- }
@@ -1,37 +0,0 @@
1
- import { QuerySyntaxException } from '../exceptions.js'
2
-
3
- export const options = (options, properties, system) => {
4
- if (options.sort !== undefined) options.sort = sort(options.sort, properties)
5
-
6
- if (options.projection !== undefined) projection(options.projection, properties)
7
-
8
- return options
9
- }
10
-
11
- const sort = (sort, properties) => {
12
- const result = []
13
-
14
- for (const sorting of sort) {
15
- const [property, direction] = sorting.split(':')
16
-
17
- if (properties[property] === undefined) {
18
- throw new QuerySyntaxException(`Sort property '${property}' is not defined`)
19
- }
20
-
21
- result.push([property, direction || 'asc'])
22
- }
23
-
24
- return result
25
- }
26
-
27
- const projection = (projection, properties) => {
28
- for (const property of projection) {
29
- if (properties[property] === undefined) {
30
- throw new QuerySyntaxException(`Projection property '${property}' is not defined`)
31
- }
32
- }
33
-
34
- for (const property of ['_version', '_created', '_updated', '_deleted'])
35
- if (!projection.includes(property))
36
- projection.push(property)
37
- }