orez 0.2.27 → 0.2.30

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 (157) hide show
  1. package/dist/cf-do/worker.d.ts +3 -0
  2. package/dist/cf-do/worker.d.ts.map +1 -1
  3. package/dist/cf-do/worker.js +37 -15
  4. package/dist/cf-do/worker.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +8 -0
  7. package/dist/index.js.map +1 -1
  8. package/package.json +3 -4
  9. package/src/admin/admin-data.test.ts +0 -348
  10. package/src/admin/http-proxy.ts +0 -252
  11. package/src/admin/log-store.ts +0 -192
  12. package/src/admin/server.ts +0 -471
  13. package/src/admin/ui.ts +0 -1322
  14. package/src/bench/proxy-throughput.bench.ts +0 -343
  15. package/src/bench/serial-mutations.bench.ts +0 -270
  16. package/src/browser.ts +0 -203
  17. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  18. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  19. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  20. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  21. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  22. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  23. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  24. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  25. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
  26. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
  27. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
  28. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
  29. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
  30. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
  31. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
  32. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
  33. package/src/cf-do/ARCHITECTURE.md +0 -93
  34. package/src/cf-do/CHAT_E2E.md +0 -213
  35. package/src/cf-do/watermark.test.ts +0 -103
  36. package/src/cf-do/watermark.ts +0 -118
  37. package/src/cf-do/worker.ts +0 -1041
  38. package/src/cf-do/wrangler.toml +0 -11
  39. package/src/cf-pglite/README.md +0 -19
  40. package/src/change-tracking.ts +0 -25
  41. package/src/child-process.test.ts +0 -147
  42. package/src/child-process.ts +0 -90
  43. package/src/cli-entry.ts +0 -72
  44. package/src/cli.test.ts +0 -40
  45. package/src/cli.ts +0 -1214
  46. package/src/config.ts +0 -150
  47. package/src/do-sql-tracking.test.ts +0 -19
  48. package/src/do-sql-tracking.ts +0 -19
  49. package/src/index.ts +0 -1215
  50. package/src/integration/integration.test.ts +0 -517
  51. package/src/integration/native-binary.guard.test.ts +0 -13
  52. package/src/integration/native-startup.test.ts +0 -44
  53. package/src/integration/replication-latency.test.ts +0 -428
  54. package/src/integration/restore-live-stress.test.ts +0 -433
  55. package/src/integration/restore-reset.test.ts +0 -400
  56. package/src/integration/restore.test.ts +0 -274
  57. package/src/integration/test-permissions.ts +0 -147
  58. package/src/load-config.ts +0 -46
  59. package/src/log.ts +0 -96
  60. package/src/mutex.ts +0 -47
  61. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  62. package/src/pg-proxy-browser.ts +0 -2022
  63. package/src/pg-proxy-do-backend.test.ts +0 -3890
  64. package/src/pg-proxy-do-backend.ts +0 -7191
  65. package/src/pg-proxy.ts +0 -1087
  66. package/src/pg-sqlite-compiler/README.md +0 -53
  67. package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
  68. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
  69. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
  70. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
  71. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
  72. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
  73. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
  74. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
  75. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
  76. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
  77. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
  78. package/src/pg-sqlite-compiler/index.ts +0 -73
  79. package/src/pg-sqlite-compiler/integration.test.ts +0 -136
  80. package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
  81. package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
  82. package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
  83. package/src/pg-sqlite-compiler/passes/index.ts +0 -49
  84. package/src/pg-sqlite-compiler/passes/types.ts +0 -156
  85. package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
  86. package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
  87. package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
  88. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
  89. package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
  90. package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
  91. package/src/pg-sqlite-compiler/types.ts +0 -63
  92. package/src/pglite-ipc.test.ts +0 -116
  93. package/src/pglite-ipc.ts +0 -266
  94. package/src/pglite-manager.ts +0 -557
  95. package/src/pglite-web-proxy.test.ts +0 -57
  96. package/src/pglite-web-proxy.ts +0 -221
  97. package/src/pglite-web-worker.ts +0 -152
  98. package/src/pglite-worker-thread.ts +0 -253
  99. package/src/port.ts +0 -25
  100. package/src/process-title.ts +0 -9
  101. package/src/recovery.ts +0 -155
  102. package/src/replication/change-tracker.test.ts +0 -357
  103. package/src/replication/change-tracker.ts +0 -279
  104. package/src/replication/handler.test.ts +0 -511
  105. package/src/replication/handler.ts +0 -1190
  106. package/src/replication/pgoutput-encoder.test.ts +0 -697
  107. package/src/replication/pgoutput-encoder.ts +0 -373
  108. package/src/replication/tcp-replication.test.ts +0 -876
  109. package/src/replication/zero-compat.test.ts +0 -1150
  110. package/src/restore-stress.test.ts +0 -188
  111. package/src/s3-local.ts +0 -203
  112. package/src/shim/hooks.mjs +0 -120
  113. package/src/shim/register.mjs +0 -4
  114. package/src/sqlite-mode/apply-mode.ts +0 -224
  115. package/src/sqlite-mode/index.ts +0 -15
  116. package/src/sqlite-mode/native-binary.ts +0 -89
  117. package/src/sqlite-mode/package-resolve.ts +0 -17
  118. package/src/sqlite-mode/resolve-mode.ts +0 -80
  119. package/src/sqlite-mode/shim-template.ts +0 -159
  120. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  121. package/src/sqlite-mode/types.ts +0 -30
  122. package/src/vite-plugin.ts +0 -67
  123. package/src/wasm-sqlite.test.ts +0 -537
  124. package/src/worker/browser-admin.ts +0 -52
  125. package/src/worker/browser-build-config.test.ts +0 -71
  126. package/src/worker/browser-build-config.ts +0 -109
  127. package/src/worker/browser-embed-admin.test.ts +0 -75
  128. package/src/worker/browser-embed.ts +0 -345
  129. package/src/worker/cf-patches.ts +0 -384
  130. package/src/worker/embed-integration.test.ts +0 -321
  131. package/src/worker/index.ts +0 -138
  132. package/src/worker/shims/fastify.test.ts +0 -255
  133. package/src/worker/shims/fastify.ts +0 -306
  134. package/src/worker/shims/http-service.test.ts +0 -355
  135. package/src/worker/shims/http-service.ts +0 -293
  136. package/src/worker/shims/node-stub.ts +0 -290
  137. package/src/worker/shims/oxfmt.ts +0 -3
  138. package/src/worker/shims/postgres-browser.ts +0 -59
  139. package/src/worker/shims/postgres-socket.test.ts +0 -576
  140. package/src/worker/shims/postgres-socket.ts +0 -310
  141. package/src/worker/shims/postgres.test.ts +0 -364
  142. package/src/worker/shims/postgres.ts +0 -1454
  143. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  144. package/src/worker/shims/sqlite-browser.ts +0 -175
  145. package/src/worker/shims/sqlite.test.ts +0 -786
  146. package/src/worker/shims/sqlite.ts +0 -978
  147. package/src/worker/shims/stream-browser.ts +0 -15
  148. package/src/worker/shims/ws-browser.test.ts +0 -205
  149. package/src/worker/shims/ws-browser.ts +0 -248
  150. package/src/worker/shims/ws.test.ts +0 -288
  151. package/src/worker/shims/ws.ts +0 -467
  152. package/src/worker/shims/zero-process-env.ts +0 -11
  153. package/src/worker/types.ts +0 -75
  154. package/src/worker/worker-integration.test.ts +0 -223
  155. package/src/worker/worker.test.ts +0 -136
  156. package/src/worker/zero-cache-embed-cf.ts +0 -463
  157. package/src/worker/zero-cache-embed.ts +0 -277
