@livestore/sqlite-wasm
Version:
63 lines • 2.72 kB
JavaScript
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