@cosmicdrift/kumiko-types 0.163.2 → 0.164.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.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cosmicdrift/kumiko-types",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.164.0",
|
|
4
4
|
"description": "Framework-Type-Definitions für Kumiko — FeatureDefinition, BootCheck-Types und die reinen Engine-Types, ohne Runtime-Code. Erlaubt Downstream-Konsumenten, gegen die Type-Contracts zu bauen, ohne das ganze Framework-Package zu importieren.",
|
|
5
5
|
"license": "BUSL-1.1",
|
|
6
6
|
"author": "Marc Frost <marc@cosmicdriftgamestudio.com>",
|
|
@@ -15,6 +15,25 @@ export class VersionConflictError extends Error {
|
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
// Thrown when append() collides on the partial unique index over
|
|
19
|
+
// metadata.idempotencyKey (tenant-scoped). Distinct from VersionConflictError:
|
|
20
|
+
// a version conflict means two writers raced the same predecessor; this
|
|
21
|
+
// means the same idempotency key was used twice, which is a caller-side
|
|
22
|
+
// retry that must have already appended once. Callers that set
|
|
23
|
+
// idempotencyKey should treat this as "already applied" rather than retry.
|
|
24
|
+
export class IdempotentAppendConflictError extends Error {
|
|
25
|
+
public readonly tenantId: string;
|
|
26
|
+
public readonly idempotencyKey: string;
|
|
27
|
+
constructor(tenantId: string, idempotencyKey: string) {
|
|
28
|
+
super(
|
|
29
|
+
`Idempotency conflict on tenant ${tenantId}: an event with idempotencyKey "${idempotencyKey}" was already appended.`,
|
|
30
|
+
);
|
|
31
|
+
this.name = "IdempotentAppendConflictError";
|
|
32
|
+
this.tenantId = tenantId;
|
|
33
|
+
this.idempotencyKey = idempotencyKey;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
18
37
|
// Thrown when ctx.appendEvent targets an archived stream. Archived aggregates
|
|
19
38
|
// are read-only — restoreStream() makes them writable again. The archive
|
|
20
39
|
// state is not carried on the events themselves; it lives on the sparse
|
package/src/event-store-types.ts
CHANGED
|
@@ -12,6 +12,14 @@ export type EventMetadata = {
|
|
|
12
12
|
// set to event.id when an MSP-apply runs ctx.appendEvent. Together with
|
|
13
13
|
// correlationId forms a causation DAG across aggregate streams.
|
|
14
14
|
readonly causationId?: string;
|
|
15
|
+
// Opt-in second line of defense against duplicate appends when the
|
|
16
|
+
// Redis-backed HTTP idempotency guard (pipeline/idempotency.ts) misses a
|
|
17
|
+
// retry window (Redis unreachable, TTL race). Callers that want a hard
|
|
18
|
+
// per-event uniqueness guarantee set a stable key derived from the
|
|
19
|
+
// triggering request; the event-store enforces it via a tenant-scoped
|
|
20
|
+
// partial unique index and throws IdempotentAppendConflictError on a
|
|
21
|
+
// repeat. Unset by default — no uniqueness constraint applies.
|
|
22
|
+
readonly idempotencyKey?: string;
|
|
15
23
|
// Marten-conform free key/value space for app-specific metadata that
|
|
16
24
|
// doesn't deserve its own EventMetadata field. Examples: A/B-test bucket,
|
|
17
25
|
// feature-flag snapshot, geo-region, client SDK version. Persisted into
|