@ddd-ts-kit/drizzle 0.8.0 → 0.10.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/README.md CHANGED
@@ -502,6 +502,27 @@ and on PostgreSQL 18.
502
502
  of each event, so that its consumers run in that tenant. Switching an existing project is one
503
503
  generated migration that adds the column.
504
504
 
505
+ ## Event store
506
+
507
+ ```ts
508
+ // src/contexts/scheduling/infrastructure/persistence/scheduling.schema.ts, read by drizzle-kit
509
+ export const { events, head, snapshots, checkpoints, subjectKeys } = eventStoreTables('scheduling');
510
+
511
+ // the composition root
512
+ const stores = createDrizzleEventSourcing(database, { schema: 'scheduling' });
513
+ ```
514
+
515
+ `eventStoreTables` declares the tables drizzle-kit creates in a migration of the project, with
516
+ the columns of `eventStoreTablesSql` of the kernel.
517
+
518
+ Each statement runs on the executor of the context: an append joins the transaction of the
519
+ unit of work, so the stream and the outbox records its events publish commit together
520
+ (`eventStoreUnitOfWorkContract`). Appends take the head of the store, a row locked until their
521
+ transaction ends: positions are given in commit order, without gaps, and two appends never run
522
+ side by side, whatever their streams. PostgreSQL only. The stores are the ones of the kernel
523
+ (`PostgresEventStore` and its companions), held to `eventStoreContract` here; how an
524
+ event-sourced aggregate uses them: the README of `@ddd-ts-kit/kernel`, section "Event sourcing".
525
+
505
526
  ## Testing an adapter
506
527
 
507
528
  The unit of work of this package passes `unitOfWorkContract`, and its stores
