@qwik.dev/core 2.0.0-beta.7 → 2.0.0-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/bindings/qwik.darwin-arm64.node +0 -0
  2. package/bindings/qwik.darwin-x64.node +0 -0
  3. package/bindings/qwik.linux-x64-gnu.node +0 -0
  4. package/bindings/qwik.win32-x64-msvc.node +0 -0
  5. package/bindings/qwik_wasm_bg.wasm +0 -0
  6. package/dist/backpatch/index.cjs +6 -0
  7. package/dist/backpatch/index.d.ts +2 -0
  8. package/dist/backpatch/index.mjs +5 -0
  9. package/dist/backpatch/package.json +8 -0
  10. package/dist/backpatch-executor.debug.js +34 -0
  11. package/dist/backpatch-executor.js +1 -0
  12. package/dist/build/package.json +1 -1
  13. package/dist/cli.cjs +17 -17
  14. package/dist/core-internal.d.ts +112 -56
  15. package/dist/core.cjs +1022 -469
  16. package/dist/core.cjs.map +1 -1
  17. package/dist/core.min.mjs +1 -1
  18. package/dist/core.mjs +1018 -469
  19. package/dist/core.mjs.map +1 -1
  20. package/dist/core.prod.cjs +654 -361
  21. package/dist/core.prod.mjs +729 -373
  22. package/dist/loader/index.cjs +2 -2
  23. package/dist/loader/index.mjs +2 -2
  24. package/dist/loader/package.json +1 -1
  25. package/dist/optimizer.cjs +78 -76
  26. package/dist/optimizer.mjs +78 -78
  27. package/dist/qwikloader.debug.js +0 -13
  28. package/dist/qwikloader.js +1 -1
  29. package/dist/server.cjs +217 -63
  30. package/dist/server.d.ts +9 -0
  31. package/dist/server.mjs +213 -63
  32. package/dist/starters/features/auth/package.json +1 -1
  33. package/dist/starters/features/localize/package.json +3 -3
  34. package/dist/starters/features/pandacss/package.json +1 -1
  35. package/dist/starters/features/playwright/playwright-report/index.html +943 -903
  36. package/dist/starters/features/postcss/postcss.config.js +1 -1
  37. package/dist/starters/features/tailwind/package.json +2 -2
  38. package/dist/starters/features/tailwind/prettier.config.js +10 -0
  39. package/dist/starters/features/tailwind-v3/package.json +1 -1
  40. package/dist/starters/features/tailwind-v3/prettier.config.js +10 -0
  41. package/dist/testing/index.cjs +3826 -952
  42. package/dist/testing/index.d.ts +972 -1
  43. package/dist/testing/index.mjs +3811 -946
  44. package/dist/testing/package.json +1 -1
  45. package/package.json +8 -6
  46. package/dist/starters/features/tailwind/.prettierrc.js +0 -3
@@ -6,10 +6,186 @@ import type { JSXNodeInternal } from '../internal';
6
6
  import { JSXOutput } from '..';
7
7
  import type { _QDocument } from '../internal';
8
8
  import { RenderResult } from '..';
9
+ import type { StreamWriter as StreamWriter_2 } from '..';
9
10
  import type { _Stringifiable } from '../internal';
10
11
  import type { _VirtualVNode } from '../internal';
11
12
  import type { _VNode } from '../internal';
12
13
 
