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.
- package/dist/admin/http-proxy.d.ts.map +1 -1
- package/dist/admin/http-proxy.js.map +1 -1
- package/dist/admin/log-store.d.ts.map +1 -1
- package/dist/admin/log-store.js.map +1 -1
- package/dist/admin/server.d.ts +2 -2
- package/dist/admin/server.d.ts.map +1 -1
- package/dist/admin/server.js.map +1 -1
- package/dist/admin/ui.d.ts.map +1 -1
- package/dist/admin/ui.js +2 -2
- package/dist/admin/ui.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +6 -112
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +0 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -5
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +0 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +91 -249
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +0 -9
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +1 -24
- package/dist/log.js.map +1 -1
- package/dist/mutex.d.ts.map +1 -1
- package/dist/mutex.js +2 -13
- package/dist/mutex.js.map +1 -1
- package/dist/pg-proxy.d.ts +2 -3
- package/dist/pg-proxy.d.ts.map +1 -1
- package/dist/pg-proxy.js +167 -377
- package/dist/pg-proxy.js.map +1 -1
- package/dist/pglite-manager.d.ts +0 -1
- package/dist/pglite-manager.d.ts.map +1 -1
- package/dist/pglite-manager.js +1 -1
- package/dist/pglite-manager.js.map +1 -1
- package/dist/replication/change-tracker.d.ts +0 -6
- package/dist/replication/change-tracker.d.ts.map +1 -1
- package/dist/replication/change-tracker.js +0 -74
- package/dist/replication/change-tracker.js.map +1 -1
- package/dist/replication/handler.d.ts.map +1 -1
- package/dist/replication/handler.js +5 -47
- package/dist/replication/handler.js.map +1 -1
- package/dist/vite-plugin.d.ts +0 -3
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.js +0 -24
- package/dist/vite-plugin.js.map +1 -1
- package/package.json +5 -4
- package/src/admin/http-proxy.ts +5 -1
- package/src/admin/log-store.ts +4 -1
- package/src/admin/server.ts +7 -3
- package/src/admin/ui.ts +682 -680
- package/src/cli.ts +6 -111
- package/src/config.ts +0 -10
- package/src/index.ts +92 -262
- package/src/integration/integration.test.ts +264 -133
- package/src/log.ts +1 -25
- package/src/mutex.ts +2 -12
- package/src/pg-proxy.ts +187 -449
- package/src/pglite-manager.ts +1 -1
- package/src/replication/change-tracker.ts +0 -92
- package/src/replication/handler.ts +4 -50
- package/src/shim/hooks.mjs +34 -1
- package/src/vite-plugin.ts +0 -28
- 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
|
-
|
|
275
|
-
|
|
276
|
-
|
|
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)
|
|
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:
|
|
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
|
|
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
|
|