import { ClientContainer } from '..';
import type { ClientContainer as ClientContainer_2 } from '../internal';
import type { CorePlatform } from '..';
import type { _DomContainer } from '../internal';
import type { _ElementVNode } from '../internal';
import type { JSXNodeInternal } from '../internal';
import { JSXOutput } from '..';
import type { _QDocument } from '../internal';
import { RenderResult } from '..';
import type { _Stringifiable } from '../internal';
import type { _VirtualVNode } from '../internal';
import type { _VNode } from '../internal';

declare interface AddRootFn {
    (obj: unknown, returnRef?: never): number;
    (obj: unknown, returnRef: true): SeenRef;
}

declare type AllSignalFlags = SignalFlags | WrappedSignalFlags | SerializationSignalFlags;

declare type AsyncComputedCtx = {
    track: Tracker;
    cleanup: (callback: () => void) => void;
};

/** @public */
declare type AsyncComputedFn<T> = (ctx: AsyncComputedCtx) => Promise<T>;

declare type AsyncComputeQRL<T> = QRLInternal<AsyncComputedFn<T>>;

/** Class for back reference to the EffectSubscription */
declare abstract class BackRef {
    [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | 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'];

declare interface Chore<T extends ChoreType = ChoreType> {
    $type$: T;
    $idx$: number | string;
    $host$: HostElement;
    $target$: ChoreTarget | null;
    $payload$: unknown;
    $state$: ChoreState;
    $blockedChores$: ChoreArray | null;
    $startTime$: number | undefined;
    $endTime$: number | undefined;
    $resolve$: ((value: any) => void) | undefined;
    $reject$: ((reason?: any) => void) | undefined;
    $returnValue$: ValueOrPromise<ChoreReturnValue<T>>;
}

declare class ChoreArray extends Array<Chore> {
    add(value: Chore): number;
    delete(value: Chore): number;
}

declare type ChoreReturnValue<T extends ChoreType = ChoreType> = T extends ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS | ChoreType.WAIT_FOR_QUEUE | ChoreType.NODE_PROP ? void : T extends ChoreType.NODE_DIFF | ChoreType.COMPONENT ? JSXOutput_2 : unknown;

declare enum ChoreState {
    NONE = 0,
    RUNNING = 1,
    FAILED = 2,
    DONE = 3
}

declare type ChoreTarget = HostElement | QRLInternal<(...args: unknown[]) => unknown> | Signal | StoreTarget;

declare const enum ChoreType {
    MACRO = 240,
    MICRO = 15,
    /** Ensure that the QRL promise is resolved before processing next chores in the queue */
    QRL_RESOLVE = 1,
    RUN_QRL = 2,
    TASK = 3,
    NODE_DIFF = 4,
    NODE_PROP = 5,
    COMPONENT = 6,
    RECOMPUTE_AND_SCHEDULE_EFFECTS = 7,
    VISIBLE = 16,
    CLEANUP_VISIBLE = 32,
    WAIT_FOR_QUEUE = 255
}

/** @public */
declare type ComputedFn<T> = () => T;

declare type ComputeQRL<T> = QRLInternal<ComputedFn<T>>;

/**
 * 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 | ISsrNode | SignalImpl;

declare interface Container {
    readonly $version$: string;
    readonly $scheduler$: Scheduler;
    readonly $storeProxyMap$: ObjToProxyMap;
    readonly $locale$: string;
    readonly $getObjectById$: (id: number | string) => any;
    readonly $serverData$: Record<string, any>;
    $currentUniqueId$: number;
    $buildBase$: string | null;
    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;
}

/**
 * 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
 */
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;
}

/**
 * Create emulated `Document` for server environment. Does not implement the full browser `document`
 * and `window` API. This api may be removed in the future.
 *
 * @public
 */
export declare function createDocument(opts?: MockDocumentOptions): Document;

/**
 * CreatePlatform and CreateDocument
 *
 * @public
 */
export declare const createDOM: ({ html }?: {
    html?: string;
}) => Promise<{
    render: (jsxElement: JSXOutput) => Promise<RenderResult>;
    screen: HTMLElement;
    userEvent: (queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string | keyof WindowEventMap, eventPayload?: any) => Promise<void>;
}>;

declare const createScheduler: (container: Container, journalFlush: () => void, choreQueue: ChoreArray, blockedChores: ChoreArray, runningChores: Set<Chore>) => {
    (type: ChoreType.QRL_RESOLVE, ignore: null, target: ComputeQRL<any> | AsyncComputeQRL<any>): Chore<ChoreType.QRL_RESOLVE>;
    (type: ChoreType.WAIT_FOR_QUEUE): Chore<ChoreType.WAIT_FOR_QUEUE>;
    (type: ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS, host: HostElement | undefined, target: Signal<unknown> | StoreTarget, effects: Set<EffectSubscription> | undefined): Chore<ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS>;
    (type: ChoreType.TASK | ChoreType.VISIBLE, task: Task): Chore<ChoreType.TASK | ChoreType.VISIBLE>;
    (type: ChoreType.RUN_QRL, host: HostElement, target: QRLInternal<(...args: unknown[]) => unknown>, args: unknown[]): Chore<ChoreType.RUN_QRL>;
    (type: ChoreType.COMPONENT, host: HostElement, qrl: QRLInternal<OnRenderFn<unknown>>, props: Props | null): Chore<ChoreType.COMPONENT>;
    (type: ChoreType.NODE_DIFF, host: HostElement, target: HostElement, value: JSXOutput_2 | Signal): Chore<ChoreType.NODE_DIFF>;
    (type: ChoreType.NODE_PROP, host: HostElement, prop: string, value: any): Chore<ChoreType.NODE_PROP>;
    (type: ChoreType.CLEANUP_VISIBLE, task: Task): Chore<ChoreType.CLEANUP_VISIBLE>;
};

declare interface DescriptorBase<T = unknown, B = unknown> extends BackRef {
    $flags$: number;
    $index$: number;
    $el$: HostElement;
    $qrl$: QRLInternal<T>;
    $state$: B | undefined;
    $destroy$: NoSerialize<() => void> | null;
}

/** @public */
declare interface DevJSX {
    fileName: string;
    lineNumber: number;
    columnNumber: number;
    stack?: string;
}

declare type DomRef = {
    $ssrNode$: SsrNode;
};

/** @public */
export declare function domRender(jsx: JSXOutput, opts?: {
    debug?: boolean;
}): Promise<{
    document: Document;
    container: ClientContainer;
    vNode: _VNode | null;
    getStyles: () => Record<string, string | string[]>;
}>;

/** @internal */
declare const _EFFECT_BACK_REF: unique symbol;

declare const enum EffectProperty {
    COMPONENT = ":",
    VNODE = "."
}

/**
 * An effect consumer plus type of effect, back references to producers and additional data
 *
 * An effect can be trigger by one or more of signal inputs. The first step of re-running an effect
 * is to clear its subscriptions so that the effect can re add new set of subscriptions. In order to
 * clear the subscriptions we need to store them here.
 *
 * Imagine you have effect such as:
 *
 * ```
 * function effect1() {
 *   console.log(signalA.value ? signalB.value : 'default');
 * }
 * ```
 *
 * In the above case the `signalB` needs to be unsubscribed when `signalA` is falsy. We do this by
 * always clearing all of the subscriptions
 *
 * The `EffectSubscription` stores
 *
 * ```
 * subscription1 = [effectConsumer1, EffectProperty.COMPONENT, Set[(signalA, signalB)]];
 * ```
 *
 * The `signal1` and `signal2` back references are needed to "clear" existing subscriptions.
 *
 * Both `signalA` as well as `signalB` will have a reference to `subscription` to the so that the
 * effect can be scheduled if either `signalA` or `signalB` triggers. The `subscription1` is shared
 * between the signals.
 *
 * The second position `EffectProperty|string` store the property name of the effect.
 *
 * - Property name of the VNode
 * - `EffectProperty.COMPONENT` if component
 * - `EffectProperty.VNODE` if VNode
 */
declare type EffectSubscription = [
Consumer,
// EffectSubscriptionProp.CONSUMER
EffectProperty | string,
// EffectSubscriptionProp.PROPERTY or string for attributes
Set<SignalImpl | StoreTarget> | null,
// EffectSubscriptionProp.BACK_REF
SubscriptionData | null
];

/**
 * Creates a simple DOM structure for testing components.
 *
 * By default `EntityFixture` creates:
 *
 * ```html
 * <host q:view="./component_fixture.noop">
 *   <child></child>
 * </host>
 * ```
 *
 * @public
 */
export declare class ElementFixture {
    window: MockWindow;
    document: MockDocument;
    superParent: HTMLElement;
    parent: HTMLElement;
    host: HTMLElement;
    child: HTMLElement;
    constructor(options?: ElementFixtureOptions);
}

/** @public */
declare interface ElementFixtureOptions {
    tagName?: string;
    html?: string;
}

/** @internal */
declare class ElementVNode extends VNode {
    firstChild: VNode | null | undefined;
    lastChild: VNode | null | undefined;
    element: QElement;
    elementName: string | undefined;
    constructor(flags: VNodeFlags, parent: ElementVNode | VirtualVNode | null, previousSibling: VNode | null | undefined, nextSibling: VNode | null | undefined, firstChild: VNode | null | undefined, lastChild: VNode | null | undefined, element: QElement, elementName: string | undefined);
}

/** @public */
export declare function emulateExecutionOfQwikFuncs(document: Document): void;

/** @public */
export declare function expectDOM(actual: Element, expected: string): Promise<void>;

/**
 * Any function taking a props object that returns JSXOutput.
 *
 * The `key`, `flags` and `dev` parameters are for internal use.
 *
 * @public
 */
declare type FunctionComponent<P = unknown> = {
    renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput_2;
}['renderFn'];

/** @public */
export declare function getTestPlatform(): TestPlatform;

declare type HostElement = VNode | ISsrNode;

/** The shared state during an invoke() call */
declare interface InvokeContext {
    $url$: URL | undefined;
    /** The Virtual parent component for the current component code */
    $hostElement$: HostElement | undefined;
    /** The current DOM element */
    $element$: Element | undefined;
    /** The event we're currently handling */
    $event$: PossibleEvents | undefined;
    /** The QRL function we're currently executing */
    $qrl$: QRL | undefined;
    $effectSubscriber$: EffectSubscription | undefined;
    $locale$: string | undefined;
    $container$: Container | undefined;
}

declare type InvokeTuple = [Element, Event, URL?];

declare interface ISsrNode {
    id: string;
    flags: SsrNodeFlags;
    parentComponent: ISsrNode | null;
    vnodeData: VNodeData;
    currentFile: string | null;
    setProp(name: string, value: any): void;
    getProp(name: string): any;
    removeProp(name: string): void;
    addChild(child: ISsrNode): void;
    setTreeNonUpdatable(): void;
}

/** @public */
declare type JSXChildren = string | number | boolean | null | undefined | Function | RegExp | JSXChildren[] | Promise<JSXChildren> | Signal<JSXChildren> | JSXNode;

/**
 * A JSX Node, an internal structure. You probably want to use `JSXOutput` instead.
 *
 * @public
 */
declare interface JSXNode<T extends string | FunctionComponent | unknown = unknown> {
    type: T;
    props: T extends FunctionComponent<infer P> ? P : Record<any, unknown>;
    children: JSXChildren | null;
    key: string | null;
    dev?: DevJSX;
}

/**
 * Any valid output for a component
 *
 * @public
 */
declare type JSXOutput_2 = JSXNode | string | number | boolean | null | undefined | JSXOutput_2[];

/** @public */
declare interface MockDocument extends Document {
}

/**
 * Options when creating a mock Qwik Document object.
 *
 * @public
 */
declare interface MockDocumentOptions {
    url?: URL | string;
    html?: string;
}

/** @public */
declare interface MockWindow extends Window {
    document: MockDocument;
}

declare interface NodePropData {
    $scopedStyleIdPrefix$: string | null;
    $isConst$: boolean;
}

/**
 * Returned type of the `noSerialize()` function. It will be TYPE or undefined.
 *
 * @public
 * @see noSerialize
 */
declare type NoSerialize<T> = (T & {
    __no_serialize__: true;
}) | undefined;

declare type ObjToProxyMap = WeakMap<any, any>;

/** @public */
declare type OnRenderFn<PROPS> = (props: PROPS) => JSXOutput_2;

declare type PossibleEvents = Event | SimplifiedServerRequestEvent | typeof TaskEvent | typeof RenderEvent | typeof ResourceEvent;

declare type Props = Record<string, unknown>;

declare interface QElement extends Element {
    qDispatchEvent?: (event: Event, scope: QwikLoaderEventScope) => ValueOrPromise<unknown>;
    vNode?: VNode;
}

/**
 * The `QRL` type represents a lazy-loadable AND serializable resource.
 *
 * QRL stands for Qwik URL.
 *
 * Use `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code
 * (functions) but can also be used for other resources such as `string`s in the case of styles.
 *
 * `QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties
 * in `QRL` as it may change between versions.)
 *
 * ## Creating `QRL` references
 *
 * Creating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik
 * Optimizer that marks that the code should be extracted into a lazy-loaded symbol.
 *
 * ```tsx
 * useOnDocument(
 *   'mousemove',
 *   $((event) => console.log('mousemove', event))
 * );
 * ```
 *
 * In the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below:
 *
 * ```tsx
 * // FILE: <current file>
 * useOnDocument('mousemove', qrl('./chunk-abc.js', 'onMousemove'));
 *
 * // FILE: chunk-abc.js
 * export const onMousemove = () => console.log('mousemove');
 * ```
 *
 * NOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke
 * this function directly in your application. The `qrl(...)` function should be invoked only after
 * the Qwik Optimizer transformation.
 *
 * ## Using `QRL`s
 *
 * Use `QRL` type in your application when you want to get a lazy-loadable reference to a resource
 * (most likely a function).
 *
 * ```tsx
 * // Example of declaring a custom functions which takes callback as QRL.
 * export function useMyFunction(callback: QRL<() => void>) {
 *   doExtraStuff();
 *   // The callback passed to `onDocument` requires `QRL`.
 *   useOnDocument('mousemove', callback);
 * }
 * ```
 *
 * In the above example, the way to think about the code is that you are not asking for a callback
 * function but rather a reference to a lazy-loadable callback function. Specifically, the function
 * loading should be delayed until it is actually needed. In the above example, the function would
 * not load until after a `mousemove` event on `document` fires.
 *
 * ## Resolving `QRL` references
 *
 * At times it may be necessary to resolve a `QRL` reference to the actual value. This can be
 * performed using `QRL.resolve(..)` function.
 *
 * ```tsx
 * // Assume you have QRL reference to a greet function
 * const lazyGreet: QRL<() => void> = $(() => console.log('Hello World!'));
 *
 * // Use `qrlImport` to load / resolve the reference.
 * const greet: () => void = await lazyGreet.resolve();
 *
 * //  Invoke it
 * greet();
 * ```
 *
 * NOTE: `element` is needed because `QRL`s are relative and need a base location to resolve
 * against. The base location is encoded in the HTML in the form of `<div q:base="/url">`.
 *
 * ## `QRL.resolved`
 *
 * Once `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to
 * be used without having to await `QRL.resolve()` again.
 *
 * ## Question: Why not just use `import()`?
 *
 * At first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle
 * differences that need to be taken into account.
 *
 * 1. `QRL`s must be serializable into HTML.
 * 2. `QRL`s must be resolved by framework relative to `q:base`.
 * 3. `QRL`s must be able to capture lexically scoped variables.
 * 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer.
 * 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names.
 *
 * Let's assume that you intend to write code such as this:
 *
 * ```tsx
 * return <button onClick={() => (await import('./chunk-abc.js')).onClick}>
 * ```
 *
 * The above code needs to be serialized into DOM such as:
 *
 * ```
 * <div q:base="/build/">
 *   <button on:click="./chunk-abc.js#onClick">...</button>
 * </div>
 * ```
 *
 * 1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML.
 * 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to
 *    where the `import()` file is declared. Because it is our framework doing the load, the
 *    `./chunk-abc.js` would become relative to the framework file. This is not correct, as it
 *    should be relative to the original file generated by the bundler.
 * 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is
 *    encoded in the HTML.
 * 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading
 *    top-level symbols which don't capture variables.)
 * 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You
 *    just want to say: "this should be lazy."
 *
 * These are the main reasons why Qwik introduces its own concept of `QRL`.
 *
 * @public
 * @see `$`
 */
declare type QRL<TYPE = unknown> = {
    __qwik_serializable__?: any;
    __brand__QRL__: TYPE;
    /** Resolve the QRL and return the actual value. */
    resolve(): Promise<TYPE>;
    /** The resolved value, once `resolve()` returns. */
    resolved: undefined | TYPE;
    getCaptured(): unknown[] | null;
    getSymbol(): string;
    getHash(): string;
    dev?: QRLDev | null;
} & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;

declare type QrlArgs<T> = T extends (...args: infer ARGS) => any ? ARGS : unknown[];

/** @public */
declare interface QRLDev {
    file: string;
    lo: number;
    hi: number;
}

/** @internal */
declare type QRLInternal<TYPE = unknown> = QRL<TYPE> & QRLInternalMethods<TYPE>;

declare type QRLInternalMethods<TYPE> = {
    readonly $chunk$: string | null;
    readonly $symbol$: string;
    readonly $hash$: string;
    $capture$: string[] | null;
    $captureRef$: unknown[] | null;
    dev: QRLDev | null;
    resolved: undefined | TYPE;
    resolve(containerEl?: Element): Promise<TYPE>;
    getSymbol(): string;
    getHash(): string;
    getCaptured(): unknown[] | null;
    getFn(currentCtx?: InvokeContext | InvokeTuple, beforeFn?: () => void): TYPE extends (...args: any) => any ? (...args: Parameters<TYPE>) => ValueOrPromise<ReturnType<TYPE>> : unknown;
    $setContainer$(containerEl: Element | undefined): Element | undefined;
};

declare type QrlReturn<T> = T extends (...args: any) => infer R ? Awaited<R> : unknown;

declare type QwikLoaderEventScope = '-document' | '-window' | '';

/** @public */
declare interface ReadonlySignal<T = unknown> {
    readonly value: T;
}

declare const RenderEvent = "qRender";

declare const ResourceEvent = "qResource";

declare interface ResourceReturnInternal<T> {
    __brand: 'resource';
    _state: 'pending' | 'resolved' | 'rejected';
    _resolved: T | undefined;
    _error: Error | undefined;
    _cache: number;
    _timeout: number;
    value: Promise<T>;
    loading: boolean;
}

declare type Scheduler = ReturnType<typeof createScheduler>;

/** Stores the location of an object. If no parent, it's a root. */
declare type SeenRef = {
    $index$: number;
    $parent$?: SeenRef | null;
};

declare interface SerializationContext {
    $serialize$: () => void;
    $symbolToChunkResolver$: SymbolToChunkResolver;
    /**
     * Map from object to parent and index reference.
     *
     * If object is found in `objMap` will return the parent reference and index path.
     *
     * `objMap` return:
     *
     * - `{ parent, index }` - The parent object and the index within that parent.
     * - `undefined` - Object has not been seen yet.
     */
    getSeenRef: (obj: unknown) => SeenRef | undefined;
    /** Returns the root index of the object, if it is a root. Otherwise returns undefined. */
    $hasRootId$: (obj: unknown) => number | undefined;
    /**
     * Root objects which need to be serialized.
     *
     * Roots are entry points into the object graph. Typically the roots are held by the listeners.
     *
     * Returns the index of the root object.
     */
    $addRoot$: AddRootFn;
    /** Mark an object as seen during serialization. This is used to handle backreferences and cycles */
    $markSeen$: (obj: unknown, parent: SeenRef | undefined, index: number) => SeenRef;
    $roots$: unknown[];
    $promoteToRoot$: (ref: SeenRef, index?: number) => void;
    $addSyncFn$($funcStr$: string | null, argsCount: number, fn: Function): number;
    $isSsrNode$: (obj: unknown) => obj is SsrNode;
    $isDomRef$: (obj: unknown) => obj is DomRef;
    $writer$: StreamWriter;
    $syncFns$: string[];
    $eventQrls$: Set<QRL>;
    $eventNames$: Set<string>;
    $resources$: Set<ResourceReturnInternal<unknown>>;
    $renderSymbols$: Set<string>;
    $storeProxyMap$: ObjToProxyMap;
    $getProp$: (obj: any, prop: string) => any;
    $setProp$: (obj: any, prop: string, value: any) => void;
}

declare const enum SerializationSignalFlags {
    SERIALIZATION_STRATEGY_NEVER = 16,
    SERIALIZATION_STRATEGY_ALWAYS = 32
}

/**
 * A signal is a reactive value which can be read and written. When the signal is written, all tasks
 * which are tracking the signal will be re-run and all components that read the signal will be
 * re-rendered.
 *
 * Furthermore, when a signal value is passed as a prop to a component, the optimizer will
 * automatically forward the signal. This means that `return <div title={signal.value}>hi</div>`
 * will update the `title` attribute when the signal changes without having to re-render the
 * component.
 *
 * @public
 */
declare interface Signal<T = any> extends ReadonlySignal<T> {
    value: T;
}

declare const enum SignalFlags {
    INVALID = 1,
    RUN_EFFECTS = 2
}

declare class SignalImpl<T = any> implements Signal<T> {
    $untrackedValue$: T;
    /** Store a list of effects which are dependent on this signal. */
    $effects$: undefined | Set<EffectSubscription>;
    $container$: Container | null;
    $wrappedSignal$: WrappedSignalImpl<T> | null;
    constructor(container: Container | null, value: T);
    /**
     * Use this to force running subscribers, for example when the calculated value has mutated but
     * remained the same object
     */
    force(): void;
    get untrackedValue(): T;
    set untrackedValue(value: T);
    get value(): T;
    set value(value: T);
    valueOf(): void;
    toString(): string;
    toJSON(): {
        value: T;
    };
}

declare interface SimplifiedServerRequestEvent<T = unknown> {
    url: URL;
    locale: string | undefined;
    request: Request;
}

declare type SsrAttrKey = string;

declare type SsrAttrs = Array<SsrAttrKey | SsrAttrValue>;

declare type SsrAttrValue = string | Signal<any> | Promise<any> | boolean | object | null;

/** A selection of attributes of the real thing */
declare type SsrNode = {
    id: string;
    children: ISsrNode[] | null;
    vnodeData: VNodeData;
    [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | null;
};

declare const enum SsrNodeFlags {
    Updatable = 1
}

/** @public */
export declare function ssrRenderToDom(jsx: JSXOutput, opts?: {
    /** Print debug information to console. */
    debug?: boolean;
    /** Treat JSX as raw, (don't wrap in in head/body) */
    raw?: boolean;
    /** Include QwikLoader */
    qwikLoader?: boolean;
    /** Inject nodes into the document before test runs (for testing purposes) */
    onBeforeResume?: (document: Document) => void;
}): Promise<{
    container: _DomContainer;
    document: Document;
    vNode: _VNode | null;
    getStyles: () => Record<string, string | string[]>;
}>;

declare type StoreTarget = Record<string | symbol, any>;

/** @internal */
declare interface StreamWriter {
    write(chunk: string): void;
}

/** @internal */
declare class SubscriptionData {
    data: NodePropData;
    constructor(data: NodePropData);
}

declare type SymbolToChunkResolver = (symbol: string) => string;

declare class Task<T = unknown, B = T> extends BackRef implements DescriptorBase<unknown, Signal<B> | ResourceReturnInternal<B>> {
    $flags$: number;
    $index$: number;
    $el$: HostElement;
    $qrl$: QRLInternal<T>;
    $state$: Signal<B> | ResourceReturnInternal<B> | undefined;
    $destroy$: NoSerialize<() => void> | null;
    constructor($flags$: number, $index$: number, $el$: HostElement, $qrl$: QRLInternal<T>, $state$: Signal<B> | ResourceReturnInternal<B> | undefined, $destroy$: NoSerialize<() => void> | null);
}

declare const TaskEvent = "qTask";

/** @public */
declare interface TestPlatform extends CorePlatform {
    /**
     * @deprecated No longer used, please use {@link waitForDrain} instead.
     * @example With `ssrRenderToDom`
     *
     * ```ts
     * import { waitForDrain } from '@qwik.dev/testing';
     *
     * const { container } = ssrRenderToDom(...);
     * await waitForDrain(container);
     * ```
     *
     * @example With `domRender`
     *
     * ```ts
     * import { waitForDrain } from '@qwik.dev/testing';
     *
     * const { container } = domRender(...);
     * await waitForDrain(container);
     * ```
     */
    flush: () => Promise<void>;
}

/**
 * Used to signal to Qwik which state should be watched for changes.
 *
 * The `Tracker` is passed into the `taskFn` of `useTask`. It is intended to be used to wrap state
 * objects in a read proxy which signals to Qwik which properties should be watched for changes. A
 * change to any of the properties causes the `taskFn` to rerun.
 *
 * ### Example
 *
 * The `obs` passed into the `taskFn` is used to mark `state.count` as a property of interest. Any
 * changes to the `state.count` property will cause the `taskFn` to rerun.
 *
 * ```tsx
 * const Cmp = component$(() => {
 *   const store = useStore({ count: 0, doubleCount: 0 });
 *   const signal = useSignal(0);
 *   useTask$(({ track }) => {
 *     // Any signals or stores accessed inside the task will be tracked
 *     const count = track(() => store.count);
 *     // You can also pass a signal to track() directly
 *     const signalCount = track(signal);
 *     store.doubleCount = count + signalCount;
 *   });
 *   return (
 *     <div>
 *       <span>
 *         {store.count} / {store.doubleCount}
 *       </span>
 *       <button
 *         onClick$={() => {
 *           store.count++;
 *           signal.value++;
 *         }}
 *       >
 *         +
 *       </button>
 *     </div>
 *   );
 * });
 * ```
 *
 * @public
 * @see `useTask`
 */
declare interface Tracker {
    /**
     * Include the expression using stores / signals to track:
     *
     * ```tsx
     * track(() => store.count);
     * ```
     *
     * The `track()` function also returns the value of the scoped expression:
     *
     * ```tsx
     * const count = track(() => store.count);
     * ```
     */
    <T>(fn: () => T): T;
    /**
     * Used to track the whole object. If any property of the passed store changes, the task will be
     * scheduled to run. Also accepts signals.
     *
     * Note that the change tracking is not deep. If you want to track changes to nested properties,
     * you need to use `track` on each of them.
     *
     * ```tsx
     * track(store); // returns store
     * track(signal); // returns signal.value
     * ```
     */
    <T extends object>(obj: T): T extends Signal<infer U> ? U : T;
    /**
     * Used to track to track a specific property of an object.
     *
     * Note that the change tracking is not deep. If you want to track changes to nested properties,
     * you need to use `track` on each of them.
     *
     * ```tsx
     * track(store, 'propA'); // returns store.propA
     * ```
     */
    <T extends object, P extends keyof T>(obj: T, prop: P): T[P];
}

/**
 * Trigger an event in unit tests on an element. Needs to be kept in sync with the Qwik Loader event
 * dispatching.
 *
 * Future deprecation candidate.
 *
 * @public
 */
export declare function trigger(root: Element, queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventName: string, eventPayload?: any, options?: {
    waitForIdle?: boolean;
}): Promise<void>;

/**
 * Type representing a value which is either resolve or a promise.
 *
 * @public
 */
declare type ValueOrPromise<T> = T | Promise<T>;

/** @internal */
declare class VirtualVNode extends VNode {
    firstChild: VNode | null | undefined;
    lastChild: VNode | null | undefined;
    constructor(flags: VNodeFlags, parent: ElementVNode | VirtualVNode | null, previousSibling: VNode | null | undefined, nextSibling: VNode | null | undefined, firstChild: VNode | null | undefined, lastChild: VNode | null | undefined);
}

/** @internal */
declare abstract class VNode extends BackRef {
    flags: VNodeFlags;
    parent: ElementVNode | VirtualVNode | null;
    previousSibling: VNode | null | undefined;
    nextSibling: VNode | null | undefined;
    props: unknown[] | null;
    slotParent: VNode | null;
    chores: ChoreArray | null;
    blockedChores: ChoreArray | null;
    constructor(flags: VNodeFlags, parent: ElementVNode | VirtualVNode | null, previousSibling: VNode | null | undefined, nextSibling: VNode | null | undefined);
    getProp<T>(key: string, getObject: ((id: string) => any) | null): T | null;
    setProp(key: string, value: any): void;
    getAttr(key: string): string | null;
    setAttr(key: string, value: string | null | boolean, journal: VNodeJournal | null): void;
    toString(): string;
}

/** @public */
export declare function vnode_fromJSX(jsx: JSXOutput): {
    vParent: _ElementVNode | _VirtualVNode;
    vNode: _VNode | null;
    document: _QDocument;
    container: ClientContainer_2;
};

/**
 * Array of numbers which describes virtual nodes in the tree.
 *
 * HTML can't account for:
 *
 * - Multiple text nodes in a row. (it treats it as a single text node)
 * - Empty text nodes. (it ignores them)
 * - And virtual nodes such as `<Fragment/>` or `<MyComponent/>`
 *
 * So we need to encode all of that information into the VNodeData.
 *
 * Encoding:
 *
 * - First position is special and encodes state information and stores VNodeDataFlag.
 * - Positive numbers are text node lengths. (0 is a special case for empty text node)
 * - Negative numbers are element counts.
 * - `OPEN_FRAGMENT` is start of virtual node.
 *
 *   - If `OPEN_FRAGMENT` than the previous node is an `Array` which contains the props (see
 *       `SsrAttrs`). NOTE: The array is never going to be the last item in the VNodeData, so we can
 *       always assume that the last item in `vNodeData` is a number.
 * - `CLOSE_FRAGMENT` is end of virtual node.
 *
 * NOTE: This is how we store the information during the SSR streaming, once the SSR is complete
 * this data needs to be serialized into a string and stored in the DOM as a script tag which has
 * deferent serialization format.
 */
declare type VNodeData = [VNodeDataFlag, ...(SsrAttrs | number)[]];

/**
 * Flags for VNodeData (Flags con be bitwise combined)
 *
 * @internal
 */
declare const enum VNodeDataFlag {
    NONE = 0,
    TEXT_DATA = 1,
    VIRTUAL_NODE = 2,
    ELEMENT_NODE = 4,
    REFERENCE = 8,
    SERIALIZE = 16
}

/**
 * Flags for VNode.
 *
 * # Materialize vs Inflation
 *
 * - Materialized: The node has all of its children. Specifically `firstChild`/`lastChild` are NOT
 *   `undefined`. Materialization creates lazy instantiation of the children. NOTE: Only
 *   ElementVNode need to be materialized.
 * - Inflation:
 *
 *   - If Text: It means that it is safe to write to the node. When Text nodes are first Deserialized
 *       multiple text nodes can share the same DOM node. On write the sibling text nodes need to be
 *       converted into separate text nodes.
 *   - If Element: It means that the element tag attributes have not yet been read from the DOM.
 *
 * Inflation and materialization are not the same, they are two independent things.
 *
 * @internal
 */
declare const enum VNodeFlags {
    Element = 1,
    Virtual = 2,
    ELEMENT_OR_VIRTUAL_MASK = 3,
    Text = 4,
    ELEMENT_OR_TEXT_MASK = 5,
    TYPE_MASK = 7,
    INFLATED_TYPE_MASK = 15,
    Inflated = 8,
    Resolved = 16,
    Deleted = 32,
    NAMESPACE_MASK = 192,
    NEGATED_NAMESPACE_MASK = -193,
    NS_html = 0,// http://www.w3.org/1999/xhtml
    NS_svg = 64,// http://www.w3.org/2000/svg
    NS_math = 128
}

declare type VNodeJournal = Array<VNodeJournalOpCode | Document | Element | Text | string | boolean | null>;

/**
 * Fundamental DOM operations are:
 *
 * - Insert new DOM element/text
 * - Remove DOM element/text
 * - Set DOM element attributes
 * - Set text node value
 */
declare const enum VNodeJournalOpCode {
    SetText = 1,// ------ [SetAttribute, target, text]
    SetAttribute = 2,// - [SetAttribute, target, ...(key, values)]]
    HoistStyles = 3,// -- [HoistStyles, document]
    Remove = 4,// ------- [Remove, target(parent), ...nodes]
    RemoveAll = 5,// ------- [RemoveAll, target(parent)]
    Insert = 6
}

/**
 * Wait for the scheduler to drain.
 *
 * This is useful when testing async code.
 *
 * @param container - The application container.
 * @public
 */
export declare function waitForDrain(container: Container): Promise<void>;

/** @public */
export declare function walkJSX(jsx: JSXOutput, apply: {
    enter: (jsx: JSXNodeInternal) => void;
    leave: (jsx: JSXNodeInternal) => void;
    text: (text: _Stringifiable) => void;
}): void;

declare const enum WrappedSignalFlags {
    UNWRAP = 4
}

declare class WrappedSignalImpl<T> extends SignalImpl<T> implements BackRef {
    $args$: any[];
    $func$: (...args: any[]) => T;
    $funcStr$: string | null;
    $flags$: AllSignalFlags;
    $hostElement$: HostElement | undefined;
    [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | undefined;
    constructor(container: Container | null, fn: (...args: any[]) => T, args: any[], fnStr: string | null, flags?: SignalFlags);
    invalidate(): void;
    /**
     * Use this to force running subscribers, for example when the calculated value has mutated but
     * remained the same object.
     */
    force(): void;
    get untrackedValue(): T;
    $computeIfNeeded$(): void;
    $unwrapIfSignal$(): SignalImpl<T> | WrappedSignalImpl<T>;
    set value(_: any);
    get value(): any;
}

export { }