14
+ declare type AsyncComputedCtx = {
15
+ track: Tracker;
16
+ cleanup: (callback: () => void) => void;
17
+ };
18
+
19
+ /** @public */
20
+ declare type AsyncComputedFn<T> = (ctx: AsyncComputedCtx) => Promise<T>;
21
+
22
+ declare type AsyncComputeQRL<T> = QRLInternal<AsyncComputedFn<T>>;
23
+
24
+ /** Class for back reference to the EffectSubscription */
25
+ declare abstract class BackRef {
26
+ [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | null;
27
+ }
28
+
29
+ declare type BivariantQrlFn<ARGS extends any[], RETURN> = {
30
+ /**
31
+ * Resolve the QRL of closure and invoke it.
32
+ *
33
+ * @param args - Closure arguments.
34
+ * @returns A promise of the return value of the closure.
35
+ */
36
+ bivarianceHack(...args: ARGS): Promise<RETURN>;
37
+ }['bivarianceHack'];
38
+
39
+ declare interface Chore<T extends ChoreType = ChoreType> {
40
+ $type$: T;
41
+ $idx$: number | string;
42
+ $host$: HostElement;
43
+ $target$: ChoreTarget | null;
44
+ $payload$: unknown;
45
+ $state$: ChoreState;
46
+ $blockedChores$: Chore[] | null;
47
+ $startTime$: number | undefined;
48
+ $endTime$: number | undefined;
49
+ $resolve$: ((value: any) => void) | undefined;
50
+ $reject$: ((reason?: any) => void) | undefined;
51
+ $returnValue$: ValueOrPromise<ChoreReturnValue<T>>;
52
+ }
53
+
54
+ 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;
55
+
56
+ declare enum ChoreState {
57
+ NONE = 0,
58
+ RUNNING = 1,
59
+ FAILED = 2,
60
+ DONE = 3
61
+ }
62
+
63
+ declare type ChoreTarget = HostElement | QRLInternal<(...args: unknown[]) => unknown> | Signal | StoreTarget;
64
+
65
+ declare const enum ChoreType {
66
+ MACRO = 240,
67
+ MICRO = 15,
68
+ /** Ensure that the QRL promise is resolved before processing next chores in the queue */
69
+ QRL_RESOLVE = 1,
70
+ RUN_QRL = 2,
71
+ TASK = 3,
72
+ NODE_DIFF = 4,
73
+ NODE_PROP = 5,
74
+ COMPONENT = 6,
75
+ RECOMPUTE_AND_SCHEDULE_EFFECTS = 7,
76
+ VISIBLE = 16,
77
+ CLEANUP_VISIBLE = 32,
78
+ WAIT_FOR_QUEUE = 255
79
+ }
80
+
81
+ /** @public */
82
+ declare type ComputedFn<T> = () => T;
83
+
84
+ declare type ComputeQRL<T> = QRLInternal<ComputedFn<T>>;
85
+
86
+ /**
87
+ * Effect is something which needs to happen (side-effect) due to signal value change.
88
+ *
89
+ * There are three types of effects:
90
+ *
91
+ * - `Task`: `useTask`, `useVisibleTask`, `useResource`
92
+ * - `VNode` and `ISsrNode`: Either a component or `<Signal>`
93
+ * - `Signal2`: A derived signal which contains a computation function.
94
+ */
95
+ declare type Consumer = Task | VNode | ISsrNode | SignalImpl;
96
+
97
+ declare interface Container {
98
+ readonly $version$: string;
99
+ readonly $scheduler$: Scheduler;
100
+ readonly $storeProxyMap$: ObjToProxyMap;
101
+ readonly $locale$: string;
102
+ readonly $getObjectById$: (id: number | string) => any;
103
+ readonly $serverData$: Record<string, any>;
104
+ $currentUniqueId$: number;
105
+ $buildBase$: string | null;
106
+ handleError(err: any, $host$: HostElement | null): void;
107
+ getParentHost(host: HostElement): HostElement | null;
108
+ setContext<T>(host: HostElement, context: ContextId<T>, value: T): void;
109
+ resolveContext<T>(host: HostElement, contextId: ContextId<T>): T | undefined;
110
+ setHostProp<T>(host: HostElement, name: string, value: T): void;
111
+ getHostProp<T>(host: HostElement, name: string): T | null;
112
+ $appendStyle$(content: string, styleId: string, host: HostElement, scoped: boolean): void;
113
+ /**
114
+ * When component is about to be executed, it may add/remove children. This can cause problems
115
+ * with the projection because deleting content will prevent the projection references from
116
+ * looking up vnodes. Therefore before we execute the component we need to ensure that all of its
117
+ * references to vnode are resolved.
118
+ *
119
+ * @param renderHost - Host element to ensure projection is resolved.
120
+ */
121
+ ensureProjectionResolved(host: HostElement): void;
122
+ serializationCtxFactory(NodeConstructor: {
123
+ new (...rest: any[]): {
124
+ __brand__: 'SsrNode';
125
+ };
126
+ } | null, DomRefConstructor: {
127
+ new (...rest: any[]): {
128
+ __brand__: 'DomRef';
129
+ };
130
+ } | null, symbolToChunkResolver: SymbolToChunkResolver, writer?: StreamWriter): SerializationContext;
131
+ }
132
+
133
+ /**
134
+ * ContextId is a typesafe ID for your context.
135
+ *
136
+ * Context is a way to pass stores to the child components without prop-drilling.
137
+ *
138
+ * Use `createContextId()` to create a `ContextId`. A `ContextId` is just a serializable identifier
139
+ * for the context. It is not the context value itself. See `useContextProvider()` and
140
+ * `useContext()` for the values. Qwik needs a serializable ID for the context so that the it can
141
+ * track context providers and consumers in a way that survives resumability.
142
+ *
143
+ * ### Example
144
+ *
145
+ * ```tsx
146
+ * // Declare the Context type.
147
+ * interface TodosStore {
148
+ * items: string[];
149
+ * }
150
+ * // Create a Context ID (no data is saved here.)
151
+ * // You will use this ID to both create and retrieve the Context.
152
+ * export const TodosContext = createContextId<TodosStore>('Todos');
153
+ *
154
+ * // Example of providing context to child components.
155
+ * export const App = component$(() => {
156
+ * useContextProvider(
157
+ * TodosContext,
158
+ * useStore<TodosStore>({
159
+ * items: ['Learn Qwik', 'Build Qwik app', 'Profit'],
160
+ * })
161
+ * );
162
+ *
163
+ * return <Items />;
164
+ * });
165
+ *
166
+ * // Example of retrieving the context provided by a parent component.
167
+ * export const Items = component$(() => {
168
+ * const todos = useContext(TodosContext);
169
+ * return (
170
+ * <ul>
171
+ * {todos.items.map((item) => (
172
+ * <li>{item}</li>
173
+ * ))}
174
+ * </ul>
175
+ * );
176
+ * });
177
+ *
178
+ * ```
179
+ *
180
+ * @public
181
+ */
182
+ declare interface ContextId<STATE> {
183
+ /** Design-time property to store type information for the context. */
184
+ readonly __brand_context_type__: STATE;
185
+ /** A unique ID for the context. */
186
+ readonly id: string;
187
+ }
188
+
13
189
  /**
14
190
  * Create emulated `Document` for server environment. Does not implement the full browser `document`
15
191
  * and `window` API. This api may be removed in the future.
@@ -31,6 +207,40 @@ export declare const createDOM: ({ html }?: {
31
207
  userEvent: (queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventNameCamel: string | keyof WindowEventMap, eventPayload?: any) => Promise<void>;
32
208
  }>;
33
209
 
210
+ declare const createScheduler: (container: Container, journalFlush: () => void, choreQueue?: Chore[], blockedChores?: Set<Chore>, runningChores?: Set<Chore>) => {
211
+ (type: ChoreType.QRL_RESOLVE, ignore: null, target: ComputeQRL<any> | AsyncComputeQRL<any>): Chore<ChoreType.QRL_RESOLVE>;
212
+ (type: ChoreType.WAIT_FOR_QUEUE): Chore<ChoreType.WAIT_FOR_QUEUE>;
213
+ (type: ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS, host: HostElement | null, target: Signal | StoreHandler, effects: Set<EffectSubscription> | null): Chore<ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS>;
214
+ (type: ChoreType.TASK | ChoreType.VISIBLE, task: Task): Chore<ChoreType.TASK | ChoreType.VISIBLE>;
215
+ (type: ChoreType.RUN_QRL, host: HostElement, target: QRLInternal<(...args: unknown[]) => unknown>, args: unknown[]): Chore<ChoreType.RUN_QRL>;
216
+ (type: ChoreType.COMPONENT, host: HostElement, qrl: QRLInternal<OnRenderFn<unknown>>, props: Props | null): Chore<ChoreType.COMPONENT>;
217
+ (type: ChoreType.NODE_DIFF, host: HostElement, target: HostElement, value: JSXOutput_2 | Signal): Chore<ChoreType.NODE_DIFF>;
218
+ (type: ChoreType.NODE_PROP, host: HostElement, prop: string, value: any): Chore<ChoreType.NODE_PROP>;
219
+ (type: ChoreType.CLEANUP_VISIBLE, task: Task): Chore<ChoreType.CLEANUP_VISIBLE>;
220
+ };
221
+
222
+ /** @public */
223
+ declare interface DescriptorBase<T = unknown, B = unknown> extends BackRef {
224
+ $flags$: number;
225
+ $index$: number;
226
+ $el$: HostElement;
227
+ $qrl$: QRLInternal<T>;
228
+ $state$: B | undefined;
229
+ $destroy$: NoSerialize<() => void> | null;
230
+ }
231
+
232
+ /** @public */
233
+ declare interface DevJSX {
234
+ fileName: string;
235
+ lineNumber: number;
236
+ columnNumber: number;
237
+ stack?: string;
238
+ }
239
+
240
+ declare type DomRef = {
241
+ $ssrNode$: SsrNode;
242
+ };
243
+
34
244
  /** @public */
35
245
  export declare function domRender(jsx: JSXOutput, opts?: {
36
246
  debug?: boolean;
@@ -41,6 +251,60 @@ export declare function domRender(jsx: JSXOutput, opts?: {
41
251
  getStyles: () => Record<string, string | string[]>;
42
252
  }>;
43
253
 
254
+ /** @internal */
255
+ declare const _EFFECT_BACK_REF: unique symbol;
256
+
257
+ declare const enum EffectProperty {
258
+ COMPONENT = ":",
259
+ VNODE = "."
260
+ }
261
+
262
+ /**
263
+ * An effect consumer plus type of effect, back references to producers and additional data
264
+ *
265
+ * An effect can be trigger by one or more of signal inputs. The first step of re-running an effect
266
+ * is to clear its subscriptions so that the effect can re add new set of subscriptions. In order to
267
+ * clear the subscriptions we need to store them here.
268
+ *
269
+ * Imagine you have effect such as:
270
+ *
271
+ * ```
272
+ * function effect1() {
273
+ * console.log(signalA.value ? signalB.value : 'default');
274
+ * }
275
+ * ```
276
+ *
277
+ * In the above case the `signalB` needs to be unsubscribed when `signalA` is falsy. We do this by
278
+ * always clearing all of the subscriptions
279
+ *
280
+ * The `EffectSubscription` stores
281
+ *
282
+ * ```
283
+ * subscription1 = [effectConsumer1, EffectProperty.COMPONENT, Set[(signalA, signalB)]];
284
+ * ```
285
+ *
286
+ * The `signal1` and `signal2` back references are needed to "clear" existing subscriptions.
287
+ *
288
+ * Both `signalA` as well as `signalB` will have a reference to `subscription` to the so that the
289
+ * effect can be scheduled if either `signalA` or `signalB` triggers. The `subscription1` is shared
290
+ * between the signals.
291
+ *
292
+ * The second position `EffectProperty|string` store the property name of the effect.
293
+ *
294
+ * - Property name of the VNode
295
+ * - `EffectProperty.COMPONENT` if component
296
+ * - `EffectProperty.VNODE` if VNode
297
+ */
298
+ declare type EffectSubscription = [
299
+ Consumer,
300
+ // EffectSubscriptionProp.CONSUMER
301
+ EffectProperty | string,
302
+ // EffectSubscriptionProp.PROPERTY or string for attributes
303
+ Set<SignalImpl | StoreTarget> | null,
304
+ // EffectSubscriptionProp.BACK_REF
305
+ SubscriptionData | null
306
+ ];
307
+
44
308
  /**
45
309
  * Creates a simple DOM structure for testing components.
46
310
  *
@@ -70,15 +334,105 @@ declare interface ElementFixtureOptions {
70
334
  html?: string;
71
335
  }
72
336
 
337
+ /** @internal */
338
+ declare type ElementVNode = [
339
+ VNodeFlags.Element,
340
+ ////////////// 0 - Flags
341
+ VNode | null,
342
+ /////////////// 1 - Parent
343
+ VNode | null,
344
+ /////////////// 2 - Previous sibling
345
+ VNode | null,
346
+ /////////////// 3 - Next sibling
347
+ VNode | null | undefined,
348
+ /// 4 - First child - undefined if children need to be materialize
349
+ VNode | null | undefined,
350
+ Element,
351
+ //////////////////// 6 - Element
352
+ string | undefined,
353
+ (string | null)[]
354
+ ] & {
355
+ __brand__: 'ElementVNode';
356
+ };
357
+
73
358
  /** @public */
74
359
  export declare function emulateExecutionOfQwikFuncs(document: Document): void;
75
360
 
76
361
  /** @public */
77
362
  export declare function expectDOM(actual: Element, expected: string): Promise<void>;
78
363
 
364
+ /**
365
+ * Any function taking a props object that returns JSXOutput.
366
+ *
367
+ * The `key`, `flags` and `dev` parameters are for internal use.
368
+ *
369
+ * @public
370
+ */
371
+ declare type FunctionComponent<P = unknown> = {
372
+ renderFn(props: P, key: string | null, flags: number, dev?: DevJSX): JSXOutput_2;
373
+ }['renderFn'];
374
+
79
375
  /** @public */
80
376
  export declare function getTestPlatform(): TestPlatform;
81
377
 
378
+ declare type HostElement = VNode | ISsrNode;
379
+
380
+ /** The shared state during an invoke() call */
381
+ declare interface InvokeContext {
382
+ $url$: URL | undefined;
383
+ /** The next available index for the sequentialScope array */
384
+ $i$: number;
385
+ /** The Virtual parent component for the current component code */
386
+ $hostElement$: HostElement | undefined;
387
+ /** The current DOM element */
388
+ $element$: Element | undefined;
389
+ /** The event we're currently handling */
390
+ $event$: PossibleEvents | undefined;
391
+ /** The QRL function we're currently executing */
392
+ $qrl$: QRL | undefined;
393
+ $effectSubscriber$: EffectSubscription | undefined;
394
+ $locale$: string | undefined;
395
+ $container$: Container | undefined;
396
+ }
397
+
398
+ declare type InvokeTuple = [Element, Event, URL?];
399
+
400
+ declare interface ISsrNode {
401
+ id: string;
402
+ flags: SsrNodeFlags;
403
+ parentComponent: ISsrNode | null;
404
+ vnodeData: VNodeData;
405
+ currentFile: string | null;
406
+ setProp(name: string, value: any): void;
407
+ getProp(name: string): any;
408
+ removeProp(name: string): void;
409
+ addChild(child: ISsrNode): void;
410
+ setTreeNonUpdatable(): void;
411
+ }
412
+
413
+ /** @public */
414
+ declare type JSXChildren = string | number | boolean | null | undefined | Function | RegExp | JSXChildren[] | Promise<JSXChildren> | Signal<JSXChildren> | JSXNode;
415
+
416
+ /**
417
+ * A JSX Node, an internal structure. You probably want to use `JSXOutput` instead.
418
+ *
419
+ * @public
420
+ */
421
+ declare interface JSXNode<T extends string | FunctionComponent | unknown = unknown> {
422
+ type: T;
423
+ props: T extends FunctionComponent<infer P> ? P : Record<any, unknown>;
424
+ children: JSXChildren | null;
425
+ key: string | null;
426
+ dev?: DevJSX;
427
+ }
428
+
429
+ /**
430
+ * Any valid output for a component
431
+ *
432
+ * @public
433
+ */
434
+ declare type JSXOutput_2 = JSXNode | string | number | boolean | null | undefined | JSXOutput_2[];
435
+
82
436
  /** @public */
83
437
  declare interface MockDocument extends Document {
84
438
  }
@@ -98,6 +452,333 @@ declare interface MockWindow extends Window {
98
452
  document: MockDocument;
99
453
  }
100
454
 
455
+ declare interface NodePropData {
456
+ $scopedStyleIdPrefix$: string | null;
457
+ $isConst$: boolean;
458
+ }
459
+
460
+ /**
461
+ * Returned type of the `noSerialize()` function. It will be TYPE or undefined.
462
+ *
463
+ * @public
464
+ * @see noSerialize
465
+ */
466
+ declare type NoSerialize<T> = (T & {
467
+ __no_serialize__: true;
468
+ }) | undefined;
469
+
470
+ declare type ObjToProxyMap = WeakMap<any, any>;
471
+
472
+ /** @public */
473
+ declare type OnRenderFn<PROPS> = (props: PROPS) => JSXOutput_2;
474
+
475
+ declare type PossibleEvents = Event | SimplifiedServerRequestEvent | typeof TaskEvent | typeof RenderEvent | typeof ResourceEvent;
476
+
477
+ declare type Props = Record<string, unknown>;
478
+
479
+ /**
480
+ * The `QRL` type represents a lazy-loadable AND serializable resource.
481
+ *
482
+ * QRL stands for Qwik URL.
483
+ *
484
+ * Use `QRL` when you want to refer to a lazy-loaded resource. `QRL`s are most often used for code
485
+ * (functions) but can also be used for other resources such as `string`s in the case of styles.
486
+ *
487
+ * `QRL` is an opaque token that is generated by the Qwik Optimizer. (Do not rely on any properties
488
+ * in `QRL` as it may change between versions.)
489
+ *
490
+ * ## Creating `QRL` references
491
+ *
492
+ * Creating `QRL` is done using `$(...)` function. `$(...)` is a special marker for the Qwik
493
+ * Optimizer that marks that the code should be extracted into a lazy-loaded symbol.
494
+ *
495
+ * ```tsx
496
+ * useOnDocument(
497
+ * 'mousemove',
498
+ * $((event) => console.log('mousemove', event))
499
+ * );
500
+ * ```
501
+ *
502
+ * In the above code, the Qwik Optimizer detects `$(...)` and transforms the code as shown below:
503
+ *
504
+ * ```tsx
505
+ * // FILE: <current file>
506
+ * useOnDocument('mousemove', qrl('./chunk-abc.js', 'onMousemove'));
507
+ *
508
+ * // FILE: chunk-abc.js
509
+ * export const onMousemove = () => console.log('mousemove');
510
+ * ```
511
+ *
512
+ * NOTE: `qrl(...)` is a result of Qwik Optimizer transformation. You should never have to invoke
513
+ * this function directly in your application. The `qrl(...)` function should be invoked only after
514
+ * the Qwik Optimizer transformation.
515
+ *
516
+ * ## Using `QRL`s
517
+ *
518
+ * Use `QRL` type in your application when you want to get a lazy-loadable reference to a resource
519
+ * (most likely a function).
520
+ *
521
+ * ```tsx
522
+ * // Example of declaring a custom functions which takes callback as QRL.
523
+ * export function useMyFunction(callback: QRL<() => void>) {
524
+ * doExtraStuff();
525
+ * // The callback passed to `onDocument` requires `QRL`.
526
+ * useOnDocument('mousemove', callback);
527
+ * }
528
+ * ```
529
+ *
530
+ * In the above example, the way to think about the code is that you are not asking for a callback
531
+ * function but rather a reference to a lazy-loadable callback function. Specifically, the function
532
+ * loading should be delayed until it is actually needed. In the above example, the function would
533
+ * not load until after a `mousemove` event on `document` fires.
534
+ *
535
+ * ## Resolving `QRL` references
536
+ *
537
+ * At times it may be necessary to resolve a `QRL` reference to the actual value. This can be
538
+ * performed using `QRL.resolve(..)` function.
539
+ *
540
+ * ```tsx
541
+ * // Assume you have QRL reference to a greet function
542
+ * const lazyGreet: QRL<() => void> = $(() => console.log('Hello World!'));
543
+ *
544
+ * // Use `qrlImport` to load / resolve the reference.
545
+ * const greet: () => void = await lazyGreet.resolve();
546
+ *
547
+ * // Invoke it
548
+ * greet();
549
+ * ```
550
+ *
551
+ * NOTE: `element` is needed because `QRL`s are relative and need a base location to resolve
552
+ * against. The base location is encoded in the HTML in the form of `<div q:base="/url">`.
553
+ *
554
+ * ## `QRL.resolved`
555
+ *
556
+ * Once `QRL.resolve()` returns, the value is stored under `QRL.resolved`. This allows the value to
557
+ * be used without having to await `QRL.resolve()` again.
558
+ *
559
+ * ## Question: Why not just use `import()`?
560
+ *
561
+ * At first glance, `QRL` serves the same purpose as `import()`. However, there are three subtle
562
+ * differences that need to be taken into account.
563
+ *
564
+ * 1. `QRL`s must be serializable into HTML.
565
+ * 2. `QRL`s must be resolved by framework relative to `q:base`.
566
+ * 3. `QRL`s must be able to capture lexically scoped variables.
567
+ * 4. `QRL`s encapsulate the difference between running with and without Qwik Optimizer.
568
+ * 5. `QRL`s allow expressing lazy-loaded boundaries without thinking about chunk and symbol names.
569
+ *
570
+ * Let's assume that you intend to write code such as this:
571
+ *
572
+ * ```tsx
573
+ * return <button onClick={() => (await import('./chunk-abc.js')).onClick}>
574
+ * ```
575
+ *
576
+ * The above code needs to be serialized into DOM such as:
577
+ *
578
+ * ```
579
+ * <div q:base="/build/">
580
+ * <button on:click="./chunk-abc.js#onClick">...</button>
581
+ * </div>
582
+ * ```
583
+ *
584
+ * 1. Notice there is no easy way to extract chunk (`./chunk-abc.js`) and symbol (`onClick`) into HTML.
585
+ * 2. Notice that even if you could extract it, the `import('./chunk-abc.js')` would become relative to
586
+ * where the `import()` file is declared. Because it is our framework doing the load, the
587
+ * `./chunk-abc.js` would become relative to the framework file. This is not correct, as it
588
+ * should be relative to the original file generated by the bundler.
589
+ * 3. Next, the framework needs to resolve the `./chunk-abc.js` and needs a base location that is
590
+ * encoded in the HTML.
591
+ * 4. The QRL needs to be able to capture lexically scoped variables. (`import()` only allows loading
592
+ * top-level symbols which don't capture variables.)
593
+ * 5. As a developer, you don't want to think about `import` and naming the chunks and symbols. You
594
+ * just want to say: "this should be lazy."
595
+ *
596
+ * These are the main reasons why Qwik introduces its own concept of `QRL`.
597
+ *
598
+ * @public
599
+ * @see `$`
600
+ */
601
+ declare type QRL<TYPE = unknown> = {
602
+ __qwik_serializable__?: any;
603
+ __brand__QRL__: TYPE;
604
+ /** Resolve the QRL and return the actual value. */
605
+ resolve(): Promise<TYPE>;
606
+ /** The resolved value, once `resolve()` returns. */
607
+ resolved: undefined | TYPE;
608
+ getCaptured(): unknown[] | null;
609
+ getSymbol(): string;
610
+ getHash(): string;
611
+ dev: QRLDev | null;
612
+ } & BivariantQrlFn<QrlArgs<TYPE>, QrlReturn<TYPE>>;
613
+
614
+ declare type QrlArgs<T> = T extends (...args: infer ARGS) => any ? ARGS : unknown[];
615
+
616
+ /** @public */
617
+ declare interface QRLDev {
618
+ file: string;
619
+ lo: number;
620
+ hi: number;
621
+ }
622
+
623
+ declare type QRLInternal<TYPE = unknown> = QRL<TYPE> & QRLInternalMethods<TYPE>;
624
+
625
+ declare type QRLInternalMethods<TYPE> = {
626
+ readonly $chunk$: string | null;
627
+ readonly $symbol$: string;
628
+ readonly $hash$: string;
629
+ $capture$: string[] | null;
630
+ $captureRef$: unknown[] | null;
631
+ dev: QRLDev | null;
632
+ resolved: undefined | TYPE;
633
+ resolve(containerEl?: Element): Promise<TYPE>;
634
+ getSymbol(): string;
635
+ getHash(): string;
636
+ getCaptured(): unknown[] | null;
637
+ getFn(currentCtx?: InvokeContext | InvokeTuple, beforeFn?: () => void): TYPE extends (...args: any) => any ? (...args: Parameters<TYPE>) => ValueOrPromise<ReturnType<TYPE>> : unknown;
638
+ $setContainer$(containerEl: Element | undefined): Element | undefined;
639
+ };
640
+
641
+ declare type QrlReturn<T> = T extends (...args: any) => infer R ? Awaited<R> : unknown;
642
+
643
+ /** @public */
644
+ declare interface ReadonlySignal<T = unknown> {
645
+ readonly value: T;
646
+ }
647
+
648
+ declare const RenderEvent = "qRender";
649
+
650
+ declare const ResourceEvent = "qResource";
651
+
652
+ declare interface ResourceReturnInternal<T> {
653
+ __brand: 'resource';
654
+ _state: 'pending' | 'resolved' | 'rejected';
655
+ _resolved: T | undefined;
656
+ _error: Error | undefined;
657
+ _cache: number;
658
+ _timeout: number;
659
+ value: Promise<T>;
660
+ loading: boolean;
661
+ }
662
+
663
+ declare type Scheduler = ReturnType<typeof createScheduler>;
664
+
665
+ declare type SeenRef = {
666
+ $parent$: unknown | null;
667
+ $index$: number;
668
+ $rootIndex$: number;
669
+ };
670
+
671
+ declare interface SerializationContext {
672
+ $serialize$: () => void;
673
+ $symbolToChunkResolver$: SymbolToChunkResolver;
674
+ /**
675
+ * Map from object to parent and index reference.
676
+ *
677
+ * If object is found in `objMap` will return the parent reference and index path.
678
+ *
679
+ * `objMap` return:
680
+ *
681
+ * - `{ parent, index }` - The parent object and the index within that parent.
682
+ * - `undefined` - Object has not been seen yet.
683
+ */
684
+ $wasSeen$: (obj: unknown) => SeenRef | undefined;
685
+ $hasRootId$: (obj: unknown) => number | undefined;
686
+ /**
687
+ * Root objects which need to be serialized.
688
+ *
689
+ * Roots are entry points into the object graph. Typically the roots are held by the listeners.
690
+ *
691
+ * Returns a path string representing the path from roots through all parents to the object.
692
+ * Format: "3 2 0" where each number is the index within its parent, from root to leaf.
693
+ */
694
+ $addRoot$: (obj: unknown, parent?: unknown) => number;
695
+ /**
696
+ * Get root path of the object without creating a new root.
697
+ *
698
+ * This is used during serialization, as new roots can't be created during serialization.
699
+ *
700
+ * The function throws if the root was not found.
701
+ */
702
+ $addRootPath$: (obj: any) => string | number;
703
+ $seen$: (obj: unknown, parent: unknown | null, index: number) => void;
704
+ $roots$: unknown[];
705
+ $objectPathStringCache$: Map<unknown, string | number>;
706
+ $addSyncFn$($funcStr$: string | null, argsCount: number, fn: Function): number;
707
+ $isSsrNode$: (obj: unknown) => obj is SsrNode;
708
+ $isDomRef$: (obj: unknown) => obj is DomRef;
709
+ $writer$: StreamWriter_2;
710
+ $syncFns$: string[];
711
+ $eventQrls$: Set<QRL>;
712
+ $eventNames$: Set<string>;
713
+ $resources$: Set<ResourceReturnInternal<unknown>>;
714
+ $renderSymbols$: Set<string>;
715
+ $storeProxyMap$: ObjToProxyMap;
716
+ $getProp$: (obj: any, prop: string) => any;
717
+ $setProp$: (obj: any, prop: string, value: any) => void;
718
+ }
719
+
720
+ /**
721
+ * A signal is a reactive value which can be read and written. When the signal is written, all tasks
722
+ * which are tracking the signal will be re-run and all components that read the signal will be
723
+ * re-rendered.
724
+ *
725
+ * Furthermore, when a signal value is passed as a prop to a component, the optimizer will
726
+ * automatically forward the signal. This means that `return <div title={signal.value}>hi</div>`
727
+ * will update the `title` attribute when the signal changes without having to re-render the
728
+ * component.
729
+ *
730
+ * @public
731
+ */
732
+ declare interface Signal<T = any> extends ReadonlySignal<T> {
733
+ value: T;
734
+ }
735
+
736
+ declare class SignalImpl<T = any> implements Signal<T> {
737
+ $untrackedValue$: T;
738
+ /** Store a list of effects which are dependent on this signal. */
739
+ $effects$: null | Set<EffectSubscription>;
740
+ $container$: Container | null;
741
+ constructor(container: Container | null, value: T);
742
+ /**
743
+ * Use this to force running subscribers, for example when the calculated value has mutated but
744
+ * remained the same object
745
+ */
746
+ force(): void;
747
+ get untrackedValue(): T;
748
+ set untrackedValue(value: T);
749
+ get value(): T;
750
+ set value(value: T);
751
+ valueOf(): void;
752
+ toString(): string;
753
+ toJSON(): {
754
+ value: T;
755
+ };
756
+ }
757
+
758
+ declare interface SimplifiedServerRequestEvent<T = unknown> {
759
+ url: URL;
760
+ locale: string | undefined;
761
+ request: Request;
762
+ }
763
+
764
+ declare type SsrAttrKey = string;
765
+
766
+ declare type SsrAttrs = Array<SsrAttrKey | SsrAttrValue>;
767
+
768
+ declare type SsrAttrValue = string | Signal<any> | boolean | object | null;
769
+
770
+ /** A selection of attributes of the real thing */
771
+ declare type SsrNode = {
772
+ id: string;
773
+ children: ISsrNode[] | null;
774
+ vnodeData: VNodeData;
775
+ [_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | null;
776
+ };
777
+
778
+ declare const enum SsrNodeFlags {
779
+ Updatable = 1
780
+ }
781
+
101
782
  /** @public */
102
783
  export declare function ssrRenderToDom(jsx: JSXOutput, opts?: {
103
784
  debug?: boolean;
@@ -109,11 +790,181 @@ export declare function ssrRenderToDom(jsx: JSXOutput, opts?: {
109
790
  getStyles: () => Record<string, string | string[]>;
110
791
  }>;
111
792
 
793
+ declare const enum StoreFlags {
794
+ NONE = 0,
795
+ RECURSIVE = 1,
796
+ IMMUTABLE = 2
797
+ }
798
+
799
+ declare class StoreHandler implements ProxyHandler<StoreTarget> {
800
+ $flags$: StoreFlags;
801
+ $container$: Container | null;
802
+ $effects$: null | Map<string | symbol, Set<EffectSubscription>>;
803
+ constructor($flags$: StoreFlags, $container$: Container | null);
804
+ toString(): string;
805
+ force(prop: keyof StoreTarget): void;
806
+ get(target: StoreTarget, prop: string | symbol): any;
807
+ /** In the case of oldValue and value are the same, the effects are not triggered. */
808
+ set(target: StoreTarget, prop: string | symbol, value: any): boolean;
809
+ deleteProperty(target: StoreTarget, prop: string | symbol): boolean;
810
+ has(target: StoreTarget, prop: string | symbol): boolean;
811
+ ownKeys(target: StoreTarget): ArrayLike<string | symbol>;
812
+ getOwnPropertyDescriptor(target: StoreTarget, prop: string | symbol): PropertyDescriptor | undefined;
813
+ }
814
+
815
+ declare type StoreTarget = Record<string | symbol, any>;
816
+
817
+ /** @internal */
818
+ declare interface StreamWriter {
819
+ write(chunk: string): void;
820
+ }
821
+
822
+ /** @internal */
823
+ declare class SubscriptionData {
824
+ data: NodePropData;
825
+ constructor(data: NodePropData);
826
+ }
827
+
828
+ declare type SymbolToChunkResolver = (symbol: string) => string;
829
+
830
+ declare class Task<T = unknown, B = T> extends BackRef implements DescriptorBase<unknown, Signal<B> | ResourceReturnInternal<B>> {
831
+ $flags$: number;
832
+ $index$: number;
833
+ $el$: HostElement;
834
+ $qrl$: QRLInternal<T>;
835
+ $state$: Signal<B> | ResourceReturnInternal<B> | undefined;
836
+ $destroy$: NoSerialize<() => void> | null;
837
+ constructor($flags$: number, $index$: number, $el$: HostElement, $qrl$: QRLInternal<T>, $state$: Signal<B> | ResourceReturnInternal<B> | undefined, $destroy$: NoSerialize<() => void> | null);
838
+ }
839
+
840
+ declare const TaskEvent = "qTask";
841
+
112
842
  /** @public */
113
843
  declare interface TestPlatform extends CorePlatform {
844
+ /**
845
+ * @deprecated No longer used, please use {@link waitForDrain} instead.
846
+ * @example With `ssrRenderToDom`
847
+ *
848
+ * ```ts
849
+ * import { waitForDrain } from '@qwik.dev/testing';
850
+ *
851
+ * const { container } = ssrRenderToDom(...);
852
+ * await waitForDrain(container);
853
+ * ```
854
+ *
855
+ * @example With `domRender`
856
+ *
857
+ * ```ts
858
+ * import { waitForDrain } from '@qwik.dev/testing';
859
+ *
860
+ * const { container } = domRender(...);
861
+ * await waitForDrain(container);
862
+ * ```
863
+ */
114
864
  flush: () => Promise<void>;
115
865
  }
116
866
 
867
+ /** @internal */
868
+ declare type TextVNode = [
869
+ VNodeFlags.Text | VNodeFlags.Inflated,
870
+ // 0 - Flags
871
+ VNode | null,
872
+ ///////////////// 1 - Parent
873
+ VNode | null,
874
+ ///////////////// 2 - Previous sibling
875
+ VNode | null,
876
+ ///////////////// 3 - Next sibling
877
+ Text | null | undefined,
878
+ string
879
+ ] & {
880
+ __brand__: 'TextVNode';
881
+ };
882
+
883
+ /**
884
+ * Used to signal to Qwik which state should be watched for changes.
885
+ *
886
+ * The `Tracker` is passed into the `taskFn` of `useTask`. It is intended to be used to wrap state
887
+ * objects in a read proxy which signals to Qwik which properties should be watched for changes. A
888
+ * change to any of the properties causes the `taskFn` to rerun.
889
+ *
890
+ * ### Example
891
+ *
892
+ * The `obs` passed into the `taskFn` is used to mark `state.count` as a property of interest. Any
893
+ * changes to the `state.count` property will cause the `taskFn` to rerun.
894
+ *
895
+ * ```tsx
896
+ * const Cmp = component$(() => {
897
+ * const store = useStore({ count: 0, doubleCount: 0 });
898
+ * const signal = useSignal(0);
899
+ * useTask$(({ track }) => {
900
+ * // Any signals or stores accessed inside the task will be tracked
901
+ * const count = track(() => store.count);
902
+ * // You can also pass a signal to track() directly
903
+ * const signalCount = track(signal);
904
+ * store.doubleCount = count + signalCount;
905
+ * });
906
+ * return (
907
+ * <div>
908
+ * <span>
909
+ * {store.count} / {store.doubleCount}
910
+ * </span>
911
+ * <button
912
+ * onClick$={() => {
913
+ * store.count++;
914
+ * signal.value++;
915
+ * }}
916
+ * >
917
+ * +
918
+ * </button>
919
+ * </div>
920
+ * );
921
+ * });
922
+ * ```
923
+ *
924
+ * @public
925
+ * @see `useTask`
926
+ */
927
+ declare interface Tracker {
928
+ /**
929
+ * Include the expression using stores / signals to track:
930
+ *
931
+ * ```tsx
932
+ * track(() => store.count);
933
+ * ```
934
+ *
935
+ * The `track()` function also returns the value of the scoped expression:
936
+ *
937
+ * ```tsx
938
+ * const count = track(() => store.count);
939
+ * ```
940
+ */
941
+ <T>(fn: () => T): T;
942
+ /**
943
+ * Used to track the whole object. If any property of the passed store changes, the task will be
944
+ * scheduled to run. Also accepts signals.
945
+ *
946
+ * Note that the change tracking is not deep. If you want to track changes to nested properties,
947
+ * you need to use `track` on each of them.
948
+ *
949
+ * ```tsx
950
+ * track(store); // returns store
951
+ * track(signal); // returns signal.value
952
+ * ```
953
+ */
954
+ <T extends object>(obj: T): T extends Signal<infer U> ? U : T;
955
+ /**
956
+ * Used to track to track a specific property of an object.
957
+ *
958
+ * Note that the change tracking is not deep. If you want to track changes to nested properties,
959
+ * you need to use `track` on each of them.
960
+ *
961
+ * ```tsx
962
+ * track(store, 'propA'); // returns store.propA
963
+ * ```
964
+ */
965
+ <T extends object, P extends keyof T>(obj: T, prop: P): T[P];
966
+ }
967
+
117
968
  /**
118
969
  * Trigger an event in unit tests on an element.
119
970
  *
@@ -121,7 +972,37 @@ declare interface TestPlatform extends CorePlatform {
121
972
  *
122
973
  * @public
123
974
  */
124
- export declare function trigger(root: Element, queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventName: string, eventPayload?: any): Promise<void>;
975
+ export declare function trigger(root: Element, queryOrElement: string | Element | keyof HTMLElementTagNameMap | null, eventName: string, eventPayload?: any, options?: {
976
+ waitForIdle?: boolean;
977
+ }): Promise<void>;
978
+
979
+ /**
980
+ * Type representing a value which is either resolve or a promise.
981
+ *
982
+ * @public
983
+ */
984
+ declare type ValueOrPromise<T> = T | Promise<T>;
985
+
986
+ /** @internal */
987
+ declare type VirtualVNode = [
988
+ VNodeFlags.Virtual,
989
+ ///////////// 0 - Flags
990
+ VNode | null,
991
+ /////////////// 1 - Parent
992
+ VNode | null,
993
+ /////////////// 2 - Previous sibling
994
+ VNode | null,
995
+ /////////////// 3 - Next sibling
996
+ VNode | null,
997
+ /////////////// 4 - First child
998
+ VNode | null,
999
+ (string | null | boolean)[]
1000
+ ] & {
1001
+ __brand__: 'FragmentNode' & 'HostElement';
1002
+ };
1003
+
1004
+ /** @internal */
1005
+ declare type VNode = ElementVNode | TextVNode | VirtualVNode;
125
1006
 
126
1007
  /** @public */
127
1008
  export declare function vnode_fromJSX(jsx: JSXOutput): {
@@ -131,6 +1012,96 @@ export declare function vnode_fromJSX(jsx: JSXOutput): {
131
1012
  container: ClientContainer;
132
1013
  };
133
1014
 
1015
+ /**
1016
+ * Array of numbers which describes virtual nodes in the tree.
1017
+ *
1018
+ * HTML can't account for:
1019
+ *
1020
+ * - Multiple text nodes in a row. (it treats it as a single text node)
1021
+ * - Empty text nodes. (it ignores them)
1022
+ * - And virtual nodes such as `<Fragment/>` or `<MyComponent/>`
1023
+ *
1024
+ * So we need to encode all of that information into the VNodeData.
1025
+ *
1026
+ * Encoding:
1027
+ *
1028
+ * - First position is special and encodes state information and stores VNodeDataFlag.
1029
+ * - Positive numbers are text node lengths. (0 is a special case for empty text node)
1030
+ * - Negative numbers are element counts.
1031
+ * - `OPEN_FRAGMENT` is start of virtual node.
1032
+ *
1033
+ * - If `OPEN_FRAGMENT` than the previous node is an `Array` which contains the props (see
1034
+ * `SsrAttrs`). NOTE: The array is never going to be the last item in the VNodeData, so we can
1035
+ * always assume that the last item in `vNodeData` is a number.
1036
+ * - `CLOSE_FRAGMENT` is end of virtual node.
1037
+ *
1038
+ * NOTE: This is how we store the information during the SSR streaming, once the SSR is complete
1039
+ * this data needs to be serialized into a string and stored in the DOM as a script tag which has
1040
+ * deferent serialization format.
1041
+ */
1042
+ declare type VNodeData = [VNodeDataFlag, ...(SsrAttrs | number)[]];
1043
+
1044
+ /**
1045
+ * Flags for VNodeData (Flags con be bitwise combined)
1046
+ *
1047
+ * @internal
1048
+ */
1049
+ declare const enum VNodeDataFlag {
1050
+ NONE = 0,
1051
+ TEXT_DATA = 1,
1052
+ VIRTUAL_NODE = 2,
1053
+ ELEMENT_NODE = 4,
1054
+ REFERENCE = 8,
1055
+ SERIALIZE = 16
1056
+ }
1057
+
1058
+ /**
1059
+ * Flags for VNode.
1060
+ *
1061
+ * # Materialize vs Inflation
1062
+ *
1063
+ * - Materialized: The node has all of its children. Specifically `firstChild`/`lastChild` are NOT
1064
+ * `undefined`. Materialization creates lazy instantiation of the children. NOTE: Only
1065
+ * ElementVNode need to be materialized.
1066
+ * - Inflation:
1067
+ *
1068
+ * - If Text: It means that it is safe to write to the node. When Text nodes are first Deserialized
1069
+ * multiple text nodes can share the same DOM node. On write the sibling text nodes need to be
1070
+ * converted into separate text nodes.
1071
+ * - If Element: It means that the element tag attributes have not yet been read from the DOM.
1072
+ *
1073
+ * Inflation and materialization are not the same, they are two independent things.
1074
+ *
1075
+ * @internal
1076
+ */
1077
+ declare const enum VNodeFlags {
1078
+ Element = 1,
1079
+ Virtual = 2,
1080
+ ELEMENT_OR_VIRTUAL_MASK = 3,
1081
+ Text = 4,
1082
+ ELEMENT_OR_TEXT_MASK = 5,
1083
+ TYPE_MASK = 7,
1084
+ INFLATED_TYPE_MASK = 15,
1085
+ Inflated = 8,
1086
+ Resolved = 16,
1087
+ Deleted = 32,
1088
+ NAMESPACE_MASK = 192,
1089
+ NEGATED_NAMESPACE_MASK = -193,
1090
+ NS_html = 0,// http://www.w3.org/1999/xhtml
1091
+ NS_svg = 64,// http://www.w3.org/2000/svg
1092
+ NS_math = 128
1093
+ }
1094
+
1095
+ /**
1096
+ * Wait for the scheduler to drain.
1097
+ *
1098
+ * This is useful when testing async code.
1099
+ *
1100
+ * @param container - The application container.
1101
+ * @public
1102
+ */
1103
+ export declare function waitForDrain(container: Container): Promise<void>;
1104
+
134
1105
  /** @public */
135
1106
  export declare function walkJSX(jsx: JSXOutput, apply: {
136
1107
  enter: (jsx: JSXNodeInternal) => void;