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.
- package/dist/cf-do/worker.d.ts +3 -0
- package/dist/cf-do/worker.d.ts.map +1 -1
- package/dist/cf-do/worker.js +37 -15
- package/dist/cf-do/worker.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
- package/src/admin/admin-data.test.ts +0 -348
- package/src/admin/http-proxy.ts +0 -252
- package/src/admin/log-store.ts +0 -192
- package/src/admin/server.ts +0 -471
- package/src/admin/ui.ts +0 -1322
- package/src/bench/proxy-throughput.bench.ts +0 -343
- package/src/bench/serial-mutations.bench.ts +0 -270
- package/src/browser.ts +0 -203
- package/src/cf-do/.wrangler/cache/cf.json +0 -1
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
- package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
- package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
- package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
- package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
- package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
- package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
- package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
- package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
- package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
- package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
- package/src/cf-do/ARCHITECTURE.md +0 -93
- package/src/cf-do/CHAT_E2E.md +0 -213
- package/src/cf-do/watermark.test.ts +0 -103
- package/src/cf-do/watermark.ts +0 -118
- package/src/cf-do/worker.ts +0 -1041
- package/src/cf-do/wrangler.toml +0 -11
- package/src/cf-pglite/README.md +0 -19
- package/src/change-tracking.ts +0 -25
- package/src/child-process.test.ts +0 -147
- package/src/child-process.ts +0 -90
- package/src/cli-entry.ts +0 -72
- package/src/cli.test.ts +0 -40
- package/src/cli.ts +0 -1214
- package/src/config.ts +0 -150
- package/src/do-sql-tracking.test.ts +0 -19
- package/src/do-sql-tracking.ts +0 -19
- package/src/index.ts +0 -1215
- package/src/integration/integration.test.ts +0 -517
- package/src/integration/native-binary.guard.test.ts +0 -13
- package/src/integration/native-startup.test.ts +0 -44
- package/src/integration/replication-latency.test.ts +0 -428
- package/src/integration/restore-live-stress.test.ts +0 -433
- package/src/integration/restore-reset.test.ts +0 -400
- package/src/integration/restore.test.ts +0 -274
- package/src/integration/test-permissions.ts +0 -147
- package/src/load-config.ts +0 -46
- package/src/log.ts +0 -96
- package/src/mutex.ts +0 -47
- package/src/pg-proxy-browser.singledb.test.ts +0 -233
- package/src/pg-proxy-browser.ts +0 -2022
- package/src/pg-proxy-do-backend.test.ts +0 -3890
- package/src/pg-proxy-do-backend.ts +0 -7191
- package/src/pg-proxy.ts +0 -1087
- package/src/pg-sqlite-compiler/README.md +0 -53
- package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
- package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
- package/src/pg-sqlite-compiler/index.ts +0 -73
- package/src/pg-sqlite-compiler/integration.test.ts +0 -136
- package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
- package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
- package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
- package/src/pg-sqlite-compiler/passes/index.ts +0 -49
- package/src/pg-sqlite-compiler/passes/types.ts +0 -156
- package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
- package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
- package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
- package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
- package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
- package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
- package/src/pg-sqlite-compiler/types.ts +0 -63
- package/src/pglite-ipc.test.ts +0 -116
- package/src/pglite-ipc.ts +0 -266
- package/src/pglite-manager.ts +0 -557
- package/src/pglite-web-proxy.test.ts +0 -57
- package/src/pglite-web-proxy.ts +0 -221
- package/src/pglite-web-worker.ts +0 -152
- package/src/pglite-worker-thread.ts +0 -253
- package/src/port.ts +0 -25
- package/src/process-title.ts +0 -9
- package/src/recovery.ts +0 -155
- package/src/replication/change-tracker.test.ts +0 -357
- package/src/replication/change-tracker.ts +0 -279
- package/src/replication/handler.test.ts +0 -511
- package/src/replication/handler.ts +0 -1190
- package/src/replication/pgoutput-encoder.test.ts +0 -697
- package/src/replication/pgoutput-encoder.ts +0 -373
- package/src/replication/tcp-replication.test.ts +0 -876
- package/src/replication/zero-compat.test.ts +0 -1150
- package/src/restore-stress.test.ts +0 -188
- package/src/s3-local.ts +0 -203
- package/src/shim/hooks.mjs +0 -120
- package/src/shim/register.mjs +0 -4
- package/src/sqlite-mode/apply-mode.ts +0 -224
- package/src/sqlite-mode/index.ts +0 -15
- package/src/sqlite-mode/native-binary.ts +0 -89
- package/src/sqlite-mode/package-resolve.ts +0 -17
- package/src/sqlite-mode/resolve-mode.ts +0 -80
- package/src/sqlite-mode/shim-template.ts +0 -159
- package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
- package/src/sqlite-mode/types.ts +0 -30
- package/src/vite-plugin.ts +0 -67
- package/src/wasm-sqlite.test.ts +0 -537
- package/src/worker/browser-admin.ts +0 -52
- package/src/worker/browser-build-config.test.ts +0 -71
- package/src/worker/browser-build-config.ts +0 -109
- package/src/worker/browser-embed-admin.test.ts +0 -75
- package/src/worker/browser-embed.ts +0 -345
- package/src/worker/cf-patches.ts +0 -384
- package/src/worker/embed-integration.test.ts +0 -321
- package/src/worker/index.ts +0 -138
- package/src/worker/shims/fastify.test.ts +0 -255
- package/src/worker/shims/fastify.ts +0 -306
- package/src/worker/shims/http-service.test.ts +0 -355
- package/src/worker/shims/http-service.ts +0 -293
- package/src/worker/shims/node-stub.ts +0 -290
- package/src/worker/shims/oxfmt.ts +0 -3
- package/src/worker/shims/postgres-browser.ts +0 -59
- package/src/worker/shims/postgres-socket.test.ts +0 -576
- package/src/worker/shims/postgres-socket.ts +0 -310
- package/src/worker/shims/postgres.test.ts +0 -364
- package/src/worker/shims/postgres.ts +0 -1454
- package/src/worker/shims/sqlite-browser.test.ts +0 -233
- package/src/worker/shims/sqlite-browser.ts +0 -175
- package/src/worker/shims/sqlite.test.ts +0 -786
- package/src/worker/shims/sqlite.ts +0 -978
- package/src/worker/shims/stream-browser.ts +0 -15
- package/src/worker/shims/ws-browser.test.ts +0 -205
- package/src/worker/shims/ws-browser.ts +0 -248
- package/src/worker/shims/ws.test.ts +0 -288
- package/src/worker/shims/ws.ts +0 -467
- package/src/worker/shims/zero-process-env.ts +0 -11
- package/src/worker/types.ts +0 -75
- package/src/worker/worker-integration.test.ts +0 -223
- package/src/worker/worker.test.ts +0 -136
- package/src/worker/zero-cache-embed-cf.ts +0 -463
- package/src/worker/zero-cache-embed.ts +0 -277
package/src/wasm-sqlite.test.ts
DELETED
|
@@ -1,537 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* wasm sqlite compatibility tests.
|
|
3
|
-
*
|
|
4
|
-
* validates that bedrock-sqlite (wasm) behaves identically to native
|
|
5
|
-
* @rocicorp/zero-sqlite3 for the patterns zero-cache uses:
|
|
6
|
-
* - statement caching with begin/commit
|
|
7
|
-
* - BEGIN CONCURRENT
|
|
8
|
-
* - unsafeMode
|
|
9
|
-
* - WAL/WAL2 journal modes
|
|
10
|
-
* - pragma support
|
|
11
|
-
*
|
|
12
|
-
* adapted from zero mono: packages/zero-cache/src/db/statements.test.ts,
|
|
13
|
-
* packages/zero-cache/src/db/begin-concurrent.test.ts
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
import { existsSync, mkdirSync, unlinkSync } from 'node:fs'
|
|
17
|
-
import { tmpdir } from 'node:os'
|
|
18
|
-
import { resolve } from 'node:path'
|
|
19
|
-
|
|
20
|
-
// import bedrock-sqlite directly (our wasm build)
|
|
21
|
-
// @ts-expect-error - CJS module
|
|
22
|
-
import bedrockSqlite from 'bedrock-sqlite'
|
|
23
|
-
const { Database } = bedrockSqlite
|
|
24
|
-
import { describe, test, expect, beforeEach, afterEach } from 'vitest'
|
|
25
|
-
|
|
26
|
-
// helper: temp db file
|
|
27
|
-
function tmpDbPath(name: string): string {
|
|
28
|
-
const dir = resolve(tmpdir(), 'orez-test')
|
|
29
|
-
mkdirSync(dir, { recursive: true })
|
|
30
|
-
return resolve(dir, `${name}-${Date.now()}-${Math.random().toString(36).slice(2)}.db`)
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function deleteLiteDB(path: string) {
|
|
34
|
-
for (const suffix of ['', '-wal', '-wal2', '-shm', '-journal']) {
|
|
35
|
-
try {
|
|
36
|
-
if (existsSync(path + suffix)) unlinkSync(path + suffix)
|
|
37
|
-
} catch {}
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// minimal statement cache matching zero-cache's StatementCache
|
|
42
|
-
class StatementCache {
|
|
43
|
-
#cache = new Map<string, any[]>()
|
|
44
|
-
#db: any
|
|
45
|
-
#size = 0
|
|
46
|
-
|
|
47
|
-
constructor(db: any) {
|
|
48
|
-
this.#db = db
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
get size() {
|
|
52
|
-
return this.#size
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
get(sql: string) {
|
|
56
|
-
const statements = this.#cache.get(sql)
|
|
57
|
-
if (statements && statements.length > 0) {
|
|
58
|
-
const stmt = statements.pop()!
|
|
59
|
-
this.#size--
|
|
60
|
-
if (statements.length === 0) this.#cache.delete(sql)
|
|
61
|
-
return { sql, statement: stmt }
|
|
62
|
-
}
|
|
63
|
-
return { sql, statement: this.#db.prepare(sql) }
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
use(sql: string, cb: (cached: any) => any) {
|
|
67
|
-
const stmt = this.get(sql)
|
|
68
|
-
try {
|
|
69
|
-
return cb(stmt)
|
|
70
|
-
} finally {
|
|
71
|
-
this.return(stmt)
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return(stmt: any) {
|
|
76
|
-
if (!this.#cache.has(stmt.sql)) this.#cache.set(stmt.sql, [])
|
|
77
|
-
this.#cache.get(stmt.sql)!.push(stmt.statement)
|
|
78
|
-
this.#size++
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// minimal StatementRunner matching zero-cache's
|
|
83
|
-
class StatementRunner {
|
|
84
|
-
db: any
|
|
85
|
-
statementCache: StatementCache
|
|
86
|
-
|
|
87
|
-
constructor(db: any) {
|
|
88
|
-
this.db = db
|
|
89
|
-
this.statementCache = new StatementCache(db)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
run(sql: string, ...args: any[]) {
|
|
93
|
-
return this.statementCache.use(sql, (c) => c.statement.run(...args))
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
get(sql: string, ...args: any[]) {
|
|
97
|
-
return this.statementCache.use(sql, (c) => c.statement.get(...args))
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
all(sql: string, ...args: any[]) {
|
|
101
|
-
return this.statementCache.use(sql, (c) => c.statement.all(...args))
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
begin() {
|
|
105
|
-
return this.run('BEGIN')
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
beginConcurrent() {
|
|
109
|
-
return this.run('BEGIN CONCURRENT')
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
beginImmediate() {
|
|
113
|
-
return this.run('BEGIN IMMEDIATE')
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
commit() {
|
|
117
|
-
return this.run('COMMIT')
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
rollback() {
|
|
121
|
-
return this.run('ROLLBACK')
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
describe('wasm-sqlite: statement caching', () => {
|
|
126
|
-
let db: any
|
|
127
|
-
let runner: StatementRunner
|
|
128
|
-
|
|
129
|
-
beforeEach(() => {
|
|
130
|
-
db = new Database(':memory:')
|
|
131
|
-
db.exec('CREATE TABLE foo(id INT PRIMARY KEY)')
|
|
132
|
-
runner = new StatementRunner(db)
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
afterEach(() => {
|
|
136
|
-
db?.close()
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
test('statement caching with insert and select', () => {
|
|
140
|
-
expect(runner.statementCache.size).toBe(0)
|
|
141
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 123)
|
|
142
|
-
expect(runner.all('SELECT * FROM foo')).toEqual([{ id: 123 }])
|
|
143
|
-
expect(runner.statementCache.size).toBe(2)
|
|
144
|
-
|
|
145
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 456)
|
|
146
|
-
expect(runner.all('SELECT * FROM foo')).toEqual([{ id: 123 }, { id: 456 }])
|
|
147
|
-
// same statements reused
|
|
148
|
-
expect(runner.statementCache.size).toBe(2)
|
|
149
|
-
})
|
|
150
|
-
|
|
151
|
-
test('begin/commit with cached statements', () => {
|
|
152
|
-
runner.begin()
|
|
153
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 1)
|
|
154
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 2)
|
|
155
|
-
runner.commit()
|
|
156
|
-
|
|
157
|
-
expect(runner.all('SELECT * FROM foo')).toEqual([{ id: 1 }, { id: 2 }])
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
test('begin/rollback with cached statements', () => {
|
|
161
|
-
runner.begin()
|
|
162
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 1)
|
|
163
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 2)
|
|
164
|
-
runner.rollback()
|
|
165
|
-
|
|
166
|
-
expect(runner.all('SELECT * FROM foo')).toEqual([])
|
|
167
|
-
})
|
|
168
|
-
|
|
169
|
-
test('multiple transactions with cached statements', () => {
|
|
170
|
-
for (let i = 0; i < 10; i++) {
|
|
171
|
-
runner.begin()
|
|
172
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', i)
|
|
173
|
-
runner.commit()
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const rows = runner.all('SELECT * FROM foo')
|
|
177
|
-
expect(rows).toHaveLength(10)
|
|
178
|
-
})
|
|
179
|
-
|
|
180
|
-
test('interleaved reads and writes within transaction', () => {
|
|
181
|
-
runner.begin()
|
|
182
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 1)
|
|
183
|
-
expect(runner.get('SELECT count(*) as c FROM foo')).toEqual({ c: 1 })
|
|
184
|
-
runner.run('INSERT INTO foo(id) VALUES(?)', 2)
|
|
185
|
-
expect(runner.get('SELECT count(*) as c FROM foo')).toEqual({ c: 2 })
|
|
186
|
-
runner.commit()
|
|
187
|
-
|
|
188
|
-
expect(runner.all('SELECT * FROM foo')).toEqual([{ id: 1 }, { id: 2 }])
|
|
189
|
-
})
|
|
190
|
-
})
|
|
191
|
-
|
|
192
|
-
describe('wasm-sqlite: BEGIN CONCURRENT', () => {
|
|
193
|
-
let dbPath: string
|
|
194
|
-
|
|
195
|
-
beforeEach(() => {
|
|
196
|
-
dbPath = tmpDbPath('begin-concurrent')
|
|
197
|
-
const conn = new Database(dbPath)
|
|
198
|
-
conn.pragma('journal_mode = WAL')
|
|
199
|
-
conn.pragma('synchronous = NORMAL')
|
|
200
|
-
conn.exec('CREATE TABLE foo(id INTEGER PRIMARY KEY)')
|
|
201
|
-
conn.close()
|
|
202
|
-
})
|
|
203
|
-
|
|
204
|
-
afterEach(() => {
|
|
205
|
-
deleteLiteDB(dbPath)
|
|
206
|
-
})
|
|
207
|
-
|
|
208
|
-
test('independent concurrent actions before commit', () => {
|
|
209
|
-
const conn1 = new Database(dbPath)
|
|
210
|
-
conn1.pragma('journal_mode = WAL')
|
|
211
|
-
conn1.prepare('BEGIN CONCURRENT').run()
|
|
212
|
-
|
|
213
|
-
const conn2 = new Database(dbPath)
|
|
214
|
-
conn2.pragma('journal_mode = WAL')
|
|
215
|
-
conn2.prepare('BEGIN CONCURRENT').run()
|
|
216
|
-
|
|
217
|
-
conn1.prepare('INSERT INTO foo(id) VALUES(1)').run()
|
|
218
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([{ id: 1 }])
|
|
219
|
-
|
|
220
|
-
conn2.prepare('INSERT INTO foo(id) VALUES(2)').run()
|
|
221
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([{ id: 2 }])
|
|
222
|
-
|
|
223
|
-
conn1.prepare('COMMIT').run()
|
|
224
|
-
conn2.prepare('ROLLBACK').run()
|
|
225
|
-
|
|
226
|
-
conn1.close()
|
|
227
|
-
conn2.close()
|
|
228
|
-
})
|
|
229
|
-
|
|
230
|
-
test('begin concurrent is deferred', () => {
|
|
231
|
-
const conn1 = new Database(dbPath)
|
|
232
|
-
conn1.pragma('journal_mode = WAL')
|
|
233
|
-
conn1.prepare('BEGIN CONCURRENT').run()
|
|
234
|
-
|
|
235
|
-
const conn2 = new Database(dbPath)
|
|
236
|
-
conn2.pragma('journal_mode = WAL')
|
|
237
|
-
conn2.prepare('BEGIN CONCURRENT').run()
|
|
238
|
-
|
|
239
|
-
conn1.prepare('INSERT INTO foo(id) VALUES(1)').run()
|
|
240
|
-
conn1.prepare('COMMIT').run()
|
|
241
|
-
|
|
242
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([{ id: 1 }])
|
|
243
|
-
|
|
244
|
-
// conn2's transaction starts here (deferred), sees conn1's commit
|
|
245
|
-
conn2.prepare('INSERT INTO foo(id) VALUES(2)').run()
|
|
246
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([{ id: 1 }, { id: 2 }])
|
|
247
|
-
|
|
248
|
-
conn2.prepare('ROLLBACK').run()
|
|
249
|
-
conn1.close()
|
|
250
|
-
conn2.close()
|
|
251
|
-
})
|
|
252
|
-
|
|
253
|
-
test('simulate immediate - concurrent isolation', () => {
|
|
254
|
-
const conn1 = new Database(dbPath)
|
|
255
|
-
conn1.pragma('journal_mode = WAL')
|
|
256
|
-
conn1.prepare('BEGIN CONCURRENT').run()
|
|
257
|
-
// force transaction start
|
|
258
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([])
|
|
259
|
-
|
|
260
|
-
const conn2 = new Database(dbPath)
|
|
261
|
-
conn2.pragma('journal_mode = WAL')
|
|
262
|
-
conn2.prepare('BEGIN CONCURRENT').run()
|
|
263
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([])
|
|
264
|
-
|
|
265
|
-
conn1.prepare('INSERT INTO foo(id) VALUES(1)').run()
|
|
266
|
-
conn1.prepare('COMMIT').run()
|
|
267
|
-
|
|
268
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([{ id: 1 }])
|
|
269
|
-
|
|
270
|
-
// conn2 should NOT see conn1's commit (snapshot isolation)
|
|
271
|
-
conn2.prepare('INSERT INTO foo(id) VALUES(2)').run()
|
|
272
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([{ id: 2 }])
|
|
273
|
-
|
|
274
|
-
conn2.prepare('ROLLBACK').run()
|
|
275
|
-
conn1.close()
|
|
276
|
-
conn2.close()
|
|
277
|
-
})
|
|
278
|
-
|
|
279
|
-
test('begin concurrent with savepoints', () => {
|
|
280
|
-
const conn1 = new Database(dbPath)
|
|
281
|
-
conn1.pragma('journal_mode = WAL')
|
|
282
|
-
conn1.prepare('BEGIN CONCURRENT').run()
|
|
283
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([])
|
|
284
|
-
|
|
285
|
-
const conn2 = new Database(dbPath)
|
|
286
|
-
conn2.pragma('journal_mode = WAL')
|
|
287
|
-
conn2.prepare('BEGIN CONCURRENT').run()
|
|
288
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([])
|
|
289
|
-
|
|
290
|
-
conn1.prepare('INSERT INTO foo(id) VALUES(1)').run()
|
|
291
|
-
conn1.prepare('COMMIT').run()
|
|
292
|
-
|
|
293
|
-
expect(conn1.prepare('SELECT * FROM foo').all()).toEqual([{ id: 1 }])
|
|
294
|
-
|
|
295
|
-
conn2.prepare('SAVEPOINT foobar').run()
|
|
296
|
-
conn2.prepare('INSERT INTO foo(id) VALUES(2)').run()
|
|
297
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([{ id: 2 }])
|
|
298
|
-
|
|
299
|
-
conn2.prepare('ROLLBACK TO foobar').run()
|
|
300
|
-
expect(conn2.prepare('SELECT * FROM foo').all()).toEqual([])
|
|
301
|
-
|
|
302
|
-
conn2.prepare('ROLLBACK').run()
|
|
303
|
-
conn1.close()
|
|
304
|
-
conn2.close()
|
|
305
|
-
})
|
|
306
|
-
})
|
|
307
|
-
|
|
308
|
-
describe('wasm-sqlite: unsafeMode', () => {
|
|
309
|
-
let db: any
|
|
310
|
-
|
|
311
|
-
beforeEach(() => {
|
|
312
|
-
db = new Database(':memory:')
|
|
313
|
-
db.exec('CREATE TABLE foo(id INT PRIMARY KEY, val TEXT)')
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
afterEach(() => {
|
|
317
|
-
db?.close()
|
|
318
|
-
})
|
|
319
|
-
|
|
320
|
-
test('unsafeMode exists and is chainable', () => {
|
|
321
|
-
const ret = db.unsafeMode(true)
|
|
322
|
-
expect(ret).toBe(db)
|
|
323
|
-
db.unsafeMode(false)
|
|
324
|
-
})
|
|
325
|
-
|
|
326
|
-
test('commit works with cached statements after unsafeMode', () => {
|
|
327
|
-
db.unsafeMode(true)
|
|
328
|
-
db.pragma('journal_mode = OFF')
|
|
329
|
-
db.pragma('synchronous = OFF')
|
|
330
|
-
|
|
331
|
-
const insert = db.prepare('INSERT INTO foo(id, val) VALUES(?, ?)')
|
|
332
|
-
insert.run(1, 'a')
|
|
333
|
-
insert.run(2, 'b')
|
|
334
|
-
|
|
335
|
-
const rows = db.prepare('SELECT * FROM foo').all()
|
|
336
|
-
expect(rows).toEqual([
|
|
337
|
-
{ id: 1, val: 'a' },
|
|
338
|
-
{ id: 2, val: 'b' },
|
|
339
|
-
])
|
|
340
|
-
|
|
341
|
-
db.unsafeMode(false)
|
|
342
|
-
})
|
|
343
|
-
})
|
|
344
|
-
|
|
345
|
-
describe('wasm-sqlite: WAL modes', () => {
|
|
346
|
-
let dbPath: string
|
|
347
|
-
|
|
348
|
-
beforeEach(() => {
|
|
349
|
-
dbPath = tmpDbPath('wal-modes')
|
|
350
|
-
})
|
|
351
|
-
|
|
352
|
-
afterEach(() => {
|
|
353
|
-
deleteLiteDB(dbPath)
|
|
354
|
-
})
|
|
355
|
-
|
|
356
|
-
test('WAL mode works', () => {
|
|
357
|
-
const db = new Database(dbPath)
|
|
358
|
-
const result = db.pragma('journal_mode = WAL')
|
|
359
|
-
expect(result).toEqual([{ journal_mode: 'wal' }])
|
|
360
|
-
db.exec('CREATE TABLE t(id INT)')
|
|
361
|
-
db.exec('INSERT INTO t VALUES(1)')
|
|
362
|
-
expect(db.prepare('SELECT * FROM t').all()).toEqual([{ id: 1 }])
|
|
363
|
-
db.close()
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
test('WAL2 mode works', () => {
|
|
367
|
-
const db = new Database(dbPath)
|
|
368
|
-
const result = db.pragma('journal_mode = WAL2')
|
|
369
|
-
expect(result).toEqual([{ journal_mode: 'wal2' }])
|
|
370
|
-
db.exec('CREATE TABLE t(id INT)')
|
|
371
|
-
db.exec('INSERT INTO t VALUES(1)')
|
|
372
|
-
expect(db.prepare('SELECT * FROM t').all()).toEqual([{ id: 1 }])
|
|
373
|
-
db.close()
|
|
374
|
-
})
|
|
375
|
-
|
|
376
|
-
test('DELETE mode works', () => {
|
|
377
|
-
const db = new Database(dbPath)
|
|
378
|
-
db.pragma('journal_mode = DELETE')
|
|
379
|
-
db.exec('CREATE TABLE t(id INT)')
|
|
380
|
-
db.exec('INSERT INTO t VALUES(1)')
|
|
381
|
-
expect(db.prepare('SELECT * FROM t').all()).toEqual([{ id: 1 }])
|
|
382
|
-
db.close()
|
|
383
|
-
})
|
|
384
|
-
})
|
|
385
|
-
|
|
386
|
-
describe('wasm-sqlite: pragmas', () => {
|
|
387
|
-
test('busy_timeout', () => {
|
|
388
|
-
const db = new Database(':memory:')
|
|
389
|
-
db.pragma('busy_timeout = 30000')
|
|
390
|
-
const result = db.pragma('busy_timeout')
|
|
391
|
-
expect(result).toEqual([{ timeout: 30000 }])
|
|
392
|
-
db.close()
|
|
393
|
-
})
|
|
394
|
-
|
|
395
|
-
test('synchronous', () => {
|
|
396
|
-
const db = new Database(':memory:')
|
|
397
|
-
db.pragma('synchronous = NORMAL')
|
|
398
|
-
const result = db.pragma('synchronous')
|
|
399
|
-
// 1 = NORMAL
|
|
400
|
-
expect(result[0].synchronous).toBe(1)
|
|
401
|
-
db.close()
|
|
402
|
-
})
|
|
403
|
-
|
|
404
|
-
test('foreign_keys', () => {
|
|
405
|
-
const db = new Database(':memory:')
|
|
406
|
-
db.pragma('foreign_keys = OFF')
|
|
407
|
-
expect(db.pragma('foreign_keys')).toEqual([{ foreign_keys: 0 }])
|
|
408
|
-
db.close()
|
|
409
|
-
})
|
|
410
|
-
})
|
|
411
|
-
|
|
412
|
-
describe('wasm-sqlite: transaction() helper', () => {
|
|
413
|
-
test('transaction commits on success', () => {
|
|
414
|
-
const db = new Database(':memory:')
|
|
415
|
-
db.exec('CREATE TABLE t(id INT)')
|
|
416
|
-
|
|
417
|
-
db.transaction(() => {
|
|
418
|
-
db.prepare('INSERT INTO t VALUES(1)').run()
|
|
419
|
-
db.prepare('INSERT INTO t VALUES(2)').run()
|
|
420
|
-
})()
|
|
421
|
-
|
|
422
|
-
expect(db.prepare('SELECT * FROM t').all()).toEqual([{ id: 1 }, { id: 2 }])
|
|
423
|
-
db.close()
|
|
424
|
-
})
|
|
425
|
-
|
|
426
|
-
test('transaction rolls back on error', () => {
|
|
427
|
-
const db = new Database(':memory:')
|
|
428
|
-
db.exec('CREATE TABLE t(id INT PRIMARY KEY)')
|
|
429
|
-
|
|
430
|
-
try {
|
|
431
|
-
db.transaction(() => {
|
|
432
|
-
db.prepare('INSERT INTO t VALUES(1)').run()
|
|
433
|
-
db.prepare('INSERT INTO t VALUES(1)').run() // duplicate
|
|
434
|
-
})()
|
|
435
|
-
} catch {}
|
|
436
|
-
|
|
437
|
-
expect(db.prepare('SELECT * FROM t').all()).toEqual([])
|
|
438
|
-
db.close()
|
|
439
|
-
})
|
|
440
|
-
})
|
|
441
|
-
|
|
442
|
-
describe('wasm-sqlite: scanStatusV2', () => {
|
|
443
|
-
test('scanStatusV2 exists on statements', () => {
|
|
444
|
-
const db = new Database(':memory:')
|
|
445
|
-
db.exec('CREATE TABLE t(id INT)')
|
|
446
|
-
const stmt = db.prepare('SELECT * FROM t')
|
|
447
|
-
expect(typeof stmt.scanStatusV2).toBe('function')
|
|
448
|
-
db.close()
|
|
449
|
-
})
|
|
450
|
-
})
|
|
451
|
-
|
|
452
|
-
describe('wasm-sqlite: zero-cache replicator pattern', () => {
|
|
453
|
-
let dbPath: string
|
|
454
|
-
|
|
455
|
-
beforeEach(() => {
|
|
456
|
-
dbPath = tmpDbPath('replicator-pattern')
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
afterEach(() => {
|
|
460
|
-
deleteLiteDB(dbPath)
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
test('replicator: unsafeMode + journal_mode OFF + vacuum', () => {
|
|
464
|
-
// mirrors zero-cache replicator.js connect() vacuum path
|
|
465
|
-
const db = new Database(dbPath)
|
|
466
|
-
db.pragma('journal_mode = WAL')
|
|
467
|
-
db.exec('CREATE TABLE "_zero.changeLog"(id INT)')
|
|
468
|
-
db.exec('INSERT INTO "_zero.changeLog" VALUES(1)')
|
|
469
|
-
|
|
470
|
-
db.unsafeMode(true)
|
|
471
|
-
db.pragma('journal_mode = OFF')
|
|
472
|
-
db.exec('DELETE FROM "_zero.changeLog"')
|
|
473
|
-
db.exec('VACUUM')
|
|
474
|
-
db.unsafeMode(false)
|
|
475
|
-
|
|
476
|
-
db.pragma('journal_mode = WAL2')
|
|
477
|
-
db.pragma('busy_timeout = 30000')
|
|
478
|
-
|
|
479
|
-
expect(db.prepare('SELECT count(*) as c FROM "_zero.changeLog"').get()).toEqual({
|
|
480
|
-
c: 0,
|
|
481
|
-
})
|
|
482
|
-
db.close()
|
|
483
|
-
})
|
|
484
|
-
|
|
485
|
-
test('replicator: begin concurrent + statement cache + commit', () => {
|
|
486
|
-
// mirrors the change-processor transaction flow
|
|
487
|
-
const db = new Database(dbPath)
|
|
488
|
-
db.pragma('journal_mode = WAL2')
|
|
489
|
-
db.pragma('busy_timeout = 30000')
|
|
490
|
-
db.exec(`
|
|
491
|
-
CREATE TABLE issues(
|
|
492
|
-
issueID INTEGER PRIMARY KEY,
|
|
493
|
-
title TEXT,
|
|
494
|
-
_0_version TEXT
|
|
495
|
-
)
|
|
496
|
-
`)
|
|
497
|
-
|
|
498
|
-
const runner = new StatementRunner(db)
|
|
499
|
-
|
|
500
|
-
// simulate processing a replication message batch
|
|
501
|
-
runner.beginConcurrent()
|
|
502
|
-
runner.run(
|
|
503
|
-
'INSERT INTO issues(issueID, title, _0_version) VALUES(?, ?, ?)',
|
|
504
|
-
1,
|
|
505
|
-
'bug',
|
|
506
|
-
'01'
|
|
507
|
-
)
|
|
508
|
-
runner.run(
|
|
509
|
-
'INSERT INTO issues(issueID, title, _0_version) VALUES(?, ?, ?)',
|
|
510
|
-
2,
|
|
511
|
-
'feat',
|
|
512
|
-
'01'
|
|
513
|
-
)
|
|
514
|
-
runner.commit()
|
|
515
|
-
|
|
516
|
-
expect(runner.all('SELECT * FROM issues')).toEqual([
|
|
517
|
-
{ issueID: 1, title: 'bug', _0_version: '01' },
|
|
518
|
-
{ issueID: 2, title: 'feat', _0_version: '01' },
|
|
519
|
-
])
|
|
520
|
-
|
|
521
|
-
// second batch
|
|
522
|
-
runner.beginConcurrent()
|
|
523
|
-
runner.run(
|
|
524
|
-
'INSERT OR REPLACE INTO issues(issueID, title, _0_version) VALUES(?, ?, ?)',
|
|
525
|
-
1,
|
|
526
|
-
'bug fix',
|
|
527
|
-
'02'
|
|
528
|
-
)
|
|
529
|
-
runner.commit()
|
|
530
|
-
|
|
531
|
-
expect(runner.get('SELECT title FROM issues WHERE issueID = ?', 1)).toEqual({
|
|
532
|
-
title: 'bug fix',
|
|
533
|
-
})
|
|
534
|
-
|
|
535
|
-
db.close()
|
|
536
|
-
})
|
|
537
|
-
})
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
export interface HttpRequest {
|
|
2
|
-
method: string
|
|
3
|
-
url: string
|
|
4
|
-
headers?: Record<string, string>
|
|
5
|
-
body?: string | null
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface HttpResponse {
|
|
9
|
-
status: number
|
|
10
|
-
headers: Record<string, string>
|
|
11
|
-
body: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const ADMIN_HEADERS = {
|
|
15
|
-
'access-control-allow-origin': '*',
|
|
16
|
-
'access-control-allow-methods': 'GET, OPTIONS',
|
|
17
|
-
'access-control-allow-headers': '*',
|
|
18
|
-
'content-type': 'application/json',
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function jsonResponse(status: number, body: unknown): HttpResponse {
|
|
22
|
-
return {
|
|
23
|
-
status,
|
|
24
|
-
headers: ADMIN_HEADERS,
|
|
25
|
-
body: JSON.stringify(body),
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function handleDisabledBrowserAdminRequest(
|
|
30
|
-
request: HttpRequest
|
|
31
|
-
): HttpResponse | null {
|
|
32
|
-
const url = new URL(request.url, 'http://localhost')
|
|
33
|
-
if (!url.pathname.startsWith('/__orez/')) return null
|
|
34
|
-
|
|
35
|
-
const method = request.method.toUpperCase()
|
|
36
|
-
if (method === 'OPTIONS') {
|
|
37
|
-
return { status: 200, headers: ADMIN_HEADERS, body: '' }
|
|
38
|
-
}
|
|
39
|
-
if (method !== 'GET') {
|
|
40
|
-
return jsonResponse(405, { error: 'method not allowed', admin: 'disabled' })
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (url.pathname === '/__orez/api/logs') {
|
|
44
|
-
return jsonResponse(200, { entries: [], cursor: 0, admin: 'disabled' })
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (url.pathname === '/__orez/api/status') {
|
|
48
|
-
return jsonResponse(200, { ready: true, admin: 'disabled' })
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
return jsonResponse(404, { error: 'not found', admin: 'disabled' })
|
|
52
|
-
}
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect } from 'vitest'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
getBrowserAliases,
|
|
5
|
-
getBrowserDefine,
|
|
6
|
-
getBrowserBuildConfig,
|
|
7
|
-
} from './browser-build-config.js'
|
|
8
|
-
import { getHeapStatistics } from './shims/node-stub.js'
|
|
9
|
-
|
|
10
|
-
describe('browser build config', () => {
|
|
11
|
-
describe('getBrowserAliases', () => {
|
|
12
|
-
it('returns an alias map', () => {
|
|
13
|
-
const aliases = getBrowserAliases()
|
|
14
|
-
expect(typeof aliases).toBe('object')
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it('includes orez shims', () => {
|
|
18
|
-
const aliases = getBrowserAliases()
|
|
19
|
-
expect(aliases.postgres).toBe('orez/worker/shims/postgres-browser')
|
|
20
|
-
expect(aliases['@rocicorp/zero-sqlite3']).toBe('orez/worker/shims/sqlite')
|
|
21
|
-
expect(aliases.fastify).toBe('orez/worker/shims/fastify')
|
|
22
|
-
expect(aliases.ws).toBe('orez/worker/shims/ws')
|
|
23
|
-
expect(aliases.oxfmt).toBe('orez/worker/shims/oxfmt')
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
it('includes Node.js polyfills', () => {
|
|
27
|
-
const aliases = getBrowserAliases()
|
|
28
|
-
expect(aliases['node:events']).toBe('events')
|
|
29
|
-
expect(aliases['node:stream']).toBe('orez/worker/shims/stream-browser')
|
|
30
|
-
expect(aliases['node:path']).toBe('path-browserify')
|
|
31
|
-
expect(aliases['node:os']).toBe('orez/worker/shims/node-stub')
|
|
32
|
-
})
|
|
33
|
-
|
|
34
|
-
it('includes Node.js stubs', () => {
|
|
35
|
-
const aliases = getBrowserAliases()
|
|
36
|
-
expect(aliases['node:fs']).toBe('orez/worker/shims/node-stub')
|
|
37
|
-
expect(aliases['node:net']).toBe('orez/worker/shims/node-stub')
|
|
38
|
-
expect(aliases['node:child_process']).toBe('orez/worker/shims/node-stub')
|
|
39
|
-
expect(aliases['node:http']).toBe('orez/worker/shims/node-stub')
|
|
40
|
-
expect(aliases['node:crypto']).toBe('orez/worker/shims/node-stub')
|
|
41
|
-
expect(aliases['node:v8']).toBe('orez/worker/shims/node-stub')
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
describe('getBrowserDefine', () => {
|
|
46
|
-
it('returns define map', () => {
|
|
47
|
-
const define = getBrowserDefine()
|
|
48
|
-
expect(define['process.env.NODE_ENV']).toBe('"development"')
|
|
49
|
-
expect(define['process.env.SINGLE_PROCESS']).toBe('"1"')
|
|
50
|
-
})
|
|
51
|
-
})
|
|
52
|
-
|
|
53
|
-
describe('getBrowserBuildConfig', () => {
|
|
54
|
-
it('returns combined config', () => {
|
|
55
|
-
const config = getBrowserBuildConfig()
|
|
56
|
-
expect(config.alias).toBeDefined()
|
|
57
|
-
expect(config.define).toBeDefined()
|
|
58
|
-
expect(config.format).toBe('esm')
|
|
59
|
-
expect(config.platform).toBe('browser')
|
|
60
|
-
expect(config.bundle).toBe(true)
|
|
61
|
-
})
|
|
62
|
-
})
|
|
63
|
-
|
|
64
|
-
describe('node:v8 shim', () => {
|
|
65
|
-
it('reports a positive worker heap budget', () => {
|
|
66
|
-
const stats = getHeapStatistics()
|
|
67
|
-
expect(stats.heap_size_limit).toBe(128 * 1024 * 1024)
|
|
68
|
-
expect(stats.heap_size_limit - stats.used_heap_size).toBeGreaterThan(0)
|
|
69
|
-
})
|
|
70
|
-
})
|
|
71
|
-
})
|