UNPKG

observablehq-file-attachments

Version:

Library to handle ObservableHQ's file attachments more flexibly, and to support virtualizing them.

188 lines 6.63 kB
/** * The various types used in the system. * * @module types */ import { AFile } from './AFile'; import { AFileSystem } from './AFileSystem'; import { CACHED_METADATA, DIRECTORY, FILE, METADATA, TAGS } from './symbols'; /** * Options for requestion data from a [[VFile]]/ */ export interface DataOptions { /** * For TSV and CSV, whether to return the rows as an array. */ array?: boolean; /** * For TSV and CSV, whether to attempt to convert the values to e.g. numbers */ typed?: boolean; /** * Whether data should be interconverted between text and binary based on utf8, rather than utf16. */ utf8?: boolean; } /** * Objects that JSON.parse can produce. */ export declare type JsonObject = { [k: string]: JsonObject; } | string | number | null | Array<JsonObject>; /** * The known metadata types. Additional keys may be used, without typing. */ export declare type Metadata = { name: string; url?: string; contentType?: string; length?: number; modificationDate?: Date; eTag?: string; } & { [k in Exclude<string, 'modificationDate'>]: any | undefined; }; /** * The properties we add to track metadata. */ interface MetadataProps { [CACHED_METADATA]?: Metadata; [METADATA]?: Metadata; } /** * The common portion of the ObservableHQ](https://observablehq.com)-supplied * [FileAttachment](https://observablehq.com/@observablehq/file-attachments) * interface. */ interface FileAttachmentBase { json(opts?: DataOptions): Promise<JsonObject>; blob(opts?: DataOptions): Promise<Blob>; text(opts?: DataOptions): Promise<string>; arrayBuffer(opts?: DataOptions): Promise<ArrayBuffer>; csv(opts?: DataOptions): Promise<any>; tsv(opts?: DataOptions): Promise<any>; url(): Promise<string>; name: string; } /** * The ObservableHQ](https://observablehq.com)-supplied * [FileAttachment](https://observablehq.com/@observablehq/file-attachments). */ export interface FileAttachment extends FileAttachmentBase, MetadataProps { ['content-type']?: string; } /** * The interface for the [FileAttachment](https://observablehq.com/@observablehq/file-attachments) * analogs we supply. These differ in that [[IAFile.url]] returns a `Promise<string>` rather * than a `string`. */ export interface IAFile extends FileAttachmentBase, MetadataProps { } /** * The methods of an interface that return a `Promise`. */ declare type AsyncMethodsOf<I, T extends keyof I = keyof I> = T extends string ? I[T] extends (...args: any) => Promise<any> ? T : never : never; /** * Split out the methods of [[IAFile]] that are async. */ declare type IAFileMethods = AsyncMethodsOf<IAFile>; /** * Split out everything in [[IAFile]] that is not an async method. */ declare type IAFileOther = Exclude<keyof IAFile, IAFileMethods>; /** * Extract the wrapped type from a promise. */ declare type UnwrapPromise<T> = T extends Promise<infer P> ? P : T; /** * Add another allowed return type to an async function. */ declare type AddReturnType<T extends (...args: any[]) => any, R> = (...args: Parameters<T>) => Promise<R | UnwrapPromise<ReturnType<T>>>; /** * The async methods of [[AFileAwait]] should return the same values as [[IAFile]] except each `Promise` can also * resolve to `undefined`. */ export declare type IAFileAwait = { [k in IAFileMethods]: AddReturnType<IAFile[k], undefined>; } & { [k in IAFileOther]: IAFile[k]; }; /** * Version numbers/tags (labels) for files. */ export declare type Version = 'latest' | 'earliest' | string | number; /** * Version, including the special version '*'. */ export declare type DeleteVersion = Version | '*'; export interface Tags { [k: string]: VFile; } /** * File entries are either a [ObservableHQ](https://observablehq.com)-supplied * [FileAttachment](https://observablehq.com/@observablehq/file-attachments), or an [[AFile]] */ export declare type VFile = AFile | FileAttachment; /** * An array of file versions. The array can be sparse if versions are * deleted. File version indexes start at 1, but the arrays start at 0. * * So the tree: * ```javascript * const tree: Tree = { * myFile: [file1, file2] * }; * ``` * provides 2 versions of `/myFile`. Version 1 is _file1_ and version 2 is _file2_. */ export interface Files extends Array<VFile> { [TAGS]?: Tags; [METADATA]?: Metadata; } /** * A directory tree, denoting the hierarchy of files. Javascript `Object`s are the directories. * * Entries in the directory are named by keys. * * If the value of an entry is another Javascript `Object`, it is a subdirectory. * * If the value of an entry is an `Array`, it is a list of file versions. See [[Files]] */ export declare type Tree = { /** * Special symbol entry [[FILE]] provides a function that dynamically adds files on demand. */ [FILE]?: FileHandler; /** * Special symbol entry [[DIRECTORY]] provides a function that dynamically adds subdirectories on demand. */ [DIRECTORY]?: DirectoryHandler; /** * Regular entries */ [k: string]: Tree | Files; }; /** * A value, or a `Promise` of a value, where either synchronous or async code may be used. * @typeParam T the wrapped type */ export declare type PromiseOr<T> = T | Promise<T>; /** * A handler to dynamically add files. It is called when a file is not found, and can add that file or more. * * The handler implementation will typically return an array of a single [[AFile]] instance (or zero if no file should be added). * * Advanced usages can return multiple versions in the array, or use {@link setVersion | setVersion()} to tag entries in the * array. */ export declare type FileHandler = (filesystem: AFileSystem, path: string, name: string, version: Version, rest: string[], tree: Tree) => PromiseOr<Files>; /** * A handler to dynamically add subdirectories. It is called when a directory is not found, and can create * a subdirectory heirarchy on demand. A [[DirectoryHandler]] that adds itself to the returned tree as a * [[DIRECTORY]] handler can create an infinite on-demand hierarchy. */ export declare type DirectoryHandler = (filesystem: AFileSystem, path: string, name: string, rest: string[], tree: Tree) => PromiseOr<Tree>; export interface Regenerable { updateCount: number; updated(v: this): void; errored(e: Error): void; } export {}; //# sourceMappingURL=types.d.ts.map