@reventlessdev/reventless-core 3.0.0-alpha.271 → 3.0.0-alpha.273
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/CHANGELOG.md +15 -0
- package/package.json +9 -9
- package/src/components/Dcb/Dcb_Builder.res +26 -15
- package/src/components/Dcb/Dcb_Builder.res.mjs +8 -5
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res +14 -0
- package/src/components/StateChangeSlice/StateChangeSlice_Callback.res.mjs +5 -3
- package/tests/dcb/DcbTagTest.res.mjs +10 -10
- package/tests/dcb/DcbValidationTest.res.mjs +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.273 (2026-09-24)
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **dcb:** a command reference no decision reads by stays out of the query ([3ae149a](https://github.com/ReventlessDev/reventless-core/commit/3ae149ae91ebab63413be57df5827c5fd4390160))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.272 (2026-09-23)
|
|
14
|
+
|
|
15
|
+
**Note:** Version bump only for package @reventlessdev/reventless-core
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
6
21
|
# 3.0.0-alpha.271 (2026-09-23)
|
|
7
22
|
|
|
8
23
|
**Note:** Version bump only for package @reventlessdev/reventless-core
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-core",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.273",
|
|
4
4
|
"description": "Core package for Reventless framework",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -29,21 +29,21 @@
|
|
|
29
29
|
"sury": "11.0.0",
|
|
30
30
|
"uuid": "^13.0.0",
|
|
31
31
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.34",
|
|
32
|
-
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.
|
|
33
|
-
"@reventlessdev/rescript-jest": "1.0.0-alpha.11",
|
|
34
|
-
"@reventlessdev/rescript-node": "2.0.0-alpha.14",
|
|
32
|
+
"@reventlessdev/rescript-fast-csv": "2.0.0-alpha.15",
|
|
35
33
|
"@reventlessdev/rescript-hash-object": "1.2.0-alpha.15",
|
|
34
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.11",
|
|
35
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.15",
|
|
36
36
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.22",
|
|
37
|
-
"@reventlessdev/rescript-ssh2": "2.0.0-alpha.
|
|
38
|
-
"@reventlessdev/reventless-infra": "3.0.0-alpha.171",
|
|
39
|
-
"@reventlessdev/reventless-interop": "3.0.0-alpha.38",
|
|
37
|
+
"@reventlessdev/rescript-ssh2": "2.0.0-alpha.15",
|
|
40
38
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.1",
|
|
41
|
-
"@reventlessdev/reventless-
|
|
39
|
+
"@reventlessdev/reventless-infra": "3.0.0-alpha.173",
|
|
40
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.145",
|
|
41
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.38"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"rescript": "12.3.1",
|
|
45
45
|
"sury-ppx": "11.0.0",
|
|
46
|
-
"@reventlessdev/reventless-ppx": "1.0.0-alpha.
|
|
46
|
+
"@reventlessdev/reventless-ppx": "1.0.0-alpha.92"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"rescript": "^12.3.1"
|
|
@@ -306,21 +306,6 @@ module Make = (
|
|
|
306
306
|
->Array.map(schema => Reventless.DcbTag.extractTagKeysByEventType(schema))
|
|
307
307
|
->Reventless.DcbTag.mergeTagKeysByEventType
|
|
308
308
|
|
|
309
|
-
// Warn on composite (multi-tag) decision reads that would silently miss an
|
|
310
|
-
// event carrying extra tags (the tag_composite key is the event's full tag
|
|
311
|
-
// set, so composite reads are exact-match). Non-fatal — today's slices are
|
|
312
|
-
// aligned; the guard catches a tag added to a multi-tag event later.
|
|
313
|
-
Reventless.DcbValidation.validateCompositeReads(
|
|
314
|
-
~slices=stateChangeSlices->Array.map((module(Sc: StateChangeSlice.T)) => (
|
|
315
|
-
Sc.Spec.name,
|
|
316
|
-
Sc.Spec.commandSchema->S.castToUnknown,
|
|
317
|
-
Sc.Spec.consumedEventSchema->S.castToUnknown,
|
|
318
|
-
)),
|
|
319
|
-
~producedTagKeys=tagKeysByEventType,
|
|
320
|
-
)->Array.forEach(w =>
|
|
321
|
-
log.warn(~comp="Dcb_Builder", `DCB composite-read warning (${w.sliceName}): ${w.message}`)
|
|
322
|
-
)
|
|
323
|
-
|
|
324
309
|
// --- Phase 2 (dcb-tag-scope-inference): derive scope from the global slice
|
|
325
310
|
// graph and THREAD it into the decision-query wiring, replacing the
|
|
326
311
|
// annotation-based extraction. The derived `tagKeysByEventType` is what
|
|
@@ -388,6 +373,32 @@ module Make = (
|
|
|
388
373
|
let effectiveCrossPartitionTagKeys = effective.crossPartitionTagKeys
|
|
389
374
|
let effectiveTagKeysByEventType = effective.tagKeysByEventType
|
|
390
375
|
|
|
376
|
+
// Warn on composite (multi-tag) decision reads that would silently miss an
|
|
377
|
+
// event carrying extra tags (the tag_composite key is the event's full tag
|
|
378
|
+
// set, so composite reads are exact-match). Non-fatal — today's slices are
|
|
379
|
+
// aligned; the guard catches a tag added to a multi-tag event later.
|
|
380
|
+
Reventless.DcbValidation.validateCompositeReads(
|
|
381
|
+
~slices=stateChangeSlices->Array.map((module(Sc: StateChangeSlice.T)) => (
|
|
382
|
+
Sc.Spec.name,
|
|
383
|
+
Sc.Spec.commandSchema->S.castToUnknown,
|
|
384
|
+
Sc.Spec.consumedEventSchema->S.castToUnknown,
|
|
385
|
+
)),
|
|
386
|
+
~producedTagKeys=tagKeysByEventType,
|
|
387
|
+
~payloadTagKeysBySlice=sliceSchemas
|
|
388
|
+
->Array.map(slice => (
|
|
389
|
+
slice.name,
|
|
390
|
+
slice
|
|
391
|
+
->Reventless.DcbTag.sliceShape
|
|
392
|
+
->Reventless.DcbTag.commandPayloadTagKeys(
|
|
393
|
+
~partitionTag=partitionTagOf(slice.name),
|
|
394
|
+
~crossPartitionTagKeys=effectiveCrossPartitionTagKeys,
|
|
395
|
+
),
|
|
396
|
+
))
|
|
397
|
+
->Dict.fromArray,
|
|
398
|
+
)->Array.forEach(w =>
|
|
399
|
+
log.warn(~comp="Dcb_Builder", `DCB composite-read warning (${w.sliceName}): ${w.message}`)
|
|
400
|
+
)
|
|
401
|
+
|
|
391
402
|
// An ambiguity is a warning above because a boundary can fall back and
|
|
392
403
|
// lose nothing. Losing a cross-partition key is not that: the decision
|
|
393
404
|
// read for every slice that references another entity silently narrows to
|
|
@@ -198,11 +198,6 @@ function Make(DcbEventLogStorage) {
|
|
|
198
198
|
});
|
|
199
199
|
DcbValidation$Reventless.validateCrossPartitionScope(produced).forEach(err => log.error("Dcb_Builder", undefined, `DCB cross-partition scope error (` + err.sliceName + `): ` + err.message));
|
|
200
200
|
let tagKeysByEventType = DcbTag$Reventless.mergeTagKeysByEventType(producedSchemas.map(DcbTag$Reventless.extractTagKeysByEventType));
|
|
201
|
-
DcbValidation$Reventless.validateCompositeReads(stateChangeSlices.map(Sc => [
|
|
202
|
-
Sc.Spec.name,
|
|
203
|
-
Sc.Spec.commandSchema,
|
|
204
|
-
Sc.Spec.consumedEventSchema
|
|
205
|
-
]), tagKeysByEventType).forEach(w => log.warn("Dcb_Builder", undefined, `DCB composite-read warning (` + w.sliceName + `): ` + w.message));
|
|
206
201
|
let inferred = DcbScopeInference$Reventless.infer(inferenceShapes);
|
|
207
202
|
if (Primitive_object.notequal(inferred.crossPartitionTagKeys, crossPartitionTagKeys)) {
|
|
208
203
|
log.info("Dcb_Builder", undefined, `DCB scope-inference diff: crossPartitionTagKeys annotated=[` + crossPartitionTagKeys.join(", ") + `] inferred=[` + inferred.crossPartitionTagKeys.join(", ") + `]`);
|
|
@@ -227,6 +222,14 @@ function Make(DcbEventLogStorage) {
|
|
|
227
222
|
let effective = DcbTag$Reventless.deriveEffectiveScope(sliceSchemas);
|
|
228
223
|
let effectiveCrossPartitionTagKeys = effective.crossPartitionTagKeys;
|
|
229
224
|
let effectiveTagKeysByEventType = effective.tagKeysByEventType;
|
|
225
|
+
DcbValidation$Reventless.validateCompositeReads(stateChangeSlices.map(Sc => [
|
|
226
|
+
Sc.Spec.name,
|
|
227
|
+
Sc.Spec.commandSchema,
|
|
228
|
+
Sc.Spec.consumedEventSchema
|
|
229
|
+
]), tagKeysByEventType, Object.fromEntries(sliceSchemas.map(slice => [
|
|
230
|
+
slice.name,
|
|
231
|
+
DcbTag$Reventless.commandPayloadTagKeys(DcbTag$Reventless.sliceShape(slice), DcbTag$Reventless.slicePartitionTag(boundaryPartition, slice.name), effectiveCrossPartitionTagKeys)
|
|
232
|
+
]))).forEach(w => log.warn("Dcb_Builder", undefined, `DCB composite-read warning (` + w.sliceName + `): ` + w.message));
|
|
230
233
|
if (effective.droppedCrossPartitionTagKeys.length !== 0) {
|
|
231
234
|
log.error("Dcb_Builder", undefined, `DCB scope degraded (` + name + `): cross-partition reads of [` + effective.droppedCrossPartitionTagKeys.join(", ") + `] were derived but dropped — an ambiguous slice forced the boundary onto @crossPartition annotations that do not carry them. Slices referencing another entity by these keys will decide against an empty history and reject valid commands. Resolve: ` + effective.ambiguities.map(param => param[0] + ` (` + param[1] + `)`).join(" | "));
|
|
232
235
|
}
|
|
@@ -93,6 +93,15 @@ module Make = (
|
|
|
93
93
|
}
|
|
94
94
|
)
|
|
95
95
|
|
|
96
|
+
// A command key the slice does not decide by stays out of its query; which keys
|
|
97
|
+
// those are depends on the partition, so `handleCommands` asks per boundary.
|
|
98
|
+
let scopeShape = Reventless.DcbTag.sliceShapeFromSchemas(
|
|
99
|
+
~name=Spec.name,
|
|
100
|
+
~commandSchema=Spec.commandSchema,
|
|
101
|
+
~consumedEventSchema=Spec.consumedEventSchema,
|
|
102
|
+
~eventSchema=Spec.eventSchema,
|
|
103
|
+
)
|
|
104
|
+
|
|
96
105
|
// Extracts the entity id of a read event from its own tags, for logging
|
|
97
106
|
// which events the decision model was built from. Prefers this slice's
|
|
98
107
|
// partition key, but consumed events from other sources are tagged by their
|
|
@@ -162,6 +171,7 @@ module Make = (
|
|
|
162
171
|
let handleSingleCommand = (
|
|
163
172
|
~tagKeysByEventType,
|
|
164
173
|
~crossPartitionTagKeys,
|
|
174
|
+
~payloadTagKeys,
|
|
165
175
|
~partitionTag,
|
|
166
176
|
dcbEventLog: DcbEventLog.operations,
|
|
167
177
|
command': Message.command'<Reventless.Id.String.t, Spec.command>,
|
|
@@ -186,6 +196,7 @@ module Make = (
|
|
|
186
196
|
~value=command'.command,
|
|
187
197
|
~tagKeysByEventType,
|
|
188
198
|
~crossPartitionTagKeys,
|
|
199
|
+
~payloadTagKeys,
|
|
189
200
|
)
|
|
190
201
|
|
|
191
202
|
// Log the DCB query parameters — the OR clauses (event types + tags) the
|
|
@@ -504,11 +515,14 @@ module Make = (
|
|
|
504
515
|
| Some(_) => partitionTag
|
|
505
516
|
| None => slicePartitionTag->Lazy.get
|
|
506
517
|
}
|
|
518
|
+
let payloadTagKeys =
|
|
519
|
+
scopeShape->Reventless.DcbTag.commandPayloadTagKeys(~partitionTag, ~crossPartitionTagKeys)
|
|
507
520
|
stream
|
|
508
521
|
->Stream.mapEffect(({ReventlessInfra.CommandTopic.reference: reference, command}) =>
|
|
509
522
|
handleSingleCommand(
|
|
510
523
|
~tagKeysByEventType,
|
|
511
524
|
~crossPartitionTagKeys,
|
|
525
|
+
~payloadTagKeys,
|
|
512
526
|
~partitionTag,
|
|
513
527
|
dcbEventLog,
|
|
514
528
|
command,
|
|
@@ -36,6 +36,7 @@ function Make(Spec) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
});
|
|
39
|
+
let scopeShape = DcbTag$Reventless.sliceShapeFromSchemas(Spec.name, Spec.commandSchema, Spec.consumedEventSchema, Spec.eventSchema, undefined);
|
|
39
40
|
let readEventId = (partitionTag, tags) => {
|
|
40
41
|
let ownTagValues = () => {
|
|
41
42
|
let vals = Stdlib_Array.reduce(tags, [], (acc, t) => {
|
|
@@ -70,10 +71,10 @@ function Make(Spec) {
|
|
|
70
71
|
};
|
|
71
72
|
let projectionCache = Lru$ReventlessCore.make(100);
|
|
72
73
|
let resetCache = () => Lru$ReventlessCore.clear(projectionCache);
|
|
73
|
-
let handleSingleCommand = (tagKeysByEventType, crossPartitionTagKeys, partitionTag, dcbEventLog, command$p) => {
|
|
74
|
+
let handleSingleCommand = (tagKeysByEventType, crossPartitionTagKeys, payloadTagKeys, partitionTag, dcbEventLog, command$p) => {
|
|
74
75
|
let cmdJson = Message$ReventlessCore.commandJsonOfCommand$p(Id$Reventless.$$String.toString, Spec.commandSchema, command$p);
|
|
75
76
|
Effect.runSync(EffectLogger$ReventlessCore.logInfo(comp, cmdJson.commandJson, `handling command: ` + LogFormat$ReventlessCore.cmdDetailNoId(cmdJson)));
|
|
76
|
-
let query = DcbTag$Reventless.buildQueryFromCommand(queryEventTypes, Spec.commandSchema, command$p.command, tagKeysByEventType, crossPartitionTagKeys);
|
|
77
|
+
let query = DcbTag$Reventless.buildQueryFromCommand(queryEventTypes, Spec.commandSchema, command$p.command, tagKeysByEventType, crossPartitionTagKeys, payloadTagKeys);
|
|
77
78
|
let queryDetail = query.map(qi => {
|
|
78
79
|
let ts = qi.eventTypes;
|
|
79
80
|
let types = ts !== undefined ? ts.map(LogFormat$ReventlessCore.bold).join("|") : "*";
|
|
@@ -315,9 +316,10 @@ function Make(Spec) {
|
|
|
315
316
|
let tagKeysByEventType = tagKeysByEventTypeOpt !== undefined ? tagKeysByEventTypeOpt : ({});
|
|
316
317
|
let crossPartitionTagKeys = crossPartitionTagKeysOpt !== undefined ? crossPartitionTagKeysOpt : [];
|
|
317
318
|
let partitionTag$1 = partitionTag !== undefined ? partitionTag : Stdlib_Lazy.get(slicePartitionTag);
|
|
319
|
+
let payloadTagKeys = DcbTag$Reventless.commandPayloadTagKeys(scopeShape, partitionTag$1, crossPartitionTagKeys);
|
|
318
320
|
return Stream.runCollect(Stream$1.mapEffect(stream, param => {
|
|
319
321
|
let reference = param.reference;
|
|
320
|
-
return Effect.map(handleSingleCommand(tagKeysByEventType, crossPartitionTagKeys, partitionTag$1, dcbEventLog, param.command), result => {
|
|
322
|
+
return Effect.map(handleSingleCommand(tagKeysByEventType, crossPartitionTagKeys, payloadTagKeys, partitionTag$1, dcbEventLog, param.command), result => {
|
|
321
323
|
if (result.TAG === "Ok") {
|
|
322
324
|
return {
|
|
323
325
|
TAG: "Ok",
|
|
@@ -540,7 +540,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
540
540
|
TAG: "CreateItem",
|
|
541
541
|
itemId: "item-1",
|
|
542
542
|
name: "Test"
|
|
543
|
-
}, undefined, undefined)).toEqual([{
|
|
543
|
+
}, undefined, undefined, undefined)).toEqual([{
|
|
544
544
|
eventTypes: eventTypes,
|
|
545
545
|
tags: [{
|
|
546
546
|
key: "itemId",
|
|
@@ -557,7 +557,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
557
557
|
"prod-1",
|
|
558
558
|
"prod-2"
|
|
559
559
|
]
|
|
560
|
-
}, undefined, undefined)).toEqual([
|
|
560
|
+
}, undefined, undefined, undefined)).toEqual([
|
|
561
561
|
{
|
|
562
562
|
eventTypes: eventTypes,
|
|
563
563
|
tags: [{
|
|
@@ -587,7 +587,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
587
587
|
orderId: "ord-1",
|
|
588
588
|
customerId: "cust-1",
|
|
589
589
|
productId: ["prod-1"]
|
|
590
|
-
}, undefined, undefined)).toEqual([
|
|
590
|
+
}, undefined, undefined, undefined)).toEqual([
|
|
591
591
|
{
|
|
592
592
|
eventTypes: eventTypes,
|
|
593
593
|
tags: [{
|
|
@@ -610,7 +610,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
610
610
|
orderId: "ord-1",
|
|
611
611
|
customerId: "cust-1",
|
|
612
612
|
productId: []
|
|
613
|
-
}, undefined, undefined)).toEqual([{
|
|
613
|
+
}, undefined, undefined, undefined)).toEqual([{
|
|
614
614
|
eventTypes: eventTypes,
|
|
615
615
|
tags: [{
|
|
616
616
|
key: "orderId",
|
|
@@ -644,7 +644,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
644
644
|
orderId: "ord-1",
|
|
645
645
|
customerId: "cust-1",
|
|
646
646
|
productId: ["prod-1"]
|
|
647
|
-
}, orderTagKeys, undefined)).toEqual([
|
|
647
|
+
}, orderTagKeys, undefined, undefined)).toEqual([
|
|
648
648
|
{
|
|
649
649
|
eventTypes: ["OrderPlaced"],
|
|
650
650
|
tags: [{
|
|
@@ -672,7 +672,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
672
672
|
TAG: "CreateItem",
|
|
673
673
|
itemId: "item-1",
|
|
674
674
|
name: "Test"
|
|
675
|
-
}, orderTagKeys, undefined)).toEqual([{
|
|
675
|
+
}, orderTagKeys, undefined, undefined)).toEqual([{
|
|
676
676
|
eventTypes: [],
|
|
677
677
|
tags: [{
|
|
678
678
|
key: "itemId",
|
|
@@ -689,7 +689,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
689
689
|
orderId: "ord-1",
|
|
690
690
|
customerId: "cust-1",
|
|
691
691
|
productId: ["prod-1"]
|
|
692
|
-
}, {}, undefined)).toEqual([
|
|
692
|
+
}, {}, undefined, undefined)).toEqual([
|
|
693
693
|
{
|
|
694
694
|
eventTypes: [
|
|
695
695
|
"OrderPlaced",
|
|
@@ -723,7 +723,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
723
723
|
TAG: "SubscribeStudent",
|
|
724
724
|
courseId: "C1",
|
|
725
725
|
studentId: "S1"
|
|
726
|
-
}, undefined, ["studentId"])).toEqual([
|
|
726
|
+
}, undefined, ["studentId"], undefined)).toEqual([
|
|
727
727
|
{
|
|
728
728
|
eventTypes: ["StudentSubscribed"],
|
|
729
729
|
tags: [{
|
|
@@ -745,7 +745,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
745
745
|
TAG: "SubscribeStudent",
|
|
746
746
|
courseId: "C1",
|
|
747
747
|
studentId: "S1"
|
|
748
|
-
}, undefined, undefined)).toEqual([{
|
|
748
|
+
}, undefined, undefined, undefined)).toEqual([{
|
|
749
749
|
eventTypes: ["StudentSubscribed"],
|
|
750
750
|
tags: [
|
|
751
751
|
{
|
|
@@ -813,7 +813,7 @@ globalThis.describe("DcbTag:", () => {
|
|
|
813
813
|
"prod-1",
|
|
814
814
|
"prod-2"
|
|
815
815
|
]
|
|
816
|
-
}, undefined, undefined)).toEqual([
|
|
816
|
+
}, undefined, undefined, undefined)).toEqual([
|
|
817
817
|
{
|
|
818
818
|
eventTypes: [
|
|
819
819
|
"OrderPlaced",
|
|
@@ -372,7 +372,7 @@ globalThis.describe("DcbValidation:", () => {
|
|
|
372
372
|
"RecordDemand",
|
|
373
373
|
recordDemandCommandSchema,
|
|
374
374
|
demandConsumedSchema
|
|
375
|
-
]], producedTagKeys);
|
|
375
|
+
]], producedTagKeys, undefined);
|
|
376
376
|
globalThis.expect(warnings.length).toBe(1);
|
|
377
377
|
let w = warnings[0];
|
|
378
378
|
globalThis.expect(w.sliceName).toBe("RecordDemand");
|
|
@@ -384,7 +384,7 @@ globalThis.describe("DcbValidation:", () => {
|
|
|
384
384
|
"RecordDemand",
|
|
385
385
|
recordDemandCommandSchema,
|
|
386
386
|
demandConsumedSchema
|
|
387
|
-
]], producedTagKeys);
|
|
387
|
+
]], producedTagKeys, undefined);
|
|
388
388
|
globalThis.expect(warnings.some(w => w.message.includes("ProductDemandRecorded"))).toBe(false);
|
|
389
389
|
});
|
|
390
390
|
globalThis.test("ignores single-tag commands (partition read, not composite)", () => {
|
|
@@ -392,7 +392,7 @@ globalThis.describe("DcbValidation:", () => {
|
|
|
392
392
|
"TouchDemand",
|
|
393
393
|
touchDemandCommandSchema,
|
|
394
394
|
demandConsumedSchema
|
|
395
|
-
]], producedTagKeys);
|
|
395
|
+
]], producedTagKeys, undefined);
|
|
396
396
|
globalThis.expect(warnings).toEqual([]);
|
|
397
397
|
});
|
|
398
398
|
globalThis.test("ignores tagged-array commands (per-element OR, not composite)", () => {
|
|
@@ -400,11 +400,11 @@ globalThis.describe("DcbValidation:", () => {
|
|
|
400
400
|
"PlaceOrder",
|
|
401
401
|
placeOrderCommandSchema,
|
|
402
402
|
demandConsumedSchema
|
|
403
|
-
]], producedTagKeys);
|
|
403
|
+
]], producedTagKeys, undefined);
|
|
404
404
|
globalThis.expect(warnings).toEqual([]);
|
|
405
405
|
});
|
|
406
406
|
globalThis.test("no warnings when nothing reads compositely", () => {
|
|
407
|
-
globalThis.expect(DcbValidation$Reventless.validateCompositeReads([], producedTagKeys)).toEqual([]);
|
|
407
|
+
globalThis.expect(DcbValidation$Reventless.validateCompositeReads([], producedTagKeys, undefined)).toEqual([]);
|
|
408
408
|
});
|
|
409
409
|
});
|
|
410
410
|
globalThis.describe("validateCrossPartitionScope (Issue 13)", () => {
|