@chaos-overlords/storage 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.
Files changed (46) hide show
  1. package/LICENSE +674 -0
  2. package/NOTICE +21 -0
  3. package/README.md +35 -0
  4. package/dist/node/index.d.ts +29 -0
  5. package/dist/node/index.d.ts.map +1 -0
  6. package/dist/node/index.js +60 -0
  7. package/dist/node/index.js.map +1 -0
  8. package/dist/postgres/index.d.ts +3 -0
  9. package/dist/postgres/index.d.ts.map +1 -0
  10. package/dist/postgres/index.js +3 -0
  11. package/dist/postgres/index.js.map +1 -0
  12. package/dist/postgres/repositories.d.ts +11 -0
  13. package/dist/postgres/repositories.d.ts.map +1 -0
  14. package/dist/postgres/repositories.js +396 -0
  15. package/dist/postgres/repositories.js.map +1 -0
  16. package/dist/postgres/schema.d.ts +1002 -0
  17. package/dist/postgres/schema.d.ts.map +1 -0
  18. package/dist/postgres/schema.js +103 -0
  19. package/dist/postgres/schema.js.map +1 -0
  20. package/dist/shared/constraints.d.ts +6 -0
  21. package/dist/shared/constraints.d.ts.map +1 -0
  22. package/dist/shared/constraints.js +49 -0
  23. package/dist/shared/constraints.js.map +1 -0
  24. package/dist/shared/mappers.d.ts +105 -0
  25. package/dist/shared/mappers.d.ts.map +1 -0
  26. package/dist/shared/mappers.js +55 -0
  27. package/dist/shared/mappers.js.map +1 -0
  28. package/dist/sqlite/index.d.ts +3 -0
  29. package/dist/sqlite/index.d.ts.map +1 -0
  30. package/dist/sqlite/index.js +3 -0
  31. package/dist/sqlite/index.js.map +1 -0
  32. package/dist/sqlite/repositories.d.ts +11 -0
  33. package/dist/sqlite/repositories.d.ts.map +1 -0
  34. package/dist/sqlite/repositories.js +392 -0
  35. package/dist/sqlite/repositories.js.map +1 -0
  36. package/dist/sqlite/schema.d.ts +1063 -0
  37. package/dist/sqlite/schema.d.ts.map +1 -0
  38. package/dist/sqlite/schema.js +103 -0
  39. package/dist/sqlite/schema.js.map +1 -0
  40. package/migrations/postgres/0000_glorious_zaladane.sql +94 -0
  41. package/migrations/postgres/meta/0000_snapshot.json +637 -0
  42. package/migrations/postgres/meta/_journal.json +13 -0
  43. package/migrations/sqlite/0000_exotic_warbird.sql +94 -0
  44. package/migrations/sqlite/meta/0000_snapshot.json +605 -0
  45. package/migrations/sqlite/meta/_journal.json +13 -0
  46. package/package.json +94 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/postgres/schema.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCnB,CAAA;AAED,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgBnB,CAAA;AAED,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBjB,CAAA;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EActB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAavB,CAAA;AAED,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAcrB,CAAA;AAED,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAYvB,CAAA"}
