@toa.io/core 1.0.0-alpha.283 → 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.
- package/package.json +19 -7
- package/source/assignment.ts +27 -0
- package/{src/call.js → source/call.ts} +16 -21
- package/{src/cascade.js → source/cascade.ts} +6 -8
- package/{src/component.js → source/component.ts} +27 -25
- package/{src/composition.js → source/composition.ts} +9 -3
- package/{src/connector.js → source/connector.ts} +36 -55
- package/source/context.ts +67 -0
- package/source/contract/contract.ts +23 -0
- package/{src/contract/reply.js → source/contract/reply.ts} +26 -19
- package/source/contract/request.ts +85 -0
- package/source/contract/schemas.ts +39 -0
- package/{src/discovery.js → source/discovery.ts} +15 -8
- package/source/effect.ts +14 -0
- package/{src/emission.js → source/emission.ts} +5 -3
- package/source/entities/changeset.ts +37 -0
- package/source/entities/entity.ts +137 -0
- package/source/entities/factory.ts +52 -0
- package/source/entities/index.ts +4 -0
- package/{src/entities/newid.js → source/entities/newid.ts} +1 -1
- package/{src/entities/set.js → source/entities/set.ts} +8 -5
- package/source/event.ts +57 -0
- package/{src/exceptions.js → source/exceptions.ts} +52 -33
- package/source/exposition.ts +33 -0
- package/source/guard.ts +16 -0
- package/{src/index.js → source/index.ts} +8 -0
- package/{src/locator.js → source/locator.ts} +17 -30
- package/source/observation.ts +16 -0
- package/source/operation.ts +138 -0
- package/{src/outbox/outbox.js → source/outbox/outbox.ts} +95 -51
- package/source/query/criteria.ts +90 -0
- package/source/query/options.ts +35 -0
- package/{src/query.js → source/query.ts} +14 -17
- package/source/receiver.ts +120 -0
- package/source/reflection.ts +20 -0
- package/source/remote.ts +20 -0
- package/source/state.ts +179 -0
- package/source/transition.ts +79 -0
- package/{src/transmission.js → source/transmission.ts} +8 -8
- package/source/types/atomicity.ts +63 -0
- package/source/types/bindings.ts +59 -0
- package/source/types/bridges.ts +54 -0
- package/source/types/extensions.ts +89 -0
- package/{types → source/types}/index.ts +9 -16
- package/{types/message.d.ts → source/types/message.ts} +2 -1
- package/source/types/operations.ts +31 -0
- package/source/types/outbox.ts +35 -0
- package/source/types/receiver.ts +10 -0
- package/{types/request.d.ts → source/types/request.ts} +8 -9
- package/source/types/state.ts +9 -0
- package/source/types/storages.ts +129 -0
- package/source/unmanaged.ts +8 -0
- package/test/call.fixtures.js +3 -1
- package/test/call.test.js +28 -7
- package/test/component.test.js +10 -5
- package/test/connector.fixtures.js +7 -7
- package/test/connector.test.js +15 -2
- package/test/context.fixtures.js +1 -1
- package/test/context.test.js +4 -4
- package/test/contract/conditions.test.js +6 -2
- package/test/contract/contract.fixtures.js +3 -4
- package/test/contract/request.test.js +68 -34
- package/test/discovery.test.js +10 -3
- package/test/emission.test.js +16 -8
- package/test/entities/entity.fixtures.js +5 -6
- package/test/entities/entity.test.js +54 -20
- package/test/entities/factory.fixtures.js +11 -10
- package/test/entities/factory.test.js +47 -10
- package/test/entities/set.test.js +1 -1
- package/test/event.test.js +29 -11
- package/test/locator.test.js +10 -4
- package/test/outbox.test.js +95 -14
- package/test/query.test.js +76 -7
- package/test/receiver.fixtures.js +2 -2
- package/test/receiver.test.js +53 -27
- package/test/reflection.test.js +3 -3
- package/test/state.fixtures.js +10 -3
- package/test/state.test.js +77 -14
- package/test/transmission.test.js +25 -12
- package/transpiled/assignment.d.ts +6 -0
- package/transpiled/assignment.js +20 -0
- package/transpiled/assignment.js.map +1 -0
- package/transpiled/call.d.ts +10 -0
- package/transpiled/call.js +52 -0
- package/transpiled/call.js.map +1 -0
- package/transpiled/cascade.d.ts +7 -0
- package/transpiled/cascade.js +28 -0
- package/transpiled/cascade.js.map +1 -0
- package/transpiled/component.d.ts +15 -0
- package/transpiled/component.js +61 -0
- package/transpiled/component.js.map +1 -0
- package/transpiled/composition.d.ts +6 -0
- package/transpiled/composition.js +23 -0
- package/transpiled/composition.js.map +1 -0
- package/transpiled/connector.d.ts +47 -0
- package/transpiled/connector.js +143 -0
- package/transpiled/connector.js.map +1 -0
- package/transpiled/context.d.ts +18 -0
- package/transpiled/context.js +41 -0
- package/transpiled/context.js.map +1 -0
- package/transpiled/contract/contract.d.ts +10 -0
- package/transpiled/contract/contract.js +14 -0
- package/transpiled/contract/contract.js.map +1 -0
- package/transpiled/contract/index.d.ts +2 -0
- package/transpiled/contract/index.js +3 -0
- package/transpiled/contract/index.js.map +1 -0
- package/transpiled/contract/reply.d.ts +7 -0
- package/transpiled/contract/reply.js +48 -0
- package/transpiled/contract/reply.js.map +1 -0
- package/transpiled/contract/request.d.ts +24 -0
- package/transpiled/contract/request.js +59 -0
- package/transpiled/contract/request.js.map +1 -0
- package/transpiled/contract/schemas.d.ts +4 -0
- package/transpiled/contract/schemas.js +36 -0
- package/transpiled/contract/schemas.js.map +1 -0
- package/transpiled/discovery.d.ts +12 -0
- package/transpiled/discovery.js +34 -0
- package/transpiled/discovery.js.map +1 -0
- package/transpiled/effect.d.ts +5 -0
- package/transpiled/effect.js +11 -0
- package/transpiled/effect.js.map +1 -0
- package/transpiled/emission.d.ts +8 -0
- package/transpiled/emission.js +14 -0
- package/transpiled/emission.js.map +1 -0
- package/transpiled/entities/changeset.d.ts +10 -0
- package/transpiled/entities/changeset.js +27 -0
- package/transpiled/entities/changeset.js.map +1 -0
- package/transpiled/entities/entity.d.ts +19 -0
- package/transpiled/entities/entity.js +109 -0
- package/transpiled/entities/entity.js.map +1 -0
- package/transpiled/entities/factory.d.ts +22 -0
- package/transpiled/entities/factory.js +34 -0
- package/transpiled/entities/factory.js.map +1 -0
- package/transpiled/entities/index.d.ts +4 -0
- package/transpiled/entities/index.js +5 -0
- package/transpiled/entities/index.js.map +1 -0
- package/transpiled/entities/newid.d.ts +1 -0
- package/transpiled/entities/newid.js +7 -0
- package/transpiled/entities/newid.js.map +1 -0
- package/transpiled/entities/set.d.ts +10 -0
- package/transpiled/entities/set.js +19 -0
- package/transpiled/entities/set.js.map +1 -0
- package/transpiled/event.d.ts +14 -0
- package/transpiled/event.js +38 -0
- package/transpiled/event.js.map +1 -0
- package/transpiled/exceptions.d.ts +61 -0
- package/transpiled/exceptions.js +93 -0
- package/transpiled/exceptions.js.map +1 -0
- package/transpiled/exposition.d.ts +18 -0
- package/transpiled/exposition.js +18 -0
- package/transpiled/exposition.js.map +1 -0
- package/transpiled/guard.d.ts +7 -0
- package/transpiled/guard.js +12 -0
- package/transpiled/guard.js.map +1 -0
- package/transpiled/index.d.ts +35 -0
- package/transpiled/index.js +29 -0
- package/transpiled/index.js.map +1 -0
- package/transpiled/locator.d.ts +12 -0
- package/transpiled/locator.js +32 -0
- package/transpiled/locator.js.map +1 -0
- package/transpiled/observation.d.ts +5 -0
- package/transpiled/observation.js +12 -0
- package/transpiled/observation.js.map +1 -0
- package/transpiled/operation.d.ts +49 -0
- package/transpiled/operation.js +77 -0
- package/transpiled/operation.js.map +1 -0
- package/transpiled/outbox/index.d.ts +1 -0
- package/transpiled/outbox/index.js +2 -0
- package/transpiled/outbox/index.js.map +1 -0
- package/transpiled/outbox/outbox.d.ts +46 -0
- package/transpiled/outbox/outbox.js +267 -0
- package/transpiled/outbox/outbox.js.map +1 -0
- package/transpiled/query/criteria.d.ts +6 -0
- package/transpiled/query/criteria.js +74 -0
- package/transpiled/query/criteria.js.map +1 -0
- package/transpiled/query/options.d.ts +3 -0
- package/transpiled/query/options.js +27 -0
- package/transpiled/query/options.js.map +1 -0
- package/transpiled/query.d.ts +9 -0
- package/transpiled/query.js +57 -0
- package/transpiled/query.js.map +1 -0
- package/transpiled/receiver.d.ts +20 -0
- package/transpiled/receiver.js +92 -0
- package/transpiled/receiver.js.map +1 -0
- package/transpiled/reflection.d.ts +9 -0
- package/transpiled/reflection.js +13 -0
- package/transpiled/reflection.js.map +1 -0
- package/transpiled/remote.d.ts +10 -0
- package/transpiled/remote.js +12 -0
- package/transpiled/remote.js.map +1 -0
- package/transpiled/state.d.ts +33 -0
- package/transpiled/state.js +126 -0
- package/transpiled/state.js.map +1 -0
- package/transpiled/transition.d.ts +14 -0
- package/transpiled/transition.js +51 -0
- package/transpiled/transition.js.map +1 -0
- package/transpiled/transmission.d.ts +8 -0
- package/transpiled/transmission.js +30 -0
- package/transpiled/transmission.js.map +1 -0
- package/transpiled/types/atomicity.d.ts +56 -0
- package/transpiled/types/atomicity.js +2 -0
- package/transpiled/types/atomicity.js.map +1 -0
- package/transpiled/types/bindings.d.ts +42 -0
- package/transpiled/types/bindings.js +2 -0
- package/transpiled/types/bindings.js.map +1 -0
- package/transpiled/types/bridges.d.ts +38 -0
- package/transpiled/types/bridges.js +2 -0
- package/transpiled/types/bridges.js.map +1 -0
- package/transpiled/types/extensions.d.ts +62 -0
- package/transpiled/types/extensions.js +2 -0
- package/transpiled/types/extensions.js.map +1 -0
- package/transpiled/types/index.d.ts +13 -0
- package/transpiled/types/index.js +8 -0
- package/transpiled/types/index.js.map +1 -0
- package/transpiled/types/message.d.ts +5 -0
- package/transpiled/types/message.js +2 -0
- package/transpiled/types/message.js.map +1 -0
- package/transpiled/types/operations.d.ts +15 -0
- package/transpiled/types/operations.js +2 -0
- package/transpiled/types/operations.js.map +1 -0
- package/transpiled/types/outbox.d.ts +28 -0
- package/transpiled/types/outbox.js +2 -0
- package/transpiled/types/outbox.js.map +1 -0
- package/transpiled/types/receiver.d.ts +9 -0
- package/transpiled/types/receiver.js +2 -0
- package/transpiled/types/receiver.js.map +1 -0
- package/transpiled/types/request.d.ts +55 -0
- package/transpiled/types/request.js +2 -0
- package/transpiled/types/request.js.map +1 -0
- package/transpiled/types/state.d.ts +9 -0
- package/transpiled/types/state.js +2 -0
- package/transpiled/types/state.js.map +1 -0
- package/transpiled/types/storages.d.ts +106 -0
- package/transpiled/types/storages.js +2 -0
- package/transpiled/types/storages.js.map +1 -0
- package/transpiled/unmanaged.d.ts +5 -0
- package/transpiled/unmanaged.js +7 -0
- package/transpiled/unmanaged.js.map +1 -0
- package/tsconfig.json +10 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/CHANGELOG.md +0 -180
- package/src/assignment.js +0 -28
- package/src/context.js +0 -57
- package/src/contract/contract.js +0 -18
- package/src/contract/request.js +0 -77
- package/src/contract/schemas/error.yaml +0 -9
- package/src/contract/schemas/index.js +0 -11
- package/src/contract/schemas/query.yaml +0 -43
- package/src/contract/schemas/source.yaml +0 -23
- package/src/effect.js +0 -15
- package/src/entities/changeset.js +0 -36
- package/src/entities/entity.js +0 -119
- package/src/entities/factory.js +0 -40
- package/src/entities/index.js +0 -1
- package/src/event.js +0 -54
- package/src/exposition.js +0 -24
- package/src/guard.js +0 -13
- package/src/observation.js +0 -8
- package/src/operation.js +0 -95
- package/src/query/criteria.js +0 -37
- package/src/query/options.js +0 -37
- package/src/receiver.js +0 -123
- package/src/reflection.js +0 -24
- package/src/remote.js +0 -14
- package/src/state.js +0 -138
- package/src/transition.js +0 -61
- package/src/unmanaged.js +0 -7
- package/types/atomicity.d.ts +0 -58
- package/types/bindings.d.ts +0 -42
- package/types/bridges.ts +0 -33
- package/types/call.d.ts +0 -13
- package/types/component.d.ts +0 -12
- package/types/connector.d.ts +0 -18
- package/types/context.d.ts +0 -24
- package/types/entity.d.ts +0 -46
- package/types/event.d.ts +0 -11
- package/types/exception.d.ts +0 -4
- package/types/extensions.d.ts +0 -73
- package/types/guard.d.ts +0 -5
- package/types/locator.d.ts +0 -13
- package/types/operations.d.ts +0 -8
- package/types/outbox.d.ts +0 -53
- package/types/query.d.ts +0 -17
- package/types/receiver.d.ts +0 -12
- package/types/reflection.d.ts +0 -14
- package/types/remote.d.ts +0 -18
- package/types/state.d.ts +0 -38
- package/types/storages.d.ts +0 -96
- /package/{src/contract/index.js → source/contract/index.ts} +0 -0
- /package/{src/outbox/index.js → source/outbox/index.ts} +0 -0
package/test/context.test.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { describe, it, beforeEach
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
2
|
import assert from 'node:assert/strict'
|
|
3
3
|
|
|
4
4
|
import * as fixtures from './context.fixtures.js'
|
|
5
|
-
import { Context } from '../
|
|
5
|
+
import { Context } from '../source/context.js'
|
|
6
6
|
|
|
7
|
-
/** @type {toa.core.Context} */
|
|
7
|
+
/** @type {import('@toa.io/core').Context} */
|
|
8
8
|
let context
|
|
9
9
|
|
|
10
10
|
beforeEach(() => {
|
|
@@ -29,7 +29,7 @@ describe('call', () => {
|
|
|
29
29
|
})
|
|
30
30
|
})
|
|
31
31
|
|
|
32
|
-
function resetCalls
|
|
32
|
+
function resetCalls(target = [assert, fixtures], seen = new Set()) {
|
|
33
33
|
if (target === null || typeof target !== 'object' || seen.has(target)) return
|
|
34
34
|
|
|
35
35
|
seen.add(target)
|
|
@@ -4,7 +4,7 @@ import { isDeepStrictEqual } from 'node:util'
|
|
|
4
4
|
|
|
5
5
|
import { generate } from 'randomstring'
|
|
6
6
|
|
|
7
|
-
import { Contract } from '../../
|
|
7
|
+
import { Contract } from '../../source/contract/contract.js'
|
|
8
8
|
import * as fixtures from './contract.fixtures.js'
|
|
9
9
|
|
|
10
10
|
let contract
|
|
@@ -18,7 +18,11 @@ it('should fit value', () => {
|
|
|
18
18
|
|
|
19
19
|
contract.fit(value)
|
|
20
20
|
|
|
21
|
-
assert.ok(
|
|
21
|
+
assert.ok(
|
|
22
|
+
fixtures.schema.fit.mock.calls.some(
|
|
23
|
+
(call) => call.arguments.length === 1 && isDeepStrictEqual(call.arguments[0], value)
|
|
24
|
+
)
|
|
25
|
+
)
|
|
22
26
|
})
|
|
23
27
|
|
|
24
28
|
it('should throw on invalid value', () => {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { mock } from 'node:test'
|
|
2
2
|
|
|
3
3
|
import { generate } from 'randomstring'
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
import { resolve } from 'path'
|
|
4
|
+
|
|
5
|
+
import { query as querySchema } from '../../source/contract/schemas.js'
|
|
7
6
|
|
|
8
7
|
// noinspection JSCheckFunctionSignatures
|
|
9
8
|
export const schema = {
|
|
@@ -21,7 +20,7 @@ export const schemas = {
|
|
|
21
20
|
type: 'object',
|
|
22
21
|
properties: {
|
|
23
22
|
input: { type: 'null' },
|
|
24
|
-
query:
|
|
23
|
+
query: querySchema,
|
|
25
24
|
authentic: { type: 'boolean' }
|
|
26
25
|
},
|
|
27
26
|
additionalProperties: true
|
|
@@ -6,8 +6,8 @@ import { isDeepStrictEqual } from 'node:util'
|
|
|
6
6
|
import clone from 'clone-deep'
|
|
7
7
|
import { generate } from 'randomstring'
|
|
8
8
|
|
|
9
|
-
import { Request } from '../../
|
|
10
|
-
import { Contract } from '../../
|
|
9
|
+
import { Request } from '../../source/contract/request.js'
|
|
10
|
+
import { Contract } from '../../source/contract/contract.js'
|
|
11
11
|
import * as fixtures from './contract.fixtures.js'
|
|
12
12
|
|
|
13
13
|
// the base is real; what it was constructed with and told to fit is observable
|
|
@@ -22,7 +22,7 @@ beforeEach(() => {
|
|
|
22
22
|
contract = new Request(fixtures.schema, {})
|
|
23
23
|
})
|
|
24
24
|
|
|
25
|
-
const dummy = {
|
|
25
|
+
const dummy = { properties: {} }
|
|
26
26
|
|
|
27
27
|
it('should extend Conditions', () => {
|
|
28
28
|
assert.ok(contract instanceof Contract)
|
|
@@ -34,8 +34,11 @@ it('should fit request', () => {
|
|
|
34
34
|
|
|
35
35
|
contract.fit(request)
|
|
36
36
|
|
|
37
|
-
assert.ok(
|
|
38
|
-
|
|
37
|
+
assert.ok(
|
|
38
|
+
fit.mock.calls.some(
|
|
39
|
+
(call) => call.this === contract && isDeepStrictEqual(call.arguments[0], request)
|
|
40
|
+
)
|
|
41
|
+
)
|
|
39
42
|
})
|
|
40
43
|
|
|
41
44
|
describe('schema', () => {
|
|
@@ -70,21 +73,45 @@ describe('schema', () => {
|
|
|
70
73
|
|
|
71
74
|
it('should require query if declaration.query is true', () => {
|
|
72
75
|
schema.required = ['query']
|
|
73
|
-
assert.ok(
|
|
76
|
+
assert.ok(
|
|
77
|
+
['query'].every((item) =>
|
|
78
|
+
Request.schema({ query: true }, dummy).required.some((candidate) =>
|
|
79
|
+
isDeepStrictEqual(candidate, item)
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
74
83
|
})
|
|
75
84
|
|
|
76
85
|
it('should forbid projection for non observations', () => {
|
|
77
|
-
assert.strictEqual(
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
assert.strictEqual(
|
|
87
|
+
Request.schema({ type: 'transition' }, dummy).properties.query.properties
|
|
88
|
+
.projection,
|
|
89
|
+
undefined
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
assert.strictEqual(
|
|
93
|
+
Request.schema({ type: 'assignment' }, dummy).properties.query.properties
|
|
94
|
+
.projection,
|
|
95
|
+
undefined
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
assert.notStrictEqual(
|
|
99
|
+
Request.schema({ type: 'observation' }, dummy).properties.query.properties
|
|
100
|
+
.projection,
|
|
101
|
+
undefined
|
|
102
|
+
)
|
|
82
103
|
})
|
|
83
104
|
|
|
84
105
|
it('should forbid version for observations', () => {
|
|
85
|
-
assert.notStrictEqual(
|
|
86
|
-
|
|
87
|
-
|
|
106
|
+
assert.notStrictEqual(
|
|
107
|
+
Request.schema({ type: 'transition' }, dummy).properties.query.properties.version,
|
|
108
|
+
undefined
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
assert.strictEqual(
|
|
112
|
+
Request.schema({ type: 'observation' }, dummy).properties.query.properties.version,
|
|
113
|
+
undefined
|
|
114
|
+
)
|
|
88
115
|
})
|
|
89
116
|
|
|
90
117
|
it('should allow omit, limit only for set observations', () => {
|
|
@@ -94,18 +121,24 @@ describe('schema', () => {
|
|
|
94
121
|
assert.strictEqual(transition.omit, undefined)
|
|
95
122
|
assert.strictEqual(transition.limit, undefined)
|
|
96
123
|
|
|
97
|
-
const object = Request.schema(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
124
|
+
const object = Request.schema(
|
|
125
|
+
{
|
|
126
|
+
type: 'observation',
|
|
127
|
+
scope: 'object'
|
|
128
|
+
},
|
|
129
|
+
dummy
|
|
130
|
+
).properties.query.properties
|
|
101
131
|
|
|
102
132
|
assert.strictEqual(object.omit, undefined)
|
|
103
133
|
assert.strictEqual(object.limit, undefined)
|
|
104
134
|
|
|
105
|
-
const objects = Request.schema(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
135
|
+
const objects = Request.schema(
|
|
136
|
+
{
|
|
137
|
+
type: 'observation',
|
|
138
|
+
scope: 'objects'
|
|
139
|
+
},
|
|
140
|
+
dummy
|
|
141
|
+
).properties.query.properties
|
|
109
142
|
|
|
110
143
|
assert.notStrictEqual(objects.omit, undefined)
|
|
111
144
|
assert.notStrictEqual(objects.limit, undefined)
|
|
@@ -113,16 +146,13 @@ describe('schema', () => {
|
|
|
113
146
|
})
|
|
114
147
|
|
|
115
148
|
describe('source', () => {
|
|
116
|
-
|
|
117
|
-
|
|
118
149
|
const compile = (definition, entity) =>
|
|
119
|
-
schemas.schema(Request.schema(definition, entity)
|
|
150
|
+
schemas.schema(Request.schema(definition, entity))
|
|
120
151
|
|
|
121
|
-
it('should
|
|
152
|
+
it('should not hold source to a schema', () => {
|
|
122
153
|
const schema = Request.schema({}, dummy)
|
|
123
154
|
|
|
124
|
-
assert.
|
|
125
|
-
assert.deepStrictEqual(schema.properties.source.additionalProperties, false)
|
|
155
|
+
assert.strictEqual(schema.properties.source, undefined)
|
|
126
156
|
})
|
|
127
157
|
|
|
128
158
|
it('should pass known source variants', () => {
|
|
@@ -140,18 +170,22 @@ describe('source', () => {
|
|
|
140
170
|
}
|
|
141
171
|
})
|
|
142
172
|
|
|
143
|
-
//
|
|
144
|
-
//
|
|
145
|
-
it('should
|
|
173
|
+
// whatever a peer puts beside the keys this release knows travels through: what reads
|
|
174
|
+
// `source` takes the keys it knows, and the contract does not fail a call over the rest
|
|
175
|
+
it('should pass a source a peer added to', () => {
|
|
146
176
|
const schema = compile({}, undefined)
|
|
147
|
-
const request = {
|
|
177
|
+
const request = {
|
|
178
|
+
input: null,
|
|
179
|
+
query: null,
|
|
180
|
+
source: { service: 'exposition', mystery: 'x' }
|
|
181
|
+
}
|
|
148
182
|
|
|
149
183
|
assert.deepStrictEqual(schema.fit(request), null)
|
|
150
|
-
assert.deepStrictEqual(request.source, { service: 'exposition' })
|
|
184
|
+
assert.deepStrictEqual(request.source, { service: 'exposition', mystery: 'x' })
|
|
151
185
|
})
|
|
152
186
|
})
|
|
153
187
|
|
|
154
|
-
function resetCalls
|
|
188
|
+
function resetCalls(target = [assert, clone, fixtures, dummy], seen = new Set()) {
|
|
155
189
|
if (target === null || typeof target !== 'object' || seen.has(target)) return
|
|
156
190
|
|
|
157
191
|
seen.add(target)
|
package/test/discovery.test.js
CHANGED
|
@@ -3,8 +3,8 @@ import assert from 'node:assert/strict'
|
|
|
3
3
|
import { isDeepStrictEqual } from 'node:util'
|
|
4
4
|
|
|
5
5
|
import { console } from 'openspan'
|
|
6
|
-
import { Connector } from '../
|
|
7
|
-
import { Discovery } from '../
|
|
6
|
+
import { Connector } from '../source/connector.js'
|
|
7
|
+
import { Discovery } from '../source/discovery.js'
|
|
8
8
|
|
|
9
9
|
class Lookup extends Connector {
|
|
10
10
|
invoke = mock.fn(async () => ({ operations: {} }))
|
|
@@ -60,5 +60,12 @@ it('should keep warning while a lookup is unanswered', async () => {
|
|
|
60
60
|
|
|
61
61
|
assert.strictEqual(warn.mock.callCount(), 2)
|
|
62
62
|
|
|
63
|
-
assert.ok(
|
|
63
|
+
assert.ok(
|
|
64
|
+
((call) =>
|
|
65
|
+
call.arguments.length === 2 &&
|
|
66
|
+
isDeepStrictEqual(call.arguments[0], 'Waiting for lookup response') &&
|
|
67
|
+
isDeepStrictEqual(call.arguments[1], { component: locator.id, waiting: 10 }))(
|
|
68
|
+
warn.mock.calls.at(-1) ?? { arguments: [] }
|
|
69
|
+
)
|
|
70
|
+
)
|
|
64
71
|
})
|
package/test/emission.test.js
CHANGED
|
@@ -4,15 +4,16 @@ import { isDeepStrictEqual } from 'node:util'
|
|
|
4
4
|
|
|
5
5
|
import clone from 'clone-deep'
|
|
6
6
|
|
|
7
|
-
import { Connector } from '../
|
|
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) =>
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
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(
|
|
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
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
|
1
|
+
import { describe, it, beforeEach } from 'node:test'
|
|
2
2
|
import assert from 'node:assert/strict'
|
|
3
3
|
|
|
4
|
-
import { Entity } from '../../
|
|
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(),
|
|
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(
|
|
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
|
|
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().
|
|
94
|
+
assert.strictEqual(entity.get().DELETED, null)
|
|
61
95
|
assert.strictEqual(entity.deleted, false)
|
|
62
|
-
assert.strictEqual(entity.event().state.
|
|
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(),
|
|
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.
|
|
105
|
+
state.DELETED = timestamp
|
|
72
106
|
entity.set(state)
|
|
73
107
|
|
|
74
|
-
assert.strictEqual(entity.get().
|
|
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.
|
|
125
|
+
assert.strictEqual(event.state.VERSION, 1)
|
|
92
126
|
assert.notStrictEqual(event.origin.foo, 'new value')
|
|
93
127
|
})
|
|
94
128
|
|
|
95
|
-
function resetCalls
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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('../../
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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.
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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
|
|
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 '../../
|
|
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', () => {
|