@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/sqlite/schema.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BnB,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 { index, integer, primaryKey, sqliteTable, text } from 'drizzle-orm/sqlite-core';
2
+ /**
3
+ * The SQLite dialect, shared byte-for-byte by better-sqlite3 (Node) and D1 (Cloudflare): one
4
+ * migration lineage serves both. Timestamps are epoch milliseconds; JSON columns are text.
5
+ * `name`, `visibility` and `max_players` are copied out of `settings` so the lobby list and the
6
+ * seat-capacity check are plain SQL; `settings` stays the source clients read back. Every child
7
+ * table cascades from `matches`, so retention is one delete of the rows a match owns.
8
+ */
9
+ export const matches = sqliteTable('matches', {
10
+ id: text('id').primaryKey(),
11
+ status: text('status').notNull(),
12
+ name: text('name').notNull(),
13
+ visibility: text('visibility').notNull(),
14
+ maxPlayers: integer('max_players').notNull(),
15
+ settings: text('settings', { mode: 'json' }).notNull(),
16
+ hostPlayerId: text('host_player_id').notNull(),
17
+ joinCode: text('join_code').notNull().unique(),
18
+ passwordHash: text('password_hash'),
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: integer('created_at', { mode: 'timestamp_ms' }).notNull(),
25
+ updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).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 = sqliteTable('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: integer('joined_at', { mode: 'timestamp_ms' }).notNull(),
45
+ }, (table) => [index('players_match_idx').on(table.matchId)]);
46
+ export const turns = sqliteTable('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: integer('opened_at', { mode: 'timestamp_ms' }).notNull(),
53
+ deadlineAt: integer('deadline_at', { mode: 'timestamp_ms' }),
54
+ sealedAt: integer('sealed_at', { mode: 'timestamp_ms' }),
55
+ orderSetHash: text('order_set_hash'),
56
+ /** `[{ playerId, slot }]` frozen at seal time: exactly what `order_set_hash` was taken over. */
57
+ sealedSlots: text('sealed_slots', { mode: 'json' }),
58
+ }, (table) => [
59
+ primaryKey({ columns: [table.matchId, table.number] }),
60
+ index('turns_deadline_idx').on(table.status, table.deadlineAt),
61
+ ]);
62
+ export const turnOrders = sqliteTable('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: text('orders', { mode: 'json' }),
69
+ ordersHash: text('orders_hash'),
70
+ ready: integer('ready', { mode: 'boolean' }).notNull().default(false),
71
+ submittedAt: integer('submitted_at', { mode: 'timestamp_ms' }),
72
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn, table.playerId] })]);
73
+ export const turnReports = sqliteTable('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: integer('finished', { mode: 'boolean' }).notNull().default(false),
81
+ reportedAt: integer('reported_at', { mode: 'timestamp_ms' }).notNull(),
82
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn, table.playerId] })]);
83
+ export const snapshots = sqliteTable('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: integer('uploaded_at', { mode: 'timestamp_ms' }).notNull(),
92
+ body: text('body').notNull(),
93
+ }, (table) => [primaryKey({ columns: [table.matchId, table.turn] })]);
94
+ export const matchEvents = sqliteTable('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: text('payload', { mode: 'json' }).notNull(),
101
+ createdAt: integer('created_at', { mode: 'timestamp_ms' }).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/sqlite/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ CREATE TABLE "match_events" (
2
+ "match_id" text NOT NULL,
3
+ "seq" integer NOT NULL,
4
+ "type" text NOT NULL,
5
+ "payload" jsonb NOT NULL,
6
+ "created_at" timestamp with time zone NOT NULL,
7
+ CONSTRAINT "match_events_match_id_seq_pk" PRIMARY KEY("match_id","seq")
8
+ );
9
+ --> statement-breakpoint
10
+ CREATE TABLE "matches" (
11
+ "id" text PRIMARY KEY NOT NULL,
12
+ "status" text NOT NULL,
13
+ "name" text NOT NULL,
14
+ "visibility" text NOT NULL,
15
+ "max_players" integer NOT NULL,
16
+ "settings" jsonb NOT NULL,
17
+ "host_player_id" text NOT NULL,
18
+ "join_code" text NOT NULL,
19
+ "password_hash" text,
20
+ "seed" integer,
21
+ "current_turn" integer DEFAULT 0 NOT NULL,
22
+ "seat_count" integer DEFAULT 1 NOT NULL,
23
+ "join_counter" integer DEFAULT 1 NOT NULL,
24
+ "created_at" timestamp with time zone NOT NULL,
25
+ "updated_at" timestamp with time zone NOT NULL,
26
+ CONSTRAINT "matches_join_code_unique" UNIQUE("join_code")
27
+ );
28
+ --> statement-breakpoint
29
+ CREATE TABLE "players" (
30
+ "id" text PRIMARY KEY NOT NULL,
31
+ "match_id" text NOT NULL,
32
+ "slot" integer DEFAULT -1 NOT NULL,
33
+ "join_order" integer DEFAULT 0 NOT NULL,
34
+ "display_name" text NOT NULL,
35
+ "token_hash" text,
36
+ "status" text NOT NULL,
37
+ "joined_at" timestamp with time zone NOT NULL,
38
+ CONSTRAINT "players_token_hash_unique" UNIQUE("token_hash")
39
+ );
40
+ --> statement-breakpoint
41
+ CREATE TABLE "snapshots" (
42
+ "match_id" text NOT NULL,
43
+ "turn" integer NOT NULL,
44
+ "format_version" integer NOT NULL,
45
+ "state_hash" text NOT NULL,
46
+ "uploaded_by_player_id" text NOT NULL,
47
+ "uploaded_at" timestamp with time zone NOT NULL,
48
+ "body" text NOT NULL,
49
+ CONSTRAINT "snapshots_match_id_turn_pk" PRIMARY KEY("match_id","turn")
50
+ );
51
+ --> statement-breakpoint
52
+ CREATE TABLE "turn_orders" (
53
+ "match_id" text NOT NULL,
54
+ "turn" integer NOT NULL,
55
+ "player_id" text NOT NULL,
56
+ "orders" jsonb,
57
+ "orders_hash" text,
58
+ "ready" boolean DEFAULT false NOT NULL,
59
+ "submitted_at" timestamp with time zone,
60
+ CONSTRAINT "turn_orders_match_id_turn_player_id_pk" PRIMARY KEY("match_id","turn","player_id")
61
+ );
62
+ --> statement-breakpoint
63
+ CREATE TABLE "turn_reports" (
64
+ "match_id" text NOT NULL,
65
+ "turn" integer NOT NULL,
66
+ "player_id" text NOT NULL,
67
+ "state_hash" text NOT NULL,
68
+ "finished" boolean DEFAULT false NOT NULL,
69
+ "reported_at" timestamp with time zone NOT NULL,
70
+ CONSTRAINT "turn_reports_match_id_turn_player_id_pk" PRIMARY KEY("match_id","turn","player_id")
71
+ );
72
+ --> statement-breakpoint
73
+ CREATE TABLE "turns" (
74
+ "match_id" text NOT NULL,
75
+ "number" integer NOT NULL,
76
+ "status" text NOT NULL,
77
+ "opened_at" timestamp with time zone NOT NULL,
78
+ "deadline_at" timestamp with time zone,
79
+ "sealed_at" timestamp with time zone,
80
+ "order_set_hash" text,
81
+ "sealed_slots" jsonb,
82
+ CONSTRAINT "turns_match_id_number_pk" PRIMARY KEY("match_id","number")
83
+ );
84
+ --> statement-breakpoint
85
+ ALTER TABLE "match_events" ADD CONSTRAINT "match_events_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
86
+ ALTER TABLE "players" ADD CONSTRAINT "players_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
87
+ ALTER TABLE "snapshots" ADD CONSTRAINT "snapshots_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
88
+ ALTER TABLE "turn_orders" ADD CONSTRAINT "turn_orders_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
89
+ ALTER TABLE "turn_reports" ADD CONSTRAINT "turn_reports_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
90
+ ALTER TABLE "turns" ADD CONSTRAINT "turns_match_id_matches_id_fk" FOREIGN KEY ("match_id") REFERENCES "public"."matches"("id") ON DELETE cascade ON UPDATE no action;--> statement-breakpoint
91
+ CREATE INDEX "matches_status_updated_idx" ON "matches" USING btree ("status","updated_at");--> statement-breakpoint
92
+ CREATE INDEX "matches_lobby_idx" ON "matches" USING btree ("status","visibility","created_at");--> statement-breakpoint
93
+ CREATE INDEX "players_match_idx" ON "players" USING btree ("match_id");--> statement-breakpoint
94
+ CREATE INDEX "turns_deadline_idx" ON "turns" USING btree ("status","deadline_at");