@photon-grove/evt 0.1.1 → 0.2.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 (86) hide show
  1. package/README.md +51 -4
  2. package/dist/aggregate.d.ts +26 -0
  3. package/dist/aggregate.d.ts.map +1 -1
  4. package/dist/aggregate.js.map +1 -1
  5. package/dist/dynamodb/head.d.ts +6 -0
  6. package/dist/dynamodb/head.d.ts.map +1 -1
  7. package/dist/dynamodb/head.js +11 -0
  8. package/dist/dynamodb/head.js.map +1 -1
  9. package/dist/dynamodb/index.d.ts +2 -1
  10. package/dist/dynamodb/index.d.ts.map +1 -1
  11. package/dist/dynamodb/index.js +2 -1
  12. package/dist/dynamodb/index.js.map +1 -1
  13. package/dist/dynamodb/repository.d.ts +9 -2
  14. package/dist/dynamodb/repository.d.ts.map +1 -1
  15. package/dist/dynamodb/repository.js +123 -27
  16. package/dist/dynamodb/repository.js.map +1 -1
  17. package/dist/dynamodb/requests.d.ts +37 -3
  18. package/dist/dynamodb/requests.d.ts.map +1 -1
  19. package/dist/dynamodb/requests.js +67 -9
  20. package/dist/dynamodb/requests.js.map +1 -1
  21. package/dist/dynamodb/views.d.ts +18 -0
  22. package/dist/dynamodb/views.d.ts.map +1 -0
  23. package/dist/dynamodb/views.js +56 -0
  24. package/dist/dynamodb/views.js.map +1 -0
  25. package/dist/errors.d.ts +51 -4
  26. package/dist/errors.d.ts.map +1 -1
  27. package/dist/errors.js +60 -4
  28. package/dist/errors.js.map +1 -1
  29. package/dist/index.d.ts +4 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +3 -1
  32. package/dist/index.js.map +1 -1
  33. package/dist/memory/repository.d.ts +3 -2
  34. package/dist/memory/repository.d.ts.map +1 -1
  35. package/dist/memory/repository.js +78 -29
  36. package/dist/memory/repository.js.map +1 -1
  37. package/dist/postgres/client.d.ts +32 -0
  38. package/dist/postgres/client.d.ts.map +1 -0
  39. package/dist/postgres/client.js +4 -0
  40. package/dist/postgres/client.js.map +1 -0
  41. package/dist/postgres/index.d.ts +4 -0
  42. package/dist/postgres/index.d.ts.map +1 -0
  43. package/dist/postgres/index.js +6 -0
  44. package/dist/postgres/index.js.map +1 -0
  45. package/dist/postgres/repository.d.ts +62 -0
  46. package/dist/postgres/repository.d.ts.map +1 -0
  47. package/dist/postgres/repository.js +598 -0
  48. package/dist/postgres/repository.js.map +1 -0
  49. package/dist/postgres/schema.d.ts +81 -0
  50. package/dist/postgres/schema.d.ts.map +1 -0
  51. package/dist/postgres/schema.js +249 -0
  52. package/dist/postgres/schema.js.map +1 -0
  53. package/dist/repository.d.ts +101 -6
  54. package/dist/repository.d.ts.map +1 -1
  55. package/dist/repository.js +108 -6
  56. package/dist/repository.js.map +1 -1
  57. package/dist/staging.d.ts +28 -0
  58. package/dist/staging.d.ts.map +1 -0
  59. package/dist/staging.js +89 -0
  60. package/dist/staging.js.map +1 -0
  61. package/dist/store.d.ts +15 -3
  62. package/dist/store.d.ts.map +1 -1
  63. package/dist/store.js +38 -54
  64. package/dist/store.js.map +1 -1
  65. package/dist/transaction.d.ts +113 -0
  66. package/dist/transaction.d.ts.map +1 -0
  67. package/dist/transaction.js +207 -0
  68. package/dist/transaction.js.map +1 -0
  69. package/package.json +5 -1
  70. package/src/aggregate.ts +28 -0
  71. package/src/dynamodb/head.ts +15 -0
  72. package/src/dynamodb/index.ts +2 -0
  73. package/src/dynamodb/repository.ts +177 -33
  74. package/src/dynamodb/requests.ts +114 -10
  75. package/src/dynamodb/views.ts +67 -0
  76. package/src/errors.ts +86 -4
  77. package/src/index.ts +19 -6
  78. package/src/memory/repository.ts +93 -32
  79. package/src/postgres/client.ts +37 -0
  80. package/src/postgres/index.ts +23 -0
  81. package/src/postgres/repository.ts +858 -0
  82. package/src/postgres/schema.ts +302 -0
  83. package/src/repository.ts +220 -8
  84. package/src/staging.ts +138 -0
  85. package/src/store.ts +66 -65
  86. package/src/transaction.ts +322 -0
