@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
@@ -4,15 +4,16 @@ import { isDeepStrictEqual } from 'node:util'
4
4
 
5
5
  import clone from 'clone-deep'
6
6
 
7
- import { Connector } from '../src/connector.js'
7
+ import { Connector } from '../source/connector.js'
8
8
 
9
9
  // the fixtures are not connectors, so a dependency is recorded rather than linked
10
10
  const depends = mock.method(Connector.prototype, 'depends', () => undefined)
11
11
 
12
- const dependencies = (instance) => depends.mock.calls
13
- .filter((call) => call.this === instance)
14
- .map((call) => call.arguments[0])
15
- import { Emission } from '../src/emission.js'
12
+ const dependencies = (instance) =>
13
+ depends.mock.calls
14
+ .filter((call) => call.this === instance)
15
+ .map((call) => call.arguments[0])
16
+ import { Emission } from '../source/emission.js'
16
17
  import * as fixtures from './emission.fixtures.js'
17
18
 
18
19
  let emission, event
@@ -33,15 +34,22 @@ it('should depend on events', () => {
33
34
  })
34
35
 
35
36
  it('should emit events', async () => {
36
-
37
37
  await emission.emit(event)
38
38
 
39
39
  for (const evt of fixtures.events) {
40
- assert.ok(evt.emit.mock.calls.some((call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], event)))
40
+ assert.ok(
41
+ evt.emit.mock.calls.some(
42
+ (call) =>
43
+ call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], event)
44
+ )
45
+ )
41
46
  }
42
47
  })
43
48
 