@@ -1,279 +0,0 @@
1
- import { log } from '../log.js'
2
-
3
- export interface ChangeRecord {
4
- watermark: number
5
- table_name: string
6
- op: 'INSERT' | 'UPDATE' | 'DELETE'
7
- row_data: Record<string, unknown> | null
8
- old_data: Record<string, unknown> | null
9
- }
10
-
11
- /**
12
- * minimal db interface change tracking needs. any sql executor that provides
13
- * these two methods (e.g., a PGlite instance or a proxy wrapper) is accepted.
14
- * using a structural type here keeps this module free of heavy imports so it
15
- * can be loaded as the standalone `orez/change-tracking` entrypoint without
16
- * pulling in pglite-manager or other server-only modules.
17
- */
18
- export interface ChangeTrackingDb {
19
- exec(sql: string): Promise<Array<{ affectedRows?: number }>>
20
- query<T>(sql: string, params?: unknown[]): Promise<{ rows: T[] }>
21
- }
22
-
23
- // PGlite returns JSONB columns as parsed objects; the DO backend returns them
24
- // as JSON strings (it stores `row_data TEXT`). normalize once at the consumer
25
- // boundary so callers always get an object.
26
- function jsonRecord(value: unknown): Record<string, unknown> | null {
27
- if (value === null || value === undefined) return null
28
- if (typeof value === 'object') return value as Record<string, unknown>
29
- if (typeof value !== 'string' || value === '') return null
30
- return JSON.parse(value) as Record<string, unknown>
31
- }
32
-
33
- export async function installChangeTracking(db: ChangeTrackingDb): Promise<void> {
34
- // use _orez schema for internal tables - survives pg_restore of public schema
35
- await db.exec(`CREATE SCHEMA IF NOT EXISTS _orez`)
36
-
37
- // create changes table and watermark sequence
38
- // watermark is the primary key - monotonically increasing, no separate id needed
39
- await db.exec(`
40
- CREATE SEQUENCE IF NOT EXISTS _orez._zero_watermark;
41
-
42
- CREATE TABLE IF NOT EXISTS _orez._zero_changes (
43
- watermark BIGINT NOT NULL DEFAULT nextval('_orez._zero_watermark') PRIMARY KEY,
44
- table_name TEXT NOT NULL,
45
- op TEXT NOT NULL CHECK (op IN ('INSERT', 'UPDATE', 'DELETE')),
46
- row_data JSONB,
47
- old_data JSONB
48
- );
49
-
50
- CREATE TABLE IF NOT EXISTS _orez._zero_replication_slots (
51
- slot_name TEXT PRIMARY KEY,
52
- restart_lsn TEXT NOT NULL DEFAULT '0/1000000',
53
- confirmed_flush_lsn TEXT NOT NULL DEFAULT '0/1000000',
54
- wal_status TEXT NOT NULL DEFAULT 'reserved',
55
- plugin TEXT NOT NULL DEFAULT 'pgoutput',
56
- slot_type TEXT NOT NULL DEFAULT 'logical',
57
- active BOOLEAN NOT NULL DEFAULT false,
58
- active_pid INTEGER DEFAULT NULL,
59
- created_at TIMESTAMPTZ DEFAULT NOW()
60
- );
61
- `)
62
-
63
- // create trigger functions (writes to _orez schema)
64
- // uses to_jsonb() directly instead of row_to_json()::jsonb to avoid double conversion.
65
- // per-row trigger for single-row operations
66
- await db.exec(`
67
- CREATE OR REPLACE FUNCTION public._zero_track_change() RETURNS TRIGGER AS $$
68
- BEGIN
69
- IF TG_OP = 'DELETE' THEN
70
- INSERT INTO _orez._zero_changes (table_name, op, old_data)
71
- VALUES (TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, 'DELETE', to_jsonb(OLD));
72
- RETURN OLD;
73
- ELSIF TG_OP = 'UPDATE' THEN
74
- -- skip no-op updates where no columns actually changed
75
- IF to_jsonb(NEW) = to_jsonb(OLD) THEN
76
- RETURN NEW;
77
- END IF;
78
- INSERT INTO _orez._zero_changes (table_name, op, row_data, old_data)
79
- VALUES (TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, 'UPDATE', to_jsonb(NEW), to_jsonb(OLD));
80
- RETURN NEW;
81
- ELSE
82
- INSERT INTO _orez._zero_changes (table_name, op, row_data)
83
- VALUES (TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, 'INSERT', to_jsonb(NEW));
84
- RETURN NEW;
85
- END IF;
86
- END;
87
- $$ LANGUAGE plpgsql;
88
- `)
89
-
90
- // install triggers on all public tables
91
- await installTriggersOnAllTables(db)
92
- }
93
-
94
- function quoteIdent(name: string): string {
95
- return '"' + name.replace(/"/g, '""') + '"'
96
- }
97
-
98
- async function installTriggersOnAllTables(db: ChangeTrackingDb): Promise<void> {
99
- // If a publication is configured, respect it strictly. This avoids accidentally
100
- // streaming private tables when publication membership is temporarily empty.
101
- const pubName = process.env.ZERO_APP_PUBLICATIONS?.trim()
102
- let tables: { tablename: string }[]
103
- if (pubName) {
104
- const result = await db.query<{ tablename: string }>(
105
- `SELECT tablename FROM pg_publication_tables
106
- WHERE pubname = $1
107
- AND schemaname = 'public'
108
- AND tablename NOT LIKE '_zero_%'`,
109
- [pubName]
110
- )
111
- tables = result.rows
112
- if (tables.length > 0) {
113
- log.debug.pglite(`using publication "${pubName}" (${tables.length} tables)`)
114
- } else {
115
- log.pglite(`publication "${pubName}" is empty; installing no public table triggers`)
116
- }
117
- } else {
118
- const all = await db.query<{ tablename: string }>(
119
- `SELECT tablename FROM pg_tables
120
- WHERE schemaname = 'public'
121
- AND tablename NOT IN ('migrations')
122
- AND tablename NOT LIKE '_zero_%'`
123
- )
124
- tables = all.rows
125
- log.debug.pglite(`using all public tables (${tables.length})`)
126
- }
127
-
128
- // drop stale triggers from tables NOT in the publication
129
- // (these may exist from a prior install before the publication was created)
130
- const publishedSet = new Set(tables.map((t) => t.tablename))
131
- const allTriggered = await db.query<{ event_object_table: string }>(
132
- `SELECT DISTINCT event_object_table FROM information_schema.triggers
133
- WHERE trigger_name = '_zero_change_trigger'
134
- AND event_object_schema = 'public'`
135
- )
136
- for (const { event_object_table } of allTriggered.rows) {
137
- if (!publishedSet.has(event_object_table)) {
138
- const quoted = quoteIdent(event_object_table)
139
- await db.exec(`DROP TRIGGER IF EXISTS _zero_change_trigger ON public.${quoted}`)
140
- log.debug.pglite(
141
- `removed stale trigger from non-published table: ${event_object_table}`
142
- )
143
- }
144
- }
145
-
146
- let count = 0
147
- for (const { tablename } of tables) {
148
- const quoted = quoteIdent(tablename)
149
- await db.exec(`
150
- DROP TRIGGER IF EXISTS _zero_change_trigger ON public.${quoted};
151
- CREATE TRIGGER _zero_change_trigger
152
- AFTER INSERT OR UPDATE OR DELETE ON public.${quoted}
153
- FOR EACH ROW EXECUTE FUNCTION public._zero_track_change();
154
- `)
155
- count++
156
- }
157
-
158
- if (count > 0) {
159
- log.debug.pglite(`installed change tracking triggers on ${count} tables`)
160
- } else {
161
- log.debug.pglite(`no tables to install change tracking triggers on`)
162
- }
163
- }
164
-
165
- /**
166
- * install change tracking triggers on tables in shard schemas.
167
- * zero-cache creates shard schemas (e.g. chat_0) with clients/mutations
168
- * tables that track mutation confirmations. these must be replicated
169
- * for .server promises to resolve.
170
- *
171
- * caches already-tracked shard tables to avoid redundant DDL while still
172
- * handling zero-cache creating a schema before the internal tables exist.
173
- */
174
- const trackedShardTables = new Set<string>()
175
- const TRACKED_SHARD_TABLES = new Set(['clients', 'mutations'])
176
-
177
- /** reset shard schema cache (for tests) */
178
- export function resetShardSchemaCache(): void {
179
- trackedShardTables.clear()
180
- }
181
-
182
- export async function installTriggersOnShardTables(db: ChangeTrackingDb): Promise<void> {
183
- const result = await db.query<{ nspname: string }>(
184
- `SELECT nspname FROM pg_namespace
185
- WHERE nspname NOT IN ('pg_catalog', 'information_schema', 'pg_toast', 'public')
186
- AND nspname NOT LIKE 'pg_%'
187
- AND nspname NOT LIKE 'zero_%'
188
- AND nspname NOT LIKE '_zero_%'
189
- AND nspname NOT LIKE '%/%'`
190
- )
191
-
192
- if (result.rows.length === 0) return
193
-
194
- // only track the shard tables zero-cache expects in the replication stream.
195
- // `clients` advances LMID for successful .server promises; `mutations`
196
- // carries per-mutation results for application errors. other shard tables
197
- // like `replicas` are zero-cache internal state and streaming them back
198
- // causes "Unknown table" crashes in zero-cache's change-processor.
199
- let count = 0
200
- for (const { nspname } of result.rows) {
201
- // remove stale triggers from non-replicated shard tables.
202
- const stale = await db.query<{ event_object_table: string }>(
203
- `SELECT DISTINCT event_object_table FROM information_schema.triggers
204
- WHERE trigger_name = '_zero_change_trigger'
205
- AND event_object_schema = $1
206
- AND event_object_table != ALL($2)`,
207
- [nspname, [...TRACKED_SHARD_TABLES]]
208
- )
209
- for (const { event_object_table } of stale.rows) {
210
- const qs = quoteIdent(nspname)
211
- const qt = quoteIdent(event_object_table)
212
- await db.exec(`DROP TRIGGER IF EXISTS _zero_change_trigger ON ${qs}.${qt}`)
213
- log.debug.pglite(
214
- `removed stale shard trigger from ${nspname}.${event_object_table}`
215
- )
216
- }
217
-
218
- const tables = await db.query<{ tablename: string }>(
219
- `SELECT tablename FROM pg_tables WHERE schemaname = $1 AND tablename = ANY($2)`,
220
- [nspname, [...TRACKED_SHARD_TABLES]]
221
- )
222
-
223
- for (const { tablename } of tables.rows) {
224
- const key = `${nspname}.${tablename}`
225
- if (trackedShardTables.has(key)) continue
226
-
227
- const quotedSchema = quoteIdent(nspname)
228
- const quotedTable = quoteIdent(tablename)
229
- await db.exec(`
230
- DROP TRIGGER IF EXISTS _zero_change_trigger ON ${quotedSchema}.${quotedTable};
231
- CREATE TRIGGER _zero_change_trigger
232
- AFTER INSERT OR UPDATE OR DELETE ON ${quotedSchema}.${quotedTable}
233
- FOR EACH ROW EXECUTE FUNCTION public._zero_track_change();
234
- `)
235
- trackedShardTables.add(key)
236
- count++
237
- }
238
- }
239
-
240
- if (count > 0) {
241
- log.debug.pglite(`installed change tracking on ${count} shard tables`)
242
- }
243
- }
244
-
245
- export async function getChangesSince(
246
- db: ChangeTrackingDb,
247
- watermark: number,
248
- limit = 50000
249
- ): Promise<ChangeRecord[]> {
250
- const result = await db.query<ChangeRecord>(
251
- 'SELECT watermark, table_name, op, row_data, old_data FROM _orez._zero_changes WHERE watermark > $1 ORDER BY watermark LIMIT $2',
252
- [watermark, limit]
253
- )
254
- return result.rows.map((row) => ({
255
- ...row,
256
- watermark: Number(row.watermark),
257
- row_data: jsonRecord(row.row_data),
258
- old_data: jsonRecord(row.old_data),
259
- }))
260
- }
261
-
262
- export async function purgeConsumedChanges(
263
- db: ChangeTrackingDb,
264
- watermark: number
265
- ): Promise<number> {
266
- const result = await db.exec(
267
- `DELETE FROM _orez._zero_changes WHERE watermark <= ${Number(watermark)}`
268
- )
269
- return result[0]?.affectedRows ?? 0
270
- }
271
-
272
- export async function getCurrentWatermark(db: ChangeTrackingDb): Promise<number> {
273
- const result = await db.query<{ last_value: string; is_called: boolean }>(
274
- 'SELECT last_value, is_called FROM _orez._zero_watermark'
275
- )
276
- const { last_value, is_called } = result.rows[0]
277
- if (!is_called) return 0
278
- return Number(last_value)
279
- }