@@ -0,0 +1,81 @@
1
+ /** The default events table. */
2
+ export declare const DEFAULT_EVENTS_TABLE = "evt_events";
3
+ /** The default snapshots table. */
4
+ export declare const DEFAULT_SNAPSHOTS_TABLE = "evt_snapshots";
5
+ /**
6
+ * The infix the engine relations derive from the events table name with, such as
7
+ * `evt_events__evt_features`. A configured table name may not contain it, in any case, so one
8
+ * log's tables can never equal another log's derived relation.
9
+ */
10
+ export declare const RESERVED_INFIX = "__evt_";
11
+ /**
12
+ * The longest events table name, in bytes. Its longest derived relation,
13
+ * `{events}__evt_rebuild_generation_pkey`, then fills PostgreSQL's 63-byte identifier limit.
14
+ */
15
+ export declare const MAX_EVENTS_TABLE_NAME_BYTES: number;
16
+ /** The longest snapshots table name, in bytes, which leaves room for its `_pkey` index. */
17
+ export declare const MAX_SNAPSHOTS_TABLE_NAME_BYTES: number;
18
+ declare const validated: unique symbol;
19
+ /**
20
+ * An event log's two configured tables, validated and folded to lower case. Only
21
+ * {@link pgTables} makes one.
22
+ */
23
+ export interface PgTables {
24
+ readonly events: string;
25
+ readonly snapshots: string;
26
+ readonly [validated]: true;
27
+ }
28
+ /**
29
+ * Validates an event log's table names and folds them to lower case, as PostgreSQL folds unquoted
30
+ * identifiers. Each must be a plain identifier that isn't a reserved keyword, within its length
31
+ * limit, without the {@link RESERVED_INFIX}, and no two relations the schema creates may share a
32
+ * name. A name that breaks a rule fails with `invalidArgument`, as Go and Rust refuse it at
33
+ * construction.
34
+ */
35
+ export declare function pgTables(events?: string, snapshots?: string): PgTables;
36
+ /** The command-outcomes table: `evt_events` yields `evt_events__evt_command_outcomes`. */
37
+ export declare function outcomesTable(tables: PgTables): string;
38
+ /** The feature-marker table: `evt_events` yields `evt_events__evt_features`. */
39
+ export declare function featuresTable(tables: PgTables): string;
40
+ /** The rebuild-lock table: `evt_events` yields `evt_events__evt_rebuild_lock`. */
41
+ export declare function rebuildLockTable(tables: PgTables): string;
42
+ /** The rebuild-generation table: `evt_events` yields `evt_events__evt_rebuild_generation`. */
43
+ export declare function rebuildGenerationTable(tables: PgTables): string;
44
+ /** The stream-heads table: `evt_events` yields `evt_events__evt_stream_heads`. */
45
+ export declare function streamHeadsTable(tables: PgTables): string;
46
+ /** The entity-type index of the events table: `evt_events__evt_entity_type_idx`. */
47
+ export declare function entityTypeIndex(tables: PgTables): string;
48
+ /**
49
+ * The idempotent DDL of an event log, byte for byte the DDL Go's `EnsureSchema` and Rust's
50
+ * `ensure_schema` run: the events and snapshots tables, the entity-type index (dropping its
51
+ * pre-v0.9 name), and the command-outcome, feature-marker, rebuild-fence and stream-heads tables.
52
+ * Run it inside one transaction, after {@link SCHEMA_LOCK} with the events table name, as Go and
53
+ * Rust do.
54
+ */
55
+ export declare function schemaDdl(tables: PgTables): string;
56
+ /**
57
+ * Serializes schema changes across processes, in every language: `IF NOT EXISTS` alone can still
58
+ * race in PostgreSQL's catalogs. `$1` is the events table name.
59
+ */
60
+ export declare const SCHEMA_LOCK = "SELECT pg_advisory_xact_lock(1702261762, hashtext($1))";
61
+ /**
62
+ * The per-entity transaction lock every commit and snapshot write takes, `$1` being the entity
63
+ * ID. Go and Rust run this exact statement, so writers in every language exclude each other.
64
+ */
65
+ export declare const ENTITY_LOCK = "SELECT pg_advisory_xact_lock(1702261760, hashtext($1))";
66
+ /**
67
+ * The shared engine-row lock a commit takes and holds to `COMMIT`, `$1` being a key from
68
+ * {@link featuresLockKey} or {@link rebuildLockKey}. Commits don't serialize against each other.
69
+ */
70
+ export declare const ENGINE_LOCK_SHARED = "SELECT pg_advisory_xact_lock_shared(1702261761, hashtext($1))";
71
+ /**
72
+ * The exclusive engine-row lock a declaration or a rebuild lifecycle step takes for its short
73
+ * transaction, so it never slips between a commit's check and its `COMMIT`.
74
+ */
75
+ export declare const ENGINE_LOCK_EXCLUSIVE = "SELECT pg_advisory_xact_lock(1702261761, hashtext($1))";
76
+ /** The feature marker's engine-row lock key: `{events}:features`. */
77
+ export declare function featuresLockKey(tables: PgTables): string;
78
+ /** The rebuild fence's engine-row lock key: `{events}:rebuild`. */
79
+ export declare function rebuildLockKey(tables: PgTables): string;
80
+ export {};
81
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"AAMA,gCAAgC;AAChC,eAAO,MAAM,oBAAoB,eAAe,CAAA;AAEhD,mCAAmC;AACnC,eAAO,MAAM,uBAAuB,kBAAkB,CAAA;AAEtD;;;;GAIG;AACH,eAAO,MAAM,cAAc,WAAW,CAAA;AAEtC;;;GAGG;AACH,eAAO,MAAM,2BAA2B,QAA8C,CAAA;AAEtF,2FAA2F;AAC3F,eAAO,MAAM,8BAA8B,QAAsB,CAAA;AAGjE,OAAO,CAAC,MAAM,SAAS,EAAE,OAAO,MAAM,CAAA;AAEtC;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAC3B;AAkBD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CACtB,MAAM,GAAE,MAA6B,EACrC,SAAS,GAAE,MAAgC,GAC1C,QAAQ,CA0BV;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEtD;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEtD;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEzD;AAED,8FAA8F;AAC9F,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAE/D;AAED,kFAAkF;AAClF,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEzD;AAED,oFAAoF;AACpF,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CA6FlD;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,2DAA2D,CAAA;AAEnF;;;GAGG;AACH,eAAO,MAAM,WAAW,2DAA2D,CAAA;AAEnF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,kEAAkE,CAAA;AAEjG;;;GAGG;AACH,eAAO,MAAM,qBAAqB,2DAA2D,CAAA;AAE7F,qEAAqE;AACrE,wBAAgB,eAAe,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAExD;AAED,mEAAmE;AACnE,wBAAgB,cAAc,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,249 @@
1
+ // The PostgreSQL layout of an event log, independent of any driver (storage format, "PostgreSQL"):
2
+ // the table names a store is configured with, the engine relations derived from them, and the
3
+ // idempotent DDL that Go's EnsureSchema and Rust's ensure_schema run.
4
+ import { EvtError } from '../errors.js';
5
+ /** The default events table. */
6
+ export const DEFAULT_EVENTS_TABLE = 'evt_events';
7
+ /** The default snapshots table. */
8
+ export const DEFAULT_SNAPSHOTS_TABLE = 'evt_snapshots';
9
+ /**
10
+ * The infix the engine relations derive from the events table name with, such as
11
+ * `evt_events__evt_features`. A configured table name may not contain it, in any case, so one
12
+ * log's tables can never equal another log's derived relation.
13
+ */
14
+ export const RESERVED_INFIX = '__evt_';
15
+ /**
16
+ * The longest events table name, in bytes. Its longest derived relation,
17
+ * `{events}__evt_rebuild_generation_pkey`, then fills PostgreSQL's 63-byte identifier limit.
18
+ */
19
+ export const MAX_EVENTS_TABLE_NAME_BYTES = 63 - '__evt_rebuild_generation_pkey'.length;
20
+ /** The longest snapshots table name, in bytes, which leaves room for its `_pkey` index. */
21
+ export const MAX_SNAPSHOTS_TABLE_NAME_BYTES = 63 - '_pkey'.length;
22
+ const IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
23
+ // PostgreSQL's reserved keywords (pg_get_keywords() categories R and T), which can't be unquoted
24
+ // table names. The same list as Go's and Rust's.
25
+ const RESERVED_KEYWORDS = new Set(`all analyse analyze and any array as asc asymmetric authorization binary both case cast check
26
+ collate collation column concurrently constraint create cross current_catalog current_date
27
+ current_role current_schema current_time current_timestamp current_user default deferrable desc
28
+ distinct do else end except false fetch for foreign freeze from full grant group having ilike in
29
+ initially inner intersect into is isnull join lateral leading left like limit localtime
30
+ localtimestamp natural not notnull null offset on only or order outer overlaps placing primary
31
+ references returning right select session_user similar some symmetric system_user table
32
+ tablesample then to trailing true union unique user using variadic verbose when where window
33
+ with`.split(/\s+/));
34
+ /**
35
+ * Validates an event log's table names and folds them to lower case, as PostgreSQL folds unquoted
36
+ * identifiers. Each must be a plain identifier that isn't a reserved keyword, within its length
37
+ * limit, without the {@link RESERVED_INFIX}, and no two relations the schema creates may share a
38
+ * name. A name that breaks a rule fails with `invalidArgument`, as Go and Rust refuse it at
39
+ * construction.
40
+ */
41
+ export function pgTables(events = DEFAULT_EVENTS_TABLE, snapshots = DEFAULT_SNAPSHOTS_TABLE) {
42
+ for (const [name, limit] of [
43
+ [events, MAX_EVENTS_TABLE_NAME_BYTES],
44
+ [snapshots, MAX_SNAPSHOTS_TABLE_NAME_BYTES],
45
+ ]) {
46
+ if (!validIdentifier(name, limit)) {
47
+ throw invalidConfig(`invalid table name ${JSON.stringify(name)}`);
48
+ }
49
+ if (name.toLowerCase().includes(RESERVED_INFIX)) {
50
+ throw invalidConfig(`table name ${JSON.stringify(name)} must not contain the reserved infix ` +
51
+ JSON.stringify(RESERVED_INFIX));
52
+ }
53
+ }
54
+ const tables = { events: events.toLowerCase(), snapshots: snapshots.toLowerCase() };
55
+ const shared = sharedRelation(tables);
56
+ if (shared !== null) {
57
+ throw invalidConfig(`tables ${JSON.stringify(events)} and ${JSON.stringify(snapshots)} would both use the ` +
58
+ `name ${JSON.stringify(shared)}`);
59
+ }
60
+ return tables;
61
+ }
62
+ /** The command-outcomes table: `evt_events` yields `evt_events__evt_command_outcomes`. */
63
+ export function outcomesTable(tables) {
64
+ return derived(tables.events, 'command_outcomes');
65
+ }
66
+ /** The feature-marker table: `evt_events` yields `evt_events__evt_features`. */
67
+ export function featuresTable(tables) {
68
+ return derived(tables.events, 'features');
69
+ }
70
+ /** The rebuild-lock table: `evt_events` yields `evt_events__evt_rebuild_lock`. */
71
+ export function rebuildLockTable(tables) {
72
+ return derived(tables.events, 'rebuild_lock');
73
+ }
74
+ /** The rebuild-generation table: `evt_events` yields `evt_events__evt_rebuild_generation`. */
75
+ export function rebuildGenerationTable(tables) {
76
+ return derived(tables.events, 'rebuild_generation');
77
+ }
78
+ /** The stream-heads table: `evt_events` yields `evt_events__evt_stream_heads`. */
79
+ export function streamHeadsTable(tables) {
80
+ return derived(tables.events, 'stream_heads');
81
+ }
82
+ /** The entity-type index of the events table: `evt_events__evt_entity_type_idx`. */
83
+ export function entityTypeIndex(tables) {
84
+ return derived(tables.events, 'entity_type_idx');
85
+ }
86
+ /**
87
+ * The idempotent DDL of an event log, byte for byte the DDL Go's `EnsureSchema` and Rust's
88
+ * `ensure_schema` run: the events and snapshots tables, the entity-type index (dropping its
89
+ * pre-v0.9 name), and the command-outcome, feature-marker, rebuild-fence and stream-heads tables.
90
+ * Run it inside one transaction, after {@link SCHEMA_LOCK} with the events table name, as Go and
91
+ * Rust do.
92
+ */
93
+ export function schemaDdl(tables) {
94
+ const { events, snapshots } = tables;
95
+ return `
96
+ CREATE TABLE IF NOT EXISTS ${events} (
97
+ entity_id text NOT NULL,
98
+ sequence bigint NOT NULL,
99
+ event_id text NOT NULL,
100
+ event_type text NOT NULL,
101
+ version bigint NOT NULL,
102
+ entity_type text NOT NULL,
103
+ payload bytea NOT NULL,
104
+ metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
105
+ created_at timestamptz NOT NULL DEFAULT now(),
106
+ PRIMARY KEY (entity_id, sequence)
107
+ );
108
+ CREATE INDEX IF NOT EXISTS ${entityTypeIndex(tables)} ON ${events} (entity_type);
109
+ DO $$
110
+ BEGIN
111
+ IF EXISTS (
112
+ SELECT 1 FROM pg_index
113
+ WHERE indexrelid = to_regclass('${events}_entity_type_idx')
114
+ AND indrelid = '${events}'::regclass
115
+ ) THEN
116
+ DROP INDEX ${events}_entity_type_idx;
117
+ END IF;
118
+ END $$;
119
+
120
+ CREATE TABLE IF NOT EXISTS ${snapshots} (
121
+ entity_id text PRIMARY KEY,
122
+ entity_type text NOT NULL,
123
+ sequence bigint NOT NULL,
124
+ event_sequence bigint NOT NULL,
125
+ payload bytea NOT NULL,
126
+ updated_at timestamptz NOT NULL DEFAULT now()
127
+ );
128
+
129
+ CREATE TABLE IF NOT EXISTS ${outcomesTable(tables)} (
130
+ command_id text PRIMARY KEY,
131
+ status text NOT NULL CHECK (status IN ('accepted', 'rejected')),
132
+ digest text NOT NULL,
133
+ response bytea,
134
+ events jsonb NOT NULL DEFAULT '[]'::jsonb,
135
+ rejection jsonb,
136
+ code text,
137
+ created_at timestamptz NOT NULL DEFAULT now(),
138
+ command_type text,
139
+ targets jsonb,
140
+ principal text,
141
+ CHECK ((status = 'rejected' AND rejection IS NOT NULL AND code IS NOT NULL)
142
+ OR (status = 'accepted' AND rejection IS NULL AND code IS NULL))
143
+ );
144
+
145
+ DO $$
146
+ BEGIN
147
+ IF (SELECT count(*) FROM pg_attribute
148
+ WHERE attrelid = '${outcomesTable(tables)}'::regclass
149
+ AND attname IN ('command_type', 'targets', 'principal')
150
+ AND NOT attisdropped) < 3 THEN
151
+ ALTER TABLE ${outcomesTable(tables)}
152
+ ADD COLUMN IF NOT EXISTS command_type text,
153
+ ADD COLUMN IF NOT EXISTS targets jsonb,
154
+ ADD COLUMN IF NOT EXISTS principal text;
155
+ END IF;
156
+ END $$;
157
+
158
+ CREATE TABLE IF NOT EXISTS ${featuresTable(tables)} (
159
+ id integer PRIMARY KEY,
160
+ version bigint NOT NULL,
161
+ features text NOT NULL,
162
+ history_dependent text NOT NULL DEFAULT '[]',
163
+ retention text NOT NULL DEFAULT '[]'
164
+ );
165
+
166
+ CREATE TABLE IF NOT EXISTS ${rebuildLockTable(tables)} (
167
+ id integer PRIMARY KEY,
168
+ owner text NOT NULL,
169
+ generation bigint NOT NULL,
170
+ lease_expires_at timestamptz NOT NULL
171
+ );
172
+
173
+ CREATE TABLE IF NOT EXISTS ${rebuildGenerationTable(tables)} (
174
+ id integer PRIMARY KEY,
175
+ value bigint NOT NULL,
176
+ force_released boolean NOT NULL DEFAULT false
177
+ );
178
+
179
+ CREATE TABLE IF NOT EXISTS ${streamHeadsTable(tables)} (
180
+ entity_id text PRIMARY KEY,
181
+ entity_type text NOT NULL,
182
+ head bigint NOT NULL CHECK (head >= 1)
183
+ );
184
+ `;
185
+ }
186
+ /**
187
+ * Serializes schema changes across processes, in every language: `IF NOT EXISTS` alone can still
188
+ * race in PostgreSQL's catalogs. `$1` is the events table name.
189
+ */
190
+ export const SCHEMA_LOCK = 'SELECT pg_advisory_xact_lock(1702261762, hashtext($1))';
191
+ /**
192
+ * The per-entity transaction lock every commit and snapshot write takes, `$1` being the entity
193
+ * ID. Go and Rust run this exact statement, so writers in every language exclude each other.
194
+ */
195
+ export const ENTITY_LOCK = 'SELECT pg_advisory_xact_lock(1702261760, hashtext($1))';
196
+ /**
197
+ * The shared engine-row lock a commit takes and holds to `COMMIT`, `$1` being a key from
198
+ * {@link featuresLockKey} or {@link rebuildLockKey}. Commits don't serialize against each other.
199
+ */
200
+ export const ENGINE_LOCK_SHARED = 'SELECT pg_advisory_xact_lock_shared(1702261761, hashtext($1))';
201
+ /**
202
+ * The exclusive engine-row lock a declaration or a rebuild lifecycle step takes for its short
203
+ * transaction, so it never slips between a commit's check and its `COMMIT`.
204
+ */
205
+ export const ENGINE_LOCK_EXCLUSIVE = 'SELECT pg_advisory_xact_lock(1702261761, hashtext($1))';
206
+ /** The feature marker's engine-row lock key: `{events}:features`. */
207
+ export function featuresLockKey(tables) {
208
+ return `${tables.events}:features`;
209
+ }
210
+ /** The rebuild fence's engine-row lock key: `{events}:rebuild`. */
211
+ export function rebuildLockKey(tables) {
212
+ return `${tables.events}:rebuild`;
213
+ }
214
+ function derived(events, suffix) {
215
+ return `${events}${RESERVED_INFIX}${suffix}`;
216
+ }
217
+ // A valid identifier is ASCII, so its length is its byte count and folding it changes only A-Z.
218
+ // The type check refuses a non-string passed from JavaScript, which the pattern would coerce.
219
+ function validIdentifier(name, limit) {
220
+ return (typeof name === 'string' &&
221
+ name.length <= limit &&
222
+ IDENTIFIER.test(name) &&
223
+ !RESERVED_KEYWORDS.has(name.toLowerCase()));
224
+ }
225
+ // A name two relations of the schema would share, or null, with the names already folded to lower
226
+ // case. CREATE TABLE IF NOT EXISTS would otherwise skip a table whose name an index already took.
227
+ function sharedRelation(tables) {
228
+ const { events, snapshots } = tables;
229
+ const derivedTables = [
230
+ outcomesTable(tables),
231
+ featuresTable(tables),
232
+ rebuildLockTable(tables),
233
+ rebuildGenerationTable(tables),
234
+ streamHeadsTable(tables),
235
+ ];
236
+ const relations = [
237
+ events,
238
+ `${events}_pkey`,
239
+ entityTypeIndex(tables),
240
+ ...derivedTables.flatMap((table) => [table, `${table}_pkey`]),
241
+ snapshots,
242
+ `${snapshots}_pkey`,
243
+ ];
244
+ return relations.find((relation, index) => relations.indexOf(relation) !== index) ?? null;
245
+ }
246
+ function invalidConfig(message) {
247
+ return new EvtError('invalidArgument', `postgres: ${message}`);
248
+ }
249
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { EvtError, type FenceProvenance } from './errors.js';
1
2
  import { type SerializedEvent, type SerializedSnapshot } from './event.js';
