{"version":3,"file":"read.js","sourceRoot":"","sources":["../src/read.ts"],"names":[],"mappings":"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","sourcesContent":["import { type DirectoryJSON, memfs } from 'memfs';\nimport {\n  fromBinarySnapshot,\n  fromJsonSnapshot,\n  type JsonUint8Array,\n  type SnapshotNode,\n  toBinarySnapshot,\n} from 'memfs/lib/snapshot/index.js';\n\nimport { type CreateSnapshotOptions, type FsApi } from './snapshot.js';\nimport { type CborUint8Array } from './types.js';\n\n/**\n * Options for {@link readSnapshot}\n */\nexport type ReadSnapshotOptions = CreateSnapshotOptions;\n\n/**\n * Get the type of snapshot data for a given snapshot kind\n * @template K Snapshot kind\n */\nexport type SnapshotForKind<K extends SnapshotKind> = K extends typeof CBOR_KIND\n  ? CborUint8Array<SnapshotNode>\n  : K extends typeof CJSON_KIND\n    ? JsonUint8Array<SnapshotNode>\n    : K extends typeof JSON_KIND\n      ? string | Uint8Array\n      : never;\n\n/**\n * Three (3) types of \"snapshots\" are supported:\n * - `cbor`: A CBOR-encoded snapshot\n * - `cjson`: A \"compact\" JSON-encoded snapshot\n * - `json`: A DirectoryJSON snapshot-ish data structure (lossy)\n */\nexport type SnapshotKind =\n  | typeof CBOR_KIND\n  | typeof CJSON_KIND\n  | typeof JSON_KIND;\n\n/**\n * CBOR snapshot kind\n */\nexport const CBOR_KIND = 'cbor';\n\n/**\n * Compact JSON snapshot kind\n */\nexport const CJSON_KIND = 'cjson';\n\n/**\n * {@link DirectoryJSON} snapshot kind\n */\nexport const JSON_KIND = 'json';\n\n/**\n * Reads a CBOR-encoded snapshot and populates a virtual file system.\n *\n * @param data - The CBOR-encoded data representing the snapshot.\n * @param options - Options for reading the snapshot.\n * @param options.fs - The file system to populate. Defaults to an in-memory file system.\n * @param options.separator - The path separator to use.\n * @param options.source - The root path of the source.\n * @returns A promise that resolves to the populated file system API.\n */\nexport async function readCBORSnapshot(\n  data: CborUint8Array<SnapshotNode>,\n  { fs = memfs().vol, separator, source: root }: ReadSnapshotOptions = {},\n): Promise<FsApi> {\n  await fromBinarySnapshot(data, {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n    fs: fs.promises as any,\n    path: root,\n    separator,\n  });\n  return fs;\n}\n\n/**\n * Reads a CJSON snapshot and populates a filesystem with its contents.\n *\n * @param data - The JSON data representing the snapshot.\n * @param options - Options for reading the snapshot.\n * @param options.fs - The filesystem to populate. Defaults to an in-memory filesystem.\n * @param options.separator - The path separator to use.\n * @param options.source - The root path for the filesystem.\n * @returns A promise that resolves to the populated filesystem API.\n */\nexport async function readCJSONSnapshot(\n  data: JsonUint8Array<SnapshotNode>,\n  { fs = memfs().vol, separator, source: root }: ReadSnapshotOptions = {},\n): Promise<FsApi> {\n  await fromJsonSnapshot(data, {\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n    fs: fs.promises as any,\n    path: root,\n    separator,\n  });\n  return fs;\n}\n\n/**\n * Reads a directory JSON snapshot and populates a filesystem with its contents.\n *\n * @param data - The JSON data representing the directory structure. Can be a string or Uint8Array.\n * @param options - Options for reading the snapshot.\n * @param options.fs - The filesystem to populate. If not provided, a new in-memory filesystem will be created.\n * @param options.separator - The path separator to use.\n * @param options.source - The root path for the source filesystem.\n *\n * @returns A promise that resolves to the populated filesystem.\n *\n * @throws Will throw an error if the JSON data is invalid.\n */\nexport async function readDirectoryJSONSnapshot(\n  data: string | Uint8Array,\n  { fs, separator, source: root }: ReadSnapshotOptions = {},\n): Promise<FsApi> {\n  const dirJson = (\n    typeof data === 'string'\n      ? JSON.parse(data)\n      : JSON.parse(new TextDecoder().decode(data))\n  ) as DirectoryJSON;\n  const { vol } = memfs();\n  vol.fromJSON(dirJson);\n  // if the user wanted a new filesystem, we're done.\n  if (!fs) {\n    return vol;\n  }\n  // otherwise we need to create a snapshot from the temp filesystem,\n  // then write it out to the real filesystem (which may be real or virtual).\n  // unfortunately there is no such `fs.fromJSON()` method :D\n  try {\n    // CBOR is faster and smaller than CJSON\n    const snapshot = await toBinarySnapshot({ fs: vol.promises, separator });\n    await fromBinarySnapshot(snapshot, {\n      // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n      fs: fs.promises as any,\n      path: root,\n      separator,\n    });\n  } finally {\n    vol.reset();\n  }\n  return fs;\n}\n\n/**\n * Reads a snapshot into a new virtual filesystem or existing filesystem\n *\n * @param data Raw snapshot data in `DirectoryJSON`, CSJON or CBOR format\n * @param options Options\n * @returns The value of `options.fs` populated with the snapshot contents, or a new `memfs` `Volume`.\n */\nexport async function readSnapshot<\n  K extends SnapshotKind,\n  T extends SnapshotForKind<K>,\n>(kind: K, data: T, options?: ReadSnapshotOptions): Promise<FsApi> {\n  await Promise.resolve();\n  switch (kind) {\n    case CBOR_KIND: {\n      try {\n        return await readCBORSnapshot(\n          data as CborUint8Array<SnapshotNode>,\n          options,\n        );\n      } catch (err) {\n        throw new Error(\n          `Failed to read snapshot as ${kind}: ${(err as Error).message}`,\n        );\n      }\n    }\n    case CJSON_KIND: {\n      try {\n        return await readCJSONSnapshot(\n          data as JsonUint8Array<SnapshotNode>,\n          options,\n        );\n      } catch (err) {\n        throw new Error(\n          `Failed to read snapshot as ${kind}: ${(err as Error).message}`,\n        );\n      }\n    }\n    case JSON_KIND: {\n      try {\n        return await readDirectoryJSONSnapshot(data as Uint8Array, options);\n      } catch (err) {\n        throw new Error(\n          `Failed to read snapshot as ${kind}: ${(err as Error).message}`,\n        );\n      }\n    }\n    default:\n      throw new TypeError(`Unknown snapshot kind: ${kind}`);\n  }\n}\n"]}