process.env.NODE_ENV = "production"; import preact from "preact"; import { findGrantedPointerHandle, getFileSystemPointer, storeFileSystemPointer } from "./fileSystemPointer"; import { observable } from "mobx"; import { observer } from "../render-utils/observer"; import { cache, lazy } from "socket-function/src/caching"; import { css, isNode } from "typesafecss"; import { IStorageRaw } from "./IStorage"; import { runInSerial } from "socket-function/src/batching"; import { getFileStorageIndexDB } from "./IndexedDBFileFolderAPI"; import { getRemoteDirectoryHandle, testRemoteConnection, RemoteOptions } from "./remoteFileStorage"; import fs from "fs"; import path from "path"; declare global { interface Window { showSaveFilePicker(config?: { types: { description: string; accept: { [mimeType: string]: string[] } }[]; }): Promise; showDirectoryPicker(): Promise; showOpenFilePicker(config?: { types: { description: string; accept: { [mimeType: string]: string[] } }[]; }): Promise; } interface FileSystemDirectoryHandle { requestPermission(config?: { mode: "read" | "readwrite" }): Promise; } } // NOTE: IndexedDB is required for iOS, at least. We MIGHT want to make // this a user supported toggle too, so they can choose during runtime if they want it. // DO NOT enable this is isNode const USE_INDEXED_DB = false; // How often a worker rechecks the pointer IndexedDB for a granted handle when none is available yet. const WORKER_POLL_INTERVAL_MS = 60 * 1000; // These mirror the subset of the native FileSystemFileHandle / FileSystemDirectoryHandle API we use, so the native browser handles, the Node handles, and the remote handles are all interchangeable — and code written against the native handle (e.g. a recursive walk over `handle.entries()`) works on any of them. kind/name and entries() are part of that contract. export type FileWrapper = { readonly kind: "file"; readonly name: string; getFile(): Promise<{ size: number; lastModified: number; arrayBuffer(): Promise; // Matches Blob.slice (which the native File object provides), so the browser // implementation works vanilla. End is exclusive, both clamped to the file size. slice(start: number, end: number): { arrayBuffer(): Promise }; }>; createWritable(config?: { keepExistingData?: boolean }): Promise<{ seek(offset: number): Promise; write(value: Buffer): Promise; close(): Promise; }>; // Returns a URL for the file's bytes, usable in