2
3
  /** A snapshot to write with a commit. Its event sequence is the commit's last event. */
3
4
  export interface NewSnapshot {
@@ -7,9 +8,23 @@ export interface NewSnapshot {
7
8
  /** The aggregate state after the commit's events. */
8
9
  payload: Uint8Array;
9
10
  }
11
+ /**
12
+ * Operations a projector adds to a commit, for the backend it names to write in the commit's own
13
+ * transaction (Go's transaction groups). The DynamoDB repository writes `dynamodb` groups, whose
14
+ * operations are `TransactWriteItems` actions. The in-memory repository budgets every group and
15
+ * writes none, as Go's does, so code with projectors runs on it unchanged.
16
+ */
17
+ export interface ProjectorGroup {
18
+ /** The backend whose transaction carries the operations, such as `dynamodb`. */
19
+ readonly backend: string;
20
+ /** The operations, in the order they're written. */
21
+ readonly operations: readonly unknown[];
22
+ /** Each operation's size in the commit budget, as DynamoDB counts it. */
23
+ readonly sizes: readonly number[];
24
+ }
10
25
  /**
11
26
  * Everything a repository writes atomically for one command. A commit with no events is a no-op,
12
- * and its snapshot is ignored.
27
+ * and its snapshot is ignored, unless it carries projector operations: then it's refused.
13
28
  */
14
29
  export interface Commit {
15
30
  /** The stream the events are appended to. */
@@ -18,6 +33,8 @@ export interface Commit {
18
33
  events: SerializedEvent[];
19
34
  /** The snapshot to write, when the commit reaches a snapshot boundary. */
20
35
  snapshot?: NewSnapshot | null | undefined;
36
+ /** The operations the aggregate's projectors add, written first, in order. */
37
+ projections?: readonly ProjectorGroup[] | null | undefined;
21
38
  }
22
39
  /** Options every repository call takes. */
23
40
  export interface CallOptions {
@@ -41,7 +58,9 @@ export interface CallOptions {
41
58
  * {@link StreamHeadDriftError}, ranked above a gap and any other conflict;
42
59
  * - refuse a commit's snapshot whose sequence isn't the stored snapshot's plus one (1 with none
43
60
  * stored) with a {@link ConflictError};
44
- * - write a commit's events, head and snapshot atomically, or nothing;
61
+ * - write a commit's events, head and snapshot atomically, or nothing, with the projector
62
+ * operations it writes (a backend writes only its own groups), and refuse projector operations
63
+ * without events with a {@link ProjectorOnlyCommitError};
45
64
  * - refuse an entity ID in a reserved namespace on every write path, before any request;
46
65
  * - refuse every write (a commit, a snapshot write, compaction) to a store whose feature manifest
47
66
  * declares a pair this package doesn't model, with an {@link UnsupportedFeatureError}, and to
@@ -99,6 +118,74 @@ export interface StoreInitializer {
99
118
  */
100
119
  initialize(options?: CallOptions): Promise<boolean>;
101
120
  }
121
+ /**
122
+ * A stream a transaction read but doesn't write, whose head must not move before it commits (ADR
123
+ * 0007): the fence passes while the stream's stored head still equals `head`.
124
+ */
125
+ export interface ReadFence {
126
+ entityId: string;
127
+ /** The stream's entity type, which a fence on a retained type is refused for. */
128
+ entityType: string;
129
+ /** The head the transaction observed: 0 for a stream with no events. */
130
+ head: bigint;
131
+ /** Whether the engine read the head itself, or the caller stamped it. */
132
+ provenance: FenceProvenance;
133
+ }
134
+ /**
135
+ * Everything one transaction writes atomically: the streams it appends to, and fences on the
136
+ * streams it read. A fence on a stream the transaction also writes is dropped, since that stream's
137
+ * head update already conditions on the head it read. A transaction that writes nothing and fences
138
+ * nothing is a no-op.
139
+ */
140
+ export interface TransactionCommit {
141
+ /** The streams written, each a {@link Commit}, at most one per stream. */
142
+ streams: readonly Commit[];
143
+ /** The streams read but not written, at most one fence per stream. */
144
+ fences?: readonly ReadFence[] | null | undefined;
145
+ }
146
+ /**
147
+ * A repository that commits several streams atomically, with read fences (ADR 0004). A
148
+ * transaction is refused as a commit is, and also:
149
+ *
150
+ * - with `invalidCommit` when it writes a stream twice, fences a stream twice, fences at a head
151
+ * below 0 or at the largest int64, or carries a snapshot for a stream it writes no events to;
152
+ * - with a {@link RetentionConflictError} when it fences an entity type with retention: by the
153
+ * repository's own configuration before any request, and by the store's manifest after the
154
+ * manifest's other refusals, but always before the rebuild lock's;
155
+ * - with a {@link FenceConflictError} when a fenced stream's head moved, unless the stream
156
+ * drifted, ranked after every drift and gap of the transaction, in transaction order.
157
+ */
158
+ export interface TransactionalRepository extends Repository {
159
+ /** Appends to every stream and checks every fence atomically. */
160
+ commitTransaction(transaction: TransactionCommit, options?: CallOptions): Promise<void>;
161
+ }
162
+ /** A transaction as the backends write it. */
163
+ export interface NormalizedTransaction {
164
+ /** The streams it writes events to, sorted by entity ID bytes, without their projections. */
165
+ readonly streams: readonly Commit[];
166
+ /** Its fences on the streams it doesn't write, sorted the same way. */
167
+ readonly fences: readonly ReadFence[];
168
+ /** The written streams' projector groups, in the order the streams were declared. */
169
+ readonly projections: readonly ProjectorGroup[];
170
+ }
171
+ /**
172
+ * Validates a transaction and puts it in the order every backend writes it: the written streams,
173
+ * then the fences, each sorted by entity ID bytes, the order that pins a DynamoDB transaction and
174
+ * PostgreSQL's locks. The projector groups keep the order the streams were declared in. Streams
175
+ * without events are dropped, and so are the fences on streams that write events, whose head
176
+ * updates condition on the head they read. A fence on a stream listed without events stays.
177
+ */
178
+ export declare function normalizeTransaction(transaction: TransactionCommit): NormalizedTransaction;
179
+ /**
180
+ * Refuses a transaction that fences a retained entity type, by the store's manifest or the
181
+ * repository's own configuration.
182
+ */
183
+ export declare function checkFenceRetention(transaction: NormalizedTransaction, retained: (entityType: string) => boolean): void;
184
+ /**
185
+ * The error a failed transaction reports from the failures of its streams and fences, given in
186
+ * transaction order: the first drift, else the first gap, else the first of the rest.
187
+ */
188
+ export declare function rankFailures(failures: readonly EvtError[]): EvtError | undefined;
102
189
  /** The most actions one commit may carry, DynamoDB's transaction limit. */
103
190
  export declare const MAX_COMMIT_ACTIONS = 100;
104
191
  /** The most bytes one commit may carry, summed over its actions: 95% of DynamoDB's 4 MB. */
@@ -113,16 +200,24 @@ export declare function checkNotReserved(entityId: string): void;
113
200
  * Checks that a commit's events can be stored as written: each belongs to the commit's entity and
114
201
  * has the ID `{entityId}:{sequence}`, they share one entity type, the first sequence is at least
115
202
  * 1, and the sequences are contiguous. A snapshot must have the events' entity type and a
116
- * sequence of at least 1. A commit with no events is valid, and its snapshot isn't checked.
203
+ * sequence of at least 1, and each projector group a size per operation. A commit with no events
204
+ * is valid, and its snapshot isn't checked, but its projector operations are refused.
117
205
  */
118
206
  export declare function validateCommit(commit: Commit): void;
119
207
  /**
120
208
  * The size of each action a commit's transaction carries, in order: the feature-marker and
121
- * rebuild-lock checks, then the stream's head update, its event puts, and its snapshot put when
122
- * it writes one. `ttl` gives the expiry an entity type's items carry, if it's retained. Every
123
- * backend budgets a commit by these sizes, so an oversized commit fails the same way on each.
209
+ * rebuild-lock checks, the projector operations, then the stream's head update, its event puts,
210
+ * and its snapshot put when it writes one. `ttl` gives the expiry an entity type's items carry, if
211
+ * it's retained. Every backend budgets a commit by these sizes, so an oversized commit fails the
212
+ * same way on each.
124
213
  */
125
214
  export declare function commitSizes(commit: Commit, ttl: (entityType: string) => number | undefined): number[];
215
+ /**
216
+ * The size of each action a transaction carries: the two control checks, every stream's projector
217
+ * operations, every written stream's head update, event puts and snapshot put, then a check on
218
+ * every fenced stream's head. Every backend budgets a transaction by these sizes.
219
+ */
220
+ export declare function transactionSizes(transaction: NormalizedTransaction, ttl: (entityType: string) => number | undefined): number[];
126
221
  /**
127
222
  * Refuses a commit whose actions are over the budget: more than {@link MAX_COMMIT_ACTIONS}, more
128
223
  * than {@link MAX_COMMIT_BYTES} in all, or one over {@link MAX_COMMIT_ITEM_BYTES}.
@@ -1 +1 @@
1
- {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"AAOA,OAAO,EAAC,KAAK,eAAe,EAAE,KAAK,kBAAkB,EAAU,MAAM,YAAY,CAAA;AAGjF,wFAAwF;AACxF,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,OAAO,EAAE,UAAU,CAAA;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAA;IAChB,mDAAmD;IACnD,MAAM,EAAE,eAAe,EAAE,CAAA;IACzB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,GAAG,SAAS,CAAA;CAC1C;AAED,2CAA2C;AAC3C,MAAM,WAAW,WAAW;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAA;CACjC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,MAAM,WAAW,UAAU;IACzB,6EAA6E;IAC7E,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE5D,mDAAmD;IACnD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IAE3E,6DAA6D;IAC7D,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IAE/F;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAA;IAEtF,uDAAuD;IACvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAA;IAErF;;;;;;OAMG;IACH,WAAW,CAAC,QAAQ,EAAE,kBAAkB,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAElF;;;;OAIG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACxF;AAED;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;;OAKG;IACH,UAAU,CAAC,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACpD;AAED,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,MAAM,CAAA;AAErC,4FAA4F;AAC5F,eAAO,MAAM,gBAAgB,UAAY,CAAA;AAEzC,6DAA6D;AAC7D,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAG7C,CAAA;AAEF,uDAAuD;AACvD,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEpD;AAED,yFAAyF;AACzF,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAIvD;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAsDnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAC9C,MAAM,EAAE,CA4BV;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAe1D"}
1
+ {"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../src/repository.ts"],"names":[],"mappings":"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"}