@chaos-overlords/storage 0.8.1 → 0.9.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 (59) hide show
  1. package/dist/node/index.d.ts +11 -3
  2. package/dist/node/index.d.ts.map +1 -1
  3. package/dist/node/index.js +26 -7
  4. package/dist/node/index.js.map +1 -1
  5. package/dist/postgres/database.d.ts +10 -0
  6. package/dist/postgres/database.d.ts.map +1 -0
  7. package/dist/postgres/database.js +2 -0
  8. package/dist/postgres/database.js.map +1 -0
  9. package/dist/postgres/events.d.ts +9 -0
  10. package/dist/postgres/events.d.ts.map +1 -0
  11. package/dist/postgres/events.js +56 -0
  12. package/dist/postgres/events.js.map +1 -0
  13. package/dist/postgres/repositories.d.ts +2 -3
  14. package/dist/postgres/repositories.d.ts.map +1 -1
  15. package/dist/postgres/repositories.js +188 -237
  16. package/dist/postgres/repositories.js.map +1 -1
  17. package/dist/postgres/schema.d.ts +26 -9
  18. package/dist/postgres/schema.d.ts.map +1 -1
  19. package/dist/postgres/schema.js +6 -0
  20. package/dist/postgres/schema.js.map +1 -1
  21. package/dist/postgres/takeovers.d.ts +12 -0
  22. package/dist/postgres/takeovers.d.ts.map +1 -0
  23. package/dist/postgres/takeovers.js +88 -0
  24. package/dist/postgres/takeovers.js.map +1 -0
  25. package/dist/shared/constraints.d.ts +18 -0
  26. package/dist/shared/constraints.d.ts.map +1 -1
  27. package/dist/shared/constraints.js +36 -0
  28. package/dist/shared/constraints.js.map +1 -1
  29. package/dist/shared/mappers.d.ts +28 -5
  30. package/dist/shared/mappers.d.ts.map +1 -1
  31. package/dist/shared/mappers.js +31 -0
  32. package/dist/shared/mappers.js.map +1 -1
  33. package/dist/sqlite/database.d.ts +12 -0
  34. package/dist/sqlite/database.d.ts.map +1 -0
  35. package/dist/sqlite/database.js +2 -0
  36. package/dist/sqlite/database.js.map +1 -0
  37. package/dist/sqlite/events.d.ts +9 -0
  38. package/dist/sqlite/events.d.ts.map +1 -0
  39. package/dist/sqlite/events.js +56 -0
  40. package/dist/sqlite/events.js.map +1 -0
  41. package/dist/sqlite/repositories.d.ts +2 -8
  42. package/dist/sqlite/repositories.d.ts.map +1 -1
  43. package/dist/sqlite/repositories.js +214 -237
  44. package/dist/sqlite/repositories.js.map +1 -1
  45. package/dist/sqlite/schema.d.ts +26 -9
  46. package/dist/sqlite/schema.d.ts.map +1 -1
  47. package/dist/sqlite/schema.js +6 -0
  48. package/dist/sqlite/schema.js.map +1 -1
  49. package/dist/sqlite/takeovers.d.ts +12 -0
  50. package/dist/sqlite/takeovers.d.ts.map +1 -0
  51. package/dist/sqlite/takeovers.js +88 -0
  52. package/dist/sqlite/takeovers.js.map +1 -0
  53. package/migrations/postgres/0005_old_husk.sql +6 -0
  54. package/migrations/postgres/meta/0005_snapshot.json +854 -0
  55. package/migrations/postgres/meta/_journal.json +8 -1
  56. package/migrations/sqlite/0005_lumpy_stingray.sql +6 -0
  57. package/migrations/sqlite/meta/0005_snapshot.json +844 -0
  58. package/migrations/sqlite/meta/_journal.json +8 -1
  59. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../src/sqlite/database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,KAAK,KAAK,MAAM,MAAM,UAAU,CAAA;AAEvC;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=database.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/sqlite/database.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ import type { EventRepository } from '@chaos-overlords/kernel';
