UNPKG

snapshot-fs

Version:

Create a filesystem snapshot for use with memfs

132 lines 4.82 kB
import { memfs } from 'memfs'; import { fromBinarySnapshot, fromJsonSnapshot, toBinarySnapshot, } from 'memfs/lib/snapshot/index.js'; /** * CBOR snapshot kind */ export const CBOR_KIND = 'cbor'; /** * Compact JSON snapshot kind */ export const CJSON_KIND = 'cjson'; /** * {@link DirectoryJSON} snapshot kind */ export const JSON_KIND = 'json'; /** * Reads a CBOR-encoded snapshot and populates a virtual file system. * * @param data - The CBOR-encoded data representing the snapshot. * @param options - Options for reading the snapshot. * @param options.fs - The file system to populate. Defaults to an in-memory file system. * @param options.separator - The path separator to use. * @param options.source - The root path of the source. * @returns A promise that resolves to the populated file system API. */ export async function readCBORSnapshot(data, { fs = memfs().vol, separator, source: root } = {}) { await fromBinarySnapshot(data, { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fs: fs.promises, path: root, separator, }); return fs; } /** * Reads a CJSON snapshot and populates a filesystem with its contents. * * @param data - The JSON data representing the snapshot. * @param options - Options for reading the snapshot. * @param options.fs - The filesystem to populate. Defaults to an in-memory filesystem. * @param options.separator - The path separator to use. * @param options.source - The root path for the filesystem. * @returns A promise that resolves to the populated filesystem API. */ export async function readCJSONSnapshot(data, { fs = memfs().vol, separator, source: root } = {}) { await fromJsonSnapshot(data, { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fs: fs.promises, path: root, separator, }); return fs; } /** * Reads a directory JSON snapshot and populates a filesystem with its contents. * * @param data - The JSON data representing the directory structure. Can be a string or Uint8Array. * @param options - Options for reading the snapshot. * @param options.fs - The filesystem to populate. If not provided, a new in-memory filesystem will be created. * @param options.separator - The path separator to use. * @param options.source - The root path for the source filesystem. * * @returns A promise that resolves to the populated filesystem. * * @throws Will throw an error if the JSON data is invalid. */ export async function readDirectoryJSONSnapshot(data, { fs, separator, source: root } = {}) { const dirJson = (typeof data === 'string' ? JSON.parse(data) : JSON.parse(new TextDecoder().decode(data))); const { vol } = memfs(); vol.fromJSON(dirJson); // if the user wanted a new filesystem, we're done. if (!fs) { return vol; } // otherwise we need to create a snapshot from the temp filesystem, // then write it out to the real filesystem (which may be real or virtual). // unfortunately there is no such `fs.fromJSON()` method :D try { // CBOR is faster and smaller than CJSON const snapshot = await toBinarySnapshot({ fs: vol.promises, separator }); await fromBinarySnapshot(snapshot, { // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment fs: fs.promises, path: root, separator, }); } finally { vol.reset(); } return fs; } /** * Reads a snapshot into a new virtual filesystem or existing filesystem * * @param data Raw snapshot data in `DirectoryJSON`, CSJON or CBOR format * @param options Options * @returns The value of `options.fs` populated with the snapshot contents, or a new `memfs` `Volume`. */ export async function readSnapshot(kind, data, options) { await Promise.resolve(); switch (kind) { case CBOR_KIND: { try { return await readCBORSnapshot(data, options); } catch (err) { throw new Error(`Failed to read snapshot as ${kind}: ${err.message}`); } } case CJSON_KIND: { try { return await readCJSONSnapshot(data, options); } catch (err) { throw new Error(`Failed to read snapshot as ${kind}: ${err.message}`); } } case JSON_KIND: { try { return await readDirectoryJSONSnapshot(data, options); } catch (err) { throw new Error(`Failed to read snapshot as ${kind}: ${err.message}`); } } default: throw new TypeError(`Unknown snapshot kind: ${kind}`); } } //# sourceMappingURL=read.js.map