Hyperlinkv0.8.0-beta.28

FileSystem

FileSystem.makeconsteffect/FileSystem.ts:774
(
  impl: Omit<
    FileSystem,
    | typeof TypeId
    | "exists"
    | "readFileString"
    | "stream"
    | "sink"
    | "writeFileString"
  >
): FileSystem

Creates a FileSystem implementation from a partial implementation.

When to use

Use to build a concrete FileSystem service from platform-specific core operations while deriving the convenience methods that can be implemented from them.

Details

This function takes a partial FileSystem implementation and automatically provides default implementations for exists, readFileString, stream, sink, and writeFileString methods based on the provided core methods.

constructorsmakeNooplayerNoop
export const make = (
  impl: Omit<FileSystem, typeof TypeId | "exists" | "readFileString" | "stream" | "sink" | "writeFileString">
): FileSystem =>
  FileSystem.of({
    ...impl,
    [TypeId]: TypeId,
    exists: (path) =>
      pipe(
        impl.access(path),
        Effect.as(true),
        Effect.catchTag(
          "PlatformError",
          (e) => e.reason._tag === "NotFound" ? Effect.succeed(false) : Effect.fail(e)
        )
      ),
    readFileString: (path, encoding) =>
      Effect.flatMap(impl.readFile(path), (_) =>
        Effect.try({
          try: () => new TextDecoder(encoding).decode(_),
          catch: (cause) =>
            badArgument({
              module: "FileSystem",
              method: "readFileString",
              description: "invalid encoding",
              cause
            })
        })),
    stream: Effect.fnUntraced(function*(path, options) {
      const file = yield* impl.open(path, { flag: "r" })
      if (options?.offset) {
        yield* file.seek(options.offset, "start")
      }
      const bytesToRead = options?.bytesToRead !== undefined ? Size(options.bytesToRead) : undefined
      let totalBytesRead = BigInt(0)
      const chunkSize = Size(options?.chunkSize ?? 64 * 1024)
      const readChunk = file.readAlloc(chunkSize)
      return Stream.fromPull(Effect.succeed(
        Effect.flatMap(
          Effect.suspend((): Pull.Pull<Option.Option<Uint8Array>, PlatformError> => {
            if (bytesToRead !== undefined && bytesToRead <= totalBytesRead) {
              return Cause.done()
            }
            return bytesToRead !== undefined && (bytesToRead - totalBytesRead) < chunkSize
              ? file.readAlloc(bytesToRead - totalBytesRead)
              : readChunk
          }),
          Option.match({
            onNone: () => Cause.done(),
            onSome: (buf) => {
              totalBytesRead += BigInt(buf.length)
              return Effect.succeed(Arr.of(buf))
            }
          })
        )
      ))
    }, Stream.unwrap),
    sink: (path, options) =>
      pipe(
        impl.open(path, { flag: "w", ...options }),
        Effect.map((file) => Sink.forEach((_: Uint8Array) => file.writeAll(_))),
        Sink.unwrap
      ),
    writeFileString: (path, data, options) =>
      Effect.flatMap(
        Effect.try({
          try: () => new TextEncoder().encode(data),
          catch: (cause) =>
            badArgument({
              module: "FileSystem",
              method: "writeFileString",
              description: "could not encode string",
              cause
            })
        }),
        (_) => impl.writeFile(path, _, options)
      )
  })