@@ -0,0 +1,103 @@
1
+ import { boolean, index, integer, jsonb, pgTable, primaryKey, text, timestamp, } from 'drizzle-orm/pg-core';
2
+ /** The Postgres dialect. Column-for-column the SQLite schema; see that file for the layout notes. */
3
+ const stamp = (name) => timestamp(name, { withTimezone: true, mode: 'date' });
4
+ export const matches = pgTable('matches', {
5
+ id: text('id').primaryKey(),
6
+ status: text('status').notNull(),
7
+ name: text('name').notNull(),
8
+ visibility: text('visibility').notNull(),
9
+ maxPlayers: integer('max_players').notNull(),
10
+ settings: jsonb('settings').notNull(),
11
+ hostPlayerId: text('host_player_id').notNull(),
12
+ joinCode: text('join_code').notNull().unique(),
13
+ passwordHash: text('password_hash'),
14
+ /**
15
+ * A signed 32-bit integer, which is exactly what Postgres' `integer` holds: the seed is drawn to
16
+ * fit `MatchSetup.InitialSeed`, a C# `int`. No dialect divergence here — both lineages store the
17
+ * seed in the same width.
18
+ */
19
+ seed: integer('seed'),
20
+ currentTurn: integer('current_turn').notNull().default(0),
21
+ seatCount: integer('seat_count').notNull().default(1),
22
+ /** Monotonic: seats ever claimed. Never decremented, so `join_order` stays a total order. */
23
+ joinCounter: integer('join_counter').notNull().default(1),
24
+ createdAt: stamp('created_at').notNull(),
25
+ updatedAt: stamp('updated_at').notNull(),
26
+ }, (table) => [
27
+ // The sweep runs on a short interval and reads `matches` by status every tick: stalled seals of
28
+ // live matches, and inactive ones past their retention age. Without these it scans the whole
29
+ // table each time, which is the one cost that grows with every match ever played.
30
+ index('matches_status_updated_idx').on(table.status, table.updatedAt),
31
+ index('matches_lobby_idx').on(table.status, table.visibility, table.createdAt),
32
+ ]);
33
+ export const players = pgTable('players', {
34
+ id: text('id').primaryKey(),
35
+ matchId: text('match_id')
36
+ .notNull()
37
+ .references(() => matches.id, { onDelete: 'cascade' }),
38
+ slot: integer('slot').notNull().default(-1),
39
+ joinOrder: integer('join_order').notNull().default(0),
40
+ displayName: text('display_name').notNull(),
41
+ /** Null once revoked; SQL equality never matches null, so a revoked token resolves to nobody. */
42
+ tokenHash: text('token_hash').unique(),
43
+ status: text('status').notNull(),
44
+ joinedAt: stamp('joined_at').notNull(),
45
+ }, (table) => [index('players_match_idx').on(table.matchId)]);
46
+ export const turns = pgTable('turns', {
47
+ matchId: text('match_id')
48
+ .notNull()
49
+ .references(() => matches.id, { onDelete: 'cascade' }),
50
+ number: integer('number').notNull(),
51
+ status: text('status').notNull(),
52
+ openedAt: stamp('opened_at').notNull(),
53
+ deadlineAt: stamp('deadline_at'),
54
+ sealedAt: stamp('sealed_at'),
55
+ orderSetHash: text('order_set_hash'),
56
+ /** `[{ playerId, slot }]` frozen at seal time: exactly what `order_set_hash` was taken over. */
57
+ sealedSlots: jsonb('sealed_slots'),
58
+ }, (table) => [
59
+ primaryKey({ columns: [table.matchId, table.number] }),
60
+ index('turns_deadline_idx').on(table.status, table.deadlineAt),
61
+ ]);
62
+ export const turnOrders = pgTable('turn_orders', {
63
+ matchId: text('match_id')
64
+ .notNull()
65
+ .references(() => matches.id, { onDelete: 'cascade' }),
66
+ turn: integer('turn').notNull(),
67
+ playerId: text('player_id').notNull(),
68
+ orders: jsonb('orders'),
69
+ ordersHash: text('orders_hash'),
70
+ ready: boolean('ready').notNull().default(false),
71
+ submittedAt: stamp('submitted_at'),
72
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn, table.playerId] })]);
73
+ export const turnReports = pgTable('turn_reports', {
74
+ matchId: text('match_id')
75
+ .notNull()
76
+ .references(() => matches.id, { onDelete: 'cascade' }),
77
+ turn: integer('turn').notNull(),
78
+ playerId: text('player_id').notNull(),
79
+ stateHash: text('state_hash').notNull(),
80
+ finished: boolean('finished').notNull().default(false),
81
+ reportedAt: stamp('reported_at').notNull(),
82
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn, table.playerId] })]);
83
+ export const snapshots = pgTable('snapshots', {
84
+ matchId: text('match_id')
85
+ .notNull()
86
+ .references(() => matches.id, { onDelete: 'cascade' }),
87
+ turn: integer('turn').notNull(),
88
+ formatVersion: integer('format_version').notNull(),
89
+ stateHash: text('state_hash').notNull(),
90
+ uploadedByPlayerId: text('uploaded_by_player_id').notNull(),
91
+ uploadedAt: stamp('uploaded_at').notNull(),
92
+ body: text('body').notNull(),
93
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn] })]);
94
+ export const matchEvents = pgTable('match_events', {
95
+ matchId: text('match_id')
96
+ .notNull()
97
+ .references(() => matches.id, { onDelete: 'cascade' }),
98
+ seq: integer('seq').notNull(),
99
+ type: text('type').notNull(),
100
+ payload: jsonb('payload').notNull(),
101
+ createdAt: stamp('created_at').notNull(),
102
+ }, (table) => [primaryKey({ columns: [table.matchId, table.seq] })]);
103
+ //# 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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"}
@@ -0,0 +1,6 @@
1
+ /** Attempts an append makes at claiming the next sequence number before giving up. */
2
+ export declare const APPEND_ATTEMPTS = 8;
3
+ export declare function isUniqueViolation(error: unknown): boolean;
4
+ /** Runs `write`, translating a unique-constraint refusal into `false`. */
5
+ export declare function insertUnlessTaken(write: () => Promise<unknown>): Promise<boolean>;
6
+ //# sourceMappingURL=constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.d.ts","sourceRoot":"","sources":["../../src/shared/constraints.ts"],"names":[],"mappings":"AAkBA,sFAAsF;AACtF,eAAO,MAAM,eAAe,IAAI,CAAA;AAEhC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAazD;AAED,0EAA0E;AAC1E,wBAAsB,iBAAiB,CAAC,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAQvF"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Unique-constraint detection, the one place a driver's error shape is interpreted.
3
+ *
4
+ * The ports promise that a write a unique index can refuse answers `false` rather than throwing, so
5
+ * services retry (a join code collision, two appends racing for the same sequence number) without
6
+ * knowing which database they are on. Every layer reports the condition differently and Drizzle
7
+ * wraps the driver's error in its own, so the whole `cause` chain is inspected: node-postgres
8
+ * carries SQLSTATE 23505, better-sqlite3 an `SQLITE_CONSTRAINT…` code, and D1 only a message.
9
+ */
10
+ const UNIQUE_MESSAGES = [
11
+ 'UNIQUE constraint failed',
12
+ 'PRIMARY KEY must be unique',
13
+ 'duplicate key value violates unique constraint',
14
+ ];
15
+ const POSTGRES_UNIQUE_VIOLATION = '23505';
16
+ const SQLITE_CONSTRAINT_PREFIX = 'SQLITE_CONSTRAINT';
17
+ const MAX_CAUSE_DEPTH = 5;
18
+ /** Attempts an append makes at claiming the next sequence number before giving up. */
19
+ export const APPEND_ATTEMPTS = 8;
20
+ export function isUniqueViolation(error) {
21
+ let current = error;
22
+ for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth += 1) {
23
+ if (typeof current !== 'object' || current === null)
24
+ return false;
25
+ const { code, message } = current;
26
+ if (code === POSTGRES_UNIQUE_VIOLATION)
27
+ return true;
28
+ if (typeof code === 'string' && code.startsWith(SQLITE_CONSTRAINT_PREFIX))
29
+ return true;
30
+ if (typeof message === 'string' && UNIQUE_MESSAGES.some((needle) => message.includes(needle))) {
31
+ return true;
32
+ }
33
+ current = current.cause;
34
+ }
35
+ return false;
36
+ }
37
+ /** Runs `write`, translating a unique-constraint refusal into `false`. */
38
+ export async function insertUnlessTaken(write) {
39
+ try {
40
+ await write();
41
+ return true;
42
+ }
43
+ catch (error) {
44
+ if (isUniqueViolation(error))
45
+ return false;
46
+ throw error;
47
+ }
48
+ }
49
+ //# sourceMappingURL=constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constraints.js","sourceRoot":"","sources":["../../src/shared/constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,eAAe,GAAG;IACtB,0BAA0B;IAC1B,4BAA4B;IAC5B,gDAAgD;CACjD,CAAA;AACD,MAAM,yBAAyB,GAAG,OAAO,CAAA;AACzC,MAAM,wBAAwB,GAAG,mBAAmB,CAAA;AACpD,MAAM,eAAe,GAAG,CAAC,CAAA;AAEzB,sFAAsF;AACtF,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,CAAA;AAEhC,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,IAAI,OAAO,GAAY,KAAK,CAAA;IAC5B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,eAAe,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACxD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,KAAK,CAAA;QACjE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,OAAgD,CAAA;QAC1E,IAAI,IAAI,KAAK,yBAAyB;YAAE,OAAO,IAAI,CAAA;QACnD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,UAAU,CAAC,wBAAwB,CAAC;YAAE,OAAO,IAAI,CAAA;QACtF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YAC9F,OAAO,IAAI,CAAA;QACb,CAAC;QACD,OAAO,GAAI,OAA+B,CAAC,KAAK,CAAA;IAClD,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAA6B;IACnE,IAAI,CAAC;QACH,MAAM,KAAK,EAAE,CAAA;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,iBAAiB,CAAC,KAAK,CAAC;YAAE,OAAO,KAAK,CAAA;QAC1C,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
@@ -0,0 +1,105 @@
1
+ import type { Match, PersistedEvent, Player, Snapshot, Turn, TurnOrders, TurnReport } from '@chaos-overlords/kernel';
2
+ /**
3
+ * Row shapes after Drizzle's own mapping, identical across the two dialects: Dates for timestamps,
4
+ * parsed values for JSON, booleans for flags. Persisted enums are stored as text; each mapper
5
+ * narrows them back with a cast, since the service layer is the only writer.
6
+ */
7
+ export interface MatchRow {
8
+ id: string;
9
+ status: string;
10
+ settings: unknown;
11
+ hostPlayerId: string;
12
+ joinCode: string;
13
+ passwordHash: string | null;
14
+ seed: number | null;
15
+ currentTurn: number;
16
+ seatCount: number;
17
+ joinCounter: number;
18
+ createdAt: Date;
19
+ updatedAt: Date;
20
+ }
21
+ export interface PlayerRow {
22
+ id: string;
23
+ matchId: string;
24
+ slot: number;
25
+ joinOrder: number;
26
+ displayName: string;
27
+ tokenHash: string | null;
28
+ status: string;
29
+ joinedAt: Date;
30
+ }
31
+ export interface TurnRow {
32
+ matchId: string;
33
+ number: number;
34
+ status: string;
35
+ openedAt: Date;
36
+ deadlineAt: Date | null;
37
+ sealedAt: Date | null;
38
+ orderSetHash: string | null;
39
+ sealedSlots: unknown;
40
+ }
41
+ export interface TurnOrdersRow {
42
+ matchId: string;
43
+ turn: number;
44
+ playerId: string;
45
+ orders: unknown;
46
+ ordersHash: string | null;
47
+ ready: boolean;
48
+ submittedAt: Date | null;
49
+ }
50
+ export interface TurnReportRow {
51
+ matchId: string;
52
+ turn: number;
53
+ playerId: string;
54
+ stateHash: string;
55
+ finished: boolean;
56
+ reportedAt: Date;
57
+ }
58
+ export interface SnapshotRow {
59
+ matchId: string;
60
+ turn: number;
61
+ formatVersion: number;
62
+ stateHash: string;
63
+ uploadedByPlayerId: string;
64
+ uploadedAt: Date;
65
+ body: string;
66
+ }
67
+ export interface EventRow {
68
+ matchId: string;
69
+ seq: number;
70
+ type: string;
71
+ payload: unknown;
72
+ createdAt: Date;
73
+ }
74
+ export declare const toMatch: (row: MatchRow) => Match;
75
+ export declare const toMatchInsert: (match: Match) => {
76
+ id: string;
77
+ status: "lobby" | "running" | "desynced" | "finished" | "abandoned";
78
+ name: string;
79
+ visibility: "public" | "private";
80
+ maxPlayers: number;
81
+ settings: {
82
+ name: string;
83
+ maxPlayers: number;
84
+ turnTimerSeconds: number;
85
+ visibility: "public" | "private";
86
+ gameSettings: Record<string, unknown>;
87
+ };
88
+ hostPlayerId: string;
89
+ joinCode: string;
90
+ passwordHash: string | null;
91
+ seed: number | null;
92
+ currentTurn: number;
93
+ seatCount: number;
94
+ joinCounter: number;
95
+ createdAt: Date;
96
+ updatedAt: Date;
97
+ };
98
+ export declare const toPlayer: (row: PlayerRow) => Player;
99
+ export declare const toTurn: (row: TurnRow) => Turn;
100
+ export declare const toTurnOrders: (row: TurnOrdersRow) => TurnOrders;
101
+ export declare const toTurnReport: (row: TurnReportRow) => TurnReport;
102
+ export declare const toSnapshot: (row: SnapshotRow) => Snapshot;
103
+ export declare const toEvent: (row: EventRow) => PersistedEvent;
104
+ export declare const firstOrNull: <T>(rows: T[]) => T | null;
105
+ //# sourceMappingURL=mappers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappers.d.ts","sourceRoot":"","sources":["../../src/shared/mappers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export const toMatch = (row) => ({
2
+ id: row.id,
3
+ status: row.status,
4
+ settings: row.settings,
5
+ hostPlayerId: row.hostPlayerId,
6
+ joinCode: row.joinCode,
7
+ passwordHash: row.passwordHash,
8
+ seed: row.seed,
9
+ currentTurn: row.currentTurn,
10
+ seatCount: row.seatCount,
11
+ joinCounter: row.joinCounter,
12
+ createdAt: row.createdAt,
13
+ updatedAt: row.updatedAt,
14
+ });
15
+ export const toMatchInsert = (match) => ({
16
+ id: match.id,
17
+ status: match.status,
18
+ name: match.settings.name,
19
+ visibility: match.settings.visibility,
20
+ maxPlayers: match.settings.maxPlayers,
21
+ settings: match.settings,
22
+ hostPlayerId: match.hostPlayerId,
23
+ joinCode: match.joinCode,
24
+ passwordHash: match.passwordHash,
25
+ seed: match.seed,
26
+ currentTurn: match.currentTurn,
27
+ seatCount: match.seatCount,
28
+ joinCounter: match.joinCounter,
29
+ createdAt: match.createdAt,
30
+ updatedAt: match.updatedAt,
31
+ });
32
+ export const toPlayer = (row) => ({
33
+ ...row,
34
+ status: row.status,
35
+ });
36
+ export const toTurn = (row) => ({
37
+ ...row,
38
+ status: row.status,
39
+ sealedSlots: (row.sealedSlots ?? null),
40
+ });
41
+ export const toTurnOrders = (row) => ({
42
+ ...row,
43
+ orders: (row.orders ?? null),
44
+ });
45
+ export const toTurnReport = (row) => ({ ...row });
46
+ export const toSnapshot = (row) => ({ ...row });
47
+ export const toEvent = (row) => ({
48
+ matchId: row.matchId,
49
+ seq: row.seq,
50
+ type: row.type,
51
+ payload: row.payload,
52
+ createdAt: row.createdAt.toISOString(),
53
+ });
54
+ export const firstOrNull = (rows) => rows[0] ?? null;
55
+ //# sourceMappingURL=mappers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mappers.js","sourceRoot":"","sources":["../../src/shared/mappers.ts"],"names":[],"mappings":"AAiGA,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAa,EAAS,EAAE,CAAC,CAAC;IAChD,EAAE,EAAE,GAAG,CAAC,EAAE;IACV,MAAM,EAAE,GAAG,CAAC,MAAqB;IACjC,QAAQ,EAAE,GAAG,CAAC,QAAyB;IACvC,YAAY,EAAE,GAAG,CAAC,YAAY;IAC9B,QAAQ,EAAE,GAAG,CAAC,QAAQ;IACtB,YAAY,EAAE,GAAG,CAAC,YAAY;IAC9B,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,WAAW,EAAE,GAAG,CAAC,WAAW;IAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;IACxB,WAAW,EAAE,GAAG,CAAC,WAAW;IAC5B,SAAS,EAAE,GAAG,CAAC,SAAS;IACxB,SAAS,EAAE,GAAG,CAAC,SAAS;CACzB,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC;IAC9C,EAAE,EAAE,KAAK,CAAC,EAAE;IACZ,MAAM,EAAE,KAAK,CAAC,MAAM;IACpB,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI;IACzB,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;IACrC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,UAAU;IACrC,QAAQ,EAAE,KAAK,CAAC,QAAQ;IACxB,YAAY,EAAE,KAAK,CAAC,YAAY;IAChC,QAAQ,EAAE,KAAK,CAAC,QAAQ;IACxB,YAAY,EAAE,KAAK,CAAC,YAAY;IAChC,IAAI,EAAE,KAAK,CAAC,IAAI;IAChB,WAAW,EAAE,KAAK,CAAC,WAAW;IAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;IAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;IAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;IAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;CAC3B,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,GAAc,EAAU,EAAE,CAAC,CAAC;IACnD,GAAG,GAAG;IACN,MAAM,EAAE,GAAG,CAAC,MAAsB;CACnC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAY,EAAQ,EAAE,CAAC,CAAC;IAC7C,GAAG,GAAG;IACN,MAAM,EAAE,GAAG,CAAC,MAAoB;IAChC,WAAW,EAAE,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAiC;CACvE,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAkB,EAAc,EAAE,CAAC,CAAC;IAC/D,GAAG,GAAG;IACN,MAAM,EAAE,CAAC,GAAG,CAAC,MAAM,IAAI,IAAI,CAAyB;CACrD,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,GAAkB,EAAc,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAA;AAE5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,GAAgB,EAAY,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAA;AAEtE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAa,EAAkB,EAAE,CACvD,CAAC;IACC,OAAO,EAAE,GAAG,CAAC,OAAO;IACpB,GAAG,EAAE,GAAG,CAAC,GAAG;IACZ,IAAI,EAAE,GAAG,CAAC,IAAI;IACd,OAAO,EAAE,GAAG,CAAC,OAAO;IACpB,SAAS,EAAE,GAAG,CAAC,SAAS,CAAC,WAAW,EAAE;CACvC,CAAmB,CAAA;AAEtB,MAAM,CAAC,MAAM,WAAW,GAAG,CAAI,IAAS,EAAY,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { createSqliteStorage, type SqliteDatabase } from './repositories';
2
+ export * as sqliteSchema from './schema';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sqlite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACzE,OAAO,KAAK,YAAY,MAAM,UAAU,CAAA"}
@@ -0,0 +1,3 @@
1
+ export { createSqliteStorage } from './repositories';
2
+ export * as sqliteSchema from './schema';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sqlite/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAuB,MAAM,gBAAgB,CAAA;AACzE,OAAO,KAAK,YAAY,MAAM,UAAU,CAAA"}
@@ -0,0 +1,11 @@
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>;
10
+ export declare function createSqliteStorage(db: SqliteDatabase): MultiplayerStorage;
11
+ //# sourceMappingURL=repositories.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repositories.d.ts","sourceRoot":"","sources":["../../src/sqlite/repositories.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGV,kBAAkB,EAKnB,MAAM,yBAAyB,CAAA;AAgBhC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAajE,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,CAQ1E"}