orez 0.2.25 → 0.2.27

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 (175) hide show
  1. package/dist/cf-do/watermark.d.ts +21 -0
  2. package/dist/cf-do/watermark.d.ts.map +1 -0
  3. package/dist/cf-do/watermark.js +93 -0
  4. package/dist/cf-do/watermark.js.map +1 -0
  5. package/dist/cf-do/worker.d.ts +48 -22
  6. package/dist/cf-do/worker.d.ts.map +1 -1
  7. package/dist/cf-do/worker.js +650 -269
  8. package/dist/cf-do/worker.js.map +1 -1
  9. package/dist/config.js +1 -1
  10. package/dist/config.js.map +1 -1
  11. package/dist/do-sql-tracking.d.ts +6 -0
  12. package/dist/do-sql-tracking.d.ts.map +1 -0
  13. package/dist/do-sql-tracking.js +14 -0
  14. package/dist/do-sql-tracking.js.map +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +28 -14
  17. package/dist/index.js.map +1 -1
  18. package/dist/pg-proxy-browser.js +6 -6
  19. package/dist/pg-proxy-browser.js.map +1 -1
  20. package/dist/pg-proxy-do-backend.d.ts +98 -17
  21. package/dist/pg-proxy-do-backend.d.ts.map +1 -1
  22. package/dist/pg-proxy-do-backend.js +6075 -454
  23. package/dist/pg-proxy-do-backend.js.map +1 -1
  24. package/dist/pg-sqlite-compiler/catalog/seed.d.ts +67 -0
  25. package/dist/pg-sqlite-compiler/catalog/seed.d.ts.map +1 -0
  26. package/dist/pg-sqlite-compiler/catalog/seed.js +436 -0
  27. package/dist/pg-sqlite-compiler/catalog/seed.js.map +1 -0
  28. package/dist/pg-sqlite-compiler/index.d.ts +12 -0
  29. package/dist/pg-sqlite-compiler/index.d.ts.map +1 -0
  30. package/dist/pg-sqlite-compiler/index.js +59 -0
  31. package/dist/pg-sqlite-compiler/index.js.map +1 -0
  32. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts +48 -0
  33. package/dist/pg-sqlite-compiler/passes/ast-utils.d.ts.map +1 -0
  34. package/dist/pg-sqlite-compiler/passes/ast-utils.js +93 -0
  35. package/dist/pg-sqlite-compiler/passes/ast-utils.js.map +1 -0
  36. package/dist/pg-sqlite-compiler/passes/catalog.d.ts +34 -0
  37. package/dist/pg-sqlite-compiler/passes/catalog.d.ts.map +1 -0
  38. package/dist/pg-sqlite-compiler/passes/catalog.js +30 -0
  39. package/dist/pg-sqlite-compiler/passes/catalog.js.map +1 -0
  40. package/dist/pg-sqlite-compiler/passes/datetime.d.ts +21 -0
  41. package/dist/pg-sqlite-compiler/passes/datetime.d.ts.map +1 -0
  42. package/dist/pg-sqlite-compiler/passes/datetime.js +53 -0
  43. package/dist/pg-sqlite-compiler/passes/datetime.js.map +1 -0
  44. package/dist/pg-sqlite-compiler/passes/index.d.ts +21 -0
  45. package/dist/pg-sqlite-compiler/passes/index.d.ts.map +1 -0
  46. package/dist/pg-sqlite-compiler/passes/index.js +39 -0
  47. package/dist/pg-sqlite-compiler/passes/index.js.map +1 -0
  48. package/dist/pg-sqlite-compiler/passes/types.d.ts +41 -0
  49. package/dist/pg-sqlite-compiler/passes/types.d.ts.map +1 -0
  50. package/dist/pg-sqlite-compiler/passes/types.js +103 -0
  51. package/dist/pg-sqlite-compiler/passes/types.js.map +1 -0
  52. package/dist/pg-sqlite-compiler/test/oracle.d.ts +34 -0
  53. package/dist/pg-sqlite-compiler/test/oracle.d.ts.map +1 -0
  54. package/dist/pg-sqlite-compiler/test/oracle.js +204 -0
  55. package/dist/pg-sqlite-compiler/test/oracle.js.map +1 -0
  56. package/dist/pg-sqlite-compiler/types.d.ts +55 -0
  57. package/dist/pg-sqlite-compiler/types.d.ts.map +1 -0
  58. package/dist/pg-sqlite-compiler/types.js +2 -0
  59. package/dist/pg-sqlite-compiler/types.js.map +1 -0
  60. package/dist/replication/change-tracker.d.ts.map +1 -1
  61. package/dist/replication/change-tracker.js +18 -1
  62. package/dist/replication/change-tracker.js.map +1 -1
  63. package/dist/replication/handler.d.ts.map +1 -1
  64. package/dist/replication/handler.js +7 -2
  65. package/dist/replication/handler.js.map +1 -1
  66. package/dist/replication/pgoutput-encoder.d.ts.map +1 -1
  67. package/dist/replication/pgoutput-encoder.js +72 -30
  68. package/dist/replication/pgoutput-encoder.js.map +1 -1
  69. package/dist/worker/browser-build-config.d.ts.map +1 -1
  70. package/dist/worker/browser-build-config.js +2 -1
  71. package/dist/worker/browser-build-config.js.map +1 -1
  72. package/dist/worker/cf-patches.d.ts +5 -2
  73. package/dist/worker/cf-patches.d.ts.map +1 -1
  74. package/dist/worker/cf-patches.js +238 -4
  75. package/dist/worker/cf-patches.js.map +1 -1
  76. package/dist/worker/shims/node-stub.d.ts +35 -0
  77. package/dist/worker/shims/node-stub.d.ts.map +1 -1
  78. package/dist/worker/shims/node-stub.js +53 -1
  79. package/dist/worker/shims/node-stub.js.map +1 -1
  80. package/dist/worker/shims/oxfmt.d.ts +4 -0
  81. package/dist/worker/shims/oxfmt.d.ts.map +1 -0
  82. package/dist/worker/shims/oxfmt.js +4 -0
  83. package/dist/worker/shims/oxfmt.js.map +1 -0
  84. package/dist/worker/shims/postgres-socket.js +1 -1
  85. package/dist/worker/shims/postgres-socket.js.map +1 -1
  86. package/dist/worker/shims/sqlite.d.ts +1 -0
  87. package/dist/worker/shims/sqlite.d.ts.map +1 -1
  88. package/dist/worker/shims/sqlite.js +229 -9
  89. package/dist/worker/shims/sqlite.js.map +1 -1
  90. package/dist/worker/shims/ws.d.ts.map +1 -1
  91. package/dist/worker/shims/ws.js +45 -0
  92. package/dist/worker/shims/ws.js.map +1 -1
  93. package/dist/worker/shims/zero-process-env.d.ts +2 -0
  94. package/dist/worker/shims/zero-process-env.d.ts.map +1 -0
  95. package/dist/worker/shims/zero-process-env.js +9 -0
  96. package/dist/worker/shims/zero-process-env.js.map +1 -0
  97. package/dist/worker/zero-cache-embed-cf.d.ts +29 -12
  98. package/dist/worker/zero-cache-embed-cf.d.ts.map +1 -1
  99. package/dist/worker/zero-cache-embed-cf.js +83 -14
  100. package/dist/worker/zero-cache-embed-cf.js.map +1 -1
  101. package/package.json +11 -2
  102. package/src/cf-do/.wrangler/cache/cf.json +1 -0
  103. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  104. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  105. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  106. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  107. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  108. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  109. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  110. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +11 -0
  111. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +134 -0
  112. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +11 -0
  113. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +134 -0
  114. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +1059 -0
  115. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +8 -0
  116. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +1059 -0
  117. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +8 -0
  118. package/src/cf-do/ARCHITECTURE.md +93 -0
  119. package/src/cf-do/CHAT_E2E.md +213 -0
  120. package/src/cf-do/watermark.test.ts +103 -0
  121. package/src/cf-do/watermark.ts +118 -0
  122. package/src/cf-do/worker.ts +1041 -0
  123. package/src/cf-do/wrangler.toml +11 -0
  124. package/src/cli.test.ts +3 -1
  125. package/src/config.ts +1 -1
  126. package/src/do-sql-tracking.test.ts +19 -0
  127. package/src/do-sql-tracking.ts +19 -0
  128. package/src/index.ts +29 -14
  129. package/src/pg-proxy-browser.ts +6 -6
  130. package/src/pg-proxy-do-backend.test.ts +3890 -0
  131. package/src/pg-proxy-do-backend.ts +6833 -482
  132. package/src/pg-sqlite-compiler/README.md +53 -0
  133. package/src/pg-sqlite-compiler/catalog/seed.ts +524 -0
  134. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +307 -0
  135. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +377 -0
  136. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +12 -0
  137. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +447 -0
  138. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +32 -0
  139. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +397 -0
  140. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +337 -0
  141. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +337 -0
  142. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +537 -0
  143. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +1837 -0
  144. package/src/pg-sqlite-compiler/index.ts +73 -0
  145. package/src/pg-sqlite-compiler/integration.test.ts +136 -0
  146. package/src/pg-sqlite-compiler/passes/ast-utils.ts +113 -0
  147. package/src/pg-sqlite-compiler/passes/catalog.ts +65 -0
  148. package/src/pg-sqlite-compiler/passes/datetime.ts +74 -0
  149. package/src/pg-sqlite-compiler/passes/index.ts +49 -0
  150. package/src/pg-sqlite-compiler/passes/types.ts +156 -0
  151. package/src/pg-sqlite-compiler/smoke.test.ts +69 -0
  152. package/src/pg-sqlite-compiler/test/catalog.test.ts +171 -0
  153. package/src/pg-sqlite-compiler/test/corpus.test.ts +161 -0
  154. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +102 -0
  155. package/src/pg-sqlite-compiler/test/oracle.ts +237 -0
  156. package/src/pg-sqlite-compiler/test/types.test.ts +109 -0
  157. package/src/pg-sqlite-compiler/types.ts +63 -0
  158. package/src/replication/change-tracker.ts +16 -1
  159. package/src/replication/handler.test.ts +35 -0
  160. package/src/replication/handler.ts +7 -2
  161. package/src/replication/pgoutput-encoder.test.ts +71 -2
  162. package/src/replication/pgoutput-encoder.ts +65 -30
  163. package/src/worker/browser-build-config.test.ts +12 -0
  164. package/src/worker/browser-build-config.ts +2 -1
  165. package/src/worker/cf-patches.ts +274 -4
  166. package/src/worker/shims/node-stub.ts +53 -1
  167. package/src/worker/shims/oxfmt.ts +3 -0
  168. package/src/worker/shims/postgres-socket.ts +1 -1
  169. package/src/worker/shims/sqlite.test.ts +145 -0
  170. package/src/worker/shims/sqlite.ts +256 -9
  171. package/src/worker/shims/ws.ts +45 -0
  172. package/src/worker/shims/zero-process-env.ts +11 -0
  173. package/src/worker/zero-cache-embed-cf.ts +114 -18
  174. package/src/query-rewrites.test.ts +0 -30
  175. package/src/query-rewrites.ts +0 -152