2
+ import type { SqliteDatabase } from './database';
3
+ /**
4
+ * The match event log in the SQLite dialect: the gapless, self-allocating sequence every stream
5
+ * cursor moves along. Its own module because the allocation rule — `max(seq) + 1` inside the
6
+ * insert, retried on the primary key — is the one invariant the whole delivery contract rests on.
7
+ */
8
+ export declare function sqliteEventRepository(db: SqliteDatabase): EventRepository;
9
+ //# sourceMappingURL=events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sqlite/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,yBAAyB,CAAA;AAI9E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAGhD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,cAAc,GAAG,eAAe,CA6CzE"}
@@ -0,0 +1,56 @@
1
+ import { and, asc, desc, eq, sql } from 'drizzle-orm';
2
+ import { appendWithRetry } from '../shared/constraints';
3
+ import { toEvent } from '../shared/mappers';
4
+ import * as schema from './schema';
5
+ /**
6
+ * The match event log in the SQLite dialect: the gapless, self-allocating sequence every stream
7
+ * cursor moves along. Its own module because the allocation rule — `max(seq) + 1` inside the
8
+ * insert, retried on the primary key — is the one invariant the whole delivery contract rests on.
9
+ */
10
+ export function sqliteEventRepository(db) {
11
+ const { matchEvents } = schema;
12
+ return {
13
+ /**
14
+ * The sequence number comes from the log itself inside the insert, so the allocation cannot be
15
+ * separated from the write: a committed `seq` therefore implies every lower one is committed,
16
+ * which is the invariant a stream cursor relies on. Concurrent appends collide on the primary
17
+ * key and the loser simply re-reads the maximum.
18
+ */
19
+ async append(event) {
20
+ const nextSeq = sql `(select coalesce(max(${matchEvents.seq}), 0) + 1 from ${matchEvents} where ${eq(matchEvents.matchId, event.matchId)})`;
21
+ const seq = await appendWithRetry(event.matchId, async () => {
22
+ const rows = await db
23
+ .insert(matchEvents)
24
+ .values({
25
+ matchId: event.matchId,
26
+ seq: nextSeq,
27
+ type: event.type,
28
+ payload: event.payload,
29
+ createdAt: new Date(event.createdAt),
30
+ })
31
+ .returning({ seq: matchEvents.seq });
32
+ return rows[0]?.seq;
33
+ });
34
+ return { ...event, seq };
35
+ },
36
+ async listAfter(matchId, afterSeq, limit) {
37
+ const rows = await db
38
+ .select()
39
+ .from(matchEvents)
40
+ .where(and(eq(matchEvents.matchId, matchId), sql `${matchEvents.seq} > ${afterSeq}`))
41
+ .orderBy(asc(matchEvents.seq))
42
+ .limit(limit);
43
+ return rows.map(toEvent);
44
+ },
45
+ async lastSeq(matchId) {
46
+ const rows = await db
47
+ .select({ seq: matchEvents.seq })
48
+ .from(matchEvents)
49
+ .where(eq(matchEvents.matchId, matchId))
50
+ .orderBy(desc(matchEvents.seq))
51
+ .limit(1);
52
+ return rows[0]?.seq ?? 0;
53
+ },
54
+ };
55
+ }
56
+ //# sourceMappingURL=events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sqlite/events.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAE3C,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAElC;;;;GAIG;AACH,MAAM,UAAU,qBAAqB,CAAC,EAAkB;IACtD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAA;IAC9B,OAAO;QACL;;;;;WAKG;QACH,KAAK,CAAC,MAAM,CAAC,KAAK;YAChB,MAAM,OAAO,GAAG,GAAG,CAAQ,wBAAwB,WAAW,CAAC,GAAG,kBAAkB,WAAW,UAAU,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAA;YAClJ,MAAM,GAAG,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;gBAC1D,MAAM,IAAI,GAAG,MAAM,EAAE;qBAClB,MAAM,CAAC,WAAW,CAAC;qBACnB,MAAM,CAAC;oBACN,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,GAAG,EAAE,OAAO;oBACZ,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC;iBACrC,CAAC;qBACD,SAAS,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC,CAAA;gBACtC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,CAAA;YACrB,CAAC,CAAC,CAAA;YACF,OAAO,EAAE,GAAG,KAAK,EAAE,GAAG,EAAoB,CAAA;QAC5C,CAAC;QACD,KAAK,CAAC,SAAS,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK;YACtC,MAAM,IAAI,GAAG,MAAM,EAAE;iBAClB,MAAM,EAAE;iBACR,IAAI,CAAC,WAAW,CAAC;iBACjB,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,EAAE,GAAG,CAAA,GAAG,WAAW,CAAC,GAAG,MAAM,QAAQ,EAAE,CAAC,CAAC;iBACnF,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;iBAC7B,KAAK,CAAC,KAAK,CAAC,CAAA;YACf,OAAO,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QAC1B,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,OAAO;YACnB,MAAM,IAAI,GAAG,MAAM,EAAE;iBAClB,MAAM,CAAC,EAAE,GAAG,EAAE,WAAW,CAAC,GAAG,EAAE,CAAC;iBAChC,IAAI,CAAC,WAAW,CAAC;iBACjB,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;iBACvC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;iBAC9B,KAAK,CAAC,CAAC,CAAC,CAAA;YACX,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -1,11 +1,5 @@
1
1
  import type { MultiplayerStorage } from '@chaos-overlords/kernel';
2
- import type { BaseSQLiteDatabase } from 'drizzle-orm/sqlite-core';
3
- import * as schema from './schema';
4
- /**
5
- * Either SQLite driver Drizzle offers: better-sqlite3 (`'sync'`) or D1 (`'async'`). Awaiting a
6
- * synchronous result is a no-op, so one implementation serves both. Every conditional write ends
7
- * in `.returning()` because the two drivers report affected rows in different shapes.
8
- */
9
- export type SqliteDatabase = BaseSQLiteDatabase<'sync' | 'async', unknown, typeof schema>;
2
+ import type { SqliteDatabase } from './database';
3
+ export type { SqliteDatabase };
10
4
  export declare function createSqliteStorage(db: SqliteDatabase): MultiplayerStorage;
11
5
  //# sourceMappingURL=repositories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repositories.d.ts","sourceRoot":"","sources":["../../src/sqlite/repositories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,kBAAkB,EAMnB,MAAM,yBAAyB,CAAA;AAiBhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAejE,OAAO,KAAK,MAAM,MAAM,UAAU,CAAA;AAElC;;;;GAIG;AACH,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAC,MAAM,GAAG,OAAO,EAAE,OAAO,EAAE,OAAO,MAAM,CAAC,CAAA;AAEzF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,kBAAkB,CAS1E"}
1
+ {"version":3,"file":"repositories.d.ts","sourceRoot":"","sources":["../../src/sqlite/repositories.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,kBAAkB,EAMnB,MAAM,yBAAyB,CAAA;AAgChC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKhD,YAAY,EAAE,cAAc,EAAE,CAAA;AAE9B,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,cAAc,GAAG,kBAAkB,CAS1E"}