import * as Debug from "@starbeam/debug"; import { Stack, DebugFilter, DebugListener, DebugTimeline } from "@starbeam/debug"; import * as interfaces from "@starbeam/interfaces"; import { CompositeInternals, Description, MutableInternals, ReactiveId, Timestamp, Diff } from "@starbeam/interfaces"; import { Frame as IFrame } from "@starbeam/interfaces"; import { UNINITIALIZED, REACTIVE } from "@starbeam/shared"; declare class Context { #private; readonly component: ComponentContext; set app(app: object); get app(): object; hasApp(): boolean; create(key: object, constructor: (...args: Args) => Ret, ...args: Args): Ret; } declare class ComponentContext { #private; get current(): object; push(component: object): void; pop(): void; exists(): boolean; create(constructor: (...args: Args) => Ret, ...args: Args): Ret; } declare const CONTEXT: Context; type Unsubscribe = () => void; /** * Implement this interface if you are building a new abstraction that wants to * expose cleanup in an idiomatic way. * * Note that users could always use `LIFETIME.on.cleanup(object, handler)` and * `LIFETIME.link(parent, child)` directly, but {@link CleanupTarget} is a way * to add cleanup support to objects consistently and idiomatically. */ interface CleanupTarget { readonly link: (child: object) => Unsubscribe; readonly on: OnCleanup; } interface OnCleanup { readonly cleanup: (finalizer: () => void) => Unsubscribe; } declare class LifetimeAPI { #private; readonly on: { cleanup: (object: object, handler: () => void) => Unsubscribe; }; /** * Finalize an object. This will run all of the finalizers registered on the * object, then finalize all associated children. */ finalize(object: object): void; link(parent: object, child: object, options?: { root: object; }): Unsubscribe; unlink(parent: object, child: object): void; } declare const LIFETIME: LifetimeAPI; type Lifetime = { [P in keyof LifetimeAPI]: LifetimeAPI[P]; }; declare const INSPECT: unique symbol; declare class TimestampImpl implements interfaces.Timestamp { #private; /** * Returns the current `Timestamp` according to @starbeam/shared */ static now(): interfaces.Timestamp; /** * The earliest timestamp from @starbeam/shared that was visible to this @starbeam/timeline. */ static zero(): interfaces.Timestamp; static assert(timestamp: interfaces.Timestamp, what: string): asserts timestamp is TimestampImpl; static debug(timestamp: interfaces.Timestamp): { at: number; }; [INSPECT]: () => object; constructor(timestamp: number); gt(other: Timestamp): boolean; eq(other: Timestamp): boolean; /** * Bump the timestamp using `@starbeam/shared` */ next(): Timestamp; toString: () => string; } declare function zero(): interfaces.Timestamp; declare function getNow(): interfaces.Timestamp; type Timestamp$0 = interfaces.Timestamp; declare const Timestamp: typeof TimestampImpl; declare function max(...timestamps: interfaces.Timestamp[]): interfaces.Timestamp; declare class Now { #private; get now(): interfaces.Timestamp; bump(): interfaces.Timestamp; } interface ExhaustiveMatcher { mutable: (internals: interfaces.MutableInternals) => T; composite: (internals: interfaces.CompositeInternals) => T; delegate: (internals: interfaces.DelegateInternals) => T; static: (internals: interfaces.StaticInternals) => T; } interface DefaultMatcher extends Partial> { default: (internals: interfaces.ReactiveInternals) => T; } type Matcher = ExhaustiveMatcher | DefaultMatcher; type ReactiveProtocol = interfaces.ReactiveProtocol; declare const ReactiveProtocol: { readonly description: (this: void, reactive: ReactiveProtocol) => Debug.Description; readonly id: (this: void, reactive: ReactiveProtocol) => interfaces.ReactiveId; readonly is: (this: void, reactive: ReactiveProtocol, kind: T) => reactive is { [REACTIVE]: Extract | Extract | Extract | Extract; }; readonly match: (this: void, reactive: ReactiveProtocol, matcher: Matcher) => T_1; readonly subscribesTo: (this: void, reactive: ReactiveProtocol) => ReactiveProtocol[]; readonly dependencies: (this: void, reactive: ReactiveProtocol) => Iterable; readonly dependenciesInList: (this: void, children: readonly ReactiveProtocol[]) => Iterable; readonly lastUpdated: (this: void, reactive: ReactiveProtocol) => Timestamp; readonly lastUpdatedIn: (this: void, reactives: ReactiveProtocol[]) => Timestamp; readonly log: (this: void, reactive: ReactiveProtocol, options?: { implementation?: boolean; source?: boolean; id?: boolean; }) => void; readonly debug: (this: void, reactive: ReactiveProtocol, { implementation, source }?: { implementation?: boolean | undefined; source?: boolean | undefined; }) => string; }; declare const ReactiveInternals: { is(this: void, internals: interfaces.ReactiveInternals, kind: T): internals is Extract | Extract | Extract | Extract; id(this: void, internals: interfaces.ReactiveInternals): interfaces.ReactiveId; dependencies(internals: interfaces.ReactiveInternals): Iterable; dependenciesInList(this: void, children: readonly ReactiveInternals[]): Iterable; subscribesTo(this: void, internals: interfaces.ReactiveInternals): interfaces.ReactiveInternals[]; lastUpdated(this: void, internals: ReactiveInternals): Timestamp; lastUpdatedIn(this: void, internals: ReactiveInternals[]): Timestamp; description(this: void, internals: ReactiveInternals): Debug.Description; debug(this: void, internals: interfaces.ReactiveInternals, { implementation, source, id }?: { implementation?: boolean | undefined; source?: boolean | undefined; id?: boolean | undefined; }): string; log(this: void, internals: interfaces.ReactiveInternals, options?: { implementation?: boolean; source?: boolean; id?: boolean; }): void; match(this: void, internals: ReactiveInternals, matcher: Matcher): T_1; }; type ReactiveInternals = interfaces.ReactiveInternals; type Reactive = interfaces.Reactive; declare const Reactive: { is(this: void, value: unknown): value is interfaces.Reactive; from(this: void, value: T_1 | Reactive, description?: string | Debug.Description): Reactive; }; type ReactiveCore = interfaces.ReactiveCore; declare const ReactiveCore: { is(value: unknown): value is interfaces.ReactiveCore; }; declare class Frame implements ReactiveProtocol, IFrame { #private; static create(this: void, value: T, children: Set, finalized: Timestamp, description: Description): Frame; static uninitialized(finalized: Timestamp, description: Description): Frame; static value(this: void, frame: Frame): T; static isInitialized(this: void, frame: Frame): boolean; static update(this: void, frame: Frame, value: T, children: Set, finalized: Timestamp): Frame; static updateChildren(this: void, frame: Frame, children: Set): void; constructor(id: ReactiveId, value: T, initialized: { [REACTIVE]: Omit & { lastUpdated: Timestamp; }; }, children: Set, finalized: Timestamp, description: Description); get [REACTIVE](): CompositeInternals; get description(): Description; validate(): FrameValidation>; } declare class ActiveFrame { #private; readonly description: Description; static create(updating: Frame | null, prev: ActiveFrame | null, description: Description): ActiveFrame; private constructor(); add(child: ReactiveProtocol): void; finally(): { prev: ActiveFrame | null; }; finalize(value: T, timeline: Timeline): { prev: ActiveFrame | null; frame: Frame; }; } interface ValidFrame { readonly status: "valid"; readonly value: T; } interface InvalidFrame { readonly status: "invalid"; } type FrameValidation = ValidFrame | InvalidFrame; declare class Subscription { #private; constructor(dependencies: Set, lastNotified: undefined | Timestamp, ready: (internals: MutableInternals) => void); update(dependencies: Set): void; get dependencies(): Set; get lastNotified(): Timestamp | undefined; notify(timestamp: Timestamp, internals: MutableInternals): void; } declare class Subscriptions { #private; static create(): Subscriptions; private constructor(); notify(dependency: MutableInternals): void; register(reactive: ReactiveProtocol, ready: (internals: MutableInternals) => void): Unsubscribe; update(reactive: ReactiveProtocol): void; } declare class FrameStack { #private; static didConsumeCell(frames: FrameStack, reactive: ReactiveProtocol, caller: Stack): void; static didConsumeFrame(frames: FrameStack, frame: interfaces.Frame, diff: interfaces.Diff, caller: Stack): void; static empty(timeline: Timeline, subscriptions: Subscriptions): FrameStack; constructor(subscriptions: Subscriptions, current: ActiveFrame | null, timeline: Timeline); get currentFrame(): ActiveFrame | null; create(options: { evaluate: () => T; description: interfaces.Description; }): Frame; // FIXME Overloads shouldn't trigger member-ordering create(options: { description: interfaces.Description; }): ActiveFrame; finally(prev: ActiveFrame | null): void; update(options: { updating: Frame; evaluate: () => T; }): Frame; // FIXME Overloads shouldn't trigger member-ordering update({ updating }: { updating: Frame; }): ActiveFrame; } /** * # How Subscriptions Work at the Lowest Level * * You subscribe to an object implementing ReactiveProtocol by using `Timeline#on.change`. * * ## Composites * * If the object represents a composite, the {@linkcode Timeline} will immediately subscribe to the * dependencies of the composite. * * Whenever any of those dependencies change, the timeline will notify the subscriber. Whenever a * reactive object's composite dependencies may have changed (i.e. when it was polled), the object * is responsible for calling `TIMELINE.update(object)` to notify the timeline. This updates the * internal dependencies of that object used for notifications. * * ## Delegates * * If an object implementing {@linkcode ReactiveProtocol} simply polls another reactive object, it * can use a {@linkcode DelegateInternals} property to point to that object. In this case, the * object doesn't need to worry about `TIMELINE.update`. * * ## Notifications * * Whenever a {@linkcode MutableInternals} is updated, the timeline will notify all subscribers of * reactives that depend on that dependency. */ declare class Timeline { #private; attach: (notify: () => void, options?: { filter: DebugFilter; }) => DebugListener; on: { readonly rendered: (callback: () => void) => (() => void); readonly change: (input: ReactiveProtocol, ready: (internals: interfaces.MutableInternals) => void) => Unsubscribe; }; /** * In debug mode, register a barrier for untracked reads. This allows you to throw an error if an * untracked read occurred in a context (such as a render function) that a renderer knows will * produce rendered content. */ untrackedReadBarrier: (assertion: (reactive: ReactiveProtocol, caller: Stack) => void) => void; static create(): Timeline; private constructor(); get frame(): FrameStack; get log(): DebugTimeline; // Returns the current timestamp get now(): interfaces.Timestamp; bump(mutable: interfaces.MutableInternals, caller: Stack): interfaces.Timestamp; didConsumeCell(cell: ReactiveProtocol, caller: Stack): void; didConsumeFrame(frame: interfaces.Frame, diff: interfaces.Diff, caller: Stack): void; next(): interfaces.Timestamp; /** * When a reactive's dependencies might have changed, any renderables that depend on this reactive * need to refresh their dependencies. If there are no renderers for this reactive value, * {@linkcode update} does nothing. * * Otherwise, each relevant renderable will unsubscribe from any stale dependencies and subscribe * to any new dependencies. * * For example, Formulas call this method after recomputing their value, which results in a * possible change to their dependencies. */ update(reactive: ReactiveProtocol): void; willEvaluate(): void; mutation(description: string, callback: () => T): T; /// DEBUG MODE /// /** @internal */ untrackedRead(cell: ReactiveProtocol, caller: Stack): void; } declare const TIMELINE: Timeline; declare function diff(prev: Set | ReadonlySet, next: Set | ReadonlySet): Diff; declare namespace diff { var empty: () => Diff; } declare namespace timestamp { const INSPECT: unique symbol; class TimestampImpl implements interfaces.Timestamp { #private; /** * Returns the current `Timestamp` according to @starbeam/shared */ static now(): interfaces.Timestamp; /** * The earliest timestamp from @starbeam/shared that was visible to this @starbeam/timeline. */ static zero(): interfaces.Timestamp; static assert(timestamp: interfaces.Timestamp, what: string): asserts timestamp is TimestampImpl; static debug(timestamp: interfaces.Timestamp): { at: number; }; [INSPECT]: () => object; constructor(timestamp: number); gt(other: Timestamp): boolean; eq(other: Timestamp): boolean; /** * Bump the timestamp using `@starbeam/shared` */ next(): Timestamp; toString: () => string; } function zero(): interfaces.Timestamp; function getNow(): interfaces.Timestamp; type Timestamp = interfaces.Timestamp; const Timestamp: typeof TimestampImpl; function max(...timestamps: interfaces.Timestamp[]): interfaces.Timestamp; class Now { #private; get now(): interfaces.Timestamp; bump(): interfaces.Timestamp; } const NOW: Now; } declare const Timestamp$0: typeof timestamp.TimestampImpl; type Timestamp = interfaces.Timestamp; export { ComponentContext, Context, CONTEXT, CleanupTarget, Lifetime, OnCleanup, LIFETIME, TIMELINE, FrameValidation, ActiveFrame, Frame, Reactive, ReactiveCore, ReactiveInternals, ReactiveProtocol, Subscription, Subscriptions, INSPECT, max, getNow as now, zero, diff, Timestamp$0 as Timestamp }; export type { Unsubscribe }; export { REACTIVE } from "@starbeam/shared"; //# sourceMappingURL=index.d.ts.map