observablehq / runtime

The reactive dataflow runtime that powers Observable Framework and Observable notebooks
https://observablehq.com/@observablehq/how-observable-runs
ISC License
1k stars 71 forks source link

type declarations for typescript #326

Open benjamine opened 2 years ago

benjamine commented 2 years ago

hi 👋 , was wondering if there are, or you're interested in adding type declarations for typescript. this could be created as a .d.ts file here, or added to the https://github.com/DefinitelyTyped/DefinitelyTyped repo.

an incipient example of how this would look

declare module '@observablehq/runtime' {
  export class Inspector {
    constructor(element: unknown);

    pending(...args: unknown[]): unknown;

    rejected(...args: unknown[]): unknown;

    fulfilled(...args: unknown[]): unknown;
  }
  export class Runtime {
    constructor();

    module(
      notebook: unknown,
      handler: (name: string) => Inspector | boolean,
    ): void;

    dispose(): void;
  }
}
caleb-vear commented 2 years ago

I would be interested in it. I am doing some work using the runtime at the moment and by the time I'm done it is likely I'll have a bunch of type definitions defined. So if it is something the observable team would be interested in accepting I could consider sending through a pull request for it.

lionel-rowe commented 1 year ago

Here's what I've got currently. Might open a PR at some point unless someone else wants to pick it up.

declare module 'https://cdn.jsdelivr.net/npm/@observablehq/runtime@5/dist/runtime.js' {
    export class Runtime {
        constructor(builtins?: Builtins, global?: (name: string | symbol) => unknown)

        module(define: NotebookDefine, handler: GetObserver): Module
        dispose(): void
    }

    export class Inspector implements Required<Observer> {
        constructor(element: Element)

        static into(container: Element | string): () => Inspector

        pending(): void
        fulfilled(value: unknown, name: string | null): void
        rejected(error: unknown, name: string | null): void
    }

    export class Library implements Builtins {}
    export class RuntimeError extends Error {}

    class Module {
        variable(observer?: Observer): Variable

        derive(specifiers: string[], source: Module): Module

        define(name: string | null, value: unknown): Variable
        define(inputs: string[], getter: (...inputs: unknown[]) => unknown): Variable
        define(name: string | null, inputs: string[], getter: (...inputs: unknown[]) => unknown): Variable

        import(name: string, module: Module): Variable
        import(name: string, alias: string, module: Module): Variable

        redefine(name: string, value: unknown): Variable
        redefine(name: string, inputs: string[], getter: (...inputs: unknown[]) => unknown): Variable

        value(name: string): Variable
    }

    class Variable {
        define(name: string | null, value: unknown): this
        define(inputs: string[], getter: (...inputs: unknown[]) => unknown): this
        define(name: string | null, inputs: string[], getter: (...inputs: unknown[]) => unknown): this

        import(name: string, module: Module): this
        import(name: string, alias: string, module: Module): this

        delete(): void
    }

    type Observer = Partial<{
        pending(): void
        fulfilled(value: unknown, name: string | null): void
        rejected(error: unknown, name: string | null): void
    }>

    type Builtins = Partial<Record<string, unknown>>
    type NotebookDefine = (runtime: Runtime, observer: GetObserver) => Module
    type GetObserver = (name: string | undefined) => Observer | void
}