@@ -0,0 +1,12 @@
1
+ import type { ExtractTablesWithRelations, TablesRelationalConfig } from 'drizzle-orm';
2
+ import type { PgQueryResultHKT } from 'drizzle-orm/pg-core';
3
+ import { type EventSourcingStores, type EventStoreTablesOptions } from '@ddd-ts-kit/kernel';
4
+ import type { DrizzleContext } from '../unit-of-work/drizzle-context.js';
5
+ /**
6
+ * The event store, the snapshots, the checkpoints and the keys of the data subjects on
7
+ * PostgreSQL, through drizzle, over the tables of `eventStoreTables`. Every statement runs on
8
+ * the executor of the context, so an append joins the transaction of the unit of work, with the
9
+ * outbox. Bind each one to its port.
10
+ */
11
+ export declare function createDrizzleEventSourcing<Q extends PgQueryResultHKT, F extends Record<string, unknown> = Record<string, never>, S extends TablesRelationalConfig = ExtractTablesWithRelations<F>>(context: DrizzleContext<Q, F, S>, options?: EventStoreTablesOptions): EventSourcingStores;
12
+ //# sourceMappingURL=create-drizzle-event-sourcing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-drizzle-event-sourcing.d.ts","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/create-drizzle-event-sourcing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACtF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAyB,KAAK,mBAAmB,EAAE,KAAK,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AACnH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAGzE;;;;;GAKG;AACH,wBAAgB,0BAA0B,CACxC,CAAC,SAAS,gBAAgB,EAC1B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACzD,CAAC,SAAS,sBAAsB,GAAG,0BAA0B,CAAC,CAAC,CAAC,EAChE,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,GAAE,uBAA4B,GAAG,mBAAmB,CAE9F"}
@@ -0,0 +1,12 @@
1
+ import { postgresEventSourcing } from '@ddd-ts-kit/kernel';
2
+ import { drizzleSqlRun } from './drizzle-sql-run.js';
3
+ /**
4
+ * The event store, the snapshots, the checkpoints and the keys of the data subjects on
5
+ * PostgreSQL, through drizzle, over the tables of `eventStoreTables`. Every statement runs on
6
+ * the executor of the context, so an append joins the transaction of the unit of work, with the
7
+ * outbox. Bind each one to its port.
8
+ */
9
+ export function createDrizzleEventSourcing(context, options = {}) {
10
+ return postgresEventSourcing(drizzleSqlRun(context), options);
11
+ }
12
+ //# sourceMappingURL=create-drizzle-event-sourcing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-drizzle-event-sourcing.js","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/create-drizzle-event-sourcing.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAA0D,MAAM,oBAAoB,CAAC;AAEnH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD;;;;;GAKG;AACH,MAAM,UAAU,0BAA0B,CAIxC,OAAgC,EAAE,OAAO,GAA4B,EAAE;IACvE,OAAO,qBAAqB,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ExtractTablesWithRelations, type TablesRelationalConfig } from 'drizzle-orm';
2
+ import type { PgQueryResultHKT } from 'drizzle-orm/pg-core';
3
+ import type { SqlRun } from '@ddd-ts-kit/kernel';
4
+ import type { DrizzleContext } from '../unit-of-work/drizzle-context.js';
5
+ /** Runs the statements of the shared PostgreSQL stores on the executor of the context, each `$n` bound as a parameter. */
6
+ export declare function drizzleSqlRun<Q extends PgQueryResultHKT, F extends Record<string, unknown> = Record<string, never>, S extends TablesRelationalConfig = ExtractTablesWithRelations<F>>(context: DrizzleContext<Q, F, S>): SqlRun;
7
+ //# sourceMappingURL=drizzle-sql-run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drizzle-sql-run.d.ts","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/drizzle-sql-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAO,KAAK,0BAA0B,EAAE,KAAK,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAChG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAEzE,0HAA0H;AAC1H,wBAAgB,aAAa,CAC3B,CAAC,SAAS,gBAAgB,EAC1B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,EACzD,CAAC,SAAS,sBAAsB,GAAG,0BAA0B,CAAC,CAAC,CAAC,EAChE,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAa1C"}
@@ -0,0 +1,11 @@
1
+ import { sql } from 'drizzle-orm';
2
+ import { rowsOf } from '../read-model/rows-of.js';
3
+ /** Runs the statements of the shared PostgreSQL stores on the executor of the context, each `$n` bound as a parameter. */
4
+ export function drizzleSqlRun(context) {
5
+ return async (statement, parameters) => {
6
+ const pieces = statement.split(/\$\d+/);
7
+ const query = sql.join(pieces.flatMap((piece, index) => index < parameters.length ? [sql.raw(piece), sql `${parameters[index]}`] : [sql.raw(piece)]), sql.raw(''));
8
+ return rowsOf(await context.executor().execute(query));
9
+ };
10
+ }
11
+ //# sourceMappingURL=drizzle-sql-run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drizzle-sql-run.js","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/drizzle-sql-run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAgE,MAAM,aAAa,CAAC;AAGhG,OAAO,EAAE,MAAM,EAAE,MAAM,0BAA0B,CAAC;AAGlD,0HAA0H;AAC1H,MAAM,UAAU,aAAa,CAI3B,OAAgC;IAChC,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAExC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,CACpB,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAC9B,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,GAAG,CAAA,GAAG,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAC3F,EACD,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CACZ,CAAC;QAEF,OAAO,MAAM,CAAC,MAAM,OAAO,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;IACzD,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,451 @@
1
+ /**
2
+ * The tables of the event store, to include in the schema files drizzle-kit reads so that the
3
+ * migrations of the consuming project create them: the same columns as `eventStoreTablesSql` of
4
+ * the kernel. One schema per bounded context that keeps an event store.
5
+ */
6
+ export declare function eventStoreTables(schemaName?: string): {
7
+ head: import("drizzle-orm/pg-core").PgTableWithColumns<{
8
+ name: "stored_events_head";
9
+ schema: string | undefined;
10
+ columns: {
11
+ id: import("drizzle-orm/pg-core").PgColumn<{
12
+ name: "id";
13
+ tableName: "stored_events_head";
14
+ dataType: "number";
15
+ columnType: "PgSmallInt";
16
+ data: number;
17
+ driverParam: string | number;
18
+ notNull: true;
19
+ hasDefault: false;
20
+ isPrimaryKey: true;
21
+ isAutoincrement: false;
22
+ hasRuntimeDefault: false;
23
+ enumValues: undefined;
24
+ baseColumn: never;
25
+ identity: undefined;
26
+ generated: undefined;
27
+ }, {}, {}>;
28
+ position: import("drizzle-orm/pg-core").PgColumn<{
29
+ name: "position";
30
+ tableName: "stored_events_head";
31
+ dataType: "number";
32
+ columnType: "PgBigInt53";
33
+ data: number;
34
+ driverParam: string | number;
35
+ notNull: true;
36
+ hasDefault: false;
37
+ isPrimaryKey: false;
38
+ isAutoincrement: false;
39
+ hasRuntimeDefault: false;
40
+ enumValues: undefined;
41
+ baseColumn: never;
42
+ identity: undefined;
43
+ generated: undefined;
44
+ }, {}, {}>;
45
+ };
46
+ dialect: 'pg';
47
+ }>;
48
+ events: import("drizzle-orm/pg-core").PgTableWithColumns<{
49
+ name: "stored_events";
50
+ schema: string | undefined;
51
+ columns: {
52
+ position: import("drizzle-orm/pg-core").PgColumn<{
53
+ name: "position";
54
+ tableName: "stored_events";
55
+ dataType: "number";
56
+ columnType: "PgBigInt53";
57
+ data: number;
58
+ driverParam: string | number;
59
+ notNull: true;
60
+ hasDefault: false;
61
+ isPrimaryKey: true;
62
+ isAutoincrement: false;
63
+ hasRuntimeDefault: false;
64
+ enumValues: undefined;
65
+ baseColumn: never;
66
+ identity: undefined;
67
+ generated: undefined;
68
+ }, {}, {}>;
69
+ stream: import("drizzle-orm/pg-core").PgColumn<{
70
+ name: "stream";
71
+ tableName: "stored_events";
72
+ dataType: "string";
73
+ columnType: "PgText";
74
+ data: string;
75
+ driverParam: string;
76
+ notNull: true;
77
+ hasDefault: false;
78
+ isPrimaryKey: false;
79
+ isAutoincrement: false;
80
+ hasRuntimeDefault: false;
81
+ enumValues: [string, ...string[]];
82
+ baseColumn: never;
83
+ identity: undefined;
84
+ generated: undefined;
85
+ }, {}, {}>;
86
+ version: import("drizzle-orm/pg-core").PgColumn<{
87
+ name: "version";
88
+ tableName: "stored_events";
89
+ dataType: "number";
90
+ columnType: "PgInteger";
91
+ data: number;
92
+ driverParam: string | number;
93
+ notNull: true;
94
+ hasDefault: false;
95
+ isPrimaryKey: false;
96
+ isAutoincrement: false;
97
+ hasRuntimeDefault: false;
98
+ enumValues: undefined;
99
+ baseColumn: never;
100
+ identity: undefined;
101
+ generated: undefined;
102
+ }, {}, {}>;
103
+ eventId: import("drizzle-orm/pg-core").PgColumn<{
104
+ name: "event_id";
105
+ tableName: "stored_events";
106
+ dataType: "string";
107
+ columnType: "PgText";
108
+ data: string;
109
+ driverParam: string;
110
+ notNull: true;
111
+ hasDefault: false;
112
+ isPrimaryKey: false;
113
+ isAutoincrement: false;
114
+ hasRuntimeDefault: false;
115
+ enumValues: [string, ...string[]];
116
+ baseColumn: never;
117
+ identity: undefined;
118
+ generated: undefined;
119
+ }, {}, {}>;
120
+ type: import("drizzle-orm/pg-core").PgColumn<{
121
+ name: "type";
122
+ tableName: "stored_events";
123
+ dataType: "string";
124
+ columnType: "PgText";
125
+ data: string;
126
+ driverParam: string;
127
+ notNull: true;
128
+ hasDefault: false;
129
+ isPrimaryKey: false;
130
+ isAutoincrement: false;
131
+ hasRuntimeDefault: false;
132
+ enumValues: [string, ...string[]];
133
+ baseColumn: never;
134
+ identity: undefined;
135
+ generated: undefined;
136
+ }, {}, {}>;
137
+ schemaVersion: import("drizzle-orm/pg-core").PgColumn<{
138
+ name: "schema_version";
139
+ tableName: "stored_events";
140
+ dataType: "number";
141
+ columnType: "PgInteger";
142
+ data: number;
143
+ driverParam: string | number;
144
+ notNull: true;
145
+ hasDefault: false;
146
+ isPrimaryKey: false;
147
+ isAutoincrement: false;
148
+ hasRuntimeDefault: false;
149
+ enumValues: undefined;
150
+ baseColumn: never;
151
+ identity: undefined;
152
+ generated: undefined;
153
+ }, {}, {}>;
154
+ data: import("drizzle-orm/pg-core").PgColumn<{
155
+ name: "data";
156
+ tableName: "stored_events";
157
+ dataType: "json";
158
+ columnType: "PgJsonb";
159
+ data: unknown;
160
+ driverParam: unknown;
161
+ notNull: true;
162
+ hasDefault: false;
163
+ isPrimaryKey: false;
164
+ isAutoincrement: false;
165
+ hasRuntimeDefault: false;
166
+ enumValues: undefined;
167
+ baseColumn: never;
168
+ identity: undefined;
169
+ generated: undefined;
170
+ }, {}, {}>;
171
+ metadata: import("drizzle-orm/pg-core").PgColumn<{
172
+ name: "metadata";
173
+ tableName: "stored_events";
174
+ dataType: "json";
175
+ columnType: "PgJsonb";
176
+ data: unknown;
177
+ driverParam: unknown;
178
+ notNull: true;
179
+ hasDefault: false;
180
+ isPrimaryKey: false;
181
+ isAutoincrement: false;
182
+ hasRuntimeDefault: false;
183
+ enumValues: undefined;
184
+ baseColumn: never;
185
+ identity: undefined;
186
+ generated: undefined;
187
+ }, {}, {}>;
188
+ occurredAt: import("drizzle-orm/pg-core").PgColumn<{
189
+ name: string;
190
+ tableName: "stored_events";
191
+ dataType: "date";
192
+ columnType: "PgTimestamp";
193
+ data: Date;
194
+ driverParam: string;
195
+ notNull: true;
196
+ hasDefault: false;
197
+ isPrimaryKey: false;
198
+ isAutoincrement: false;
199
+ hasRuntimeDefault: false;
200
+ enumValues: undefined;
201
+ baseColumn: never;
202
+ identity: undefined;
203
+ generated: undefined;
204
+ }, {}, {}>;
205
+ recordedAt: import("drizzle-orm/pg-core").PgColumn<{
206
+ name: string;
207
+ tableName: "stored_events";
208
+ dataType: "date";
209
+ columnType: "PgTimestamp";
210
+ data: Date;
211
+ driverParam: string;
212
+ notNull: true;
213
+ hasDefault: true;
214
+ isPrimaryKey: false;
215
+ isAutoincrement: false;
216
+ hasRuntimeDefault: false;
217
+ enumValues: undefined;
218
+ baseColumn: never;
219
+ identity: undefined;
220
+ generated: undefined;
221
+ }, {}, {}>;
222
+ };
223
+ dialect: 'pg';
224
+ }>;
225
+ snapshots: import("drizzle-orm/pg-core").PgTableWithColumns<{
226
+ name: "stream_snapshots";
227
+ schema: string | undefined;
228
+ columns: {
229
+ stream: import("drizzle-orm/pg-core").PgColumn<{
230
+ name: "stream";
231
+ tableName: "stream_snapshots";
232
+ dataType: "string";
233
+ columnType: "PgText";
234
+ data: string;
235
+ driverParam: string;
236
+ notNull: true;
237
+ hasDefault: false;
238
+ isPrimaryKey: true;
239
+ isAutoincrement: false;
240
+ hasRuntimeDefault: false;
241
+ enumValues: [string, ...string[]];
242
+ baseColumn: never;
243
+ identity: undefined;
244
+ generated: undefined;
245
+ }, {}, {}>;
246
+ version: import("drizzle-orm/pg-core").PgColumn<{
247
+ name: "version";
248
+ tableName: "stream_snapshots";
249
+ dataType: "number";
250
+ columnType: "PgInteger";
251
+ data: number;
252
+ driverParam: string | number;
253
+ notNull: true;
254
+ hasDefault: false;
255
+ isPrimaryKey: false;
256
+ isAutoincrement: false;
257
+ hasRuntimeDefault: false;
258
+ enumValues: undefined;
259
+ baseColumn: never;
260
+ identity: undefined;
261
+ generated: undefined;
262
+ }, {}, {}>;
263
+ schemaVersion: import("drizzle-orm/pg-core").PgColumn<{
264
+ name: "schema_version";
265
+ tableName: "stream_snapshots";
266
+ dataType: "number";
267
+ columnType: "PgInteger";
268
+ data: number;
269
+ driverParam: string | number;
270
+ notNull: true;
271
+ hasDefault: false;
272
+ isPrimaryKey: false;
273
+ isAutoincrement: false;
274
+ hasRuntimeDefault: false;
275
+ enumValues: undefined;
276
+ baseColumn: never;
277
+ identity: undefined;
278
+ generated: undefined;
279
+ }, {}, {}>;
280
+ data: import("drizzle-orm/pg-core").PgColumn<{
281
+ name: "data";
282
+ tableName: "stream_snapshots";
283
+ dataType: "json";
284
+ columnType: "PgJsonb";
285
+ data: unknown;
286
+ driverParam: unknown;
287
+ notNull: true;
288
+ hasDefault: false;
289
+ isPrimaryKey: false;
290
+ isAutoincrement: false;
291
+ hasRuntimeDefault: false;
292
+ enumValues: undefined;
293
+ baseColumn: never;
294
+ identity: undefined;
295
+ generated: undefined;
296
+ }, {}, {}>;
297
+ takenAt: import("drizzle-orm/pg-core").PgColumn<{
298
+ name: string;
299
+ tableName: "stream_snapshots";
300
+ dataType: "date";
301
+ columnType: "PgTimestamp";
302
+ data: Date;
303
+ driverParam: string;
304
+ notNull: true;
305
+ hasDefault: true;
306
+ isPrimaryKey: false;
307
+ isAutoincrement: false;
308
+ hasRuntimeDefault: false;
309
+ enumValues: undefined;
310
+ baseColumn: never;
311
+ identity: undefined;
312
+ generated: undefined;
313
+ }, {}, {}>;
314
+ };
315
+ dialect: 'pg';
316
+ }>;
317
+ checkpoints: import("drizzle-orm/pg-core").PgTableWithColumns<{
318
+ name: "subscription_checkpoints";
319
+ schema: string | undefined;
320
+ columns: {
321
+ subscriber: import("drizzle-orm/pg-core").PgColumn<{
322
+ name: "subscriber";
323
+ tableName: "subscription_checkpoints";
324
+ dataType: "string";
325
+ columnType: "PgText";
326
+ data: string;
327
+ driverParam: string;
328
+ notNull: true;
329
+ hasDefault: false;
330
+ isPrimaryKey: true;
331
+ isAutoincrement: false;
332
+ hasRuntimeDefault: false;
333
+ enumValues: [string, ...string[]];
334
+ baseColumn: never;
335
+ identity: undefined;
336
+ generated: undefined;
337
+ }, {}, {}>;
338
+ position: import("drizzle-orm/pg-core").PgColumn<{
339
+ name: "position";
340
+ tableName: "subscription_checkpoints";
341
+ dataType: "number";
342
+ columnType: "PgBigInt53";
343
+ data: number;
344
+ driverParam: string | number;
345
+ notNull: true;
346
+ hasDefault: false;
347
+ isPrimaryKey: false;
348
+ isAutoincrement: false;
349
+ hasRuntimeDefault: false;
350
+ enumValues: undefined;
351
+ baseColumn: never;
352
+ identity: undefined;
353
+ generated: undefined;
354
+ }, {}, {}>;
355
+ updatedAt: import("drizzle-orm/pg-core").PgColumn<{
356
+ name: string;
357
+ tableName: "subscription_checkpoints";
358
+ dataType: "date";
359
+ columnType: "PgTimestamp";
360
+ data: Date;
361
+ driverParam: string;
362
+ notNull: true;
363
+ hasDefault: true;
364
+ isPrimaryKey: false;
365
+ isAutoincrement: false;
366
+ hasRuntimeDefault: false;
367
+ enumValues: undefined;
368
+ baseColumn: never;
369
+ identity: undefined;
370
+ generated: undefined;
371
+ }, {}, {}>;
372
+ };
373
+ dialect: 'pg';
374
+ }>;
375
+ subjectKeys: import("drizzle-orm/pg-core").PgTableWithColumns<{
376
+ name: "subject_keys";
377
+ schema: string | undefined;
378
+ columns: {
379
+ subject: import("drizzle-orm/pg-core").PgColumn<{
380
+ name: "subject";
381
+ tableName: "subject_keys";
382
+ dataType: "string";
383
+ columnType: "PgText";
384
+ data: string;
385
+ driverParam: string;
386
+ notNull: true;
387
+ hasDefault: false;
388
+ isPrimaryKey: true;
389
+ isAutoincrement: false;
390
+ hasRuntimeDefault: false;
391
+ enumValues: [string, ...string[]];
392
+ baseColumn: never;
393
+ identity: undefined;
394
+ generated: undefined;
395
+ }, {}, {}>;
396
+ keyId: import("drizzle-orm/pg-core").PgColumn<{
397
+ name: "key_id";
398
+ tableName: "subject_keys";
399
+ dataType: "string";
400
+ columnType: "PgText";
401
+ data: string;
402
+ driverParam: string;
403
+ notNull: true;
404
+ hasDefault: false;
405
+ isPrimaryKey: false;
406
+ isAutoincrement: false;
407
+ hasRuntimeDefault: false;
408
+ enumValues: [string, ...string[]];
409
+ baseColumn: never;
410
+ identity: undefined;
411
+ generated: undefined;
412
+ }, {}, {}>;
413
+ material: import("drizzle-orm/pg-core").PgColumn<{
414
+ name: "material";
415
+ tableName: "subject_keys";
416
+ dataType: "string";
417
+ columnType: "PgText";
418
+ data: string;
419
+ driverParam: string;
420
+ notNull: true;
421
+ hasDefault: false;
422
+ isPrimaryKey: false;
423
+ isAutoincrement: false;
424
+ hasRuntimeDefault: false;
425
+ enumValues: [string, ...string[]];
426
+ baseColumn: never;
427
+ identity: undefined;
428
+ generated: undefined;
429
+ }, {}, {}>;
430
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
431
+ name: string;
432
+ tableName: "subject_keys";
433
+ dataType: "date";
434
+ columnType: "PgTimestamp";
435
+ data: Date;
436
+ driverParam: string;
437
+ notNull: true;
438
+ hasDefault: true;
439
+ isPrimaryKey: false;
440
+ isAutoincrement: false;
441
+ hasRuntimeDefault: false;
442
+ enumValues: undefined;
443
+ baseColumn: never;
444
+ identity: undefined;
445
+ generated: undefined;
446
+ }, {}, {}>;
447
+ };
448
+ dialect: 'pg';
449
+ }>;
450
+ };
451
+ //# sourceMappingURL=event-store-tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-store-tables.d.ts","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/event-store-tables.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,CAAC,EAAE,MAAM;IAEhD,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACJ,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACN,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACT,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IACX,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAEd"}
@@ -0,0 +1,69 @@
1
+ import { bigint, integer, jsonb, smallint, text, timestamp, uniqueIndex } from 'drizzle-orm/pg-core';
2
+ import { EVENT_STORE_TABLES } from '@ddd-ts-kit/kernel';
3
+ import { tableIn } from '../schema/table-in.js';
4
+ /**
5
+ * The tables of the event store, to include in the schema files drizzle-kit reads so that the
6
+ * migrations of the consuming project create them: the same columns as `eventStoreTablesSql` of
7
+ * the kernel. One schema per bounded context that keeps an event store.
8
+ */
9
+ export function eventStoreTables(schemaName) {
10
+ return {
11
+ head: headTable(schemaName),
12
+ events: eventsTable(schemaName),
13
+ snapshots: snapshotsTable(schemaName),
14
+ checkpoints: checkpointsTable(schemaName),
15
+ subjectKeys: subjectKeysTable(schemaName),
16
+ };
17
+ }
18
+ function headTable(schemaName) {
19
+ return tableIn(schemaName)(EVENT_STORE_TABLES.head, {
20
+ id: smallint('id').primaryKey(),
21
+ position: bigint('position', { mode: 'number' }).notNull(),
22
+ });
23
+ }
24
+ function eventsTable(schemaName) {
25
+ return tableIn(schemaName)(EVENT_STORE_TABLES.events, {
26
+ position: bigint('position', { mode: 'number' }).primaryKey(),
27
+ stream: text('stream').notNull(),
28
+ version: integer('version').notNull(),
29
+ eventId: text('event_id').notNull(),
30
+ type: text('type').notNull(),
31
+ schemaVersion: integer('schema_version').notNull(),
32
+ data: jsonb('data').notNull(),
33
+ metadata: jsonb('metadata').notNull(),
34
+ occurredAt: instant('occurred_at').notNull(),
35
+ recordedAt: instant('recorded_at').notNull().defaultNow(),
36
+ }, (events) => [
37
+ uniqueIndex(`${EVENT_STORE_TABLES.events}_stream_version_key`).on(events.stream, events.version),
38
+ uniqueIndex(`${EVENT_STORE_TABLES.events}_event_id_key`).on(events.eventId),
39
+ ]);
40
+ }
41
+ function snapshotsTable(schemaName) {
42
+ return tableIn(schemaName)(EVENT_STORE_TABLES.snapshots, {
43
+ stream: text('stream').primaryKey(),
44
+ version: integer('version').notNull(),
45
+ schemaVersion: integer('schema_version').notNull(),
46
+ data: jsonb('data').notNull(),
47
+ takenAt: instant('taken_at').notNull().defaultNow(),
48
+ });
49
+ }
50
+ function checkpointsTable(schemaName) {
51
+ return tableIn(schemaName)(EVENT_STORE_TABLES.checkpoints, {
52
+ subscriber: text('subscriber').primaryKey(),
53
+ position: bigint('position', { mode: 'number' }).notNull(),
54
+ updatedAt: instant('updated_at').notNull().defaultNow(),
55
+ });
56
+ }
57
+ function subjectKeysTable(schemaName) {
58
+ return tableIn(schemaName)(EVENT_STORE_TABLES.subjectKeys, {
59
+ subject: text('subject').primaryKey(),
60
+ keyId: text('key_id').notNull(),
61
+ material: text('material').notNull(),
62
+ createdAt: instant('created_at').notNull().defaultNow(),
63
+ }, (keys) => [uniqueIndex(`${EVENT_STORE_TABLES.subjectKeys}_key_id_key`).on(keys.keyId)]);
64
+ }
65
+ /** To the millisecond, as the kernel writes them. */
66
+ function instant(name) {
67
+ return timestamp(name, { withTimezone: true, mode: 'date', precision: 3 });
68
+ }
69
+ //# sourceMappingURL=event-store-tables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-store-tables.js","sourceRoot":"","sources":["../../../src/postgres/event-sourcing/event-store-tables.ts"],"names":[],"mappings":"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"}
@@ -2,6 +2,8 @@ export { CONCURRENCY_CONFLICT, ConcurrencyError, optimisticUpdate, schemaNameOf,
2
2
  export * from './postgres/unit-of-work/drizzle-context.js';
3
3
  export * from './postgres/unit-of-work/create-drizzle-unit-of-work.js';
4
4
  export * from './postgres/schema/context-schema.js';
5
+ export * from './postgres/event-sourcing/create-drizzle-event-sourcing.js';
6
+ export * from './postgres/event-sourcing/event-store-tables.js';
5
7
  export * from './postgres/outbox/outbox-table.js';
6
8
  export * from './postgres/outbox/tenant-outbox-table.js';
7
9
  export * from './postgres/outbox/processed-events-table.js';
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wDAAwD,CAAC;AACvE,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mDAAmD,CAAC;AAClE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"postgres.d.ts","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,KAAK,WAAW,GACjB,MAAM,oBAAoB,CAAC;AAC5B,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wDAAwD,CAAC;AACvE,cAAc,qCAAqC,CAAC;AACpD,cAAc,4DAA4D,CAAC;AAC3E,cAAc,iDAAiD,CAAC;AAChE,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mDAAmD,CAAC;AAClE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC"}
package/dist/postgres.js CHANGED
@@ -2,6 +2,8 @@ export { CONCURRENCY_CONFLICT, ConcurrencyError, optimisticUpdate, schemaNameOf,
2
2
  export * from './postgres/unit-of-work/drizzle-context.js';
3
3
  export * from './postgres/unit-of-work/create-drizzle-unit-of-work.js';
4
4
  export * from './postgres/schema/context-schema.js';
5
+ export * from './postgres/event-sourcing/create-drizzle-event-sourcing.js';
6
+ export * from './postgres/event-sourcing/event-store-tables.js';
5
7
  export * from './postgres/outbox/outbox-table.js';
6
8
  export * from './postgres/outbox/tenant-outbox-table.js';
7
9
  export * from './postgres/outbox/processed-events-table.js';
@@ -1 +1 @@
1
- {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GAEb,MAAM,oBAAoB,CAAC;AAC5B,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wDAAwD,CAAC;AACvE,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mDAAmD,CAAC;AAClE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC"}
1
+ {"version":3,"file":"postgres.js","sourceRoot":"","sources":["../src/postgres.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GAEb,MAAM,oBAAoB,CAAC;AAC5B,cAAc,4CAA4C,CAAC;AAC3D,cAAc,wDAAwD,CAAC;AACvE,cAAc,qCAAqC,CAAC;AACpD,cAAc,4DAA4D,CAAC;AAC3E,cAAc,iDAAiD,CAAC;AAChE,cAAc,mCAAmC,CAAC;AAClD,cAAc,0CAA0C,CAAC;AACzD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,+CAA+C,CAAC;AAC9D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,qDAAqD,CAAC;AACpE,cAAc,4CAA4C,CAAC;AAC3D,cAAc,mDAAmD,CAAC;AAClE,cAAc,mDAAmD,CAAC;AAClE,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,4CAA4C,CAAC;AAC3D,cAAc,uCAAuC,CAAC;AACtD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,sCAAsC,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ddd-ts-kit/drizzle",
3
- "version": "0.8.0",
4
- "description": "Drizzle adapters for the kernel ports on PostgreSQL: unit of work, transactional outbox store, processed-event store, one schema per context.",
3
+ "version": "0.10.0",
4
+ "description": "Drizzle adapters for the kernel ports on PostgreSQL: unit of work, transactional outbox store, processed-event store, event store, one schema per context.",
5
5
  "license": "MIT",
6
6
  "repository": {
7
7
  "type": "git",
@@ -26,8 +26,8 @@
26
26
  "dist"
27
27
  ],
28
28
  "dependencies": {
29
- "@ddd-ts-kit/kernel": "0.8.0",
30
- "@ddd-ts-kit/events": "0.8.0"
29
+ "@ddd-ts-kit/kernel": "0.10.0",
30
+ "@ddd-ts-kit/events": "0.10.0"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "drizzle-orm": ">=0.40.0"
@@ -35,7 +35,7 @@
35
35
  "devDependencies": {
36
36
  "drizzle-orm": "latest",
37
37
  "@electric-sql/pglite": "0.5.9",
38
- "@ddd-ts-kit/testing": "0.8.0",
38
+ "@ddd-ts-kit/testing": "0.10.0",
39
39
  "pg": "^8.23.1",
40
40
  "@types/pg": "^8.23.1"
41
41
  }