@qwik.dev/core
Version:
An open source framework for building instant loading web apps at any scale, without the extra effort.
1,305 lines (1,240 loc) • 189 kB
TypeScript
import type { AsyncLocalStorage } from 'node:async_hooks';
import type * as CSS_2 from 'csstype';
import { isBrowser } from './build';
import { isDev } from './build';
import { isServer } from './build';
import { ResolvedManifest } from './optimizer';
import type { ServerQwikManifest } from './optimizer';
/**
* Qwik Optimizer marker function.
*
* Use `$(...)` to tell Qwik Optimizer to extract the expression in `$(...)` into a lazy-loadable
* resource referenced by `QRL`.
*
* @param expression - Expression which should be lazy loaded
* @public
* @see `implicit$FirstArg` for additional `____$(...)` rules.
*
* In this example, `$(...)` is used to capture the callback function of `onmousemove` into a
* lazy-loadable reference. This allows the code to refer to the function without actually
* loading the function. In this example, the callback function does not get loaded until
* `mousemove` event fires.
*
* ```tsx
* useOnDocument(
* 'mousemove',
* $((event) => console.log('mousemove', event))
* );
* ```
*
* In this code, the Qwik Optimizer detects `$(...)` and transforms the code into:
*
* ```tsx
* // FILE: <current file>
* useOnDocument('mousemove', qrl('./chunk-abc.js', 'onMousemove'));
*
* // FILE: chunk-abc.js
* export const onMousemove = () => console.log('mousemove');
* ```
*
* ## Special Rules
*
* The Qwik Optimizer places special rules on functions that can be lazy-loaded.
*
* 1. The expression of the `$(expression)` function must be importable by the system.
* (expression shows up in `import` or has `export`)
* 2. If inlined function, then all lexically captured values must be:
* - importable (vars show up in `import`s or `export`s)
* - const (The capturing process differs from JS capturing in that writing to captured
* variables does not update them, and therefore writes are forbidden. The best practice is that
* all captured variables are constants.)
* - Must be runtime serializable.
*
* ```tsx
*
* import { createContextId, useContext, useContextProvider } from './use/use-context';
* import { Resource } from './use/use-resource';
* import { useResource$ } from './use/use-resource-dollar';
* import { useSignal } from './use/use-signal';
*
* export const greet = () => console.log('greet');
* function topLevelFn() {}
*
* function myCode() {
* const store = useStore({});
* function localFn() {}
* // Valid Examples
* $(greet); // greet is importable
* $(() => greet()); // greet is importable;
* $(() => console.log(store)); // store is serializable.
*
* // Compile time errors
* $(topLevelFn); // ERROR: `topLevelFn` not importable
* $(() => topLevelFn()); // ERROR: `topLevelFn` not importable
*
* // Runtime errors
* $(localFn); // ERROR: `localFn` fails serialization
* $(() => localFn()); // ERROR: `localFn` fails serialization
* }
*
* ```
*/
export declare const $: <T>(expression: T) => QRL<T>;
/**
* Register an external projection on a parent component VNode.
*
* Creates a new VirtualVNode that will render the given component QRL with the given props. The
* VNode is stored as a projection on the parent, and a low-priority cursor is added so the cursor
* walker will process it.
*
* Use `_setProjectionTarget` to set the DOM target element before the cursor fires.
*
* @internal
*/
export declare function _addProjection(container: _Container, parentVNode: _VirtualVNode, componentQRL: QRL<any>, props: Record<string, unknown>, slotName: string): _VirtualVNode;
declare interface AddRootFn {
(obj: unknown, returnRef?: never): number;
(obj: unknown, returnRef: true): SeenRef;
}
declare type AllEventKeys = keyof AllEventsMap;
declare type AllEventMapRaw = QwikHTMLElementEventMap & QwikDocumentEventMap & QwikWindowEventMap;
declare type AllEventsMap = Omit<AllEventMapRaw, keyof EventCorrectionMap> & EventCorrectionMap;
declare type _AllowPlainQrl<Q> = QRLEventHandlerMulti<any, any> extends Q ? Q extends QRLEventHandlerMulti<infer EV, infer EL> ? Q | (EL extends Element ? EventHandler<EV, EL> : never) : Q : Q extends QRL<infer U> ? Q | U : NonNullable<Q> extends never ? Q : QRL<Q> | Q;
declare type AllSignalFlags = SignalFlags | WrappedSignalFlags | SerializationSignalFlags | AsyncSignalFlags;
/**
* TS defines these with the React syntax which is not compatible with Qwik. E.g. `ariaAtomic`
* instead of `aria-atomic`.
*
* @public
*/
declare interface AriaAttributes {
/**
* Identifies the currently active element when DOM focus is on a composite widget, textbox,
* group, or application.
*/
'aria-activedescendant'?: string | undefined;
/**
* Indicates whether assistive technologies will present all, or only parts of, the changed region
* based on the change notifications defined by the aria-relevant attribute.
*/
'aria-atomic'?: Booleanish | undefined;
/**
* Indicates whether inputting text could trigger display of one or more predictions of the user's
* intended value for an input and specifies how predictions would be presented if they are made.
*/
'aria-autocomplete'?: 'none' | 'inline' | 'list' | 'both' | undefined;
/**
* Indicates an element is being modified and that assistive technologies MAY want to wait until
* the modifications are complete before exposing them to the user.
*/
'aria-busy'?: Booleanish | undefined;
/**
* Indicates the current "checked" state of checkboxes, radio buttons, and other widgets.
*
* @see aria-pressed @see aria-selected.
*/
'aria-checked'?: boolean | 'false' | 'mixed' | 'true' | undefined;
/**
* Defines the total number of columns in a table, grid, or treegrid.
*
* @see aria-colindex.
*/
'aria-colcount'?: number | undefined;
/**
* Defines an element's column index or position with respect to the total number of columns
* within a table, grid, or treegrid.
*
* @see aria-colcount @see aria-colspan.
*/
'aria-colindex'?: number | undefined;
/**
* Defines the number of columns spanned by a cell or gridcell within a table, grid, or treegrid.
*
* @see aria-colindex @see aria-rowspan.
*/
'aria-colspan'?: number | undefined;
/**
* Identifies the element (or elements) whose contents or presence are controlled by the current
* element.
*
* @see aria-owns.
*/
'aria-controls'?: string | undefined;
/**
* Indicates the element that represents the current item within a container or set of related
* elements.
*/
'aria-current'?: boolean | 'false' | 'true' | 'page' | 'step' | 'location' | 'date' | 'time' | undefined;
/**
* Identifies the element (or elements) that describes the object.
*
* @see aria-labelledby
*/
'aria-describedby'?: string | undefined;
/**
* Identifies the element that provides a detailed, extended description for the object.
*
* @see aria-describedby.
*/
'aria-details'?: string | undefined;
/**
* Indicates that the element is perceivable but disabled, so it is not editable or otherwise
* operable.
*
* @see aria-hidden @see aria-readonly.
*/
'aria-disabled'?: Booleanish | undefined;
/**
* Indicates what functions can be performed when a dragged object is released on the drop target.
*
* @deprecated In ARIA 1.1
*/
'aria-dropeffect'?: 'none' | 'copy' | 'execute' | 'link' | 'move' | 'popup' | undefined;
/**
* Identifies the element that provides an error message for the object.
*
* @see aria-invalid @see aria-describedby.
*/
'aria-errormessage'?: string | undefined;
/**
* Indicates whether the element, or another grouping element it controls, is currently expanded
* or collapsed.
*/
'aria-expanded'?: Booleanish | undefined;
/**
* Identifies the next element (or elements) in an alternate reading order of content which, at
* the user's discretion, allows assistive technology to override the general default of reading
* in document source order.
*/
'aria-flowto'?: string | undefined;
/**
* Indicates an element's "grabbed" state in a drag-and-drop operation.
*
* @deprecated In ARIA 1.1
*/
'aria-grabbed'?: Booleanish | undefined;
/**
* Indicates the availability and type of interactive popup element, such as menu or dialog, that
* can be triggered by an element.
*/
'aria-haspopup'?: boolean | 'false' | 'true' | 'menu' | 'listbox' | 'tree' | 'grid' | 'dialog' | undefined;
/**
* Indicates whether the element is exposed to an accessibility API.
*
* @see aria-disabled.
*/
'aria-hidden'?: Booleanish | undefined;
/**
* Indicates the entered value does not conform to the format expected by the application.
*
* @see aria-errormessage.
*/
'aria-invalid'?: boolean | 'false' | 'true' | 'grammar' | 'spelling' | undefined;
/**
* Indicates keyboard shortcuts that an author has implemented to activate or give focus to an
* element.
*/
'aria-keyshortcuts'?: string | undefined;
/**
* Defines a string value that labels the current element.
*
* @see aria-labelledby.
*/
'aria-label'?: string | undefined;
/**
* Identifies the element (or elements) that labels the current element.
*
* @see aria-describedby.
*/
'aria-labelledby'?: string | undefined;
/** Defines the hierarchical level of an element within a structure. */
'aria-level'?: number | undefined;
/**
* Indicates that an element will be updated, and describes the types of updates the user agents,
* assistive technologies, and user can expect from the live region.
*/
'aria-live'?: 'off' | 'assertive' | 'polite' | undefined;
/** Indicates whether an element is modal when displayed. */
'aria-modal'?: Booleanish | undefined;
/** Indicates whether a text box accepts multiple lines of input or only a single line. */
'aria-multiline'?: Booleanish | undefined;
/** Indicates that the user may select more than one item from the current selectable descendants. */
'aria-multiselectable'?: Booleanish | undefined;
/** Indicates whether the element's orientation is horizontal, vertical, or unknown/ambiguous. */
'aria-orientation'?: 'horizontal' | 'vertical' | undefined;
/**
* Identifies an element (or elements) in order to define a visual, functional, or contextual
* parent/child relationship between DOM elements where the DOM hierarchy cannot be used to
* represent the relationship.
*
* @see aria-controls.
*/
'aria-owns'?: string | undefined;
/**
* Defines a short hint (a word or short phrase) intended to aid the user with data entry when the
* control has no value. A hint could be a sample value or a brief description of the expected
* format.
*/
'aria-placeholder'?: string | undefined;
/**
* Defines an element's number or position in the current set of listitems or treeitems. Not
* required if all elements in the set are present in the DOM.
*
* @see aria-setsize.
*/
'aria-posinset'?: number | undefined;
/**
* Indicates the current "pressed" state of toggle buttons.
*
* @see aria-checked @see aria-selected.
*/
'aria-pressed'?: boolean | 'false' | 'mixed' | 'true' | undefined;
/**
* Indicates that the element is not editable, but is otherwise operable.
*
* @see aria-disabled.
*/
'aria-readonly'?: Booleanish | undefined;
/**
* Indicates what notifications the user agent will trigger when the accessibility tree within a
* live region is modified.
*
* @see aria-atomic.
*/
'aria-relevant'?: 'additions' | 'additions removals' | 'additions text' | 'all' | 'removals' | 'removals additions' | 'removals text' | 'text' | 'text additions' | 'text removals' | undefined;
/** Indicates that user input is required on the element before a form may be submitted. */
'aria-required'?: Booleanish | undefined;
/** Defines a human-readable, author-localized description for the role of an element. */
'aria-roledescription'?: string | undefined;
/**
* Defines the total number of rows in a table, grid, or treegrid.
*
* @see aria-rowindex.
*/
'aria-rowcount'?: number | undefined;
/**
* Defines an element's row index or position with respect to the total number of rows within a
* table, grid, or treegrid.
*
* @see aria-rowcount @see aria-rowspan.
*/
'aria-rowindex'?: number | undefined;
/**
* Defines the number of rows spanned by a cell or gridcell within a table, grid, or treegrid.
*
* @see aria-rowindex @see aria-colspan.
*/
'aria-rowspan'?: number | undefined;
/**
* Indicates the current "selected" state of various widgets.
*
* @see aria-checked @see aria-pressed.
*/
'aria-selected'?: Booleanish | undefined;
/**
* Defines the number of items in the current set of listitems or treeitems. Not required if all
* elements in the set are present in the DOM.
*
* @see aria-posinset.
*/
'aria-setsize'?: number | undefined;
/** Indicates if items in a table or grid are sorted in ascending or descending order. */
'aria-sort'?: 'none' | 'ascending' | 'descending' | 'other' | undefined;
/** Defines the maximum allowed value for a range widget. */
'aria-valuemax'?: number | undefined;
/** Defines the minimum allowed value for a range widget. */
'aria-valuemin'?: number | undefined;
/**
* Defines the current value for a range widget.
*
* @see aria-valuetext.
*/
'aria-valuenow'?: number | undefined;
/** Defines the human readable text alternative of aria-valuenow for a range widget. */
'aria-valuetext'?: string | undefined;
}
/** @public */
declare type AriaRole = 'alert' | 'alertdialog' | 'application' | 'article' | 'banner' | 'button' | 'cell' | 'checkbox' | 'columnheader' | 'combobox' | 'complementary' | 'contentinfo' | 'definition' | 'dialog' | 'directory' | 'document' | 'feed' | 'figure' | 'form' | 'grid' | 'gridcell' | 'group' | 'heading' | 'img' | 'link' | 'list' | 'listbox' | 'listitem' | 'log' | 'main' | 'marquee' | 'math' | 'menu' | 'menubar' | 'menuitem' | 'menuitemcheckbox' | 'menuitemradio' | 'navigation' | 'none' | 'note' | 'option' | 'presentation' | 'progressbar' | 'radio' | 'radiogroup' | 'region' | 'row' | 'rowgroup' | 'rowheader' | 'scrollbar' | 'search' | 'searchbox' | 'separator' | 'slider' | 'spinbutton' | 'status' | 'switch' | 'tab' | 'table' | 'tablist' | 'tabpanel' | 'term' | 'textbox' | 'timer' | 'toolbar' | 'tooltip' | 'tree' | 'treegrid' | 'treeitem' | (string & {});
declare type AsyncCtx<T = unknown> = {
track: Tracker;
/**
* Register a cleanup callback to be called when the async computation is aborted or completed.
* The next invocation will await the previous cleanup. If you do not want this, do not return a
* Promise.
*/
cleanup: (callback: () => void | Promise<void>) => void;
/**
* A lazily created AbortSignal, for interrupting the async computation when needed, e.g. when the
* component is unmounted or the computation is invalidated. Pass it to `fetch` or other APIs that
* support it to ensure that unnecessary work is not performed.
*/
readonly abortSignal: AbortSignal;
/** The result of the previous computation, if any */
readonly previous: T | undefined;
/** Extra info passed to `invalidate(info)` for this computation, if any. */
readonly info?: unknown;
};
/**
* Note, we don't pass the generic type to AsyncCtx because it causes TypeScript to not infer the
* type of the resource correctly. The type is only used for the `previous` property, which is not
* commonly used, and can be easily cast if needed.
*
* @public
*/
export declare type AsyncFn<T> = (ctx: AsyncCtx) => ValueOrPromise<T>;
/** Retains job metadata and also serves as the argument for the compute function */
declare class AsyncJob<T> implements AsyncCtx<T> {
readonly $signal$: AsyncSignalImpl<T>;
/** First holds the compute promise and then the cleanup promise */
$promise$: Promise<void> | null | void;
$cleanupRequested$: boolean;
$canWrite$: boolean;
$track$: AsyncCtx<T>['track'] | undefined;
$cleanups$: Parameters<AsyncCtx<T>['cleanup']>[0][] | undefined;
$abortController$: AbortController | undefined;
info: unknown;
$infoVersion$: number | undefined;
constructor($signal$: AsyncSignalImpl<T>, info: unknown, $infoVersion$: number | undefined);
get track(): AsyncCtx<T>['track'];
get abortSignal(): AbortSignal;
/** Backward compatible cache method for resource */
cache(): void;
get previous(): T | undefined;
cleanup(callback: () => void): void;
}
declare type AsyncQRL<T> = _QRLInternal<AsyncFn<T>>;
/**
* An AsyncSignal holds the result of the given async function. If the function uses `track()` to
* track reactive state, and that state changes, the AsyncSignal is recalculated, and if the result
* changed, all tasks which are tracking the AsyncSignal will be re-run and all subscribers
* (components, tasks etc) that read the AsyncSignal will be updated.
*
* If the async function throws an error, the AsyncSignal will capture the error and set the `error`
* property. The error can be cleared by re-running the async function successfully.
*
* While the async function is running, the `.loading` property will be set to `true`. Once the
* function completes, `loading` will be set to `false`.
*
* If the value has not yet been resolved, reading the AsyncSignal will throw a Promise, which will
* retry the component or task once the value resolves.
*
* If the value has been resolved, but the async function is re-running, reading the AsyncSignal
* will subscribe to it and return the last resolved value until the new value is ready. As soon as
* the new value is ready, the subscribers will be updated.
*
* If the async function threw an error, reading the `.value` will throw that same error. Read from
* `.error` to check if there was an error.
*
* @public
*/
export declare interface AsyncSignal<T = unknown> extends ComputedSignal<T> {
/**
* Whether the signal is currently loading. This will trigger lazy loading of the signal, so you
* can use it like this:
*
* ```tsx
* signal.loading ? <Loading /> : signal.error ? <Error /> : <Component
* value={signal.value} />
* ```
*/
loading: boolean;
/**
* Lets you read the loading state without subscribing to `.loading` updates. It also triggers
* lazy loading of the signal.
*
* Setting it will trigger listeners for `.loading`.
*/
untrackedLoading: boolean;
/**
* The error that occurred while computing the signal, if any. This will be cleared when the
* signal is successfully computed. It does not trigger lazy loading of the signal.
*/
error: Error | undefined;
/**
* Lets you read the error state without subscribing to `.error` updates. It does not trigger lazy
* loading of the signal.
*
* Setting it will trigger listeners for `.error`.
*/
untrackedError: Error | undefined;
/**
* Expiration time in ms. Writable and immediately effective.
*
* When set, the signal is invalidated after this many ms. Whether it auto-recomputes depends on
* the `poll` property. `0` means no expiration.
*/
expires: number;
/**
* Whether to automatically re-run the function when the value expires. Writable and immediately
* effective. Only relevant when `expires` is set.
*
* Defaults to `true`.
*/
poll: boolean;
/** @deprecated Use `expires` and `poll` instead. Will be removed before v2 */
interval: number;
/** A promise that resolves when the value is computed or rejected. */
promise(): Promise<void>;
/** Abort the current computation and run cleanups if needed. */
abort(reason?: any): void;
/**
* Use this to force recalculation. If you pass `info`, it will be provided to the calculation
* function.
*/
invalidate(info?: unknown): void;
}
declare const enum AsyncSignalFlags {
EAGER_CLEANUP = 32,
CLIENT_ONLY = 64,
CLEAR_ON_INVALIDATE = 128,
NO_POLL = 256
}
/**
* # ================================
*
* AsyncSignalImpl
*
* # ================================
*
* @internal
*/
declare class AsyncSignalImpl<T> extends ComputedSignalImpl<T, AsyncQRL<T>> implements BackRef, AsyncSignal<T> {
$untrackedLoading$: boolean;
$untrackedError$: Error | undefined;
$current$: AsyncJob<T> | null;
$jobs$: AsyncJob<T>[] | undefined;
$concurrency$: number | undefined;
$expires$: number | undefined;
$timeoutMs$: number | undefined;
$loadingEffects$: undefined | Set<EffectSubscription>;
$errorEffects$: undefined | Set<EffectSubscription>;
$pollTimeoutId$: ReturnType<typeof setTimeout> | undefined;
$computationTimeoutId$: ReturnType<typeof setTimeout> | undefined;
$info$: unknown | undefined;
$infoVersion$: number | undefined;
[_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | undefined;
constructor(container: _Container | null, fn: AsyncQRL<T>, flags?: SignalFlags | SerializationSignalFlags, options?: AsyncSignalOptions<T>);
get untrackedValue(): T;
set untrackedValue(value: T);
/**
* Read the value, subscribing if in a tracking context. Triggers computation if needed.
*
* Setting the value will mark the signal as not loading and clear any error, and prevent any
* pending computations from writing their results.
*
* If you want to set the value without affecting loading or error state, set `untrackedValue`
* instead and make sure to trigger effects manually if needed.
*
* If you want to abort pending computations when setting, you have to call `abort()` manually.
*/
get value(): T;
set value(value: T);
/**
* Loading is true if the signal is still waiting for the promise to resolve, false if the promise
* has resolved or rejected.
*
* Accessing .loading will trigger computation if needed, since it's often used like
* `signal.loading ? <Loading /> : signal.value`.
*/
get loading(): boolean;
set untrackedLoading(value: boolean);
get untrackedLoading(): boolean;
/** The error that occurred when the signal was resolved. */
get error(): Error | undefined;
set untrackedError(value: Error | undefined);
get untrackedError(): Error | undefined;
get expires(): number;
set expires(value: number);
get poll(): boolean;
set poll(value: boolean);
/** @deprecated Use `expires` and `poll` instead. */
get interval(): number;
set interval(value: number);
/** Invalidates the signal, causing it to re-compute its value. */
invalidate(info?: unknown): Promise<void>;
$setInvalid$(allowRecalc: boolean, mustClear: boolean | number): void;
/** Abort the current computation and run cleanups if needed. */
abort(reason?: any): void;
/** Schedule eager cleanup on next macro task if no subscribers remain. */
$scheduleEagerCleanup$(): void;
/** Returns a promise resolves when the signal finished computing. */
promise(): Promise<void>;
/** Run the computation if needed */
$computeIfNeeded$(): void;
$runComputation$(running: AsyncJob<T>): Promise<void>;
/**
* Sets the error from the given job. We only accept errors from the current job and we ignore
* AbortErrors.
*/
$setError$(job: AsyncJob<T>, error: Error): void;
/** Called after SSR/unmount */
$destroy$(): Promise<void>;
private $clearNextPoll$;
private $scheduleNextPoll$;
private $hasSubscribers$;
$requestCleanups$(job: AsyncJob<T>, reason?: any): void;
/** Clean up and trigger signal compute once complete */
$runCleanups$(job: AsyncJob<T>): Promise<void> | undefined;
}
/** @public */
export declare interface AsyncSignalOptions<T> extends ComputedOptions {
/** Like useSignal's `initial`; prevents the throw on first read when uninitialized */
initial?: T | (() => T);
/**
* Maximum number of concurrent computations. Use `0` for unlimited.
*
* Defaults to `1`.
*/
concurrency?: number;
/**
* When subscribers drop to 0, run cleanup in the next tick, instead of waiting for the function
* inputs to change.
*
* Defaults to `false`, meaning cleanup happens only when inputs change.
*/
eagerCleanup?: boolean;
/**
* Time in milliseconds after which the value expires.
*
* When the value expires and subscribers exist, the signal is invalidated. If `poll` is `true`
* (default), the function is re-run automatically. If `poll` is `false`, the value is marked
* stale and recomputation happens when reading `.value` or `.loading`.
*
* `0` (default) means no expiration.
*/
expires?: number;
/**
* Whether to automatically re-run the function when the value expires. Only relevant when
* `expires` is set.
*
* Defaults to `true`.
*/
poll?: boolean;
/** @deprecated Use `expires` and `poll` instead. Will be removed before v2 */
interval?: number;
/**
* When true, the async computation is postponed to the browser. On SSR, the signal remains
* INVALID and does not execute the function. On the client, it will compute on first read.
*
* Defaults to `false`.
*/
clientOnly?: boolean;
/**
* When true (default), the previous value is kept while the signal re-computes after
* invalidation, so reads return stale data instead of throwing a promise. Reactivity will then
* update the readers when the new value is ready.
*
* When false, invalidation clears the value so reads throw the computation promise (like the
* initial load), which is useful for navigations where showing old data would be confusing.
*
* Note that polling invalidations (`expires` with `poll: true`) are not affected by this option
* and will keep the old value while the new value is loading, to avoid flashing loaders.
*
* This option only affects manual invalidations via `invalidate()`, and non-polling expirations
* (`poll: false`, or there are no subscribers).
*
* Defaults to `true`.
*/
allowStale?: boolean;
/**
* Maximum time in milliseconds to wait for the async computation to complete. If exceeded, the
* computation is aborted and an error is thrown.
*
* If `0`, no timeout is applied.
*
* Defaults to `0`.
*/
timeout?: number;
}
/**
* Replace given element's props with custom types and return all props specific to the element. Use
* this for known props that are incorrect or missing.
*
* Uses Prettify so we see the special props for each element in editor hover
*/
declare type Augmented<E, A = {}> = Prettify<Filtered<E, A> & A>;
/** Class for back reference to the EffectSubscription */
declare abstract class BackRef {
[_EFFECT_BACK_REF]: Map<any, any> | undefined;
}
declare type BivariantQrlFn<ARGS extends any[], RETURN> = {
/**
* Resolve the QRL of closure and invoke it.
*
* @param args - Closure arguments.
* @returns A promise of the return value of the closure.
*/
bivarianceHack(...args: ARGS): Promise<RETURN>;
}['bivarianceHack'];
/** @public */
declare type Booleanish = boolean | `${boolean}`;
declare type Capture = {
[K in keyof HTMLElementEventMap as `capture:${K}`]?: boolean;
};
/**
* The current captured scope during QRL invocation. This is used to provide the lexical scope for
* QRL functions. It is used one time per invocation, synchronously, so it is safe to store it in
* module scope.
*
* @internal
*/
export declare let _captures: Readonly<unknown[]> | null;
/**
* Handles events for bind:checked
*
* @internal
*/
export declare function _chk(this: string | undefined, _: any, element: HTMLInputElement): void;
declare const enum ChoreBits {
NONE = 0,
TASKS = 1,
NODE_DIFF = 2,
COMPONENT = 4,
INLINE_COMPONENT = 8,
NODE_PROPS = 16,
COMPUTE = 32,
CHILDREN = 64,
CLEANUP = 128,
RECONCILE = 256,
ERROR_WRAP = 512,
DIRTY_MASK = 1023
}
/**
* A class list can be a string, a boolean, an array, or an object.
*
* If it's an array, each item is a class list and they are all added.
*
* If it's an object, then the keys are class name strings, and the values are booleans that
* determine if the class name string should be added or not.
*
* @public
*/
export declare type ClassList = string | undefined | null | false | Record<string, boolean | string | number | null | undefined> | ClassList[];
/** @internal */
export declare interface ClientContainer extends _Container {
document: _QDocument;
element: _ContainerElement;
qContainer: string;
$locale$: string;
qManifestHash: string;
rootVNode: _ElementVNode;
$forwardRefs$: Array<number | string> | null;
vNodeLocate(id: string | Element): _VNode;
parseQRL<T = unknown>(qrl: string): QRL<T>;
$getForwardRef$(id: number): number | string | undefined;
$setRawState$(id: number, vParent: _ElementVNode | _VirtualVNode): void;
}
/**
* Declare a Qwik component that can be used to create UI.
*
* Use `component$` to declare a Qwik component. A Qwik component is a special kind of component
* that allows the Qwik framework to lazy load and execute the component independently of other Qwik
* components as well as lazy load the component's life-cycle hooks and event handlers.
*
* Side note: You can also declare regular (standard JSX) components that will have standard
* synchronous behavior.
*
* Qwik component is a facade that describes how the component should be used without forcing the
* implementation of the component to be eagerly loaded. A minimum Qwik definition consists of:
*
* ### Example
*
* An example showing how to create a counter component:
*
* ```tsx
* export interface CounterProps {
* initialValue?: number;
* step?: number;
* }
* export const Counter = component$((props: CounterProps) => {
* const state = useSignal(props.initialValue || 0);
* return (
* <div>
* <span>{state.value}</span>
* <button onClick$={() => (state.value += props.step || 1)}>+</button>
* </div>
* );
* });
* ```
*
* - `component$` is how a component gets declared.
* - `{ value?: number; step?: number }` declares the public (props) interface of the component.
* - `{ count: number }` declares the private (state) interface of the component.
*
* The above can then be used like so:
*
* ```tsx
* export const OtherComponent = component$(() => {
* return <Counter initialValue={100} />;
* });
* ```
*
* See also: `component`, `useCleanup`, `onResume`, `onPause`, `useOn`, `useOnDocument`,
* `useOnWindow`, `useStyles`
*
* @public
*/
export declare const component$: <PROPS = unknown>(onMount: OnRenderFn<PROPS>) => Component<PROPS>;
/**
* Type representing the Qwik component.
*
* `Component` is the type returned by invoking `component$`.
*
* ```tsx
* interface MyComponentProps {
* someProp: string;
* }
* const MyComponent: Component<MyComponentProps> = component$((props: MyComponentProps) => {
* return <span>{props.someProp}</span>;
* });
* ```
*
* @public
*/
export declare type Component<PROPS = unknown> = FunctionComponent<PublicProps<PROPS>>;
/** @public */
export declare interface ComponentBaseProps {
key?: string | number | null | undefined;
'q:slot'?: string;
}
declare type ComponentChildren<PROPS> = PROPS extends {
children: any;
} ? never : {
children?: JSXChildren;
};
/** @internal */
export declare const componentQrl: <PROPS extends Record<any, any>>(componentQrl: QRL<OnRenderFn<PROPS>>) => Component<PROPS>;
/** @public */
export declare type ComputedFn<T> = () => T;
/** @public */
export declare interface ComputedOptions {
serializationStrategy?: SerializationStrategy;
container?: _Container;
}
/** @public */
export declare type ComputedReturnType<T> = T extends Promise<any> ? never : ComputedSignal<T>;
/**
* A computed signal is a signal which is calculated from other signals. When the signals change,
* the computed signal is recalculated, and if the result changed, all tasks which are tracking the
* signal will be re-run and all components that read the signal will be re-rendered.
*
* @public
*/
export declare interface ComputedSignal<T> extends Signal<T> {
/** @deprecated Use `trigger()` instead */
force(): void;
/** Use this to force recalculation. */
invalidate(): void;
}
/**
* A signal which is computed from other signals.
*
* The value is available synchronously, but the computation is done lazily.
*/
declare class ComputedSignalImpl<T, S extends _QRLInternal = ComputeQRL<T>> extends SignalImpl<T> implements BackRef {
/**
* The compute function is stored here.
*
* The computed functions must be executed synchronously (because of this we need to eagerly
* resolve the QRL during the mark dirty phase so that any call to it will be synchronous). )
*/
$computeQrl$: S;
$flags$: SignalFlags | SerializationSignalFlags;
[_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | undefined;
constructor(container: _Container | null, fn: S, flags?: SignalFlags | SerializationSignalFlags);
invalidate(): void;
get untrackedValue(): T;
set untrackedValue(value: T);
$computeIfNeeded$(): void;
}
declare type ComputeQRL<T> = _QRLInternal<ComputedFn<T>>;
/** @internal */
export declare const _CONST_PROPS: unique symbol;
/**
* Effect is something which needs to happen (side-effect) due to signal value change.
*
* There are three types of effects:
*
* - `Task`: `useTask`, `useVisibleTask`, `useResource`
* - `VNode` and `ISsrNode`: Either a component or `<Signal>`
* - `Signal2`: A derived signal which contains a computation function.
*/
declare type Consumer = Task | _VNode | SignalImpl | ISsrNode;
/** @internal */
export declare interface _Container {
readonly $version$: string;
readonly $storeProxyMap$: ObjToProxyMap;
$rootContainer$: _Container | null;
$isOutOfOrderSegment$: boolean;
readonly $locale$: string;
readonly $getObjectById$: (id: number | string) => any;
readonly $serverData$: Record<string, any>;
readonly $instanceHash$: string | null;
$currentUniqueId$: number;
$buildBase$: string | null;
$renderPromise$: Promise<void> | null;
$resolveRenderPromise$: (() => void) | null;
$pendingCount$: number;
$checkPendingCount$(): void;
handleError(err: any, $host$: HostElement | null): void;
getParentHost(host: HostElement): HostElement | null;
setContext<T>(host: HostElement, context: ContextId<T>, value: T): void;
resolveContext<T>(host: HostElement, contextId: ContextId<T>): T | undefined;
setHostProp<T>(host: HostElement, name: string, value: T): void;
getHostProp<T>(host: HostElement, name: string): T | null;
$appendStyle$(content: string, styleId: string, host: HostElement, scoped: boolean): void;
/**
* When component is about to be executed, it may add/remove children. This can cause problems
* with the projection because deleting content will prevent the projection references from
* looking up vnodes. Therefore before we execute the component we need to ensure that all of its
* references to vnode are resolved.
*
* @param renderHost - Host element to ensure projection is resolved.
*/
ensureProjectionResolved(host: HostElement): void;
serializationCtxFactory(NodeConstructor: {
new (...rest: any[]): {
__brand__: 'SsrNode';
};
} | null, DomRefConstructor: {
new (...rest: any[]): {
__brand__: 'DomRef';
};
} | null, symbolToChunkResolver: SymbolToChunkResolver, writer?: StreamWriter): SerializationContext;
}
/** @internal */
export declare interface _ContainerElement extends HTMLElement {
qContainer?: ClientContainer;
/**
* Map of element ID to Element. If VNodeData has a reference to an element, then it is added to
* this map for later retrieval.
*
* Once retrieved the element is replaced with its VNode.
*
* NOTE: This map leaks memory! Once the application is resumed we don't know which element IDs
* are still in the deserialized state. we will probably need a GC cycle. Some process running in
* the idle time which processes few elements at a time to see if they are still referenced and
* removes them from the map if they are not.
*/
qVNodeRefs?: Map<number, Element | _ElementVNode>;
/** String from `<script type="qwik/vnode">` tag. */
qVnodeData?: string;
/** Segment-local strings from `<script type="qwik/vnode" q:r="...">` tags. */
qSegmentVnodeData?: Map<string, string>;
}
/**
* ContextId is a typesafe ID for your context.
*
* Context is a way to pass stores to the child components without prop-drilling.
*
* Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier
* for the context. It is not the context value itself. See `useContextProvider()` and
* `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can
* track context providers and consumers in a way that survives resumability.
*
* ### Example
*
* ```tsx
* // Declare the Context type.
* interface TodosStore {
* items: string[];
* }
* // Create a Context ID (no data is saved here.)
* // You will use this ID to both create and retrieve the Context.
* export const TodosContext = createContextId<TodosStore>('Todos');
*
* // Example of providing context to child components.
* export const App = component$(() => {
* useContextProvider(
* TodosContext,
* useStore<TodosStore>({
* items: ['Learn Qwik', 'Build Qwik app', 'Profit'],
* })
* );
*
* return <Items />;
* });
*
* // Example of retrieving the context provided by a parent component.
* export const Items = component$(() => {
* const todos = useContext(TodosContext);
* return (
* <ul>
* {todos.items.map((item) => (
* <li>{item}</li>
* ))}
* </ul>
* );
* });
*
* ```
*
* @public
*/
export declare interface ContextId<STATE> {
/** Design-time property to store type information for the context. */
readonly __brand_context_type__: STATE;
/** A unique ID for the context. */
readonly id: string;
}
/**
* Low-level API for platform abstraction.
*
* Different platforms (browser, node, service workers) may have different ways of handling things
* such as `requestAnimationFrame` and imports. To make Qwik platform-independent Qwik uses the
* `CorePlatform` API to access the platform API.
*
* `CorePlatform` also is responsible for importing symbols. The import map is different on the
* client (browser) then on the server. For this reason, the server has a manifest that is used to
* map symbols to javascript chunks. The manifest is encapsulated in `CorePlatform`, for this
* reason, the `CorePlatform` can't be global as there may be multiple applications running at
* server concurrently.
*
* This is a low-level API and there should not be a need for you to access this.
*
* @public
*/
export declare interface CorePlatform {
/**
* True of running on the server platform.
*
* @returns True if we are running on the server (not the browser.)
*/
isServer: boolean;
/**
* Retrieve a symbol value from QRL.
*
* Qwik needs to lazy load data and closures. For this Qwik uses QRLs that are serializable
* references of resources that are needed. The QRLs contain all the information necessary to
* retrieve the reference using `importSymbol`.
*
* Why not use `import()`? Because `import()` is relative to the current file, and the current
* file is always the Qwik framework. So QRLs have additional information that allows them to
* serialize imports relative to application base rather than the Qwik framework file.
*
* @param element - The element against which the `url` is resolved. Used to locate the container
* root and `q:base` attribute.
* @param url - Relative URL retrieved from the attribute that needs to be resolved against the
* container `q:base` attribute.
* @param symbol - The name of the symbol to import.
* @returns A promise that resolves to the imported symbol.
*/
importSymbol: (containerEl: Element | undefined, url: string | URL | undefined | null, symbol: string) => ValueOrPromise<unknown>;
/**
* Perform operation on next request-animation-frame.
*
* @param fn - The function to call when the next animation frame is ready.
*/
raf: (fn: () => any) => Promise<any>;
/**
* Retrieve chunk name for the symbol.
*
* When the application is running on the server the symbols may be imported from different files
* (as server build is typically a single javascript chunk.) For this reason, it is necessary to
* convert the chunks from server format to client (browser) format. This is done by looking up
* symbols (which are globally unique) in the manifest. (Manifest is the mapping of symbols to the
* client chunk names.)
*
* @param symbolName - Resolve `symbolName` against the manifest and return the chunk that
* contains the symbol.
*/
chunkForSymbol: (symbolName: string, chunk: string | null, parent?: string) => readonly [symbol: string, chunk: string] | undefined;
}
/** This corrects the TS definition for ToggleEvent @public */
export declare interface CorrectedToggleEvent extends Event {
readonly newState: 'open' | 'closed';
readonly prevState: 'open' | 'closed';
}
/**
* Create a signal holding a `.value` which is calculated from the given async function (QRL). The
* standalone version of `useAsync$`.
*
* @public
*/
export declare const createAsync$: <T>(qrl: (arg: AsyncCtx<T>) => Promise<T>, options?: AsyncSignalOptions<T>) => AsyncSignal<T>;
/** @internal */
export declare const createAsyncQrl: <T>(qrl: QRL<AsyncFn<T>>, options?: AsyncSignalOptions<T>) => AsyncSignalImpl<T>;
/**
* Create a computed signal which is calculated from the given QRL. A computed signal is a signal
* which is calculated from other signals. When the signals change, the computed signal is
* recalculated.
*
* The QRL must be a function which returns the value of the signal. The function must not have side
* effects, and it must be synchronous.
*
* If you need the function to be async, use `createAsync$` instead (don't forget to use `track()`).
*
* @public
*/
export declare const createComputed$: <T>(qrl: () => T, options?: ComputedOptions) => ComputedReturnType<T>;
/** @internal */
export declare const createComputedQrl: <T>(qrl: QRL<() => T>, options?: ComputedOptions) => ComputedSignalImpl<T>;
/**
* Create a context ID to be used in your application. The name should be written with no spaces.
*
* Context is a way to pass stores to the child components without prop-drilling.
*
* Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier
* for the context. It is not the context value itself. See `useContextProvider()` and
* `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can
* track context providers and consumers in a way that survives resumability.
*
* ### Example
*
* ```tsx
* // Declare the Context type.
* interface TodosStore {
* items: string[];
* }
* // Create a Context ID (no data is saved here.)
* // You will use this ID to both create and retrieve the Context.
* export const TodosContext = createContextId<TodosStore>('Todos');
*
* // Example of providing context to child components.
* export const App = component$(() => {
* useContextProvider(
* TodosContext,
* useStore<TodosStore>({
* items: ['Learn Qwik', 'Build Qwik app', 'Profit'],
* })
* );
*
* return <Items />;
* });
*
* // Example of retrieving the context provided by a parent component.
* export const Items = component$(() => {
* const todos = useContext(TodosContext);
* return (
* <ul>
* {todos.items.map((item) => (
* <li>{item}</li>
* ))}
* </ul>
* );
* });
*
* ```
*
* @param name - The name of the context.
* @public
*/
export declare const createContextId: <STATE = unknown>(name: string) => ContextId<STATE>;
/** @internal */
export declare function _createDeserializeContainer(stateData: unknown[]): DeserializeContainer;
/**
* Creates a QRL instance to represent a lazily loaded value. Normally this is a function, but it
* can be any value.
*
* When the value is a function, calling the returned qrl will load the underlying code when
* invoked, and call it with the captured scope. This always returns a promise since the code may
* not be loaded yet.
*
* To get the underlying function without invoking it, await `qrl.resolve()` and then `qrl.resolved`
* holds the loaded function, wrapped with the captured scope.
*
* @internal
*/
export declare const _createQRL: <TYPE>(chunk: string | null, symbol: string, symbolRef?: null | ValueOrPromise<TYPE>, symbolFn?: null | (() => Promise<Record<string, TYPE>>), captures?: Readonly<unknown[]> | string | null, container?: _Container) => _QRLInternal<TYPE>;
/**
* Create a signal that holds a custom serializable value. See {@link useSerializer$} for more
* details.
*
* @public
*/
export declare const createSerializer$: <T, S>(arg: SerializerArg<T, S>) => T extends Promise<any> ? never : SerializerSignal<T>;
/** @internal */
export declare const createSerializerQrl: <T, S>(arg: QRL<{
serialize: (data: S | undefined) => T;
deserialize: (data: T) => S;
initial?: S;
}>) => SerializerSignalImpl<T, S>;
/**
* Creates a Signal with the given value. If no value is given, the signal is created with
* `undefined`.
*
* @public
*/
export declare const createSignal: {
<T>(): Signal<T | undefined>;
<T>(value: T): Signal<T>;
};
/** @public */
export declare interface CSSProperties extends CSS_2.Properties<string | number>, CSS_2.PropertiesHyphen<string | number> {
/**
* The index signature was removed to enable closed typing for style using CSSType. You're able to
* use type assertion or module augmentation to add properties or an index signature of your own.
*
* For examples and more information, visit:
* https://github.com/frenic/csstype#what-should-i-do-when-i-get-type-errors
*/
[v: `--${string}`]: string | number | undefined;
}
declare class DeleteOperation {
target: Element | Text;
constructor(target: Element | Text);
}
declare interface DescriptorBase<T = unknown, B = unknown> extends BackRef {
$flags$: number;
$index$: number;
$el$: HostElement;
$qrl$: _QRLInternal<T>;
$state$: B | undefined;
$destroy$: (() => void) | null;
}
/**
* Deserialize data from string to an array of objects.
*
* @param rawStateData - Data to deserialize
* @internal
*/
export declare function _deserialize<T>(rawStateData: string): T;
declare interface DeserializeContainer {
$getObjectById$: (id: number | string) => unknown;
$getForwardRef$: (id: number) => number | string | undefined;
element: HTMLElement | null;
getSyncFn: (id: number) => (...args: unknown[]) => unknown;
$state$?: unknown[];
$storeProxyMap$: ObjToProxyMap;
$forwardRefs$: Array<number | string> | null;
}
/** @public */
export declare interface DevJSX {
fileName: string;
lineNumber: number;
columnNumber: number;
stack?: string;
}
/** The Qwik-specific attributes that DOM elements accept @public */
export declare interface DOMAttributes<EL extends Element> extends DOMAttributesBase<EL>, QwikEvents<EL> {
class?: ClassList | Signal<ClassList> | undefined;
}
declare interface DOMAttributesBase<EL extends Element> extends QwikIntrinsicAttributes, PreventDefault, StopPropagation, Capture, Passive, RefAttr<EL> {
dangerouslySetInnerHTML?: string | undefined;
}
/** @internal */
declare class DomContainer extends _SharedContainer implements ClientContainer {
element: _ContainerElement;
qContainer: string;
qManifestHash: string;
rootVNode: _ElementVNode;
document: _QDocument;
$storeProxyMap$: ObjToProxyMap;
$qFuncs$: Array<(...args: unknown[]) => unknown>;
$instanceHash$: string;
$forwardRefs$: Array<number | string> | null;
vNodeLocate: (id: string | Element) => _VNode;
private $rawStateData$;
private $stateData$;
private $rootForwardRefs$;
private $styleIds$;
constructor(element: _ContainerElement);
/** Tear down this container so stale references fail gracefully. */
$destroy$(): void;
private $processRootStateScript$;
private $stateScriptSelector$;
/**
* The first time we render we need to hoist the styles. (Meaning we need to move all styles from
* component inline to <head>)
*
* We bulk move all of the st