@cratis/chronicle 6.22.1 → 6.24.0

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 (40) hide show
  1. package/dist/eventSequences/EventSequence.d.ts.map +1 -1
  2. package/dist/eventSequences/EventSequence.js +2 -27
  3. package/dist/eventSequences/EventSequence.js.map +1 -1
  4. package/dist/eventSequences/createAppendResult.d.ts +13 -0
  5. package/dist/eventSequences/createAppendResult.d.ts.map +1 -0
  6. package/dist/eventSequences/createAppendResult.js +31 -0
  7. package/dist/eventSequences/createAppendResult.js.map +1 -0
  8. package/dist/events/constraints/Constraints.d.ts +8 -3
  9. package/dist/events/constraints/Constraints.d.ts.map +1 -1
  10. package/dist/events/constraints/Constraints.js +135 -125
  11. package/dist/events/constraints/Constraints.js.map +1 -1
  12. package/dist/testing/EventScenario.d.ts.map +1 -1
  13. package/dist/testing/EventScenario.js +70 -10
  14. package/dist/testing/EventScenario.js.map +1 -1
  15. package/dist/testing/InProcessConstraints.d.ts +17 -0
  16. package/dist/testing/InProcessConstraints.d.ts.map +1 -0
  17. package/dist/testing/InProcessConstraints.js +142 -0
  18. package/dist/testing/InProcessConstraints.js.map +1 -0
  19. package/dist/testing/InProcessEventSequence.d.ts +5 -1
  20. package/dist/testing/InProcessEventSequence.d.ts.map +1 -1
  21. package/dist/testing/InProcessEventSequence.js +43 -26
  22. package/dist/testing/InProcessEventSequence.js.map +1 -1
  23. package/dist/testing/ReactorScenario.d.ts.map +1 -1
  24. package/dist/testing/ReactorScenario.js +3 -2
  25. package/dist/testing/ReactorScenario.js.map +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/eventSequences/EventSequence.ts +3 -32
  28. package/eventSequences/createAppendResult.ts +44 -0
  29. package/events/constraints/Constraints.ts +57 -47
  30. package/events/constraints/for_Constraints/when_resolving_violation_messages.spec.ts +28 -0
  31. package/package.json +1 -1
  32. package/testing/EventScenario.constraint-discovery.spec.ts +69 -0
  33. package/testing/EventScenario.constraint-values.spec.ts +199 -0
  34. package/testing/EventScenario.constraints.spec.ts +415 -0
  35. package/testing/EventScenario.fixtures.spec.ts +5 -3
  36. package/testing/EventScenario.rejections.spec.ts +10 -3
  37. package/testing/EventScenario.ts +72 -11
  38. package/testing/InProcessConstraints.ts +148 -0
  39. package/testing/InProcessEventSequence.ts +42 -25
  40. package/testing/ReactorScenario.ts +3 -1
@@ -2,36 +2,96 @@
2
2
  // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
3
  import { DefaultClientArtifactsProvider } from '../artifacts/DefaultClientArtifactsProvider.js';
4
4
  import { TypeDiscoverer } from '../types/TypeDiscoverer.js';
5
+ import { TypeIntrospector } from '../types/TypeIntrospector.js';
5
6
  import { EventSequenceId } from '../eventSequences/EventSequenceId.js';
6
- import { getEventTypeMetadata } from '../events/eventTypeDecorator.js';
7
+ import { getEventTypeFor, getEventTypeMetadata } from '../events/eventTypeDecorator.js';
8
+ import { compileConstraints } from '../events/constraints/Constraints.js';
7
9
  import { getUniqueEventMetadata, getUniquePropertyMetadata } from '../events/constraints/unique.js';
10
+ import { getRemovedConstraintNames } from '../events/constraints/removeConstraint.js';
11
+ import { getConstraintMetadata } from '../events/constraints/constraint.js';
12
+ import { InProcessConstraints } from './InProcessConstraints.js';
8
13
  import { EventScenarioGivenBuilder } from './EventScenarioGivenBuilder.js';
9
14
  import { EventScenarioWhenBuilder } from './EventScenarioWhenBuilder.js';
10
15
  import { InProcessEventSequence } from './InProcessEventSequence.js';
11
16
  import { registerScenarioSeed } from './EventScenarioSeed.js';
12
17
  import { UnsupportedEventSequenceOperation } from './UnsupportedEventSequenceOperation.js';
