orez 0.0.47 → 0.0.49

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 (65) hide show
  1. package/dist/admin/http-proxy.d.ts.map +1 -1
  2. package/dist/admin/http-proxy.js.map +1 -1
  3. package/dist/admin/log-store.d.ts.map +1 -1
  4. package/dist/admin/log-store.js.map +1 -1
  5. package/dist/admin/server.d.ts +2 -2
  6. package/dist/admin/server.d.ts.map +1 -1
  7. package/dist/admin/server.js.map +1 -1
  8. package/dist/admin/ui.d.ts.map +1 -1
  9. package/dist/admin/ui.js +2 -2
  10. package/dist/admin/ui.js.map +1 -1
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +6 -112
  13. package/dist/cli.js.map +1 -1
  14. package/dist/config.d.ts +0 -5
  15. package/dist/config.d.ts.map +1 -1
  16. package/dist/config.js +0 -5
  17. package/dist/config.js.map +1 -1
  18. package/dist/index.d.ts +0 -9
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +91 -249
  21. package/dist/index.js.map +1 -1
  22. package/dist/log.d.ts +0 -9
  23. package/dist/log.d.ts.map +1 -1
  24. package/dist/log.js +1 -24
  25. package/dist/log.js.map +1 -1
  26. package/dist/mutex.d.ts.map +1 -1
  27. package/dist/mutex.js +2 -13
  28. package/dist/mutex.js.map +1 -1
  29. package/dist/pg-proxy.d.ts +2 -3
  30. package/dist/pg-proxy.d.ts.map +1 -1
  31. package/dist/pg-proxy.js +167 -377
  32. package/dist/pg-proxy.js.map +1 -1
  33. package/dist/pglite-manager.d.ts +0 -1
  34. package/dist/pglite-manager.d.ts.map +1 -1
  35. package/dist/pglite-manager.js +1 -1
  36. package/dist/pglite-manager.js.map +1 -1
  37. package/dist/replication/change-tracker.d.ts +0 -6
  38. package/dist/replication/change-tracker.d.ts.map +1 -1
  39. package/dist/replication/change-tracker.js +0 -74
  40. package/dist/replication/change-tracker.js.map +1 -1
  41. package/dist/replication/handler.d.ts.map +1 -1
  42. package/dist/replication/handler.js +5 -47
  43. package/dist/replication/handler.js.map +1 -1
  44. package/dist/vite-plugin.d.ts +0 -3
  45. package/dist/vite-plugin.d.ts.map +1 -1
  46. package/dist/vite-plugin.js +0 -24
  47. package/dist/vite-plugin.js.map +1 -1
  48. package/package.json +5 -4
  49. package/src/admin/http-proxy.ts +5 -1
  50. package/src/admin/log-store.ts +4 -1
  51. package/src/admin/server.ts +7 -3
  52. package/src/admin/ui.ts +682 -680
  53. package/src/cli.ts +6 -111
  54. package/src/config.ts +0 -10
  55. package/src/index.ts +92 -262
  56. package/src/integration/integration.test.ts +264 -133
  57. package/src/log.ts +1 -25
  58. package/src/mutex.ts +2 -12
  59. package/src/pg-proxy.ts +187 -449
  60. package/src/pglite-manager.ts +1 -1
  61. package/src/replication/change-tracker.ts +0 -92
  62. package/src/replication/handler.ts +4 -50
  63. package/src/shim/hooks.mjs +34 -1
  64. package/src/vite-plugin.ts +0 -28
  65. package/src/wasm-sqlite.test.ts +1 -2
