@photon-grove/evt 0.0.0-stage → 0.1.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/LICENSE +176 -0
- package/README.md +122 -2
- package/dist/aggregate.d.ts +83 -0
- package/dist/aggregate.d.ts.map +1 -0
- package/dist/aggregate.js +92 -0
- package/dist/aggregate.js.map +1 -0
- package/dist/base64.d.ts +8 -0
- package/dist/base64.d.ts.map +1 -0
- package/dist/base64.js +67 -0
- package/dist/base64.js.map +1 -0
- package/dist/codec.d.ts +56 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +90 -0
- package/dist/codec.js.map +1 -0
- package/dist/commit-id.d.ts +3 -0
- package/dist/commit-id.d.ts.map +1 -0
- package/dist/commit-id.js +43 -0
- package/dist/commit-id.js.map +1 -0
- package/dist/dynamodb/head.d.ts +34 -0
- package/dist/dynamodb/head.d.ts.map +1 -0
- package/dist/dynamodb/head.js +62 -0
- package/dist/dynamodb/head.js.map +1 -0
- package/dist/dynamodb/index.d.ts +2 -0
- package/dist/dynamodb/index.d.ts.map +1 -0
- package/dist/dynamodb/index.js +4 -0
- package/dist/dynamodb/index.js.map +1 -0
- package/dist/dynamodb/item.d.ts +68 -0
- package/dist/dynamodb/item.d.ts.map +1 -0
- package/dist/dynamodb/item.js +263 -0
- package/dist/dynamodb/item.js.map +1 -0
- package/dist/envelope.d.ts +15 -0
- package/dist/envelope.d.ts.map +1 -0
- package/dist/envelope.js +59 -0
- package/dist/envelope.js.map +1 -0
- package/dist/errors.d.ts +111 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +139 -0
- package/dist/errors.js.map +1 -0
- package/dist/event.d.ts +47 -0
- package/dist/event.d.ts.map +1 -0
- package/dist/event.js +64 -0
- package/dist/event.js.map +1 -0
- package/dist/fields.d.ts +31 -0
- package/dist/fields.d.ts.map +1 -0
- package/dist/fields.js +105 -0
- package/dist/fields.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/json.d.ts +47 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/json.js +458 -0
- package/dist/json.js.map +1 -0
- package/dist/memory/index.d.ts +2 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +3 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/repository.d.ts +34 -0
- package/dist/memory/repository.d.ts.map +1 -0
- package/dist/memory/repository.js +219 -0
- package/dist/memory/repository.js.map +1 -0
- package/dist/metadata.d.ts +47 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +75 -0
- package/dist/metadata.js.map +1 -0
- package/dist/repository.d.ts +102 -0
- package/dist/repository.d.ts.map +1 -0
- package/dist/repository.js +131 -0
- package/dist/repository.js.map +1 -0
- package/dist/retry.d.ts +25 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +50 -0
- package/dist/retry.js.map +1 -0
- package/dist/snapshots.d.ts +21 -0
- package/dist/snapshots.d.ts.map +1 -0
- package/dist/snapshots.js +35 -0
- package/dist/snapshots.js.map +1 -0
- package/dist/store.d.ts +103 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +246 -0
- package/dist/store.js.map +1 -0
- package/dist/testing/equal.d.ts +22 -0
- package/dist/testing/equal.d.ts.map +1 -0
- package/dist/testing/equal.js +121 -0
- package/dist/testing/equal.js.map +1 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/scenario.d.ts +136 -0
- package/dist/testing/scenario.d.ts.map +1 -0
- package/dist/testing/scenario.js +307 -0
- package/dist/testing/scenario.js.map +1 -0
- package/dist/utf8.d.ts +17 -0
- package/dist/utf8.d.ts.map +1 -0
- package/dist/utf8.js +82 -0
- package/dist/utf8.js.map +1 -0
- package/package.json +56 -4
- package/src/aggregate.ts +196 -0
- package/src/base64.ts +80 -0
- package/src/codec.ts +139 -0
- package/src/commit-id.ts +50 -0
- package/src/dynamodb/head.ts +93 -0
- package/src/dynamodb/index.ts +21 -0
- package/src/dynamodb/item.ts +332 -0
- package/src/envelope.ts +67 -0
- package/src/errors.ts +214 -0
- package/src/event.ts +117 -0
- package/src/fields.ts +134 -0
- package/src/globals.d.ts +39 -0
- package/src/index.ts +75 -0
- package/src/json.ts +546 -0
- package/src/memory/index.ts +3 -0
- package/src/memory/repository.ts +313 -0
- package/src/metadata.ts +120 -0
- package/src/repository.ts +247 -0
- package/src/retry.ts +74 -0
- package/src/snapshots.ts +42 -0
- package/src/store.ts +377 -0
- package/src/testing/equal.ts +146 -0
- package/src/testing/index.ts +14 -0
- package/src/testing/scenario.ts +406 -0
- package/src/utf8.ts +92 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type SerializedEvent } from './event.js';
|
|
2
|
+
/** Encodes the envelope for an event, byte for byte as the Go publisher wrote it. */
|
|
3
|
+
export declare function encodeEnvelope(event: SerializedEvent, source: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* Decodes the event from an envelope body: an SNS message, or an SQS body delivered raw. An event
|
|
6
|
+
* with no entity ID or event ID is refused.
|
|
7
|
+
*/
|
|
8
|
+
export declare function decodeEnvelope(body: string): SerializedEvent;
|
|
9
|
+
/**
|
|
10
|
+
* The message attributes the publisher set, all strings: `entityType` and `eventType`, then
|
|
11
|
+
* `commandId` and `traceparent` when they aren't empty, and `correlationId`, the command ID or
|
|
12
|
+
* else the traceparent.
|
|
13
|
+
*/
|
|
14
|
+
export declare function messageAttributes(event: SerializedEvent): Record<string, string>;
|
|
15
|
+
//# sourceMappingURL=envelope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.d.ts","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAGA,OAAO,EAAC,KAAK,eAAe,EAA6B,MAAM,YAAY,CAAA;AAO3E,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAY7E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAW5D;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBhF"}
|
package/dist/envelope.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// The stream envelope: the EventBridge-style message around each committed event, which consumers
|
|
2
|
+
// in every language unwrap. Go decodes it with projectors.StreamRecordFromEnvelope.
|
|
3
|
+
import { eventFromJson, encodeEvent } from './event.js';
|
|
4
|
+
import { DOCUMENT, invalid, objectOrNull } from './fields.js';
|
|
5
|
+
import { RawJson, parseJson, stringifyJson } from './json.js';
|
|
6
|
+
// Go's zero time.Time, which the publisher left in the time field.
|
|
7
|
+
const ZERO_TIME = '0001-01-01T00:00:00Z';
|
|
8
|
+
/** Encodes the envelope for an event, byte for byte as the Go publisher wrote it. */
|
|
9
|
+
export function encodeEnvelope(event, source) {
|
|
10
|
+
return stringifyJson({
|
|
11
|
+
version: '',
|
|
12
|
+
id: event.id,
|
|
13
|
+
'detail-type': event.type,
|
|
14
|
+
source,
|
|
15
|
+
account: '',
|
|
16
|
+
time: ZERO_TIME,
|
|
17
|
+
region: '',
|
|
18
|
+
resources: null,
|
|
19
|
+
detail: new RawJson(encodeEvent(event)),
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Decodes the event from an envelope body: an SNS message, or an SQS body delivered raw. An event
|
|
24
|
+
* with no entity ID or event ID is refused.
|
|
25
|
+
*/
|
|
26
|
+
export function decodeEnvelope(body) {
|
|
27
|
+
const envelope = objectOrNull(parseJson(body, DOCUMENT), 'envelope') ?? new Map();
|
|
28
|
+
const event = eventFromJson(objectOrNull(envelope.get('detail'), 'envelope.detail'));
|
|
29
|
+
if (event.entityId === '') {
|
|
30
|
+
throw invalid('event envelope has no entity id');
|
|
31
|
+
}
|
|
32
|
+
if (event.id === '') {
|
|
33
|
+
throw invalid('event envelope has no event id');
|
|
34
|
+
}
|
|
35
|
+
return event;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The message attributes the publisher set, all strings: `entityType` and `eventType`, then
|
|
39
|
+
* `commandId` and `traceparent` when they aren't empty, and `correlationId`, the command ID or
|
|
40
|
+
* else the traceparent.
|
|
41
|
+
*/
|
|
42
|
+
export function messageAttributes(event) {
|
|
43
|
+
const attributes = {
|
|
44
|
+
entityType: event.entityType,
|
|
45
|
+
eventType: event.type,
|
|
46
|
+
};
|
|
47
|
+
const commandId = event.metadata.commandId;
|
|
48
|
+
if (commandId !== null && commandId !== '') {
|
|
49
|
+
attributes['commandId'] = commandId;
|
|
50
|
+
attributes['correlationId'] = commandId;
|
|
51
|
+
}
|
|
52
|
+
const traceparent = event.metadata.trace?.get('traceparent');
|
|
53
|
+
if (traceparent !== undefined && traceparent !== '') {
|
|
54
|
+
attributes['traceparent'] = traceparent;
|
|
55
|
+
attributes['correlationId'] ??= traceparent;
|
|
56
|
+
}
|
|
57
|
+
return attributes;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"envelope.js","sourceRoot":"","sources":["../src/envelope.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,oFAAoF;AAEpF,OAAO,EAAuB,aAAa,EAAE,WAAW,EAAC,MAAM,YAAY,CAAA;AAC3E,OAAO,EAAC,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAC,MAAM,aAAa,CAAA;AAC3D,OAAO,EAAC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAC,MAAM,WAAW,CAAA;AAE3D,mEAAmE;AACnE,MAAM,SAAS,GAAG,sBAAsB,CAAA;AAExC,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,KAAsB,EAAE,MAAc;IACnE,OAAO,aAAa,CAAC;QACnB,OAAO,EAAE,EAAE;QACX,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,aAAa,EAAE,KAAK,CAAC,IAAI;QACzB,MAAM;QACN,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,EAAE;QACV,SAAS,EAAE,IAAI;QACf,MAAM,EAAE,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;KACxC,CAAC,CAAA;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,UAAU,CAAC,IAAI,IAAI,GAAG,EAAE,CAAA;IACjF,MAAM,KAAK,GAAG,aAAa,CAAC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAA;IACpF,IAAI,KAAK,CAAC,QAAQ,KAAK,EAAE,EAAE,CAAC;QAC1B,MAAM,OAAO,CAAC,iCAAiC,CAAC,CAAA;IAClD,CAAC;IACD,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACpB,MAAM,OAAO,CAAC,gCAAgC,CAAC,CAAA;IACjD,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAsB;IACtD,MAAM,UAAU,GAA2B;QACzC,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,SAAS,EAAE,KAAK,CAAC,IAAI;KACtB,CAAA;IAED,MAAM,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAA;IAC1C,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,EAAE,EAAE,CAAC;QAC3C,UAAU,CAAC,WAAW,CAAC,GAAG,SAAS,CAAA;QACnC,UAAU,CAAC,eAAe,CAAC,GAAG,SAAS,CAAA;IACzC,CAAC;IAED,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,aAAa,CAAC,CAAA;IAC5D,IAAI,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,EAAE,EAAE,CAAC;QACpD,UAAU,CAAC,aAAa,CAAC,GAAG,WAAW,CAAA;QACvC,UAAU,CAAC,eAAe,CAAC,KAAK,WAAW,CAAA;IAC7C,CAAC;IAED,OAAO,UAAU,CAAA;AACnB,CAAC"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What went wrong:
|
|
3
|
+
*
|
|
4
|
+
* - `invalidJson`: text that isn't JSON.
|
|
5
|
+
* - `invalidRecord`: a stored record (an event, a snapshot, an item) with the wrong shape.
|
|
6
|
+
* - `invalidArgument`: a value evt can't write, such as a float that isn't finite or an object
|
|
7
|
+
* whose key order the engine has already changed, or a read with a bad argument, such as
|
|
8
|
+
* `latest(0)`.
|
|
9
|
+
* - `invalidCommit`: a commit built wrong, such as one with another entity's event. Nothing was
|
|
10
|
+
* written.
|
|
11
|
+
* - `conflict`: optimistic concurrency failed. Another writer committed since the stream was
|
|
12
|
+
* read. Reload and run the command again.
|
|
13
|
+
* - `sequenceGap`: a commit or a load skips a sequence. A conflict.
|
|
14
|
+
* - `streamHeadDrift`: a stream's head disagrees with its events or snapshot. Never retried.
|
|
15
|
+
* - `commitTooLarge`: the commit is over the transaction budget. Nothing was written.
|
|
16
|
+
* - `compactionUncovered`: no snapshot covers the events compaction was asked to delete.
|
|
17
|
+
* - `reservedEntityId`: a write to an entity ID in a namespace only the engine writes.
|
|
18
|
+
* - `replay`: a stored event failed to upcast or decode while an aggregate loaded.
|
|
19
|
+
* - `snapshot`: a stored snapshot failed to decode while an aggregate loaded.
|
|
20
|
+
*/
|
|
21
|
+
export type EvtErrorCode = 'invalidJson' | 'invalidRecord' | 'invalidArgument' | 'invalidCommit' | 'conflict' | 'sequenceGap' | 'streamHeadDrift' | 'commitTooLarge' | 'compactionUncovered' | 'reservedEntityId' | 'replay' | 'snapshot';
|
|
22
|
+
export declare class EvtError extends Error {
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly code: EvtErrorCode;
|
|
25
|
+
constructor(code: EvtErrorCode, message: string, options?: {
|
|
26
|
+
cause?: unknown;
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
/** Optimistic concurrency failed on a written stream: its sequence or snapshot moved. */
|
|
30
|
+
export declare class ConflictError extends EvtError {
|
|
31
|
+
readonly name = "ConflictError";
|
|
32
|
+
readonly code = "conflict";
|
|
33
|
+
readonly entityId: string;
|
|
34
|
+
constructor(entityId: string, detail: string);
|
|
35
|
+
}
|
|
36
|
+
/** A commit's first event skips past the stream's head, or a load found a hole. A conflict. */
|
|
37
|
+
export declare class SequenceGapError extends EvtError {
|
|
38
|
+
readonly name = "SequenceGapError";
|
|
39
|
+
readonly code = "sequenceGap";
|
|
40
|
+
readonly entityId: string;
|
|
41
|
+
/** The last sequence before the gap. */
|
|
42
|
+
readonly after: bigint;
|
|
43
|
+
/** The sequence found next, which isn't `after + 1`. */
|
|
44
|
+
readonly found: bigint;
|
|
45
|
+
constructor(entityId: string, after: bigint, found: bigint);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* A stream's head disagrees with its events or snapshot (ADR 0007): a writer appended without
|
|
49
|
+
* raising the head, events were deleted, a snapshot is ahead of the head, or a stream has data and
|
|
50
|
+
* no head. It isn't retryable: running the command again fails the same way. Repair is offline.
|
|
51
|
+
*/
|
|
52
|
+
export declare class StreamHeadDriftError extends EvtError {
|
|
53
|
+
readonly name = "StreamHeadDriftError";
|
|
54
|
+
readonly code = "streamHeadDrift";
|
|
55
|
+
readonly entityId: string;
|
|
56
|
+
/** The stored head, or null when the stream has no head. */
|
|
57
|
+
readonly stored: bigint | null;
|
|
58
|
+
/** The head its events and snapshot imply: the higher of the two. */
|
|
59
|
+
readonly derived: bigint;
|
|
60
|
+
constructor(entityId: string, stored: bigint | null, derived: bigint);
|
|
61
|
+
}
|
|
62
|
+
/** The commit is over the transaction budget: too many actions, bytes, or bytes in one item. */
|
|
63
|
+
export declare class CommitTooLargeError extends EvtError {
|
|
64
|
+
readonly name = "CommitTooLargeError";
|
|
65
|
+
readonly code = "commitTooLarge";
|
|
66
|
+
readonly actions: number;
|
|
67
|
+
readonly bytes: number;
|
|
68
|
+
readonly largestItem: number;
|
|
69
|
+
constructor(actions: number, bytes: number, largestItem: number);
|
|
70
|
+
}
|
|
71
|
+
/** Compaction was refused because no snapshot covers the events it would delete. */
|
|
72
|
+
export declare class CompactionUncoveredError extends EvtError {
|
|
73
|
+
readonly name = "CompactionUncoveredError";
|
|
74
|
+
readonly code = "compactionUncovered";
|
|
75
|
+
readonly entityId: string;
|
|
76
|
+
readonly through: bigint;
|
|
77
|
+
/** The event sequence the stored snapshot covers, or null with no snapshot. */
|
|
78
|
+
readonly covered: bigint | null;
|
|
79
|
+
constructor(entityId: string, through: bigint, covered: bigint | null);
|
|
80
|
+
}
|
|
81
|
+
/** A write to an entity ID in a reserved namespace (`SYSTEM#`, `command-outcome#`). */
|
|
82
|
+
export declare class ReservedEntityIdError extends EvtError {
|
|
83
|
+
readonly name = "ReservedEntityIdError";
|
|
84
|
+
readonly code = "reservedEntityId";
|
|
85
|
+
readonly entityId: string;
|
|
86
|
+
constructor(entityId: string);
|
|
87
|
+
}
|
|
88
|
+
/** A load failed closed on a stored event: an upcaster threw, or the payload didn't decode. */
|
|
89
|
+
export declare class ReplayError extends EvtError {
|
|
90
|
+
readonly name = "ReplayError";
|
|
91
|
+
readonly code = "replay";
|
|
92
|
+
readonly eventType: string;
|
|
93
|
+
/** The stored version, or the version an earlier upcaster produced. */
|
|
94
|
+
readonly version: number;
|
|
95
|
+
readonly phase: 'upcast' | 'decode';
|
|
96
|
+
constructor(eventType: string, version: number, phase: 'upcast' | 'decode', detail: string, cause?: unknown);
|
|
97
|
+
}
|
|
98
|
+
/** A load found a stored snapshot whose payload the aggregate's state codec doesn't decode. */
|
|
99
|
+
export declare class SnapshotError extends EvtError {
|
|
100
|
+
readonly name = "SnapshotError";
|
|
101
|
+
readonly code = "snapshot";
|
|
102
|
+
readonly entityId: string;
|
|
103
|
+
constructor(entityId: string, cause: unknown);
|
|
104
|
+
}
|
|
105
|
+
/** Whether an error is an optimistic-concurrency conflict: a `conflict` or a `sequenceGap`. */
|
|
106
|
+
export declare function isConflict(error: unknown): boolean;
|
|
107
|
+
/** Whether reloading and running the command again may succeed. So far, only after a conflict. */
|
|
108
|
+
export declare function isRetryable(error: unknown): boolean;
|
|
109
|
+
/** An error's message, or the value itself as text. */
|
|
110
|
+
export declare function messageOf(error: unknown): string;
|
|
111
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
// Every failure evt throws is an EvtError with a code, as the Rust crate returns its Error enum.
|
|
2
|
+
// Domain outcomes (a rejected command, a duplicate) are values, never errors. A failure with
|
|
3
|
+
// details has its own subclass, so `instanceof` narrows to its fields.
|
|
4
|
+
export class EvtError extends Error {
|
|
5
|
+
name = 'EvtError';
|
|
6
|
+
code;
|
|
7
|
+
constructor(code, message, options) {
|
|
8
|
+
super(message, options);
|
|
9
|
+
this.code = code;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** Optimistic concurrency failed on a written stream: its sequence or snapshot moved. */
|
|
13
|
+
export class ConflictError extends EvtError {
|
|
14
|
+
name = 'ConflictError';
|
|
15
|
+
code = 'conflict';
|
|
16
|
+
entityId;
|
|
17
|
+
constructor(entityId, detail) {
|
|
18
|
+
super('conflict', `conflict on entity ${entityId}: ${detail}`);
|
|
19
|
+
this.entityId = entityId;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** A commit's first event skips past the stream's head, or a load found a hole. A conflict. */
|
|
23
|
+
export class SequenceGapError extends EvtError {
|
|
24
|
+
name = 'SequenceGapError';
|
|
25
|
+
code = 'sequenceGap';
|
|
26
|
+
entityId;
|
|
27
|
+
/** The last sequence before the gap. */
|
|
28
|
+
after;
|
|
29
|
+
/** The sequence found next, which isn't `after + 1`. */
|
|
30
|
+
found;
|
|
31
|
+
constructor(entityId, after, found) {
|
|
32
|
+
super('sequenceGap', `conflict on entity ${entityId}: the stream skips from sequence ${after} to ${found}: it ` +
|
|
33
|
+
'was compacted during the load, or events expired');
|
|
34
|
+
this.entityId = entityId;
|
|
35
|
+
this.after = after;
|
|
36
|
+
this.found = found;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A stream's head disagrees with its events or snapshot (ADR 0007): a writer appended without
|
|
41
|
+
* raising the head, events were deleted, a snapshot is ahead of the head, or a stream has data and
|
|
42
|
+
* no head. It isn't retryable: running the command again fails the same way. Repair is offline.
|
|
43
|
+
*/
|
|
44
|
+
export class StreamHeadDriftError extends EvtError {
|
|
45
|
+
name = 'StreamHeadDriftError';
|
|
46
|
+
code = 'streamHeadDrift';
|
|
47
|
+
entityId;
|
|
48
|
+
/** The stored head, or null when the stream has no head. */
|
|
49
|
+
stored;
|
|
50
|
+
/** The head its events and snapshot imply: the higher of the two. */
|
|
51
|
+
derived;
|
|
52
|
+
constructor(entityId, stored, derived) {
|
|
53
|
+
super('streamHeadDrift', `stream head drift on entity ${entityId}: stored head ${stored ?? 'absent'}, ` +
|
|
54
|
+
`derived head ${derived}`);
|
|
55
|
+
this.entityId = entityId;
|
|
56
|
+
this.stored = stored;
|
|
57
|
+
this.derived = derived;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** The commit is over the transaction budget: too many actions, bytes, or bytes in one item. */
|
|
61
|
+
export class CommitTooLargeError extends EvtError {
|
|
62
|
+
name = 'CommitTooLargeError';
|
|
63
|
+
code = 'commitTooLarge';
|
|
64
|
+
actions;
|
|
65
|
+
bytes;
|
|
66
|
+
largestItem;
|
|
67
|
+
constructor(actions, bytes, largestItem) {
|
|
68
|
+
super('commitTooLarge', `commit exceeds transaction budget: ${actions} actions, ${bytes} bytes, ` +
|
|
69
|
+
`largest item ${largestItem}`);
|
|
70
|
+
this.actions = actions;
|
|
71
|
+
this.bytes = bytes;
|
|
72
|
+
this.largestItem = largestItem;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** Compaction was refused because no snapshot covers the events it would delete. */
|
|
76
|
+
export class CompactionUncoveredError extends EvtError {
|
|
77
|
+
name = 'CompactionUncoveredError';
|
|
78
|
+
code = 'compactionUncovered';
|
|
79
|
+
entityId;
|
|
80
|
+
through;
|
|
81
|
+
/** The event sequence the stored snapshot covers, or null with no snapshot. */
|
|
82
|
+
covered;
|
|
83
|
+
constructor(entityId, through, covered) {
|
|
84
|
+
super('compactionUncovered', 'compaction refused: no durable snapshot covers the requested range ' +
|
|
85
|
+
`(entity ${entityId}, through ${through}, snapshot covers ${covered ?? 'nothing'})`);
|
|
86
|
+
this.entityId = entityId;
|
|
87
|
+
this.through = through;
|
|
88
|
+
this.covered = covered;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/** A write to an entity ID in a reserved namespace (`SYSTEM#`, `command-outcome#`). */
|
|
92
|
+
export class ReservedEntityIdError extends EvtError {
|
|
93
|
+
name = 'ReservedEntityIdError';
|
|
94
|
+
code = 'reservedEntityId';
|
|
95
|
+
entityId;
|
|
96
|
+
constructor(entityId) {
|
|
97
|
+
super('reservedEntityId', `entity ID ${entityId} is in a reserved namespace (SYSTEM#, command-outcome#)`);
|
|
98
|
+
this.entityId = entityId;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
/** A load failed closed on a stored event: an upcaster threw, or the payload didn't decode. */
|
|
102
|
+
export class ReplayError extends EvtError {
|
|
103
|
+
name = 'ReplayError';
|
|
104
|
+
code = 'replay';
|
|
105
|
+
eventType;
|
|
106
|
+
/** The stored version, or the version an earlier upcaster produced. */
|
|
107
|
+
version;
|
|
108
|
+
phase;
|
|
109
|
+
constructor(eventType, version, phase, detail, cause) {
|
|
110
|
+
const doing = phase === 'upcast' ? 'upcasting' : 'decoding';
|
|
111
|
+
super('replay', `replay failed while ${doing} ${eventType} v${version}: ${detail}`, { cause });
|
|
112
|
+
this.eventType = eventType;
|
|
113
|
+
this.version = version;
|
|
114
|
+
this.phase = phase;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** A load found a stored snapshot whose payload the aggregate's state codec doesn't decode. */
|
|
118
|
+
export class SnapshotError extends EvtError {
|
|
119
|
+
name = 'SnapshotError';
|
|
120
|
+
code = 'snapshot';
|
|
121
|
+
entityId;
|
|
122
|
+
constructor(entityId, cause) {
|
|
123
|
+
super('snapshot', `decoding snapshot for entity ${entityId}: ${messageOf(cause)}`, { cause });
|
|
124
|
+
this.entityId = entityId;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
/** Whether an error is an optimistic-concurrency conflict: a `conflict` or a `sequenceGap`. */
|
|
128
|
+
export function isConflict(error) {
|
|
129
|
+
return error instanceof EvtError && (error.code === 'conflict' || error.code === 'sequenceGap');
|
|
130
|
+
}
|
|
131
|
+
/** Whether reloading and running the command again may succeed. So far, only after a conflict. */
|
|
132
|
+
export function isRetryable(error) {
|
|
133
|
+
return isConflict(error);
|
|
134
|
+
}
|
|
135
|
+
/** An error's message, or the value itself as text. */
|
|
136
|
+
export function messageOf(error) {
|
|
137
|
+
return error instanceof Error ? error.message : String(error);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/event.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { type JsonObject } from './fields.js';
|
|
2
|
+
import { type Metadata } from './metadata.js';
|
|
3
|
+
/** An event as it is stored. Its JSON is the `detail` of a stream envelope. */
|
|
4
|
+
export interface SerializedEvent {
|
|
5
|
+
/** `{entityId}:{sequence}`. */
|
|
6
|
+
id: string;
|
|
7
|
+
/** The 1-based position of the event in its stream. */
|
|
8
|
+
sequence: bigint;
|
|
9
|
+
/** The event kind, such as `account:opened`. */
|
|
10
|
+
type: string;
|
|
11
|
+
/** The payload's schema version. */
|
|
12
|
+
version: number;
|
|
13
|
+
/** The stream the event belongs to. */
|
|
14
|
+
entityId: string;
|
|
15
|
+
/** The aggregate type of the entity. */
|
|
16
|
+
entityType: string;
|
|
17
|
+
/**
|
|
18
|
+
* The payload bytes, stored verbatim. Null only when decoded from a JSON `null`, which is
|
|
19
|
+
* written back as `null`, as Go does.
|
|
20
|
+
*/
|
|
21
|
+
payload: Uint8Array | null;
|
|
22
|
+
metadata: Metadata;
|
|
23
|
+
}
|
|
24
|
+
/** A snapshot of aggregate state. A stream keeps at most one, its latest. */
|
|
25
|
+
export interface SerializedSnapshot {
|
|
26
|
+
entityType: string;
|
|
27
|
+
entityId: string;
|
|
28
|
+
/** 1 for an entity's first snapshot, then one more for each. */
|
|
29
|
+
sequence: bigint;
|
|
30
|
+
/** The last event sequence folded into the snapshot. */
|
|
31
|
+
eventSequence: bigint;
|
|
32
|
+
/** The state's bytes, stored verbatim. Null only when decoded from a JSON `null`. */
|
|
33
|
+
payload: Uint8Array | null;
|
|
34
|
+
}
|
|
35
|
+
/** The event ID for a sequence of a stream: `{entityId}:{sequence}`. */
|
|
36
|
+
export declare function eventId(entityId: string, sequence: bigint): string;
|
|
37
|
+
/** Encodes an event as the JSON Go writes for it. */
|
|
38
|
+
export declare function encodeEvent(event: SerializedEvent): string;
|
|
39
|
+
/** Decodes an event's JSON leniently, as Go does. */
|
|
40
|
+
export declare function decodeEvent(json: string): SerializedEvent;
|
|
41
|
+
/** Encodes a snapshot as the JSON Go writes for it. Its entity ID key is `entityID`. */
|
|
42
|
+
export declare function encodeSnapshot(snapshot: SerializedSnapshot): string;
|
|
43
|
+
/** Decodes a snapshot's JSON leniently, as Go does. */
|
|
44
|
+
export declare function decodeSnapshot(json: string): SerializedSnapshot;
|
|
45
|
+
export declare function eventJson(event: SerializedEvent): object;
|
|
46
|
+
export declare function eventFromJson(value: JsonObject | null): SerializedEvent;
|
|
47
|
+
//# sourceMappingURL=event.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.d.ts","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"AAGA,OAAO,EASL,KAAK,UAAU,EAChB,MAAM,aAAa,CAAA;AAEpB,OAAO,EAAC,KAAK,QAAQ,EAAiC,MAAM,eAAe,CAAA;AAE3E,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAA;IACV,uDAAuD;IACvD,QAAQ,EAAE,MAAM,CAAA;IAChB,gDAAgD;IAChD,IAAI,EAAE,MAAM,CAAA;IACZ,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,UAAU,EAAE,MAAM,CAAA;IAClB;;;OAGG;IACH,OAAO,EAAE,UAAU,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAED,6EAA6E;AAC7E,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,QAAQ,EAAE,MAAM,CAAA;IAChB,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAA;IACrB,qFAAqF;IACrF,OAAO,EAAE,UAAU,GAAG,IAAI,CAAA;CAC3B;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAElE;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAE1D;AAED,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAEzD;AAED,wFAAwF;AACxF,wBAAgB,cAAc,CAAC,QAAQ,EAAE,kBAAkB,GAAG,MAAM,CAQnE;AAED,uDAAuD;AACvD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,CAU/D;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAWxD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,eAAe,CAavE"}
|
package/dist/event.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Serialized events and snapshots: the stored form every repository reads and writes, and their
|
|
2
|
+
// JSON encodings, which match Go's evt.SerializedEvent and evt.SerializedSnapshot.
|
|
3
|
+
import { DOCUMENT, bytesField, int64Argument, int64Field, objectOrNull, safeIntegerArgument, safeIntegerField, stringField, } from './fields.js';
|
|
4
|
+
import { parseJson, stringifyJson } from './json.js';
|
|
5
|
+
import { metadataFromJson, metadataJson } from './metadata.js';
|
|
6
|
+
/** The event ID for a sequence of a stream: `{entityId}:{sequence}`. */
|
|
7
|
+
export function eventId(entityId, sequence) {
|
|
8
|
+
return `${entityId}:${sequence}`;
|
|
9
|
+
}
|
|
10
|
+
/** Encodes an event as the JSON Go writes for it. */
|
|
11
|
+
export function encodeEvent(event) {
|
|
12
|
+
return stringifyJson(eventJson(event));
|
|
13
|
+
}
|
|
14
|
+
/** Decodes an event's JSON leniently, as Go does. */
|
|
15
|
+
export function decodeEvent(json) {
|
|
16
|
+
return eventFromJson(objectOrNull(parseJson(json, DOCUMENT), 'event'));
|
|
17
|
+
}
|
|
18
|
+
/** Encodes a snapshot as the JSON Go writes for it. Its entity ID key is `entityID`. */
|
|
19
|
+
export function encodeSnapshot(snapshot) {
|
|
20
|
+
return stringifyJson({
|
|
21
|
+
entityType: snapshot.entityType,
|
|
22
|
+
entityID: snapshot.entityId,
|
|
23
|
+
sequence: int64Argument(snapshot.sequence, 'snapshot.sequence'),
|
|
24
|
+
eventSequence: int64Argument(snapshot.eventSequence, 'snapshot.eventSequence'),
|
|
25
|
+
payload: snapshot.payload,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** Decodes a snapshot's JSON leniently, as Go does. */
|
|
29
|
+
export function decodeSnapshot(json) {
|
|
30
|
+
const object = objectOrNull(parseJson(json, DOCUMENT), 'snapshot') ?? new Map();
|
|
31
|
+
return {
|
|
32
|
+
entityType: stringField(object, 'entityType', 'snapshot'),
|
|
33
|
+
entityId: stringField(object, 'entityID', 'snapshot'),
|
|
34
|
+
sequence: int64Field(object, 'sequence', 'snapshot'),
|
|
35
|
+
eventSequence: int64Field(object, 'eventSequence', 'snapshot'),
|
|
36
|
+
payload: bytesField(object, 'payload', 'snapshot'),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export function eventJson(event) {
|
|
40
|
+
return {
|
|
41
|
+
id: event.id,
|
|
42
|
+
sequence: int64Argument(event.sequence, 'event.sequence'),
|
|
43
|
+
type: event.type,
|
|
44
|
+
version: safeIntegerArgument(event.version, 'event.version'),
|
|
45
|
+
entityId: event.entityId,
|
|
46
|
+
entityType: event.entityType,
|
|
47
|
+
payload: event.payload,
|
|
48
|
+
metadata: metadataJson(event.metadata),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export function eventFromJson(value) {
|
|
52
|
+
const object = value ?? new Map();
|
|
53
|
+
return {
|
|
54
|
+
id: stringField(object, 'id', 'event'),
|
|
55
|
+
sequence: int64Field(object, 'sequence', 'event'),
|
|
56
|
+
type: stringField(object, 'type', 'event'),
|
|
57
|
+
version: safeIntegerField(object, 'version', 'event'),
|
|
58
|
+
entityId: stringField(object, 'entityId', 'event'),
|
|
59
|
+
entityType: stringField(object, 'entityType', 'event'),
|
|
60
|
+
payload: bytesField(object, 'payload', 'event'),
|
|
61
|
+
metadata: metadataFromJson(object.get('metadata')),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=event.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event.js","sourceRoot":"","sources":["../src/event.ts"],"names":[],"mappings":"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"}
|
package/dist/fields.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { EvtError } from './errors.js';
|
|
2
|
+
import { type JsonValue, type ParseOptions } from './json.js';
|
|
3
|
+
export type JsonObject = Map<string, JsonValue>;
|
|
4
|
+
/** How evt parses its own documents: a repeated key is refused. */
|
|
5
|
+
export declare const DOCUMENT: ParseOptions;
|
|
6
|
+
export declare function invalid(message: string): EvtError;
|
|
7
|
+
/** An object, or null for JSON null. */
|
|
8
|
+
export declare function objectOrNull(value: JsonValue | undefined, what: string): JsonObject | null;
|
|
9
|
+
/** A string field, `""` when missing or null. */
|
|
10
|
+
export declare function stringField(object: JsonObject, name: string, what: string): string;
|
|
11
|
+
/** A string field that may be null (a Go `*string`). */
|
|
12
|
+
export declare function nullableString(object: JsonObject, name: string, what: string): string | null;
|
|
13
|
+
/** An int64 field, `0n` when missing or null. `1.0`, `1e3` and `"1"` are refused, as in Go. */
|
|
14
|
+
export declare function int64Field(object: JsonObject, name: string, what: string): bigint;
|
|
15
|
+
/** A small integer field, `0` when missing or null, refused if it isn't a safe integer. */
|
|
16
|
+
export declare function safeIntegerField(object: JsonObject, name: string, what: string): number;
|
|
17
|
+
/** Reads a JSON number as an int64. */
|
|
18
|
+
export declare function int64(value: JsonValue, what: string): bigint;
|
|
19
|
+
/** Refuses an integer outside int64. */
|
|
20
|
+
export declare function checkInt64(value: bigint, what: string): bigint;
|
|
21
|
+
/** Refuses to write an integer that no reader would read back as an int64. */
|
|
22
|
+
export declare function int64Argument(value: bigint, what: string): bigint;
|
|
23
|
+
/** Refuses to write a small integer that isn't a safe integer, such as 1.5 or NaN. */
|
|
24
|
+
export declare function safeIntegerArgument(value: number, what: string): number;
|
|
25
|
+
/** A base64 field (a Go `[]byte`), null when missing or null. */
|
|
26
|
+
export declare function bytesField(object: JsonObject, name: string, what: string): Uint8Array | null;
|
|
27
|
+
/**
|
|
28
|
+
* A Go `map[string]string`: null for a missing or null map, and `""` for a null value.
|
|
29
|
+
*/
|
|
30
|
+
export declare function stringMap(value: JsonValue | undefined, what: string): Map<string, string> | null;
|
|
31
|
+
//# sourceMappingURL=fields.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.d.ts","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"AAKA,OAAO,EAAC,QAAQ,EAAC,MAAM,aAAa,CAAA;AACpC,OAAO,EAAa,KAAK,SAAS,EAAE,KAAK,YAAY,EAAC,MAAM,WAAW,CAAA;AAEvE,MAAM,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;AAM/C,mEAAmE;AACnE,eAAO,MAAM,QAAQ,EAAE,YAAwC,CAAA;AAE/D,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAS1F;AAED,iDAAiD;AACjD,wBAAgB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAElF;AAED,wDAAwD;AACxD,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAU5F;AAED,+FAA+F;AAC/F,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOjF;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOvF;AAED,uCAAuC;AACvC,wBAAgB,KAAK,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wCAAwC;AACxC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAM9D;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjE;AAED,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvE;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAI5F;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAgBhG"}
|
package/dist/fields.js
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// Lenient decoding of engine documents by Go's rules: a missing field or null is the zero value,
|
|
2
|
+
// unknown fields are ignored, and a value of the wrong JSON type is an error. Field names match
|
|
3
|
+
// exactly, as in Rust (Go also matches them case-insensitively).
|
|
4
|
+
import { base64Decode } from './base64.js';
|
|
5
|
+
import { EvtError } from './errors.js';
|
|
6
|
+
import { JsonNumber } from './json.js';
|
|
7
|
+
const INT64_MIN = -(2n ** 63n);
|
|
8
|
+
const INT64_MAX = 2n ** 63n - 1n;
|
|
9
|
+
/** How evt parses its own documents: a repeated key is refused. */
|
|
10
|
+
export const DOCUMENT = { duplicateKeys: 'refuse' };
|
|
11
|
+
export function invalid(message) {
|
|
12
|
+
return new EvtError('invalidRecord', message);
|
|
13
|
+
}
|
|
14
|
+
/** An object, or null for JSON null. */
|
|
15
|
+
export function objectOrNull(value, what) {
|
|
16
|
+
if (value === undefined || value === null) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
if (!(value instanceof Map)) {
|
|
20
|
+
throw invalid(`${what} is not an object`);
|
|
21
|
+
}
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
/** A string field, `""` when missing or null. */
|
|
25
|
+
export function stringField(object, name, what) {
|
|
26
|
+
return nullableString(object, name, what) ?? '';
|
|
27
|
+
}
|
|
28
|
+
/** A string field that may be null (a Go `*string`). */
|
|
29
|
+
export function nullableString(object, name, what) {
|
|
30
|
+
const value = object.get(name);
|
|
31
|
+
if (value === undefined || value === null) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (typeof value !== 'string') {
|
|
35
|
+
throw invalid(`${what}.${name} is not a string`);
|
|
36
|
+
}
|
|
37
|
+
return value;
|
|
38
|
+
}
|
|
39
|
+
/** An int64 field, `0n` when missing or null. `1.0`, `1e3` and `"1"` are refused, as in Go. */
|
|
40
|
+
export function int64Field(object, name, what) {
|
|
41
|
+
const value = object.get(name);
|
|
42
|
+
if (value === undefined || value === null) {
|
|
43
|
+
return 0n;
|
|
44
|
+
}
|
|
45
|
+
return int64(value, `${what}.${name}`);
|
|
46
|
+
}
|
|
47
|
+
/** A small integer field, `0` when missing or null, refused if it isn't a safe integer. */
|
|
48
|
+
export function safeIntegerField(object, name, what) {
|
|
49
|
+
const value = int64Field(object, name, what);
|
|
50
|
+
if (value < BigInt(Number.MIN_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
51
|
+
throw invalid(`${what}.${name} is ${value}, past the integers this field holds`);
|
|
52
|
+
}
|
|
53
|
+
return Number(value);
|
|
54
|
+
}
|
|
55
|
+
/** Reads a JSON number as an int64. */
|
|
56
|
+
export function int64(value, what) {
|
|
57
|
+
if (!(value instanceof JsonNumber) || !value.isInteger) {
|
|
58
|
+
throw invalid(`${what} is not an integer`);
|
|
59
|
+
}
|
|
60
|
+
return checkInt64(BigInt(value.text), what);
|
|
61
|
+
}
|
|
62
|
+
/** Refuses an integer outside int64. */
|
|
63
|
+
export function checkInt64(value, what) {
|
|
64
|
+
if (value < INT64_MIN || value > INT64_MAX) {
|
|
65
|
+
throw invalid(`${what} is ${value}, outside int64`);
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
/** Refuses to write an integer that no reader would read back as an int64. */
|
|
70
|
+
export function int64Argument(value, what) {
|
|
71
|
+
if (value < INT64_MIN || value > INT64_MAX) {
|
|
72
|
+
throw new EvtError('invalidArgument', `${what} is ${value}, outside int64`);
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
76
|
+
/** Refuses to write a small integer that isn't a safe integer, such as 1.5 or NaN. */
|
|
77
|
+
export function safeIntegerArgument(value, what) {
|
|
78
|
+
if (!Number.isSafeInteger(value)) {
|
|
79
|
+
throw new EvtError('invalidArgument', `${what} is ${value}, not a safe integer`);
|
|
80
|
+
}
|
|
81
|
+
return value;
|
|
82
|
+
}
|
|
83
|
+
/** A base64 field (a Go `[]byte`), null when missing or null. */
|
|
84
|
+
export function bytesField(object, name, what) {
|
|
85
|
+
const text = nullableString(object, name, what);
|
|
86
|
+
return text === null ? null : base64Decode(text);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* A Go `map[string]string`: null for a missing or null map, and `""` for a null value.
|
|
90
|
+
*/
|
|
91
|
+
export function stringMap(value, what) {
|
|
92
|
+
const object = objectOrNull(value, what);
|
|
93
|
+
if (object === null) {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const map = new Map();
|
|
97
|
+
for (const [key, entry] of object) {
|
|
98
|
+
if (entry !== null && typeof entry !== 'string') {
|
|
99
|
+
throw invalid(`${what}.${key} is not a string`);
|
|
100
|
+
}
|
|
101
|
+
map.set(key, entry ?? '');
|
|
102
|
+
}
|
|
103
|
+
return map;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields.js","sourceRoot":"","sources":["../src/fields.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { type Aggregate, type AggregateDefinition, type Decision, type EventDefinition, type EventDefinitions, type EventOf, type Rejection, type Upcaster, defineAggregate, defineEvents, jsonUpcaster, } from './aggregate.js';
|
|
2
|
+
export { base64Decode, base64Encode } from './base64.js';
|
|
3
|
+
export { type Codec, type JsonOptions, type StandardResult, type StandardSchemaV1, json, } from './codec.js';
|
|
4
|
+
export { encodeEnvelope, decodeEnvelope, messageAttributes } from './envelope.js';
|
|
5
|
+
export { CommitTooLargeError, CompactionUncoveredError, ConflictError, EvtError, type EvtErrorCode, ReplayError, ReservedEntityIdError, SequenceGapError, SnapshotError, StreamHeadDriftError, isConflict, isRetryable, } from './errors.js';
|
|
6
|
+
export { type SerializedEvent, type SerializedSnapshot, decodeEvent, decodeSnapshot, encodeEvent, encodeSnapshot, eventId, } from './event.js';
|
|
7
|
+
export { JsonNumber, type JsonValue, parseJson, stringifyJson } from './json.js';
|
|
8
|
+
export { type Metadata, type Origin, decodeMetadata, effectiveCausationId, emptyMetadata, encodeMetadata, } from './metadata.js';
|
|
9
|
+
export type { CallOptions, Commit, NewSnapshot, Repository } from './repository.js';
|
|
10
|
+
export { DEFAULT_RETRY_POLICY, type RetryPolicy, retryDelay, } from './retry.js';
|
|
11
|
+
export { MAX_COMMIT_ITEM_BYTES, snapshotCommitSize, snapshotEventsDue } from './snapshots.js';
|
|
12
|
+
export { compareUtf8, utf8Length } from './utf8.js';
|
|
13
|
+
export { DEFAULT_SNAPSHOT_INTERVAL, type ExecuteOptions, type ExecuteResult, type Loaded, type RetryOptions, Store, type StoreOptions, } from './store.js';
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|