18
+ function hasConstraintDecorators(type) {
19
+ return getUniqueEventMetadata(type) !== undefined || getRemovedConstraintNames(type).length > 0 ||
20
+ TypeIntrospector.getTrackedProperties(type).some(property => getUniquePropertyMetadata(type, property) !== undefined);
21
+ }
13
22
  /** A kernel-free, fixture-bounded append scenario. No observer runs automatically. */
14
23
  export class EventScenario {
15
24
  eventSequence;
16
25
  given;
17
26
  when;
18
27
  constructor(options = {}) {
19
- const artifacts = options.artifacts ?? new DefaultClientArtifactsProvider(TypeDiscoverer.default);
28
+ const selectedArtifacts = options.artifacts;
29
+ const selectedConstraints = selectedArtifacts?.constraints;
30
+ const artifacts = selectedArtifacts ?? new DefaultClientArtifactsProvider(TypeDiscoverer.default);
20
31
  const eventTypes = [...artifacts.eventTypes];
21
- if (options.artifacts?.constraints?.length === 0 && options.constraints !== 'disabled') {
32
+ if (selectedConstraints?.length === 0 && options.constraints !== 'disabled') {
22
33
  throw new UnsupportedEventSequenceOperation('artifacts.constraints', 'empty constraint catalog', 'An empty selected catalog cannot silently disable constraint discovery; set constraints: disabled explicitly.');
23
34
  }
24
- const discovered = options.artifacts?.constraints ?? new DefaultClientArtifactsProvider(TypeDiscoverer.default).constraints;
25
- if (options.constraints !== 'disabled' && (discovered.length || eventTypes.some(type => {
26
- const metadata = getEventTypeMetadata(type);
27
- return getUniqueEventMetadata(type) || [...(metadata?.members.keys() ?? [])].some(key => getUniquePropertyMetadata(type, key));
28
- }))) {
29
- throw new UnsupportedEventSequenceOperation('artifacts.constraints', discovered.map(type => type.name).join(', ') || 'event metadata', 'Constraint definitions are rejected until kernel-backed constraint fixtures are available.');
35
+ const discoveredArtifacts = selectedArtifacts && selectedConstraints === undefined
36
+ ? new DefaultClientArtifactsProvider(TypeDiscoverer.default) : undefined;
37
+ const discovered = selectedConstraints ?? discoveredArtifacts?.constraints ?? artifacts.constraints;
38
+ let constraints;
39
+ if (options.constraints !== 'disabled') {
40
+ for (const type of discovered ?? []) {
41
+ if (!getConstraintMetadata(type))
42
+ throw new UnsupportedEventSequenceOperation('artifacts.constraints', type.name, 'Every selected constraint must have @constraint metadata.');
43
+ }
44
+ try {
45
+ // Keep global decorator contributions. A shadowed ID is accepted only when neither
46
+ // constructor has constraint decorators, so either one compiles to the same constraints.
47
+ const compiledEventTypes = [...new Set([...(discoveredArtifacts?.eventTypes ?? []), ...eventTypes])];
48
+ const constructorsById = new Map();
49
+ for (const type of compiledEventTypes) {
50
+ const id = getEventTypeFor(type).id.value;
51
+ const previous = constructorsById.get(id);
52
+ if (previous && previous !== type && (hasConstraintDecorators(previous) || hasConstraintDecorators(type))) {
53
+ throw new UnsupportedEventSequenceOperation('artifacts.eventTypes', id, 'Conflicting constructors share an event type ID; constraint discovery cannot choose one.');
54
+ }
55
+ constructorsById.set(id, type);
56
+ }
57
+ const compiled = compileConstraints({ eventTypes: [...constructorsById.values()], constraints: discovered ?? [] });
58
+ const selectedIds = new Set(eventTypes.map(type => getEventTypeFor(type).id.value));
59
+ const definitions = discoveredArtifacts ? new Map([...compiled].filter(([, capture]) => {
60
+ const constrained = capture.uniqueConstraint?.eventDefinitions.map(entry => entry.eventTypeId) ??
61
+ capture.uniqueEventType?.eventTypeIds ?? [capture.uniqueEventType?.eventTypeId];
62
+ const removedWith = [...(capture.uniqueConstraint?.removedWithEventTypeIds ?? []),
63
+ capture.uniqueConstraint?.removedWithEventTypeId,
64
+ ...(capture.uniqueEventType?.removedWithEventTypeIds ?? [])];
65
+ return [...constrained, ...removedWith].some(id => id !== undefined && selectedIds.has(id));
66
+ })) : compiled;
67
+ constraints = new InProcessConstraints(definitions);
68
+ for (const [name, capture] of definitions) {
69
+ const ids = capture.uniqueConstraint?.eventDefinitions.map(entry => entry.eventTypeId) ??
70
+ capture.uniqueEventType?.eventTypeIds ?? [capture.uniqueEventType?.eventTypeId];
71
+ const removedWith = [...(capture.uniqueConstraint?.removedWithEventTypeIds ?? []),
72
+ capture.uniqueConstraint?.removedWithEventTypeId,
73
+ ...(capture.uniqueEventType?.removedWithEventTypeIds ?? [])];
74
+ if ([...ids, ...removedWith].some(id => id !== undefined && !selectedIds.has(id))) {
75
+ throw new UnsupportedEventSequenceOperation('artifacts.constraints', name, 'Every constrained event type must be in the selected catalog.');
76
+ }
77
+ for (const entry of capture.uniqueConstraint?.eventDefinitions ?? []) {
78
+ const type = eventTypes.find(type => getEventTypeFor(type).id.value === entry.eventTypeId);
79
+ if (!['string', 'boolean'].includes(getEventTypeMetadata(type)?.schema.properties?.[entry.properties[0]]?.type ?? '')) {
80
+ throw new UnsupportedEventSequenceOperation('artifacts.constraints', name, 'The constrained property must be a schema-backed string or boolean.');
81
+ }
82
+ }
83
+ }
84
+ }
85
+ catch (error) {
86
+ if (error instanceof UnsupportedEventSequenceOperation)
87
+ throw error;
88
+ throw new UnsupportedEventSequenceOperation('artifacts.constraints', 'compiler', `Invalid constraint definition: ${String(error)}.`);
89
+ }
30
90
  }
31
91
  if (artifacts.eventTypeMigrations?.length) {
32
92
  throw new UnsupportedEventSequenceOperation('artifacts.eventTypeMigrations', artifacts.eventTypeMigrations.map(type => type.name).join(', '), 'Migrations are not fixture-backed.');
33
93
  }
34
- const sequence = new InProcessEventSequence(options, eventTypes);
94
+ const sequence = new InProcessEventSequence(options, eventTypes, constraints);
35
95
  this.eventSequence = sequence;
36
96
  registerScenarioSeed(this, (source, events) => sequence.seed(source, events));
37
97
  this.given = new EventScenarioGivenBuilder(this);
@@ -1 +1 @@
1
- {"version":3,"file":"EventScenario.js","sourceRoot":"","sources":["../../testing/EventScenario.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EventScenario.js","sourceRoot":"","sources":["../../testing/EventScenario.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { ConstraintViolation as ContractsConstraintViolation } from '@cratis/chronicle.contracts';
2
+ import type { AppendedEvent } from '../events/AppendedEvent.js';
3
+ import type { ConstraintCapture } from '../events/constraints/ConstraintBuilder.js';
4
+ import type { ConstraintViolation } from '../eventSequences/ConstraintViolation.js';
5
+ export type WireConstraintViolation = ContractsConstraintViolation;
6
+ /** Narrow, fixture-backed unscoped constraint validation over serialized event snapshots. */
7
+ export declare class InProcessConstraints {
8
+ private readonly _definitions;
9
+ private readonly _constrainedProperties;
10
+ constructor(_definitions: ReadonlyMap<string, ConstraintCapture>);
11
+ isConstrainedProperty(eventTypeId: string, property: string): boolean;
12
+ /** Validate against committed history and all earlier entries of this append, without changing state. */
13
+ validate(history: readonly AppendedEvent[], incoming: readonly AppendedEvent[]): WireConstraintViolation[];
14
+ resolveMessage(violation: ConstraintViolation): ConstraintViolation;
15
+ private unsupported;
16
+ }
17
+ //# sourceMappingURL=InProcessConstraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InProcessConstraints.d.ts","sourceRoot":"","sources":["../../testing/InProcessConstraints.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,IAAI,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AACvG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAEpF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAGpF,MAAM,MAAM,uBAAuB,GAAG,4BAA4B,CAAC;AAiBnE,6FAA6F;AAC7F,qBAAa,oBAAoB;IAGjB,OAAO,CAAC,QAAQ,CAAC,YAAY;IAFzC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAkC;IAEzE,YAA6B,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAoChF;IAED,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpE;IAED,yGAAyG;IACzG,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,EAAE,QAAQ,EAAE,SAAS,aAAa,EAAE,GAAG,uBAAuB,EAAE,CA+DzG;IAED,cAAc,CAAC,SAAS,EAAE,mBAAmB,GAAG,mBAAmB,CAElE;IAED,OAAO,CAAC,WAAW;CAGtB"}
@@ -0,0 +1,142 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+ import { createHash } from 'node:crypto';
4
+ import { resolveConstraintMessage } from '../events/constraints/Constraints.js';
5
+ import { UnsupportedEventSequenceOperation } from './UnsupportedEventSequenceOperation.js';
6
+ const unavailable = '18446744073709551615';
7
+ // Only the key characters captured by the packaged oracle, not every valid event-content character.
8
+ const provenString = /^[A-Za-z0-9 .@_:\-|{}$\u00e9]*$/;
9
+ function kernelKeyString(value, name) {
10
+ if (typeof value === 'string' && provenString.test(value))
11
+ return value;
12
+ if (typeof value === 'boolean')
13
+ return value ? 'True' : 'False';
14
+ throw new UnsupportedEventSequenceOperation('artifacts.constraints', name, 'Only fixture-backed scalar string and boolean keys are supported.');
15
+ }
16
+ function keyHash(value) {
17
+ return createHash('sha256').update(value).digest('hex');
18
+ }
19
+ /** Narrow, fixture-backed unscoped constraint validation over serialized event snapshots. */
20
+ export class InProcessConstraints {
21
+ _definitions;
22
+ _constrainedProperties = new Map();
23
+ constructor(_definitions) {
24
+ this._definitions = _definitions;
25
+ const coveredTypes = new Set();
26
+ for (const [name, capture] of _definitions) {
27
+ if (capture.uniqueConstraint && capture.uniqueEventType) {
28
+ throw this.unsupported(name, 'A definition with both constraint kinds is not fixture-backed.');
29
+ }
30
+ if (capture.scope.perEventSourceType || capture.scope.perEventStreamType || capture.scope.perEventStreamId) {
31
+ throw this.unsupported(name, 'Scoped constraints are not fixture-backed.');
32
+ }
33
+ if (capture.uniqueConstraint) {
34
+ const unique = capture.uniqueConstraint;
35
+ if (unique.ignoreCasing || unique.removedWithEventTypeId || unique.removedWithEventTypeIds?.length ||
36
+ unique.eventDefinitions.length === 0 || unique.eventDefinitions.some(entry => entry.properties.length !== 1 ||
37
+ !/^[a-z][a-zA-Z0-9]*$/.test(entry.properties[0]))) {
38
+ throw this.unsupported(name, 'Case folding, removal and composite or nested keys are not fixture-backed.');
39
+ }
40
+ for (const entry of unique.eventDefinitions) {
41
+ const properties = this._constrainedProperties.get(entry.eventTypeId) ?? new Set();
42
+ properties.add(entry.properties[0]);
43
+ this._constrainedProperties.set(entry.eventTypeId, properties);
44
+ }
45
+ }
46
+ else if (capture.uniqueEventType) {
47
+ const unique = capture.uniqueEventType;
48
+ if (unique.removedWithEventTypeIds?.length || (unique.eventTypeIds?.length ?? 1) !== 1) {
49
+ throw this.unsupported(name, 'Removal and multi-type unique event cycles are not fixture-backed.');
50
+ }
51
+ }
52
+ else {
53
+ throw this.unsupported(name, 'Unknown constraint definition.');
54
+ }
55
+ const ids = capture.uniqueConstraint?.eventDefinitions.map(entry => entry.eventTypeId) ??
56
+ capture.uniqueEventType?.eventTypeIds ?? [capture.uniqueEventType.eventTypeId];
57
+ for (const id of ids) {
58
+ if (coveredTypes.has(id))
59
+ throw this.unsupported(name, 'Overlapping constraints are not fixture-backed.');
60
+ coveredTypes.add(id);
61
+ }
62
+ }
63
+ }
64
+ isConstrainedProperty(eventTypeId, property) {
65
+ return this._constrainedProperties.get(eventTypeId)?.has(property) ?? false;
66
+ }
67
+ /** Validate against committed history and all earlier entries of this append, without changing state. */
68
+ validate(history, incoming) {
69
+ const violations = [];
70
+ const stagedKeys = new Map();
71
+ const stagedTypes = new Set();
72
+ for (const event of incoming) {
73
+ const type = event.eventType.id.value;
74
+ const source = event.context.eventSourceId;
75
+ for (const [name, definition] of this._definitions) {
76
+ const property = definition.uniqueConstraint?.eventDefinitions.find(entry => entry.eventTypeId === type)?.properties[0];
77
+ if (property !== undefined) {
78
+ const raw = kernelKeyString(event.content[property], name);
79
+ const key = keyHash(raw);
80
+ const claims = new Map();
81
+ const owners = new Map();
82
+ for (const prior of history) {
83
+ const priorProperty = definition.uniqueConstraint.eventDefinitions.find(entry => entry.eventTypeId === prior.eventType.id.value)?.properties[0];
84
+ if (priorProperty !== undefined) {
85
+ const priorValue = prior.content[priorProperty];
86
+ if (typeof priorValue !== 'string' && typeof priorValue !== 'boolean')
87
+ throw this.unsupported(name, 'History has an unproven key.');
88
+ const priorHash = keyHash(kernelKeyString(priorValue, name));
89
+ owners.set(prior.context.eventSourceId, priorHash);
90
+ claims.set(priorHash, {
91
+ source: prior.context.eventSourceId, sequence: prior.context.sequenceNumber.toString()
92
+ });
93
+ }
94
+ }
95
+ const ownerKey = owners.get(source);
96
+ if (ownerKey !== undefined && ownerKey !== key) {
97
+ throw this.unsupported(name, 'Replacing a unique key is not fixture-backed.');
98
+ }
99
+ const stagedOwner = stagedKeys.get(`${name}\u0000${source}`);
100
+ if (stagedOwner !== undefined && stagedOwner !== key) {
101
+ throw this.unsupported(name, 'Replacing a key within one batch is not fixture-backed.');
102
+ }
103
+ const existing = claims.get(key);
104
+ const batchOwner = stagedKeys.get(`${name}\u0001${key}`);
105
+ if (existing && existing.source !== source || batchOwner && batchOwner !== source) {
106
+ const details = { PropertyName: property, PropertyValue: raw };
107
+ violations.push({ EventTypeId: type, SequenceNumber: BigInt(existing?.sequence ?? unavailable), ConstraintType: 1,
108
+ ConstraintName: name,
109
+ Message: `Event '${type}' on member '${property}' violated a unique constraint on sequence number ${existing?.sequence ?? unavailable}`,
110
+ Details: details });
111
+ }
112
+ else {
113
+ stagedKeys.set(`${name}\u0000${source}`, key);
114
+ stagedKeys.set(`${name}\u0001${key}`, source);
115
+ }
116
+ }
117
+ const uniqueType = definition.uniqueEventType;
118
+ if (uniqueType && (uniqueType.eventTypeIds ?? [uniqueType.eventTypeId]).includes(type)) {
119
+ const first = history.find(prior => prior.context.eventSourceId === source &&
120
+ (uniqueType.eventTypeIds ?? [uniqueType.eventTypeId]).includes(prior.eventType.id.value));
121
+ const staged = stagedTypes.has(`${name}\u0000${source}`);
122
+ if (first || staged) {
123
+ violations.push({ EventTypeId: type, SequenceNumber: first?.context.sequenceNumber ?? BigInt(unavailable), ConstraintType: 2,
124
+ ConstraintName: name,
125
+ Message: `Event '${type}' violated a unique event type constraint on sequence number ${first?.context.sequenceNumber.toString() ?? unavailable}`,
126
+ Details: {} });
127
+ }
128
+ else
129
+ stagedTypes.add(`${name}\u0000${source}`);
130
+ }
131
+ }
132
+ }
133
+ return violations;
134
+ }
135
+ resolveMessage(violation) {
136
+ return resolveConstraintMessage(this._definitions, violation);
137
+ }
138
+ unsupported(name, reason) {
139
+ return new UnsupportedEventSequenceOperation('artifacts.constraints', name, reason);
140
+ }
141
+ }
142
+ //# sourceMappingURL=InProcessConstraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InProcessConstraints.js","sourceRoot":"","sources":["../../testing/InProcessConstraints.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ import { EventSequenceNumber } from '../eventSequences/EventSequenceNumber.js';
10
10
  import type { IEventSequence } from '../eventSequences/IEventSequence.js';
11
11
  import type { ITransactionalEventSequence } from '../eventSequences/ITransactionalEventSequence.js';
12
12
  import type { CompleteStreamResult } from '../eventSequences/CompleteStreamResult.js';
13
+ import { InProcessConstraints } from './InProcessConstraints.js';
13
14
  import type { EventScenarioOptions } from './EventScenarioOptions.js';
14
15
  import { UnsupportedEventSequenceOperation } from './UnsupportedEventSequenceOperation.js';
15
16
  /**
@@ -21,6 +22,7 @@ import { UnsupportedEventSequenceOperation } from './UnsupportedEventSequenceOpe
21
22
  export declare function observeUnsupportedOperations(sequence: object, observer: (error: UnsupportedEventSequenceOperation) => void): void;
22
23
  /** Fixture-backed, scenario-local append sequence; no kernel or observer scheduler is started. */
23
24
  export declare class InProcessEventSequence implements IEventSequence {
25
+ private readonly _constraints?;
24
26
  readonly id: EventSequenceId;
25
27
  private readonly _catalog;
26
28
  private readonly _history;
@@ -35,7 +37,7 @@ export declare class InProcessEventSequence implements IEventSequence {
35
37
  private _busy;
36
38
  private readonly _results;
37
39
  readonly appendOperations: AppendOperationsBroadcaster<AppendedEventWithResult[]>;
38
- constructor(options: EventScenarioOptions, eventTypes: Constructor[]);
40
+ constructor(options: EventScenarioOptions, eventTypes: Constructor[], _constraints?: InProcessConstraints | undefined);
39
41
  get results(): readonly AppendResult[];
40
42
  get appendedEvents(): readonly AppendedEvent[];
41
43
  /** Validate and stage all setup appends, then commit and notify in single-append order. */
@@ -60,6 +62,8 @@ export declare class InProcessEventSequence implements IEventSequence {
60
62
  private checkedDate;
61
63
  private validateSource;
62
64
  private checkedContent;
65
+ private validateConstraints;
66
+ private rejected;
63
67
  private success;
64
68
  private snapshot;
65
69
  private validateReadSource;
@@ -1 +1 @@
1
- {"version":3,"file":"InProcessEventSequence.d.ts","sourceRoot":"","sources":["../../testing/InProcessEventSequence.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"InProcessEventSequence.d.ts","sourceRoot":"","sources":["../../testing/InProcessEventSequence.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import { EventObservationState } from '@cratis/chronicle.contracts';
5
5
  import { AppendOperationsBroadcaster } from '../eventSequences/AppendOperationsBroadcaster.js';
6
6
  import { prepareBatchAppend } from '../eventSequences/prepareBatchAppend.js';
7
7
  import { createAppendNotification, mapAppendNotificationCausation } from '../eventSequences/createAppendNotification.js';
8
+ import { createAppendResult } from '../eventSequences/createAppendResult.js';
8
9
  import { Guid } from '@cratis/fundamentals';
9
10
  import { getEventTypeMetadata, getEventTypeFor } from '../events/eventTypeDecorator.js';
10
11
  import { getTagsFor } from '../events/tagDecorator.js';
@@ -17,7 +18,6 @@ import { EventSequenceId } from '../eventSequences/EventSequenceId.js';
17
18
  import { EventSequenceNumber } from '../eventSequences/EventSequenceNumber.js';
18
19
  import { prepareSingleAppend } from '../eventSequences/prepareSingleAppend.js';
19
20
  import { toContractsGuid } from '../connection/Guid.js';
20
- import { getUniqueEventMetadata, getUniquePropertyMetadata } from '../events/constraints/unique.js';
21
21
  import { getRemovedConstraintNames } from '../events/constraints/removeConstraint.js';
22
22
  import { UnsupportedEventSequenceOperation } from './UnsupportedEventSequenceOperation.js';
23
23
  // JS trim() omits U+0085, which the kernel trims. Reject unproven non-ASCII whitespace and controls.
@@ -35,6 +35,7 @@ export function observeUnsupportedOperations(sequence, observer) {
35
35
  }
36
36
  /** Fixture-backed, scenario-local append sequence; no kernel or observer scheduler is started. */
37
37
  export class InProcessEventSequence {
38
+ _constraints;
38
39
  id;
39
40
  _catalog = new Map();
40
41
  _history = [];
@@ -49,7 +50,8 @@ export class InProcessEventSequence {
49
50
  _busy = false;
50
51
  _results = [];
51
52
  appendOperations = new AppendOperationsBroadcaster();
52
- constructor(options, eventTypes) {
53
+ constructor(options, eventTypes, _constraints) {
54
+ this._constraints = _constraints;
53
55
  if (options.eventSequenceId && options.eventSequenceId.value !== EventSequenceId.eventLog.value) {
54
56
  throw this.unsupported('options.eventSequenceId', options.eventSequenceId.value, 'Custom sequences are not fixture-backed.');
55
57
  }
@@ -80,9 +82,8 @@ export class InProcessEventSequence {
80
82
  if (eventType.generation.value !== 1 || eventType.tombstone) {
81
83
  throw this.unsupported('artifacts.eventTypes', type.name, 'Only generation 1, non-tombstone events are proven.');
82
84
  }
83
- if (options.constraints !== 'disabled' && (getUniqueEventMetadata(type) || getRemovedConstraintNames(type).length ||
84
- [...metadata.members.keys()].some(key => getUniquePropertyMetadata(type, key)))) {
85
- throw this.unsupported('artifacts.eventTypes.constraints', type.name, 'Constraint metadata is not supported in this increment.');
85
+ if (options.constraints !== 'disabled' && getRemovedConstraintNames(type).length) {
86
+ throw this.unsupported('artifacts.eventTypes.constraints', type.name, 'Constraint removal is not fixture-backed.');
86
87
  }
87
88
  if (getTagsFor(type).length)
88
89
  throw this.unsupported('artifacts.eventTypes.tags', type.name, 'Tagged events are not fixture-backed.');
@@ -123,7 +124,7 @@ export class InProcessEventSequence {
123
124
  }
124
125
  const result = await pending;
125
126
  if (!result.isSuccess)
126
- throw new Error(`EventScenario given setup failed: ${JSON.stringify(result)}`);
127
+ throw new Error(`EventScenario given setup failed: ${JSON.stringify(result, (_, value) => typeof value === 'bigint' ? value.toString() : value)}`);
127
128
  }
128
129
  for (const [index, stored] of this._stagedSeeds.entries()) {
129
130
  this._history.push(stored);
@@ -162,9 +163,11 @@ export class InProcessEventSequence {
162
163
  let content;
163
164
  try {
164
165
  prepared = prepareSingleAppend(event, this._correlationId ? { correlationId: this._correlationId() } : undefined);
165
- content = JSON.parse(prepared.content);
166
+ content = this.checkedContent(event, prepared.content, 'append.content', 'Content differs from the flat scalar schema; null, missing and extra values are not proven.');
166
167
  }
167
168
  catch (error) {
169
+ if (error instanceof UnsupportedEventSequenceOperation)
170
+ throw error;
168
171
  throw this.unsupported('append.serialization', event.constructor.name, `Payload or metadata could not be serialized: ${String(error)}.`);
169
172
  }
170
173
  try {
@@ -179,13 +182,6 @@ export class InProcessEventSequence {
179
182
  Object.keys(prepared.causationChain[0].properties).length !== 0) {
180
183
  throw this.unsupported('append.context', event.constructor.name, 'Ambient identity or causation metadata is not fixture-backed.');
181
184
  }
182
- const properties = metadata.schema.properties;
183
- if (!content || typeof content !== 'object' || Array.isArray(content) ||
184
- Object.keys(content).length !== Object.keys(properties).length ||
185
- Object.entries(properties).some(([key, property]) => typeof content[key] !== property.type ||
186
- (property.type === 'string' && !/^[\x20-\x21\x23-\x5b\x5d-\x7e\u00e9]*$/.test(content[key])))) {
187
- throw this.unsupported('append.content', event.constructor.name, 'Content differs from the flat scalar schema; null, missing and extra values are not proven.');
188
- }
189
185
  const occurred = this._clock();
190
186
  // Date has millisecond precision; only the UTC year range representable by DateTimeOffset is supported.
191
187
  if (!(occurred instanceof Date) || Number.isNaN(occurred.getTime()) ||
@@ -208,11 +204,14 @@ export class InProcessEventSequence {
208
204
  tags: prepared.tags.map(tag => new Tag(tag))
209
205
  }
210
206
  };
211
- if (this._stagedSeeds)
212
- this._stagedSeeds.push(this.snapshot(stored));
213
- else
214
- this._history.push(this.snapshot(stored));
215
- const result = this.success(sequenceNumber, event.constructor.name);
207
+ const violations = this.validateConstraints([...this._history, ...(this._stagedSeeds ?? [])], [stored]);
208
+ const result = violations.length ? this.rejected(violations) : this.success(sequenceNumber, event.constructor.name);
209
+ if (result.isSuccess) {
210
+ if (this._stagedSeeds)
211
+ this._stagedSeeds.push(this.snapshot(stored));
212
+ else
213
+ this._history.push(this.snapshot(stored));
214
+ }
216
215
  if (!this._setup)
217
216
  this._results.push(result);
218
217
  if (this._stagedNotifications || this.appendOperations.hasSubscribers) {
@@ -315,14 +314,16 @@ export class InProcessEventSequence {
315
314
  } };
316
315
  return { stored, result: this.success(sequenceNumber, event.constructor.name) };
317
316
  });
318
- // Stage and validate every entry before committing any event or result.
319
- this._history.push(...staged.map(item => this.snapshot(item.stored)));
320
- const results = staged.map(item => item.result);
317
+ // The kernel validates the entire batch before persisting any events or allocating sequences.
318
+ const violations = this.validateConstraints(this._history, staged.map(item => item.stored));
319
+ const results = violations.length ? staged.map(() => this.rejected(violations)) : staged.map(item => item.result);
320
+ if (!violations.length)
321
+ this._history.push(...staged.map(item => this.snapshot(item.stored)));
321
322
  this._results.push(...results);
322
323
  if (this.appendOperations.hasSubscribers) {
323
324
  const occurredAt = new Date();
324
325
  const causationEntries = mapAppendNotificationCausation(batchCausationChain);
325
- this.appendOperations.publish(staged.map(({ result }, index) => createAppendNotification(eventsForEventSourceIds[index].eventSourceId, eventsForEventSourceIds[index].event, result, correlationId.toString(), causationEntries, eventsToAppend[index].Tags, occurredAt)));
326
+ this.appendOperations.publish(staged.map((_, index) => createAppendNotification(eventsForEventSourceIds[index].eventSourceId, eventsForEventSourceIds[index].event, results[index], correlationId.toString(), causationEntries, eventsToAppend[index].Tags, occurredAt)));
326
327
  }
327
328
  return results;
328
329
  }
@@ -427,7 +428,7 @@ export class InProcessEventSequence {
427
428
  throw this.unsupported(operation, String(source), 'Only simple source identifiers are fixture-backed.');
428
429
  }
429
430
  }
430
- checkedContent(event, serialized, operation) {
431
+ checkedContent(event, serialized, operation, mismatchReason = 'Content differs from the fixture-backed scalar schema.') {
431
432
  let content;
432
433
  try {
433
434
  content = JSON.parse(serialized);
@@ -435,15 +436,31 @@ export class InProcessEventSequence {
435
436
  catch {
436
437
  throw this.unsupported(operation, event.constructor.name, 'Content must be valid JSON.');
437
438
  }
438
- const properties = this._catalog.get(event.constructor).schema.properties;
439
+ const metadata = this._catalog.get(event.constructor);
440
+ const properties = metadata.schema.properties;
439
441
  if (!content || typeof content !== 'object' || Array.isArray(content) ||
440
442
  Object.keys(content).length !== Object.keys(properties).length ||
441
443
  Object.entries(properties).some(([key, property]) => typeof content[key] !== property.type ||
444
+ (this._constraints?.isConstrainedProperty(metadata.eventType.id.value, key) &&
445
+ (typeof Reflect.get(event, key) !== property.type || Reflect.get(event, key) !== content[key])) ||
442
446
  (property.type === 'string' && !/^[\x20-\x21\x23-\x5b\x5d-\x7e\u00e9]*$/.test(content[key])))) {
443
- throw this.unsupported(operation, event.constructor.name, 'Content differs from the fixture-backed scalar schema.');
447
+ throw this.unsupported(operation, event.constructor.name, mismatchReason);
444
448
  }
445
449
  return content;
446
450
  }
451
+ validateConstraints(history, incoming) {
452
+ try {
453
+ return this._constraints?.validate(history, incoming) ?? [];
454
+ }
455
+ catch (error) {
456
+ if (error instanceof UnsupportedEventSequenceOperation)
457
+ unsupportedObservers.get(this)?.(error);
458
+ throw error;
459
+ }
460
+ }
461
+ rejected(violations) {
462
+ return createAppendResult(18446744073709551615n, violations, [], undefined, violation => this._constraints.resolveMessage(violation), async () => ({ isSuccess: true, failedPartitions: [] }));
463
+ }
447
464
  success(sequenceNumber, artifact) {
448
465
  return Object.freeze({ sequenceNumber: Object.freeze(sequenceNumber), constraintViolations: Object.freeze([]),
449
466
  errors: Object.freeze([]), isSuccess: true,