UNPKG

@livestore/sqlite-wasm

Version:

63 lines 2.72 kB
import path from 'node:path'; import { UnexpectedError } from '@livestore/common'; import { Effect, FileSystem } from '@livestore/utils/effect'; import { makeInMemoryDb } from '../in-memory-vfs.js'; import { makeSqliteDb } from '../make-sqlite-db.js'; import { NodeFS } from './NodeFS.js'; export const sqliteDbFactory = ({ sqlite3, }) => Effect.andThen(FileSystem.FileSystem, (fs) => (input) => Effect.gen(function* () { if (input._tag === 'in-memory') { const { dbPointer, vfs } = makeInMemoryDb(sqlite3); return makeSqliteDb({ sqlite3, metadata: { _tag: 'in-memory', vfs, dbPointer, persistenceInfo: { fileName: ':memory:' }, deleteDb: () => { }, configureDb: input.configureDb ?? (() => { }), }, }); } const { dbPointer, vfs } = yield* makeNodeFsDb({ sqlite3, fileName: input.fileName, directory: input.directory, fs, }); const filePath = path.join(input.directory, input.fileName); return makeSqliteDb({ sqlite3, metadata: { _tag: 'fs', vfs, dbPointer, persistenceInfo: { fileName: input.fileName, directory: input.directory }, deleteDb: () => vfs.deleteDb(filePath), configureDb: input.configureDb ?? (() => { }), }, }); })); const nodeFsVfsMap = new Map(); const makeNodeFsDb = ({ sqlite3, fileName, directory, fs, }) => Effect.gen(function* () { // NOTE to keep the filePath short, we use the directory name in the vfs name // If this is becoming a problem, we can use a hashed version of the directory name const vfsName = `node-fs-${directory}`; if (nodeFsVfsMap.has(vfsName) === false) { // TODO refactor with Effect FileSystem instead of using `node:fs` directly inside of NodeFS const nodeFsVfs = new NodeFS(vfsName, sqlite3.module, directory); // @ts-expect-error TODO fix types sqlite3.vfs_register(nodeFsVfs, false); nodeFsVfsMap.set(vfsName, nodeFsVfs); } yield* fs.makeDirectory(directory, { recursive: true }); const FILE_NAME_MAX_LENGTH = 56; if (fileName.length > FILE_NAME_MAX_LENGTH) { throw new Error(`File name ${fileName} is too long. Maximum length is ${FILE_NAME_MAX_LENGTH} characters.`); } // NOTE SQLite will return a "disk I/O error" if the file path is too long. const dbPointer = sqlite3.open_v2Sync(fileName, undefined, vfsName); const vfs = nodeFsVfsMap.get(vfsName); return { dbPointer, vfs }; }).pipe(UnexpectedError.mapToUnexpectedError); //# sourceMappingURL=mod.js.map