44
- function resetCalls (target = [assert, clone, depends, dependencies, fixtures], seen = new Set()) {
49
+ function resetCalls(
50
+ target = [assert, clone, depends, dependencies, fixtures],
51
+ seen = new Set()
52
+ ) {
45
53
  if (target === null || typeof target !== 'object' || seen.has(target)) return
46
54
 
47
55
  seen.add(target)
@@ -4,8 +4,7 @@ import { generate } from 'randomstring'
4
4
 
5
5
  // noinspection JSCheckFunctionSignatures
6
6
  export const schema = {
7
- fit: mock.fn((object) =>
8
- (object.fail ? { [generate()]: generate() } : null)),
7
+ fit: mock.fn((object) => (object.fail ? { [generate()]: generate() } : null)),
9
8
 
10
9
  defaults: mock.fn(() => ({ [generate()]: generate() }))
11
10
  }
@@ -13,10 +12,10 @@ export const schema = {
13
12
  export const state = () => ({
14
13
  id: generate(),
15
14
  foo: generate(),
16
- _created: generate(),
17
- _updated: generate(),
18
- _deleted: generate(),
19
- _version: 0
15
+ CREATED: generate(),
16
+ UPDATED: generate(),
17
+ DELETED: generate(),
18
+ VERSION: 0
20
19
  })
21
20
 
22
21
  export const failed = () => ({
@@ -1,9 +1,11 @@
1
- import { describe, it, beforeEach, mock } from 'node:test'
1
+ import { describe, it, beforeEach } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
 
4
- import { Entity } from '../../src/entities/entity.js'
4
+ import { Entity } from '../../source/entities/entity.js'
5
5
  import * as fixtures from './entity.fixtures.js'
6
6
 
7
+ const BLANK = {}
8
+
7
9
  beforeEach(() => {
8
10
  resetCalls()
9
11
  })
@@ -11,74 +13,106 @@ beforeEach(() => {
11
13
  describe('argument', () => {
12
14
  it('should set state', () => {
13
15
  const state = fixtures.state()
14
- const entity = new Entity(fixtures.schema, state)
16
+ const entity = new Entity(fixtures.schema, BLANK, state)
15
17
 
16
18
  assert.deepStrictEqual(entity.get(), state)
17
19
  })
18
20
 
19
21
  it('should snapshot the record it may commit', () => {
20
22
  const record = fixtures.state()
21
- const entity = new Entity(fixtures.schema, record)
23
+ const entity = new Entity(fixtures.schema, BLANK, record)
22
24
 
23
25
  assert.notStrictEqual(entity.get(), record)
24
26
  assert.strictEqual(entity.event().origin, record)
25
27
  })
26
28
  })
27
29
 
30
+ describe('blank', () => {
31
+ it('should write what the component declares a record starts as', () => {
32
+ const entity = new Entity(fixtures.schema, { foo: 'declared' })
33
+ const state = entity.get()
34
+
35
+ assert.strictEqual(state.foo, 'declared')
36
+ assert.strictEqual(state.VERSION, 0)
37
+ assert.strictEqual(state.DELETED, null)
38
+ assert.strictEqual(typeof state.id, 'string')
39
+ assert.strictEqual(entity.event().origin, null)
40
+ })
41
+
42
+ it('should not validate it', () => {
43
+ const entity = new Entity(fixtures.schema, { fail: true })
44
+
45
+ assert.strictEqual(entity.get().fail, true)
46
+ assert.strictEqual(fixtures.schema.fit.mock.callCount(), 0)
47
+ })
48
+
49
+ it('should give every record its own copy', () => {
50
+ const blank = { foo: { bar: 'nested' } }
51
+ const one = new Entity(fixtures.schema, blank)
52
+ const other = new Entity(fixtures.schema, blank)
53
+
54
+ assert.notStrictEqual(one.get().foo, other.get().foo)
55
+ assert.notStrictEqual(one.get().foo, blank.foo)
56
+ })
57
+ })
58
+
28
59
  describe('read-only', () => {
29
60
  it('should take the record as it came', () => {
30
61
  const record = fixtures.state()
31
- const entity = new Entity(fixtures.schema, record, undefined, false)
62
+ const entity = new Entity(fixtures.schema, BLANK, record, undefined, false)
32
63
 
33
64
  // no pre-image to diff against, hence no copy of it
34
65
  assert.strictEqual(entity.get(), record)
35
66
  })
36
67
 
37
68
  it('should still report a tombstone', () => {
38
- const record = { ...fixtures.state(), _deleted: Date.now() }
39
- const entity = new Entity(fixtures.schema, record, undefined, false)
69
+ const record = { ...fixtures.state(), DELETED: Date.now() }
70
+ const entity = new Entity(fixtures.schema, BLANK, record, undefined, false)
40
71
 
41
72
  assert.strictEqual(entity.deleted, true)
42
73
  })
43
74
 
44
75
  it('should refuse to be modified', () => {
45
- const entity = new Entity(fixtures.schema, fixtures.state(), undefined, false)
76
+ const entity = new Entity(fixtures.schema, BLANK, fixtures.state(), undefined, false)
46
77
 
47
- assert.throws(() => entity.set(entity.get()), (error) => /read-only/.test(error.message))
78
+ assert.throws(
79
+ () => entity.set(entity.get()),
80
+ (error) => /read-only/.test(error.message)
81
+ )
48
82
  })
49
83
  })
50
84
 
51
85
  describe('tombstone', () => {
52
- it('should lift tombstone when transition leaves _deleted untouched', () => {
86
+ it('should lift tombstone when transition leaves DELETED untouched', () => {
53
87
  const origin = fixtures.state()
54
- const entity = new Entity(fixtures.schema, origin)
88
+ const entity = new Entity(fixtures.schema, BLANK, origin)
55
89
  const state = entity.get()
56
90
 
57
91
  state.foo = 'revived'
58
92
  entity.set(state)
59
93
 
60
- assert.strictEqual(entity.get()._deleted, null)
94
+ assert.strictEqual(entity.get().DELETED, null)
61
95
  assert.strictEqual(entity.deleted, false)
62
- assert.strictEqual(entity.event().state._deleted, null)
96
+ assert.strictEqual(entity.event().state.DELETED, null)
63
97
  })
64
98
 
65
99
  it('should keep tombstone written by transition', () => {
66
- const origin = { ...fixtures.state(), _deleted: null }
67
- const entity = new Entity(fixtures.schema, origin)
100
+ const origin = { ...fixtures.state(), DELETED: null }
101
+ const entity = new Entity(fixtures.schema, BLANK, origin)
68
102
  const state = entity.get()
69
103
  const timestamp = Date.now()
70
104
 
71
- state._deleted = timestamp
105
+ state.DELETED = timestamp
72
106
  entity.set(state)
73
107
 
74
- assert.strictEqual(entity.get()._deleted, timestamp)
108
+ assert.strictEqual(entity.get().DELETED, timestamp)
75
109
  assert.strictEqual(entity.deleted, true)
76
110
  })
77
111
  })
78
112
 
79
113
  it('should provide event', () => {
80
114
  const origin = fixtures.state()
81
- const entity = new Entity(fixtures.schema, origin)
115
+ const entity = new Entity(fixtures.schema, BLANK, origin)
82
116
  const state = entity.get()
83
117
 
84
118
  state.foo = 'new value'
@@ -88,11 +122,11 @@ it('should provide event', () => {
88
122
 
89
123
  assert.partialDeepStrictEqual(event, { state, origin })
90
124
  assert.strictEqual(event.state.foo, 'new value')
91
- assert.strictEqual(event.state._version, 1)
125
+ assert.strictEqual(event.state.VERSION, 1)
92
126
  assert.notStrictEqual(event.origin.foo, 'new value')
93
127
  })
94
128
 
95
- function resetCalls (target = [assert, fixtures], seen = new Set()) {
129
+ function resetCalls(target = [assert, fixtures], seen = new Set()) {
96
130
  if (target === null || typeof target !== 'object' || seen.has(target)) return
97
131
 
98
132
  seen.add(target)
@@ -2,11 +2,18 @@ import { mock } from 'node:test'
2
2
 
3
3
  import randomstring from 'randomstring'
4
4
 
5
- const schema = { [randomstring.generate()]: randomstring.generate() }
5
+ const schemas = {
6
+ entity: { [randomstring.generate()]: randomstring.generate() },
7
+ changeset: { [randomstring.generate()]: randomstring.generate() }
8
+ }
9
+
10
+ const blank = { [randomstring.generate()]: randomstring.generate() }
6
11
  const storage = { id: mock.fn(() => randomstring.generate()) }
7
12
  const entity = { [randomstring.generate()]: randomstring.generate() }
8
- const set = Array.from(Array(5))
9
- .map((_, index) => ({ id: index, [randomstring.generate()]: randomstring.generate() }))
13
+ const set = Array.from(Array(5)).map((_, index) => ({
14
+ id: index,
15
+ [randomstring.generate()]: randomstring.generate()
16
+ }))
10
17
 
11
18
  // node:test records a mock's calls but not the instances it constructed
12
19
  const entities = []
@@ -18,13 +25,7 @@ const Entity = mock.fn(function () {
18
25
 
19
26
  const EntitySet = mock.fn(function () {})
20
27
 
21
-
22
-
23
-
24
-
25
-
26
-
27
28
  // named `mock` for its consumers, which is what node:test calls its own tracker
28
29
  const mocks = { Entity, EntitySet }
29
30
 
30
- export { schema, storage, entity, set, entities, mocks as mock }
31
+ export { schemas, blank, storage, entity, set, entities, mocks as mock }
@@ -7,11 +7,14 @@ import { generate } from 'randomstring'
7
7
  import * as fixtures from './factory.fixtures.js'
8
8
  const mock = fixtures.mock
9
9
 
10
- mocking.module('../../src/entities/entity', { namedExports: ({ Entity: mock.Entity }) })
11
- mocking.module('../../src/entities/set', { namedExports: ({ EntitySet: mock.EntitySet }) })
12
-
13
- const { Factory } = await import('../../src/entities/factory.js')
10
+ mocking.module('../../source/entities/entity.js', {
11
+ namedExports: { Entity: mock.Entity }
12
+ })
13
+ mocking.module('../../source/entities/set.js', {
14
+ namedExports: { EntitySet: mock.EntitySet }
15
+ })
14
16
 
17
+ const { Factory } = await import('../../source/entities/factory.js')
15
18
 
16
19
  let factory
17
20
 
@@ -19,7 +22,7 @@ beforeEach(async () => {
19
22
  resetCalls()
20
23
  fixtures.entities.length = 0
21
24
 
22
- factory = new Factory(fixtures.schema, () => fixtures.storage.id())
25
+ factory = new Factory(fixtures.schemas, fixtures.blank, () => fixtures.storage.id())
23
26
  })
24
27
 
25
28
  it('should create initial', () => {
@@ -27,14 +30,33 @@ it('should create initial', () => {
27
30
  const initial = factory.init(id)
28
31
 
29
32
  assert.ok(initial instanceof mock.Entity)
30
- assert.ok(mock.Entity.mock.calls.some((call) => call.arguments.length === 3 && isDeepStrictEqual(call.arguments[0], fixtures.schema) && isDeepStrictEqual(call.arguments[1], id) && typeof call.arguments[2] === 'function'))
33
+ assert.ok(
34
+ mock.Entity.mock.calls.some(
35
+ (call) =>
36
+ call.arguments.length === 4 &&
37
+ isDeepStrictEqual(call.arguments[0], fixtures.schemas.entity) &&
38
+ isDeepStrictEqual(call.arguments[1], fixtures.blank) &&
39
+ isDeepStrictEqual(call.arguments[2], id) &&
40
+ typeof call.arguments[3] === 'function'
41
+ )
42
+ )
31
43
  })
32
44
 
33
45
  it('should create instance', () => {
34
46
  const object = factory.object(fixtures.entity)
35
47
 
36
48
  assert.ok(object instanceof mock.Entity)
37
- assert.ok(mock.Entity.mock.calls.some((call) => call.arguments.length === 4 && isDeepStrictEqual(call.arguments[0], fixtures.schema) && isDeepStrictEqual(call.arguments[1], fixtures.entity) && typeof call.arguments[2] === 'function' && isDeepStrictEqual(call.arguments[3], true)))
49
+ assert.ok(
50
+ mock.Entity.mock.calls.some(
51
+ (call) =>
52
+ call.arguments.length === 5 &&
53
+ isDeepStrictEqual(call.arguments[0], fixtures.schemas.entity) &&
54
+ isDeepStrictEqual(call.arguments[1], fixtures.blank) &&
55
+ isDeepStrictEqual(call.arguments[2], fixtures.entity) &&
56
+ typeof call.arguments[3] === 'function' &&
57
+ isDeepStrictEqual(call.arguments[4], true)
58
+ )
59
+ )
38
60
  })
39
61
 
40
62
  it('should create set', () => {
@@ -43,15 +65,30 @@ it('should create set', () => {
43
65
  assert.ok(objects instanceof mock.EntitySet)
44
66
 
45
67
  const instances = fixtures.set.map((entity, index) => {
46
- assert.ok(((call) => call.arguments.length === 4 && isDeepStrictEqual(call.arguments[0], fixtures.schema) && isDeepStrictEqual(call.arguments[1], entity) && typeof call.arguments[2] === 'function' && isDeepStrictEqual(call.arguments[3], true))(mock.Entity.mock.calls[index + 1 - 1] ?? { arguments: [] }))
68
+ assert.ok(
69
+ ((call) =>
70
+ call.arguments.length === 5 &&
71
+ isDeepStrictEqual(call.arguments[0], fixtures.schemas.entity) &&
72
+ isDeepStrictEqual(call.arguments[1], fixtures.blank) &&
73
+ isDeepStrictEqual(call.arguments[2], entity) &&
74
+ typeof call.arguments[3] === 'function' &&
75
+ isDeepStrictEqual(call.arguments[4], true))(
76
+ mock.Entity.mock.calls[index + 1 - 1] ?? { arguments: [] }
77
+ )
78
+ )
47
79
 
48
80
  return fixtures.entities[index]
49
81
  })
50
82
 
51
- assert.ok(mock.EntitySet.mock.calls.some((call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], instances)))
83
+ assert.ok(
84
+ mock.EntitySet.mock.calls.some(
85
+ (call) =>
86
+ call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], instances)
87
+ )
88
+ )
52
89
  })
53
90
 
54
- function resetCalls (target = [assert, fixtures, mock], seen = new Set()) {
91
+ function resetCalls(target = [assert, fixtures, mock], seen = new Set()) {
55
92
  if (target === null || typeof target !== 'object' || seen.has(target)) return
56
93
 
57
94
  seen.add(target)
@@ -1,7 +1,7 @@
1
1
  import { it } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
 
4
- import { EntitySet } from '../../src/entities/set.js'
4
+ import { EntitySet } from '../../source/entities/set.js'
5
5
  import * as fixtures from './set.fixtures.js'
6
6
 
7
7
  it('should provide state', () => {
@@ -4,8 +4,8 @@ import { isDeepStrictEqual } from 'node:util'
4
4
 
5
5
  import clone from 'clone-deep'
6
6
 
7
- import { Connector } from '../src/connector.js'
8
- import { Event } from '../src/event.js'
7
+ import { Connector } from '../source/connector.js'
8
+ import { Event } from '../source/event.js'
9
9
  import * as fixtures from './event.fixtures.js'
10
10
 
11
11
  let event, emit
@@ -13,9 +13,10 @@ let event, emit
13
13
  // the fixtures are not connectors, so the dependency is recorded rather than linked
14
14
  const depends = mock.method(Connector.prototype, 'depends', () => undefined)
15
15
 
16
- const dependencies = (instance) => depends.mock.calls
17
- .filter((call) => call.this === instance)
18
- .map((call) => call.arguments[0])
16
+ const dependencies = (instance) =>
17
+ depends.mock.calls
18
+ .filter((call) => call.this === instance)
19
+ .map((call) => call.arguments[0])
19
20
 
20
21
  beforeEach(() => {
21
22
  resetCalls()
@@ -35,7 +36,9 @@ it('should depend on bridge if provided', () => {
35
36
 
36
37
  const bridgeless = new Event(fixtures.definition, fixtures.binding)
37
38
 
38
- assert.ok(!dependencies(bridgeless).some((one) => isDeepStrictEqual(one, fixtures.bridge)))
39
+ assert.ok(
40
+ !dependencies(bridgeless).some((one) => isDeepStrictEqual(one, fixtures.bridge))
41
+ )
39
42
  })
40
43
 
41
44
  describe('condition', () => {
@@ -43,7 +46,13 @@ describe('condition', () => {
43
46
  it('should call condition', async () => {
44
47
  await emit()
45
48
 
46
- assert.ok(fixtures.bridge.condition.mock.calls.some((call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], fixtures.event)))
49
+ assert.ok(
50
+ fixtures.bridge.condition.mock.calls.some(
51
+ (call) =>
52
+ call.arguments.length === 1 &&
53
+ isDeepStrictEqual(call.arguments[0], fixtures.event)
54
+ )
55
+ )
47
56
  })
48
57
 
49
58
  it('should emit if condition returns true', async () => {
@@ -74,9 +83,15 @@ describe('condition', () => {
74
83
  })
75
84
 
76
85
  it('should not call condition', async () => {
77
- await event.emit(fixtures.event.origin, fixtures.event.changeset, fixtures.event.state)
86
+ await event.emit(
87
+ fixtures.event.origin,
88
+ fixtures.event.changeset,
89
+ fixtures.event.state
90
+ )
78
91
 
79
- assert.ok(!(fixtures.bridge.condition.mock.calls.some((call) => call.arguments.length === 0)))
92
+ assert.ok(
93
+ !fixtures.bridge.condition.mock.calls.some((call) => call.arguments.length === 0)
94
+ )
80
95
 
81
96
  const payload = await fixtures.bridge.payload.mock.calls[0].result
82
97
  assertEmitted(payload)
@@ -119,7 +134,10 @@ describe('payload', () => {
119
134
  })
120
135
  })
121
136
 
122
- function resetCalls (target = [assert, clone, fixtures, depends, dependencies], seen = new Set()) {
137
+ function resetCalls(
138
+ target = [assert, clone, fixtures, depends, dependencies],
139
+ seen = new Set()
140
+ ) {
123
141
  if (target === null || typeof target !== 'object' || seen.has(target)) return
124
142
 
125
143
  seen.add(target)
@@ -130,7 +148,7 @@ function resetCalls (target = [assert, clone, fixtures, depends, dependencies],
130
148
  }
131
149
 
132
150
  /** The message carries the payload and a telemetry token generated per emission. */
133
- function assertEmitted (payload) {
151
+ function assertEmitted(payload) {
134
152
  const emitted = fixtures.binding.emit.mock.calls
135
153
  .map((call) => call.arguments[0])
136
154
  .filter((message) => isDeepStrictEqual(message.payload, payload))
@@ -2,7 +2,7 @@ import { describe, it, beforeEach } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
 
4
4
  import { generate } from 'randomstring'
5
- import { Locator } from '../src/locator.js'
5
+ import { Locator } from '../source/locator.js'
6
6
 
7
7
  /** @type {string} */
8
8
  let name
@@ -10,7 +10,7 @@ let name
10
10
  /** @type {string} */
11
11
  let namespace
12
12
 
13
- /** @type {toa.core.Locator} */
13
+ /** @type {import('@toa.io/core').Locator} */
14
14
  let locator
15
15
 
16
16
  beforeEach(() => {
@@ -34,7 +34,10 @@ it('should expose id, label', () => {
34
34
  })
35
35
 
36
36
  it('should expose uppercase', () => {
37
- assert.deepStrictEqual(locator.uppercase, (locator.namespace + '_' + locator.name).toUpperCase())
37
+ assert.deepStrictEqual(
38
+ locator.uppercase,
39
+ (locator.namespace + '_' + locator.name).toUpperCase()
40
+ )
38
41
  })
39
42
 
40
43
  it('should throw if name is undefined', () => {
@@ -51,7 +54,10 @@ it('should expose host', () => {
51
54
  it('should expose host with given prefix', () => {
52
55
  const prefix = generate()
53
56
 
54
- assert.deepStrictEqual(locator.hostname(prefix), (prefix + '-' + namespace + '-' + name).toLowerCase())
57
+ assert.deepStrictEqual(
58
+ locator.hostname(prefix),
59
+ (prefix + '-' + namespace + '-' + name).toLowerCase()
60
+ )
55
61
  })
56
62
 
57
63
  describe('global', () => {
@@ -1,7 +1,7 @@
1
1
  import { it, beforeEach, afterEach, mock } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
 
4
- import { Outbox } from '../src/outbox/index.js'
4
+ import { Outbox } from '../source/outbox/index.js'
5
5
 
6
6
  let emission, storage, atom, outbox, listeners
7
7
 
@@ -36,7 +36,9 @@ beforeEach(() => {
36
36
  listeners.push(listener)
37
37
  listener({ i: 0, n: 1 })
38
38
 
39
- return () => { listeners = listeners.filter((one) => one !== listener) }
39
+ return () => {
40
+ listeners = listeners.filter((one) => one !== listener)
41
+ }
40
42
  },
41
43
  link: mock.fn()
42
44
  }
@@ -70,9 +72,18 @@ it('should read nothing more when the first page is short', async () => {
70
72
  })
71
73
 
72
74
  it('should keep reading while a page comes back full', async () => {
73
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, BATCH), storage.outbox.pending.mock.callCount())
74
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(BATCH, BATCH), storage.outbox.pending.mock.callCount() + 1)
75
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(2 * BATCH, 5), storage.outbox.pending.mock.callCount() + 2)
75
+ storage.outbox.pending.mock.mockImplementationOnce(
76
+ async () => page(0, BATCH),
77
+ storage.outbox.pending.mock.callCount()
78
+ )
79
+ storage.outbox.pending.mock.mockImplementationOnce(
80
+ async () => page(BATCH, BATCH),
81
+ storage.outbox.pending.mock.callCount() + 1
82
+ )
83
+ storage.outbox.pending.mock.mockImplementationOnce(
84
+ async () => page(2 * BATCH, 5),
85
+ storage.outbox.pending.mock.callCount() + 2
86
+ )
76
87
 
77
88
  await outbox.open()
78
89
  await cycle()
@@ -82,8 +93,14 @@ it('should keep reading while a page comes back full', async () => {
82
93
  })
83
94
 
84
95
  it('should continue each page from the id the one before ended on', async () => {
85
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, BATCH), storage.outbox.pending.mock.callCount())
86
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(BATCH, 1), storage.outbox.pending.mock.callCount() + 1)
96
+ storage.outbox.pending.mock.mockImplementationOnce(
97
+ async () => page(0, BATCH),
98
+ storage.outbox.pending.mock.callCount()
99
+ )
100
+ storage.outbox.pending.mock.mockImplementationOnce(
101
+ async () => page(BATCH, 1),
102
+ storage.outbox.pending.mock.callCount() + 1
103
+ )
87
104
 
88
105
  await outbox.open()
89
106
  await cycle()
@@ -95,8 +112,14 @@ it('should continue each page from the id the one before ended on', async () =>
95
112
  })
96
113
 
97
114
  it('should mark what it published, once, after the last page', async () => {
98
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, BATCH), storage.outbox.pending.mock.callCount())
99
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(BATCH, 2), storage.outbox.pending.mock.callCount() + 1)
115
+ storage.outbox.pending.mock.mockImplementationOnce(
116
+ async () => page(0, BATCH),
117
+ storage.outbox.pending.mock.callCount()
118
+ )
119
+ storage.outbox.pending.mock.mockImplementationOnce(
120
+ async () => page(BATCH, 2),
121
+ storage.outbox.pending.mock.callCount() + 1
122
+ )
100
123
 
101
124
  await outbox.open()
102
125
  await cycle()
@@ -106,9 +129,17 @@ it('should mark what it published, once, after the last page', async () => {
106
129
  })
107
130
 
108
131
  it('should not publish a row it has published and not yet marked', async () => {
109
- storage.outbox.settle.mock.mockImplementationOnce(async () => { throw new Error('mongo is out') })
110
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, 2), storage.outbox.pending.mock.callCount())
111
- storage.outbox.pending.mock.mockImplementationOnce(async () => page(0, 2), storage.outbox.pending.mock.callCount() + 1)
132
+ storage.outbox.settle.mock.mockImplementationOnce(async () => {
133
+ throw new Error('mongo is out')
134
+ })
135
+ storage.outbox.pending.mock.mockImplementationOnce(
136
+ async () => page(0, 2),
137
+ storage.outbox.pending.mock.callCount()
138
+ )
139
+ storage.outbox.pending.mock.mockImplementationOnce(
140
+ async () => page(0, 2),
141
+ storage.outbox.pending.mock.callCount() + 1
142
+ )
112
143
 
113
144
  await outbox.open()
114
145
  await cycle()
@@ -126,7 +157,7 @@ it('should read nothing while it owns no slots', async () => {
126
157
  assert.strictEqual(storage.outbox.pending.mock.callCount(), 0)
127
158
  })
128
159
 
129
- function resetCalls (target = [assert, BATCH, page, cycle], seen = new Set()) {
160
+ function resetCalls(target = [assert, BATCH, page, cycle], seen = new Set()) {
130
161
  if (target === null || typeof target !== 'object' || seen.has(target)) return
131
162
 
132
163
  seen.add(target)
@@ -150,8 +181,11 @@ it('should read as soon as a claim arrives, rather than on its next cycle', asyn
150
181
 
151
182
  await settled()
152
183
 
153
- assert.strictEqual(storage.outbox.pending.mock.callCount(), 1,
154
- 'the lane is its own now, and the cycle is up to five seconds away')
184
+ assert.strictEqual(
185
+ storage.outbox.pending.mock.callCount(),
186
+ 1,
187
+ 'the lane is its own now, and the cycle is up to five seconds away'
188
+ )
155
189
  })
156
190
 
157
191
  it('should read the lanes it inherits when the group resizes', async () => {