package/src/cli.ts CHANGED
@@ -90,7 +90,6 @@ const pgDumpCommand = defineCommand({
90
90
  } else {
91
91
  process.stdout.write(sql)
92
92
  }
93
- process.exit(0)
94
93
  } catch (err: any) {
95
94
  if (err?.message?.includes('lock')) {
96
95
  console.error(
@@ -153,13 +152,6 @@ function shouldSkipStatement(stmt: string): boolean {
153
152
  const extName = node.object?.String?.sval
154
153
  if (extName && UNSUPPORTED_EXTENSIONS.has(extName)) return true
155
154
  }
156
-
157
- // skip CREATE/ALTER/DROP PUBLICATION — pglite doesn't support wal_level=logical
158
- // internally, so CREATE PUBLICATION errors and can roll back the transaction
159
- // (orez handles replication via its own change tracker, not publications)
160
- if (nodeType === 'CreatePublicationStmt' || nodeType === 'AlterPublicationStmt')
161
- return true
162
- if (nodeType === 'DropStmt' && node.removeType === 'OBJECT_PUBLICATION') return true
163
155
  }
164
156
 
165
157
  return false
@@ -271,22 +263,9 @@ export async function execDumpFile(
271
263
  const colList =
272
264
  copyTarget.columns.length > 0 ? ` (${copyTarget.columns.join(', ')})` : ''
273
265
  const insert = `INSERT INTO ${copyTarget.table}${colList} VALUES ${copyRows.join(', ')}`
274
- try {
275
- await db.exec(insert)
276
- executed += copyRows.length
277
- batchCount += copyRows.length
278
- } catch (err: any) {
279
- log.orez(`warning: ${err?.message?.split('\n')[0] ?? err}`)
280
- skipped += copyRows.length
281
- // transaction is aborted, rollback and start fresh
282
- if (inBatch) {
283
- try {
284
- await db.exec('ROLLBACK')
285
- } catch {}
286
- inBatch = false
287
- batchCount = 0
288
- }
289
- }
266
+ await db.exec(insert)
267
+ executed += copyRows.length
268
+ batchCount += copyRows.length
290
269
  copyRows = []
291
270
  copyRowsBytes = 0
292
271
  }
@@ -479,37 +458,6 @@ export async function execDumpFile(
479
458
  return { executed, skipped }
480
459
  }
481
460
 
482
- // after restore, drop triggers whose backing functions no longer exist.
483
- // this happens when a filtered dump includes triggers on public-schema tables
484
- // that reference functions from excluded schemas (e.g. startchat.update_count()).
485
- // the triggers survive TOC filtering because they're associated with public tables.
486
- async function cleanupBrokenTriggers(db: { exec: (q: string) => Promise<unknown> }) {
487
- try {
488
- const result = (await db.exec(`
489
- SELECT tgname, relname, nspname, proname, pronamespace
490
- FROM pg_trigger t
491
- JOIN pg_class c ON c.oid = t.tgrelid
492
- JOIN pg_namespace n ON n.oid = c.relnamespace
493
- LEFT JOIN pg_proc p ON p.oid = t.tgfoid
494
- WHERE NOT t.tgisinternal
495
- AND n.nspname = 'public'
496
- AND (p.oid IS NULL OR p.pronamespace != n.oid)
497
- `)) as any
498
-
499
- const rows = result?.rows || result?.[0]?.rows || []
500
- for (const row of rows) {
501
- const trigger = row.tgname
502
- const table = row.relname
503
- try {
504
- await db.exec(`DROP TRIGGER IF EXISTS "${trigger}" ON "public"."${table}"`)
505
- log.orez(`dropped broken trigger "${trigger}" on "${table}"`)
506
- } catch {}
507
- }
508
- } catch {
509
- // best-effort cleanup
510
- }
511
- }
512
-
513
461
  // try restoring via wire protocol (postgres running on given port)
514
462
  // returns true if connected and restored, false if connection unavailable
515
463
  async function tryWireRestore(opts: {
@@ -548,8 +496,6 @@ async function tryWireRestore(opts: {
548
496
 
549
497
  const db = { exec: (query: string) => sql.unsafe(query) as Promise<unknown> }
550
498
  const { executed, skipped } = await execDumpFile(db, opts.sqlFile)
551
- await cleanupBrokenTriggers(db)
552
- await db.exec('SET search_path TO public')
553
499
  log.orez(
554
500
  `restored ${opts.sqlFile} via wire protocol (${executed} statements, ${skipped} skipped)`
555
501
  )
@@ -587,8 +533,6 @@ async function directRestore(opts: {
587
533
  }
588
534
 
589
535
  const { executed, skipped } = await execDumpFile(db, opts.sqlFile)
590
- await cleanupBrokenTriggers(db)
591
- await db.exec('SET search_path TO public')
592
536
  log.orez(
593
537
  `restored ${opts.sqlFile} into ${dataPath} (${executed} statements, ${skipped} skipped)`
594
538
  )
@@ -667,7 +611,7 @@ const pgRestoreCommand = defineCommand({
667
611
  clean: args.clean,
668
612
  sqlFile,
669
613
  })
670
- if (restored) process.exit(0)
614
+ if (restored) return
671
615
  log.orez('wire protocol unavailable, falling back to direct PGlite')
672
616
  } catch (err: any) {
673
617
  // connected but restore failed — report error, don't fall back
@@ -681,7 +625,6 @@ const pgRestoreCommand = defineCommand({
681
625
  clean: args.clean,
682
626
  sqlFile,
683
627
  })
684
- process.exit(0)
685
628
  },
686
629
  })
687
630
 
@@ -748,12 +691,7 @@ const main = defineCommand({
748
691
  'disable-wasm-sqlite': {
749
692
  type: 'boolean',
750
693
  description: 'use native @rocicorp/zero-sqlite3 instead of wasm bedrock-sqlite',
751
- default: false,
752
- },
753
- 'log-env': {
754
- type: 'boolean',
755
- description: 'log ZERO_* and related environment variables on startup',
756
- default: false,
694
+ default: true,
757
695
  },
758
696
  'on-db-ready': {
759
697
  type: 'string',
@@ -765,21 +703,6 @@ const main = defineCommand({
765
703
  description: 'command to run once all services are healthy',
766
704
  default: '',
767
705
  },
768
- admin: {
769
- type: 'boolean',
770
- description: 'start admin web ui',
771
- default: false,
772
- },
773
- 'admin-port': {
774
- type: 'string',
775
- description: 'admin ui port (default: auto)',
776
- default: '0',
777
- },
778
- 'admin-logs': {
779
- type: 'boolean',
780
- description: 'write logs to .orez/logs/ (default: true when --admin)',
781
- default: true,
782
- },
783
706
  },
784
707
  subCommands: {
785
708
  s3: s3Command,
@@ -787,8 +710,7 @@ const main = defineCommand({
787
710
  pg_restore: pgRestoreCommand,
788
711
  },
789
712
  async run({ args }) {
790
- const startTime = Date.now()
791
- const { config, stop, logStore, zeroEnv, actions, httpLogStore } = await startZeroLite({
713
+ const { config, stop } = await startZeroLite({
792
714
  pgPort: Number(args['pg-port']),
793
715
  zeroPort: Number(args['zero-port']),
794
716
  dataDir: args['data-dir'],
@@ -799,11 +721,7 @@ const main = defineCommand({
799
721
  skipZeroCache: args['skip-zero-cache'],
800
722
  disableWasmSqlite: args['disable-wasm-sqlite'],
801
723
  logLevel: (args['log-level'] as 'error' | 'warn' | 'info' | 'debug') || undefined,
802
- logEnv: args['log-env'],
803
724
  onDbReady: args['on-db-ready'],
804
- admin: args.admin,
805
- adminPort: Number(args['admin-port']),
806
- adminLogs: args['admin-logs'],
807
725
  })
808
726
 
809
727
  let s3Server: import('node:http').Server | null = null
@@ -815,27 +733,6 @@ const main = defineCommand({
815
733
  })
816
734
  }
817
735
 
818
- let adminServer: import('node:http').Server | null = null
819
- if (args.admin && logStore) {
820
- const { findPort } = await import('./port.js')
821
- const adminPort = Number(args['admin-port']) || (config.zeroPort + 2)
822
- const resolvedPort = await findPort(adminPort)
823
- const { startAdminServer } = await import('./admin/server.js')
824
- adminServer = await startAdminServer({
825
- port: resolvedPort,
826
- logStore,
827
- config,
828
- zeroEnv,
829
- actions,
830
- startTime,
831
- httpLog: httpLogStore || undefined,
832
- })
833
- log.orez(`admin: http://127.0.0.1:${resolvedPort}`)
834
- if (args['admin-logs']) {
835
- log.orez(`logs: ${resolve(args['data-dir'], 'logs', 'orez.log')}`)
836
- }
837
- }
838
-
839
736
  log.orez('ready')
840
737
  log.orez(
841
738
  `pg: postgresql://${config.pgUser}:${config.pgPassword}@127.0.0.1:${config.pgPort}/postgres`
@@ -863,13 +760,11 @@ const main = defineCommand({
863
760
  }
864
761
 
865
762
  process.on('SIGINT', async () => {
866
- adminServer?.close()
867
763
  s3Server?.close()
868
764
  await stop()
869
765
  process.exit(0)
870
766
  })
871
767
  process.on('SIGTERM', async () => {
872
- adminServer?.close()
873
768
  s3Server?.close()
874
769
  await stop()
875
770
  process.exit(0)
package/src/config.ts CHANGED
@@ -14,12 +14,7 @@ export interface ZeroLiteConfig {
14
14
  disableWasmSqlite: boolean
15
15
  logLevel: LogLevel
16
16
  pgliteOptions: Partial<PGliteOptions>
17
- logEnv: boolean
18
17
  onDbReady: string
19
- beforeZero: ((db: import('@electric-sql/pglite').PGlite) => Promise<void>) | null
20
- admin: boolean
21
- adminPort: number
22
- adminLogs: boolean
23
18
  }
24
19
 
25
20
  export function getConfig(overrides: Partial<ZeroLiteConfig> = {}): ZeroLiteConfig {
@@ -35,12 +30,7 @@ export function getConfig(overrides: Partial<ZeroLiteConfig> = {}): ZeroLiteConf
35
30
  disableWasmSqlite: overrides.disableWasmSqlite ?? false,
36
31
  logLevel: overrides.logLevel || 'warn',
37
32
  pgliteOptions: overrides.pgliteOptions || {},
38
- logEnv: overrides.logEnv ?? false,
39
33
  onDbReady: overrides.onDbReady || '',
40
- beforeZero: overrides.beforeZero || null,
41
- admin: overrides.admin ?? false,
42
- adminPort: overrides.adminPort || 0,
43
- adminLogs: overrides.adminLogs ?? true,
44
34
  }
45
35
  }
46
36