@livestore/sqlite-wasm 0.3.1 → 0.3.2-dev.1
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/README.md +20 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/FacadeVFS.d.ts +3 -0
- package/dist/FacadeVFS.d.ts.map +1 -1
- package/dist/FacadeVFS.js +6 -7
- package/dist/FacadeVFS.js.map +1 -1
- package/dist/browser/mod.d.ts +2 -2
- package/dist/browser/mod.js +4 -4
- package/dist/browser/opfs/AccessHandlePoolVFS.d.ts +12 -2
- package/dist/browser/opfs/AccessHandlePoolVFS.d.ts.map +1 -1
- package/dist/browser/opfs/AccessHandlePoolVFS.js +26 -9
- package/dist/browser/opfs/AccessHandlePoolVFS.js.map +1 -1
- package/dist/browser/opfs/index.d.ts +1 -1
- package/dist/browser/opfs/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index_.d.ts +1 -1
- package/dist/index_.js +1 -1
- package/dist/make-sqlite-db.d.ts.map +1 -1
- package/dist/make-sqlite-db.js +8 -4
- package/dist/make-sqlite-db.js.map +1 -1
- package/dist/node/NodeFS.d.ts +1 -1
- package/dist/node/NodeFS.d.ts.map +1 -1
- package/dist/node/NodeFS.js +1 -2
- package/dist/node/NodeFS.js.map +1 -1
- package/dist/node/mod.d.ts +1 -1
- package/dist/node/mod.js +3 -3
- package/package.json +8 -6
- package/src/FacadeVFS.ts +6 -7
- package/src/browser/mod.ts +5 -5
- package/src/browser/opfs/AccessHandlePoolVFS.ts +27 -11
- package/src/browser/opfs/index.ts +1 -1
- package/src/index.ts +1 -1
- package/src/index_.ts +1 -1
- package/src/make-sqlite-db.ts +8 -5
- package/src/node/NodeFS.ts +1 -2
- package/src/node/mod.ts +3 -3
package/src/browser/mod.ts
CHANGED
|
@@ -2,12 +2,12 @@ import type { MakeSqliteDb, PersistenceInfo, SqliteDb } from '@livestore/common'
|
|
|
2
2
|
import { Effect, Hash } from '@livestore/utils/effect'
|
|
3
3
|
import type { MemoryVFS } from '@livestore/wa-sqlite/src/examples/MemoryVFS.js'
|
|
4
4
|
|
|
5
|
-
import { makeInMemoryDb } from '../in-memory-vfs.
|
|
6
|
-
import { makeSqliteDb } from '../make-sqlite-db.
|
|
7
|
-
import type { AccessHandlePoolVFS } from './opfs/AccessHandlePoolVFS.
|
|
8
|
-
import { makeOpfsDb } from './opfs/index.
|
|
5
|
+
import { makeInMemoryDb } from '../in-memory-vfs.ts'
|
|
6
|
+
import { makeSqliteDb } from '../make-sqlite-db.ts'
|
|
7
|
+
import type { AccessHandlePoolVFS } from './opfs/AccessHandlePoolVFS.ts'
|
|
8
|
+
import { makeOpfsDb } from './opfs/index.ts'
|
|
9
9
|
|
|
10
|
-
export * from './opfs/opfs-sah-pool.
|
|
10
|
+
export * from './opfs/opfs-sah-pool.ts'
|
|
11
11
|
|
|
12
12
|
export type WebDatabaseMetadataInMemory = {
|
|
13
13
|
_tag: 'in-memory'
|
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { Effect, Schedule, Schema } from '@livestore/utils/effect'
|
|
3
2
|
// Based on https://github.com/rhashimoto/wa-sqlite/blob/master/src/examples/AccessHandlePoolVFS.js
|
|
4
3
|
import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
|
|
5
|
-
|
|
6
|
-
import { FacadeVFS } from '../../FacadeVFS.js'
|
|
4
|
+
import { FacadeVFS } from '../../FacadeVFS.ts'
|
|
7
5
|
|
|
8
6
|
const SECTOR_SIZE = 4096
|
|
9
7
|
|
|
@@ -123,7 +121,9 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
123
121
|
|
|
124
122
|
jRead(fileId: number, pData: Uint8Array, iOffset: number): number {
|
|
125
123
|
const file = this.#mapIdToFile.get(fileId)!
|
|
126
|
-
const nBytes = file.accessHandle.read(pData.subarray(), {
|
|
124
|
+
const nBytes = file.accessHandle.read(pData.subarray(), {
|
|
125
|
+
at: HEADER_OFFSET_DATA + iOffset,
|
|
126
|
+
})
|
|
127
127
|
if (nBytes < pData.byteLength) {
|
|
128
128
|
pData.fill(0, nBytes, pData.byteLength)
|
|
129
129
|
return VFS.SQLITE_IOERR_SHORT_READ
|
|
@@ -133,7 +133,9 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
133
133
|
|
|
134
134
|
jWrite(fileId: number, pData: Uint8Array, iOffset: number): number {
|
|
135
135
|
const file = this.#mapIdToFile.get(fileId)!
|
|
136
|
-
const nBytes = file.accessHandle.write(pData.subarray(), {
|
|
136
|
+
const nBytes = file.accessHandle.write(pData.subarray(), {
|
|
137
|
+
at: HEADER_OFFSET_DATA + iOffset,
|
|
138
|
+
})
|
|
137
139
|
return nBytes === pData.byteLength ? VFS.SQLITE_OK : VFS.SQLITE_IOERR
|
|
138
140
|
}
|
|
139
141
|
|
|
@@ -164,7 +166,7 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
164
166
|
return VFS.SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
jAccess(zName: string,
|
|
169
|
+
jAccess(zName: string, _flags: number, pResOut: DataView): number {
|
|
168
170
|
const path = this.#getPath(zName)
|
|
169
171
|
pResOut.setInt32(0, this.#mapPathToAccessHandle.has(path) ? 1 : 0, true)
|
|
170
172
|
return VFS.SQLITE_OK
|
|
@@ -219,8 +221,14 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
219
221
|
async addCapacity(n: number): Promise<number> {
|
|
220
222
|
for (let i = 0; i < n; ++i) {
|
|
221
223
|
const name = Math.random().toString(36).replace('0.', '')
|
|
222
|
-
const handle = await this.#directoryHandle!.getFileHandle(name, {
|
|
223
|
-
|
|
224
|
+
const handle = await this.#directoryHandle!.getFileHandle(name, {
|
|
225
|
+
create: true,
|
|
226
|
+
})
|
|
227
|
+
|
|
228
|
+
const accessHandle = await Effect.tryPromise({
|
|
229
|
+
try: () => handle.createSyncAccessHandle(),
|
|
230
|
+
catch: (cause) => new OpfsError({ cause, path: name }),
|
|
231
|
+
}).pipe(Effect.retry(Schedule.exponentialBackoff10Sec), Effect.runPromise)
|
|
224
232
|
this.#mapAccessHandleToName.set(accessHandle, name)
|
|
225
233
|
|
|
226
234
|
this.#setAssociatedPath(accessHandle, '', 0)
|
|
@@ -236,7 +244,7 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
236
244
|
async removeCapacity(n: number): Promise<number> {
|
|
237
245
|
let nRemoved = 0
|
|
238
246
|
for (const accessHandle of Array.from(this.#availableAccessHandles)) {
|
|
239
|
-
if (nRemoved
|
|
247
|
+
if (nRemoved === n || this.getSize() === this.getCapacity()) return nRemoved
|
|
240
248
|
|
|
241
249
|
const name = this.#mapAccessHandleToName.get(accessHandle)!
|
|
242
250
|
accessHandle.close()
|
|
@@ -260,7 +268,10 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
260
268
|
// Open access handles in parallel, separating associated and unassociated.
|
|
261
269
|
await Promise.all(
|
|
262
270
|
files.map(async ([name, handle]) => {
|
|
263
|
-
const accessHandle = await
|
|
271
|
+
const accessHandle = await Effect.tryPromise({
|
|
272
|
+
try: () => handle.createSyncAccessHandle(),
|
|
273
|
+
catch: (cause) => new OpfsError({ cause, path: name }),
|
|
274
|
+
}).pipe(Effect.retry(Schedule.exponentialBackoff10Sec), Effect.runPromise)
|
|
264
275
|
this.#mapAccessHandleToName.set(accessHandle, name)
|
|
265
276
|
const path = this.#getAssociatedPath(accessHandle)
|
|
266
277
|
if (path) {
|
|
@@ -402,3 +413,8 @@ export class AccessHandlePoolVFS extends FacadeVFS {
|
|
|
402
413
|
}
|
|
403
414
|
}
|
|
404
415
|
}
|
|
416
|
+
|
|
417
|
+
export class OpfsError extends Schema.TaggedError<OpfsError>()('OpfsError', {
|
|
418
|
+
cause: Schema.Defect,
|
|
419
|
+
path: Schema.String,
|
|
420
|
+
}) {}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Effect } from '@livestore/utils/effect'
|
|
2
2
|
import type * as WaSqlite from '@livestore/wa-sqlite'
|
|
3
3
|
|
|
4
|
-
import { AccessHandlePoolVFS } from './AccessHandlePoolVFS.
|
|
4
|
+
import { AccessHandlePoolVFS } from './AccessHandlePoolVFS.ts'
|
|
5
5
|
|
|
6
6
|
const semaphore = Effect.makeSemaphore(1).pipe(Effect.runSync)
|
|
7
7
|
const opfsVfsMap = new Map<string, AccessHandlePoolVFS>()
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * as WaSqlite from './index_.
|
|
1
|
+
export * as WaSqlite from './index_.ts'
|
package/src/index_.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from '@livestore/wa-sqlite'
|
|
2
|
-
export * from './make-sqlite-db.
|
|
2
|
+
export * from './make-sqlite-db.ts'
|
package/src/make-sqlite-db.ts
CHANGED
|
@@ -6,9 +6,9 @@ import type {
|
|
|
6
6
|
SqliteDbChangeset,
|
|
7
7
|
} from '@livestore/common'
|
|
8
8
|
import { SqliteDbHelper, SqliteError } from '@livestore/common'
|
|
9
|
+
import { EventSequenceNumber } from '@livestore/common/schema'
|
|
9
10
|
import * as SqliteConstants from '@livestore/wa-sqlite/src/sqlite-constants.js'
|
|
10
|
-
|
|
11
|
-
import { makeInMemoryDb } from './in-memory-vfs.js'
|
|
11
|
+
import { makeInMemoryDb } from './in-memory-vfs.ts'
|
|
12
12
|
|
|
13
13
|
export const makeSqliteDb = <
|
|
14
14
|
TMetadata extends {
|
|
@@ -32,6 +32,10 @@ export const makeSqliteDb = <
|
|
|
32
32
|
const sqliteDb: SqliteDb<TMetadata> = {
|
|
33
33
|
_tag: 'SqliteDb',
|
|
34
34
|
metadata,
|
|
35
|
+
debug: {
|
|
36
|
+
// Setting initially to root but will be set to correct value shortly after
|
|
37
|
+
head: EventSequenceNumber.ROOT,
|
|
38
|
+
},
|
|
35
39
|
prepare: (queryStr) => {
|
|
36
40
|
try {
|
|
37
41
|
const stmts = sqlite3.statements(dbPointer, queryStr.trim(), { unscoped: true })
|
|
@@ -75,10 +79,9 @@ export const makeSqliteDb = <
|
|
|
75
79
|
|
|
76
80
|
try {
|
|
77
81
|
// NOTE `column_names` only works for `SELECT` statements, ignoring other statements for now
|
|
78
|
-
let columns
|
|
82
|
+
let columns: string[] | undefined
|
|
79
83
|
try {
|
|
80
84
|
columns = sqlite3.column_names(stmt)
|
|
81
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
82
85
|
} catch (_e) {}
|
|
83
86
|
|
|
84
87
|
while (sqlite3.step(stmt) === SqliteConstants.SQLITE_ROW) {
|
|
@@ -209,7 +212,7 @@ export const makeSqliteDb = <
|
|
|
209
212
|
try {
|
|
210
213
|
sqlite3.changeset_apply(dbPointer, data)
|
|
211
214
|
// @ts-expect-error data should be garbage collected after use
|
|
212
|
-
// biome-ignore lint/style/noParameterAssign:
|
|
215
|
+
// biome-ignore lint/style/noParameterAssign: ...
|
|
213
216
|
data = undefined
|
|
214
217
|
} catch (cause: any) {
|
|
215
218
|
throw new SqliteError({
|
package/src/node/NodeFS.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
2
|
|
|
3
|
-
/* eslint-disable prefer-arrow/prefer-arrow-functions */
|
|
4
3
|
import * as fs from 'node:fs'
|
|
5
4
|
import path from 'node:path'
|
|
6
5
|
|
|
7
6
|
import type * as WaSqlite from '@livestore/wa-sqlite'
|
|
8
7
|
import * as VFS from '@livestore/wa-sqlite/src/VFS.js'
|
|
9
8
|
|
|
10
|
-
import { FacadeVFS } from '../FacadeVFS.
|
|
9
|
+
import { FacadeVFS } from '../FacadeVFS.ts'
|
|
11
10
|
|
|
12
11
|
interface NodeFsFile {
|
|
13
12
|
pathname: string
|
package/src/node/mod.ts
CHANGED
|
@@ -5,9 +5,9 @@ import { Effect, FileSystem } from '@livestore/utils/effect'
|
|
|
5
5
|
import type * as WaSqlite from '@livestore/wa-sqlite'
|
|
6
6
|
import type { MemoryVFS } from '@livestore/wa-sqlite/src/examples/MemoryVFS.js'
|
|
7
7
|
|
|
8
|
-
import { makeInMemoryDb } from '../in-memory-vfs.
|
|
9
|
-
import { makeSqliteDb } from '../make-sqlite-db.
|
|
10
|
-
import { NodeFS } from './NodeFS.
|
|
8
|
+
import { makeInMemoryDb } from '../in-memory-vfs.ts'
|
|
9
|
+
import { makeSqliteDb } from '../make-sqlite-db.ts'
|
|
10
|
+
import { NodeFS } from './NodeFS.ts'
|
|
11
11
|
|
|
12
12
|
export type NodeDatabaseMetadataInMemory = {
|
|
13
13
|
_tag: 'in-memory'
|