@@ -0,0 +1,11 @@
1
+ name = "zero-do"
2
+ main = "worker.ts"
3
+ compatibility_date = "2025-04-01"
4
+
5
+ [[durable_objects.bindings]]
6
+ name = "ZERO_DO"
7
+ class_name = "ZeroDO"
8
+
9
+ [[migrations]]
10
+ tag = "v1"
11
+ new_sqlite_classes = ["ZeroDO"]
package/src/cli.test.ts CHANGED
@@ -7,7 +7,9 @@ function runCli(
7
7
  args: string[]
8
8
  ): Promise<{ stdout: string; stderr: string; code: number }> {
9
9
  return new Promise((res) => {
10
- const child = spawn('bun', [resolve('dist/cli.js'), ...args], {
10
+ // cli-entry.js is the actual entry (cli.js only exports `main`; runMain
11
+ // is invoked from cli-entry).
12
+ const child = spawn('bun', [resolve('dist/cli-entry.js'), ...args], {
11
13
  timeout: 10_000,
12
14
  env: { ...process.env, NODE_ENV: 'test' },
13
15
  })
package/src/config.ts CHANGED
@@ -139,7 +139,7 @@ export function getConfig(overrides: Partial<ZeroLiteConfig> = {}): ZeroLiteConf
139
139
  checkpointIntervalMs: overrides.checkpointIntervalMs ?? 5 * 60 * 1000,
140
140
  maxLogFileSize: overrides.maxLogFileSize ?? 2 * 1024 * 1024,
141
141
  disableDiskLogs: overrides.disableDiskLogs ?? false,
142
- doBackendUrl: overrides.doBackendUrl,
142
+ doBackendUrl: overrides.doBackendUrl ?? process.env.DO_BACKEND_URL,
143
143
  onDbReady: overrides.onDbReady,
144
144
  onHealthy: overrides.onHealthy,
145
145
  }
@@ -0,0 +1,19 @@
1
+ import { describe, expect, it } from 'vitest'
2
+
3
+ import { trackedChangeRow } from './do-sql-tracking.js'
4
+
5
+ describe('trackedChangeRow', () => {
6
+ it('keeps only table columns and strips internal returning expressions', () => {
7
+ expect(
8
+ trackedChangeRow(
9
+ {
10
+ id: 't1',
11
+ body: 'hello',
12
+ __orez_returning_1: 'HELLO',
13
+ extra: 'client-visible only',
14
+ },
15
+ { rowColumns: ['id', 'body'] }
16
+ )
17
+ ).toEqual({ id: 't1', body: 'hello' })
18
+ })
19
+ })
@@ -0,0 +1,19 @@
1
+ export const RETURNING_INTERNAL_PREFIX = '__orez_returning_'
2
+
3
+ export interface TrackedRowFilter {
4
+ rowColumns?: string[]
5
+ }
6
+
7
+ export function trackedChangeRow(
8
+ row: Record<string, unknown>,
9
+ track: TrackedRowFilter
10
+ ): Record<string, unknown> {
11
+ const allowed = track.rowColumns ? new Set(track.rowColumns) : null
12
+ const out: Record<string, unknown> = {}
13
+ for (const [key, value] of Object.entries(row)) {
14
+ if (key.startsWith(RETURNING_INTERNAL_PREFIX)) continue
15
+ if (allowed && !allowed.has(key)) continue
16
+ out[key] = value
17
+ }
18
+ return out
19
+ }
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@
7
7
  */
8
8
 
9
9
  import { spawn, spawnSync, type ChildProcess } from 'node:child_process'
10
+ import { randomUUID } from 'node:crypto'
10
11
  import { existsSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from 'node:fs'
11
12
  import { resolve } from 'node:path'
12
13
 
@@ -61,6 +62,17 @@ import type { PGlite } from '@electric-sql/pglite'
61
62
 
62
63
  type ZeroChildProcess = ChildProcess & { __orezTail?: string[] }
63
64
 
65
+ function ensureDoBackendNamespace(dataDir: string): string {
66
+ const marker = resolve(dataDir, 'do-backend-namespace')
67
+ if (existsSync(marker)) {
68
+ const existing = readFileSync(marker, 'utf8').trim()
69
+ if (existing) return existing
70
+ }
71
+ const next = randomUUID()
72
+ writeFileSync(marker, `${next}\n`)
73
+ return next
74
+ }
75
+
64
76
  function resolveNodeBinary(): string {
65
77
  const explicitNode = process.env.NODE
66
78
  if (explicitNode && existsSync(explicitNode)) {
@@ -330,10 +342,11 @@ export async function startZeroLite(overrides: Partial<ZeroLiteConfig> = {}) {
330
342
  isDoBackend = true
331
343
  log.orez(`using DO backend: ${config.doBackendUrl}`)
332
344
  const backendUrl = config.doBackendUrl.replace(/\/+$/, '')
345
+ const doNamespace = ensureDoBackendNamespace(config.dataDir)
333
346
  const doInstances = {
334
- postgres: new DoBackend(backendUrl, 'postgres'),
335
- cvr: new DoBackend(backendUrl, 'zero_cvr'),
336
- cdb: new DoBackend(backendUrl, 'zero_cdb'),
347
+ postgres: new DoBackend(backendUrl, 'postgres', doNamespace),
348
+ cvr: new DoBackend(backendUrl, 'zero_cvr', doNamespace),
349
+ cdb: new DoBackend(backendUrl, 'zero_cdb', doNamespace),
337
350
  postgresReplicas: [],
338
351
  }
339
352
  await Promise.all([
@@ -381,10 +394,10 @@ export async function startZeroLite(overrides: Partial<ZeroLiteConfig> = {}) {
381
394
  log.debug.orez(`using managed publication: ${managedPub.names.join(', ')}`)
382
395
  }
383
396
 
384
- // PGlite-only: sync publications
385
- if (!isDoBackend) {
386
- await syncManagedPublications(db, managedPub.names, managedPub.managedByOrez)
387
- }
397
+ // sync publications. for DO backend this goes through the TCP proxy, which
398
+ // rewrites the catalog queries and forwards CREATE PUBLICATION / ALTER PUBLICATION
399
+ // as no-ops or DO-native equivalents (PGlite still owns the real path).
400
+ await syncManagedPublications(db, managedPub.names, managedPub.managedByOrez)
388
401
 
389
402
  // start tcp proxy (routes connections to correct instance by database name)
390
403
  const pgServer = await startPgProxy(instances, config)
@@ -410,13 +423,15 @@ export async function startZeroLite(overrides: Partial<ZeroLiteConfig> = {}) {
410
423
  OREZ_PG_PORT: String(config.pgPort),
411
424
  })
412
425
 
413
- // re-sync publication membership (PGlite-only)
414
- if (!isDoBackend) {
415
- await syncManagedPublications(db, managedPub.names, managedPub.managedByOrez)
416
- await ensurePublicationHasTables(db, managedPub.names)
417
- log.debug.orez('re-installing change tracking after on-db-ready')
418
- await installChangeTracking(db)
419
- }
426
+ // re-sync publication membership
427
+ await syncManagedPublications(db, managedPub.names, managedPub.managedByOrez)
428
+ await ensurePublicationHasTables(db, managedPub.names)
429
+ log.debug.orez('re-installing change tracking after on-db-ready')
430
+ await installChangeTracking(db)
431
+ }
432
+
433
+ if (isDoBackend) {
434
+ await installChangeTracking(db)
420
435
  }
421
436
 
422
437
  // write the ready marker so external orchestrators (e.g. CI scripts that
@@ -656,7 +656,7 @@ function messagePortToDuplexWithInject(port: MessagePort): {
656
656
  chunk.byteOffset,
657
657
  chunk.byteOffset + chunk.byteLength
658
658
  ) as ArrayBuffer
659
- port.postMessage(buf, [buf])
659
+ port.postMessage(buf)
660
660
  },
661
661
  close() {
662
662
  port.close()
@@ -668,7 +668,7 @@ function messagePortToDuplexWithInject(port: MessagePort): {
668
668
  data.byteOffset,
669
669
  data.byteOffset + data.byteLength
670
670
  ) as ArrayBuffer
671
- port.postMessage(buf, [buf])
671
+ port.postMessage(buf)
672
672
  }
673
673
 
674
674
  const injectMessage = (data: Uint8Array) => {
@@ -714,12 +714,12 @@ function messagePortToDuplex(port: MessagePort): {
714
714
  if (isDebugWire() && _globalWriteCount <= 200) {
715
715
  console.debug(`[pg-proxy-ws-write] #${_globalWriteCount} len=${chunk.byteLength}`)
716
716
  }
717
- // transfer the ArrayBuffer for zero-copy
717
+ // CF workerd MessagePort does not support transfer lists.
718
718
  const buf = chunk.buffer.slice(
719
719
  chunk.byteOffset,
720
720
  chunk.byteOffset + chunk.byteLength
721
721
  ) as ArrayBuffer
722
- port.postMessage(buf, [buf])
722
+ port.postMessage(buf)
723
723
  },
724
724
  close() {
725
725
  port.close()
@@ -733,7 +733,7 @@ function messagePortToDuplex(port: MessagePort): {
733
733
  data.byteOffset,
734
734
  data.byteOffset + data.byteLength
735
735
  ) as ArrayBuffer
736
- port.postMessage(buf, [buf])
736
+ port.postMessage(buf)
737
737
  }
738
738
 
739
739
  return { duplex: { readable, writable }, rawWrite }
@@ -1020,7 +1020,7 @@ export async function createBrowserProxy(
1020
1020
  // cause issues if the caller still references the original data
1021
1021
  const copy = new Uint8Array(data.length)
1022
1022
  copy.set(data)
1023
- port.postMessage(copy.buffer, [copy.buffer])
1023
+ port.postMessage(copy.buffer)
1024
1024
  }
1025
1025
 
1026
1026
  // step 1: send AuthenticationClearTextPassword (R, type=3) — ask for password