@calmdown/pyxis 1.0.0-rc.2 → 1.0.0-rc.4

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.
package/dist/core.d.ts CHANGED
@@ -17,32 +17,54 @@ type PropsType = { readonly [_ in string]?: any; };
17
17
  */
18
18
  declare const S_NODE_TYPE: unique symbol;
19
19
  /**
20
- * Infers the specific Node type from its props typings.
20
+ * Infers the specific Node type from its props typings, if available.
21
21
  */
22
22
  type NodeType<P> = P extends {
23
23
  readonly [S_NODE_TYPE]?: infer N;
24
24
  } ? N : unknown;
25
25
  /**
26
- * A tuple of up to 2 arguments.
26
+ * A symbol to include in props typings containing the element name.
27
+ * @deprecated **Type only, does not exist at runtime!**
27
28
  */
28
- type ArgsMax2<A0 = any, A1 = any> = [a0?: A0, a1?: A1];
29
+ declare const S_ELEM_NAME: unique symbol;
29
30
  /**
30
- * Describes a callback with up to two stored arguments.
31
+ * Infers the specific element name from its props typings, if available.
31
32
  */
32
- interface Callback<TArgs extends ArgsMax2 = ArgsMax2, TReturn = void> {}
33
- //#endregion
34
- //#region src/data/Dependency.d.ts
33
+ type ElemName<P> = P extends {
34
+ readonly [S_ELEM_NAME]?: infer N extends string;
35
+ } ? N : string;
35
36
  /**
36
- * A dependency callback of an Atom. The callback will be run whenever the relevant Atom changes.
37
+ * Flattens an intersection of objects into a single object.
38
+ *
39
+ * Note: The extra `& {}` appendix causes TypeScript to display the resulting type in its expanded
40
+ * form, rather than showing `Flatten<...>`.
37
41
  */
38
- interface Dependency<TArgs extends ArgsMax2 = ArgsMax2> extends Callback<TArgs> {}
39
- interface DependencyList<TArgs extends ArgsMax2 = ArgsMax2> {}
40
- declare function bind(lifecycle: Lifecycle, target: DependencyList, block: () => void): void;
42
+ type Flatten<T> = { [K in keyof T]: T[K]; } & {};
43
+ /**
44
+ * A tuple of up to 3 arguments.
45
+ */
46
+ type ArgsMax3<A0 = any, A1 = any, A2 = any> = [a0?: A0, a1?: A1, a2?: A2];
47
+ /**
48
+ * Describes a callback with up to two stored arguments.
49
+ */
50
+ interface Callback<TArgs extends ArgsMax3 = ArgsMax3, TReturn = void> {
51
+ fn: (this: any, ...args: TArgs) => TReturn;
52
+ a0?: TArgs[0];
53
+ a1?: TArgs[1];
54
+ a2?: TArgs[2];
55
+ }
56
+ //#endregion
57
+ //#region src/symbols.d.ts
58
+ export declare const S_ATOM: unique symbol;
59
+ export declare const S_COMPONENT: unique symbol;
60
+ export declare const S_TAG_NAME: unique symbol;
61
+ /** used as a key to attach and access dev info on JSX objects */
62
+ declare const S_DEV_INFO: unique symbol;
41
63
  //#endregion
42
64
  //#region src/data/Lifecycle.d.ts
43
65
  interface Lifecycle extends DependencyList {
44
- /** whether this Lifecycle is currently mounted or not */
45
- mounted: boolean;
66
+ /** gets a boolean indicating whether this Lifecycle is currently mounted or not */
67
+ readonly mounted: boolean;
46
68
  }
47
69
  interface MountBlock {
48
70
  (): (() => void) | void;
@@ -51,36 +73,82 @@ interface UnmountBlock {
51
73
  (): void;
52
74
  }
53
75
  /**
54
- * Registers a callback to run just after the current Component has mounted.
76
+ * Registers a block of code to run once the current Component has mounted.
55
77
  *
56
78
  * If a teardown callback is returned, it will be run just before the Component unmounts (equivalent
57
79
  * to adding a separate `unmounted` block).
58
80
  * @see {@link unmounted}
59
81
  */
60
- declare function mounted(block: MountBlock, lifecycle?: Lifecycle): void;
82
+ export declare function mounted(block: MountBlock, lifecycle?: Lifecycle): void;
83
+ /**
84
+ * Similar to {@link mounted}, but instead accepts a {@link Callback} object. Useful in hot paths
85
+ * where it may be desirable to reuse callback objects, avoid closures, or {@link Lifecycle} needs
86
+ * to be tightly controlled.
87
+ * @see {@link mounted}
88
+ */
89
+ export declare function onceMounted<TArgs extends ArgsMax3>(lifecycle: Lifecycle, callback: Callback<TArgs>): void;
61
90
  /**
62
- * Registers a callback to run once the current Component is just about to unmount.
91
+ * Registers a block of code to run once the current Component is just about to unmount.
63
92
  * @see {@link mounted}
64
93
  */
65
- declare function unmounted(block: UnmountBlock, lifecycle?: Lifecycle): void;
94
+ export declare function unmounted(block: UnmountBlock, lifecycle?: Lifecycle): void;
95
+ /**
96
+ * Similar to {@link unmounted}, but instead accepts a {@link Callback} object. Useful in hot paths
97
+ * where it may be desirable to reuse callback objects, avoid closures, or {@link Lifecycle} needs
98
+ * to be tightly controlled.
99
+ * @see {@link unmounted}
100
+ */
101
+ export declare function onceUnmounted<TArgs extends ArgsMax3>(lifecycle: Lifecycle, callback: Callback<TArgs>): void;
66
102
  /**
67
103
  * Gets the Lifecycle of the calling component.
68
104
  */
69
- declare function getLifecycle(): Lifecycle;
105
+ export declare function getLifecycle(): Lifecycle;
70
106
  /**
71
107
  * Runs a block of code with the provided Lifecycle. Calls to `getLifecycle` within the block will
72
108
  * return the specified object.
73
109
  * @see {@link getLifecycle}
74
110
  */
75
- declare function withLifecycle<TArgs extends [arg?: any], TReturn>(lifecycle: Lifecycle, block: (...args: TArgs) => TReturn, ...args: TArgs): TReturn;
111
+ export declare function withLifecycle<TArgs extends ArgsMax3, TReturn>(lifecycle: Lifecycle, block: (...args: TArgs) => TReturn, ...args: TArgs): TReturn;
112
+ //#endregion
113
+ //#region src/data/Dependency.d.ts
114
+ /**
115
+ * A dependency callback of an Atom. The callback will be run whenever the relevant Atom changes.
116
+ */
117
+ interface Dependency<TArgs extends ArgsMax3 = ArgsMax3> extends Callback<TArgs> {}
118
+ /**
119
+ * Represents an object capable of holding links to Dependencies and dispatching notifications
120
+ * to them.
121
+ */
122
+ interface DependencyList<TArgs extends ArgsMax3 = ArgsMax3> {
123
+ /**
124
+ * In chained data relations (proxy and context atoms), tracks the upstream atom forwarding
125
+ * notifications to this atom.
126
+ */
127
+ $upstream?: Nil<DependencyList>;
128
+ }
129
+ /**
130
+ * Invokes the provided {@link Dependency} and binds it to run again with each notification emitted
131
+ * by the specified target. The return value of the initial run is forwarded.
132
+ */
133
+ export declare function bind<TArgs extends ArgsMax3, TResult>(lifecycle: Lifecycle, target: DependencyList, dependency: Dependency & Callback<TArgs, TResult>): TResult;
134
+ /**
135
+ * Links a {@link Dependency} to an {@link Atom} and {@link Lifecycle}.
136
+ */
137
+ export declare function link<TArgs extends ArgsMax3>(lifecycle: Lifecycle, target: DependencyList, dep: Dependency<TArgs>): void;
138
+ /**
139
+ * Unlinks a Dependency from the Atom and Lifecycle it has been linked to.
140
+ */
141
+ export declare function unlink(dep: Dependency): void;
76
142
  //#endregion
77
143
  //#region src/data/Atom.d.ts
78
144
  /**
79
- * Pyxis Atom type guard marker.
145
+ * Holds any single value, managing reactions to its changes. A bare Atom is read-only. Use the
146
+ * `read` and `peek` functions to access its value.
147
+ * @see {@link read}
148
+ * @see {@link peek}
149
+ * @see {@link WriteAtom}
80
150
  */
81
- declare const S_ATOM: unique symbol;
82
- /** Contract for Atoms where they need to be read. */
83
- interface ReadAtom<out T> extends DependencyList {
151
+ interface Atom<out T = unknown> extends DependencyList {
84
152
  /** Pyxis Atom type guard marker. */
85
153
  readonly [S_ATOM]: true;
86
154
  /**
@@ -94,18 +162,22 @@ interface ReadAtom<out T> extends DependencyList {
94
162
  get: () => T;
95
163
  }
96
164
  /**
97
- * Holds any single value, managing reactions to its changes. Use the `read`, `write` functions to
98
- * access its value.
165
+ * Holds any single value, managing reactions to its changes. Values of WriteAtom are mutable and
166
+ * can be freely changed at any time. Use the `read`, `peek`, `write` or `update` functions to
167
+ * access or manipulate its value.
99
168
  * @see {@link read}
169
+ * @see {@link peek}
100
170
  * @see {@link write}
171
+ * @see {@link update}
172
+ * @see {@link Atom}
101
173
  */
102
- interface Atom<T = unknown> extends ReadAtom<T> {
174
+ interface WriteAtom<T = unknown> extends Atom<T> {
103
175
  /**
104
- * Sets the value of this Atom. Does nothing if this Atom is readonly. Only use this method when
105
- * the target is guaranteed to be an Atom, otherwise it is recommended to use the `write` or
106
- * `update` functions.
176
+ * Sets the value of this Atom. Does nothing if this Atom is readonly. This method does *not*
177
+ * emit any change notification to the Atom's observers; Using it recklessly can leave observers
178
+ * out of date with stale state! Please make sure you know exactly what you're doing; It is
179
+ * *strongly* recommended to use the `write` or `update` functions instead.
107
180
  *
108
- * This method does *not* send out any change notifications to observers!
109
181
  * @returns Boolean indicating whether the value of this Atom changed.
110
182
  * @see {@link write}
111
183
  * @see {@link update}
@@ -113,48 +185,56 @@ interface Atom<T = unknown> extends ReadAtom<T> {
113
185
  set: (value: T) => boolean;
114
186
  }
115
187
  /**
116
- * Union of the given type or an Atom of that type. Use the `read`, `peek`, `write`, `update` or
117
- * `isAtom` functions to interact with such values.
188
+ * Union of the given type or an Atom of that type. Use the `read`, `peek` or `isAtom` functions to
189
+ * interact with such values.
118
190
  * @see {@link read}
119
191
  * @see {@link peek}
120
- * @see {@link write}
121
- * @see {@link update}
122
192
  * @see {@link isAtom}
123
193
  */
124
194
  type MaybeAtom<T> = Atom<T> | T;
125
195
  /**
126
- * Union of the given type or the ReadAtom contract of that type. Use the `read`, `peek` or `isAtom`
127
- * functions to interact with such values.
196
+ * Union of the given type or a WriteAtom of that type. Use the `read`, `peek`, `write`, `update` or
197
+ * `isAtom` functions to interact with such values.
128
198
  * @see {@link read}
129
199
  * @see {@link peek}
200
+ * @see {@link write}
201
+ * @see {@link update}
130
202
  * @see {@link isAtom}
131
203
  */
132
- type MaybeReadAtom<T> = ReadAtom<T> | T;
204
+ type MaybeWriteAtom<T> = WriteAtom<T> | T;
133
205
  /**
134
- * Creates an empty Atom; i.e. value set to `undefined`.
206
+ * Creates an empty WriteAtom; i.e. value set to `undefined`.
135
207
  */
136
- declare function atomOf<T>(): Atom<T | undefined>;
208
+ export declare function atomOf<T>(): WriteAtom<T | undefined>;
137
209
  /**
138
- * Creates an Atom initialized to the provided value. If the provided value is already an Atom, it
139
- * is returned as-is.
140
- * @see {@link isAtom}
210
+ * Creates a WriteAtom initialized to the provided value.
211
+ *
212
+ * If the provided initial value is itself an Atom, its value is automatically unwrapped.
213
+ *
214
+ * If you're intentionally creating an Atom intended to hold other Atoms, create an empty Atom first
215
+ * and write it separately, e.g.:
216
+ *
217
+ * ```ts
218
+ * const atom = atomOf<Atom<number>>();
219
+ * write(atom, otherAtom);
220
+ * ```
141
221
  */
142
- declare function atomOf<T>(initialValue: MaybeAtom<T>, lifecycle?: Lifecycle, devId?: string): Atom<T>;
222
+ export declare function atomOf<T>(initialValue: MaybeAtom<T>, lifecycle?: Lifecycle, devId?: string): WriteAtom<T>;
143
223
  /**
144
224
  * Atom type guard, checks if the provided input is an Atom.
145
225
  */
146
- declare function isAtom<T = unknown>(input: Nil<MaybeAtom<T>>): input is Atom<T>;
147
- declare function isAtom<T = unknown>(input: Nil<MaybeReadAtom<T>>): input is ReadAtom<T>;
148
- declare function isAtom<T = unknown>(input: unknown): input is Atom<T>;
226
+ export declare function isAtom<T = unknown>(input: Nil<MaybeWriteAtom<T>>): input is WriteAtom<T>;
227
+ export declare function isAtom<T = unknown>(input: Nil<MaybeAtom<T>>): input is Atom<T>;
228
+ export declare function isAtom<T = unknown>(input: unknown): input is WriteAtom<T>;
149
229
  /**
150
230
  * Checks if the provided input is an Atom and reads its value. Non-atom inputs are returned as-is.
151
231
  * Reports read access when inside an effect.
152
232
  * @see {@link isAtom}
153
- * @see {@link write}
154
233
  * @see {@link peek}
234
+ * @see {@link write}
155
235
  * @see {@link update}
156
236
  */
157
- declare function read<A>(input: A): A extends MaybeReadAtom<infer T> ? T : never;
237
+ export declare function read<A>(input: A): A extends MaybeAtom<infer T> ? T : never;
158
238
  /**
159
239
  * Checks if the provided input is an Atom and reads its value. Non-atom inputs are returned as-is.
160
240
  * Does NOT report read access when inside an effect.
@@ -163,29 +243,261 @@ declare function read<A>(input: A): A extends MaybeReadAtom<infer T> ? T : never
163
243
  * @see {@link write}
164
244
  * @see {@link update}
165
245
  */
166
- declare function peek<A>(input: A): A extends MaybeReadAtom<infer T> ? T : never;
246
+ export declare function peek<A>(input: A): A extends MaybeAtom<infer T> ? T : never;
167
247
  /**
168
248
  * Checks if the provided input is an Atom, writes its value and returns the new value.
169
249
  *
250
+ * Writing readonly Atoms is simply a no-op. Their current value will be returned and the provided
251
+ * new value discarded.
252
+ *
170
253
  * Non-atom inputs are never modified in any way. Instead the provided new value is discarded and
171
254
  * the input is returned as-is.
172
255
  * @see {@link isAtom}
173
256
  * @see {@link read}
174
- * @see {@link write}
257
+ * @see {@link peek}
175
258
  * @see {@link update}
176
259
  */
177
- declare function write<A>(input: A, value: A extends Atom<infer T> ? T : never, force?: boolean): A extends MaybeAtom<infer T> ? T : never;
260
+ export declare function write<A>(input: A, value: A extends WriteAtom<infer T> ? T : never, force?: boolean): A extends MaybeWriteAtom<infer T> ? T : never;
178
261
  /**
179
262
  * Checks if the provided input is an Atom, updates its value using the provided transform function
180
263
  * and returns the new value.
181
264
  *
265
+ * Updating readonly Atoms is simply a no-op. Their current value will be returned and the
266
+ * transformed new value discarded.
267
+ *
182
268
  * Non-atom inputs are never modified in any way and the input is returned as-is.
183
269
  * @see {@link isAtom}
184
270
  * @see {@link read}
185
271
  * @see {@link peek}
186
272
  * @see {@link write}
187
273
  */
188
- declare function update<A>(input: A, transform: A extends Atom<infer T> ? (value: T) => T : never, force?: boolean): A extends MaybeAtom<infer T> ? T : never;
274
+ export declare function update<A>(input: A, transform: A extends WriteAtom<infer T> ? (value: T) => T : never, force?: boolean): A extends MaybeWriteAtom<infer T> ? T : never;
275
+ //#endregion
276
+ //#region src/data/Scheduler.d.ts
277
+ /**
278
+ * A function able to schedule a callback to be executed at a later time, e.g. `queueMicrotask`.
279
+ * The function must guarantee that the callback will be eventually executed.
280
+ */
281
+ interface TickFn {
282
+ (onTick: () => void): void;
283
+ }
284
+ /**
285
+ * Runs a block of code on the next tick of the scheduler, synchronized with other updates. Unless
286
+ * a tick is already pending, a new one is scheduled.
287
+ *
288
+ * Atoms written within the block will deliver their update notifications synchronously within the
289
+ * same tick.
290
+ */
291
+ export declare function tick(block: () => void, lifecycle?: Lifecycle): void;
292
+ /**
293
+ * Similar to {@link tick}, but instead accepts a {@link Callback} object. Useful in hot paths
294
+ * where it may be desirable to reuse callback objects and/or avoid closures.
295
+ * @see {@link tick}
296
+ */
297
+ export declare function scheduleTick<TArgs extends ArgsMax3>(lifecycle: Lifecycle, callback: Callback<TArgs>): void;
298
+ /**
299
+ * Runs a block of code immediately after the next tick of the scheduler, once all regular updates
300
+ * have finished. Unless a tick is already pending, a new one is scheduled.
301
+ *
302
+ * While it is possible to write Atoms within the block, their update notifications are
303
+ * no longer delivered in the same scheduler tick - they're postponed to the next one.
304
+ */
305
+ export declare function tock(block: () => void, lifecycle?: Lifecycle): void;
306
+ /**
307
+ * Similar to {@link tock}, but instead accepts a {@link Callback} object. Useful in hot paths
308
+ * where it may be desirable to reuse callback objects and/or avoid closures.
309
+ * @see {@link tock}
310
+ */
311
+ export declare function scheduleTock<TArgs extends ArgsMax3>(lifecycle: Lifecycle, callback: Callback<TArgs>): void;
312
+ //#endregion
313
+ //#region src/Adapter.d.ts
314
+ interface Adapter<TNode, TElements extends ElementsType = ElementsType> {
315
+ /**
316
+ * Carries information about the available intrinsic elements when using this Adapter.
317
+ * @deprecated **Type only, does not exist at runtime!**
318
+ */
319
+ readonly $elements?: TElements;
320
+ /**
321
+ * A function able to schedule a callback to be executed at a later time, e.g. `queueMicrotask`.
322
+ * The function must guarantee that the callback will be eventually executed.
323
+ */
324
+ readonly tick: TickFn;
325
+ /**
326
+ * Creates a native (intrinsic) element node by the element name.
327
+ */
328
+ readonly element: (name: string) => TNode;
329
+ /**
330
+ * Creates or updates a text node. In both cases the node is returned.
331
+ */
332
+ readonly text: (value: string, node: TNode | null) => TNode;
333
+ /**
334
+ * Creates a marker node used to preserve a position within the node tree.
335
+ */
336
+ readonly marker: (comment?: string) => TNode;
337
+ /**
338
+ * Creates a batch to which nodes can be inserted "offline," without causing any updates. The
339
+ * batch is later inserted all at once using the `insert` function, causing only a single
340
+ * update.
341
+ *
342
+ * Adapters may omit this function when batching is not supported.
343
+ */
344
+ readonly batch?: () => TNode;
345
+ /**
346
+ * Inserts the given `node` as a child of the `parent`. If `before` is provided, the child will
347
+ * be inserted just before the referenced node (which itself must be a child of the parent),
348
+ * otherwise the child is inserted at the end, becoming the new last child of the parent.
349
+ */
350
+ readonly insert: (node: TNode, parent: TNode, before: TNode | null) => void;
351
+ /**
352
+ * Removes a node from the hierarchy.
353
+ */
354
+ readonly remove: (node: TNode) => void;
355
+ /**
356
+ * Sets a named property of the given node.
357
+ */
358
+ readonly set: (elem: TNode, prop: string, value: any) => void;
359
+ }
360
+ type ExtensionsType<TNode> = { [_ in string]?: Extension<TNode>; };
361
+ interface Extension<TNode, TPropMapping extends ExtensionPropMapping<unknown> = ExtensionPropMapping<unknown>> {
362
+ /**
363
+ * Carries a mapping type used to infer the props this extension adds to native elements.
364
+ * @deprecated **Type only, does not exist at runtime!**
365
+ */
366
+ readonly $mapping?: TPropMapping;
367
+ /**
368
+ * Sets a named extension property of the given element. The prop name arrives unprefixed, i.e.
369
+ * without any extension key prefix.
370
+ */
371
+ readonly set: (node: TNode, prop: string, value: any, group: MountingGroup<TNode>) => void;
372
+ }
373
+ interface ExtensionPropMapping<TNode> {
374
+ /** Will contain a concrete type of the element for which props are being mapped. */
375
+ node: TNode;
376
+ /** Will contain a name of the element for which props are being mapped. */
377
+ name: string;
378
+ /**
379
+ * Override this field with an inferred object containing typed extension props. Prop names
380
+ * should be plain, do not include their extension prefix. It will be added automatically.
381
+ *
382
+ * To infer concrete types, you may use:
383
+ *
384
+ * - `this["node"]` ... concrete type of the element node
385
+ * - `this["name"]` ... the name of the element, as used in JSX
386
+ */
387
+ extension: {};
388
+ }
389
+ /** Creates an extension with a shared-runtime ID independent of its registered JSX prefix. */
390
+ export declare function extension<TNode, TPropMapping extends ExtensionPropMapping<TNode>>(propSetter: Extension<TNode>["set"]): Extension<TNode, TPropMapping>;
391
+ /**
392
+ * Builds a set of extension props using an Extension reference rather than relying on a globally
393
+ * registered prefixed extension props. The resulting object is intended to be ...spread directly
394
+ * onto JSX elements.
395
+ *
396
+ * Typically used in libraries where relying on a specific prefix convention would limit the users.
397
+ * Does not require an active component lifecycle. Repeated spreads use the last value for each
398
+ * extension/prop pair, while props from different extensions remain independent.
399
+ */
400
+ export declare function ext<TMapping extends ExtensionPropMapping<any>, TNodeType, TElemName>(extension: Extension<any, TMapping>, extensionProps: (TMapping & {
401
+ node: TNodeType;
402
+ name: TElemName;
403
+ })["extension"], targetPropsObject?: { [_ in string]?: any; }): {
404
+ readonly [S_NODE_TYPE]?: TNodeType;
405
+ readonly [S_ELEM_NAME]?: TElemName;
406
+ };
407
+ //#endregion
408
+ //#region src/Renderer.d.ts
409
+ interface Renderer<TNode, TElements extends ElementsType = ElementsType> extends Lifecycle {
410
+ /**
411
+ * Carries information about the available intrinsic elements when using this Renderer.
412
+ * @deprecated **Type only, does not exist at runtime!**
413
+ */
414
+ readonly $elements?: TElements;
415
+ mount: (root: TNode, jsx: JsxResult) => MountingGroup<TNode>;
416
+ unmount: (group: MountingGroup<TNode>) => void;
417
+ }
418
+ /** Extracts the typings of intrinsic elements supported by the given Renderer. */
419
+ type ElementsOf<TRenderer, TFallback extends ElementsType = {}> = (TRenderer extends {
420
+ readonly $elements?: infer TElements extends ElementsType;
421
+ } ? TElements : TFallback);
422
+ interface MountingGroup<TNode> extends Lifecycle, Hierarchy<TNode> {
423
+ /** the Adapter rendering this MountingGroup */
424
+ readonly adapter: Adapter<TNode>;
425
+ }
426
+ interface NativeNode<TNode> extends Hierarchy<TNode> {}
427
+ interface Hierarchy<TNode> {
428
+ /**
429
+ * tracks whether unmounting is in progress for this node, guarding against duplicate or cyclic
430
+ * unmount attempts
431
+ */
432
+ $isUnmounting?: boolean;
433
+ }
434
+ type HNode<TNode> = MountingGroup<TNode> | NativeNode<TNode>;
435
+ /**
436
+ * Unmounts a MountingGroup and removes it from the hierarchy. The removal is guaranteed even if
437
+ * user code throws during unmount. Also clears refs to its original parent node. Destroyed groups
438
+ * cannot be reused.
439
+ */
440
+ export declare function destroy<TNode>(hGroup: MountingGroup<TNode>): void;
441
+ /**
442
+ * Creates a sub-group within the provided MountingGroup. Needed whenever a subtree needs to mount
443
+ * or unmount dynamically.
444
+ */
445
+ export declare function fork<TNode>(hParent: HNode<TNode>, hBefore?: HNode<TNode> | null): MountingGroup<TNode>;
446
+ /**
447
+ * Inserts a HNode to the hierarchy. When reusing nodes, callers must make sure `untrack` has been
448
+ * previously called on the node to be re-inserted.
449
+ * @see {@link untrack}
450
+ */
451
+ export declare function track<TNode>(hNode: HNode<TNode>, hParent: HNode<TNode>, hBefore?: HNode<TNode> | null): void;
452
+ /**
453
+ * Removes a HNode from the tracking hierarchy. Removed nodes may be reused and re-inserted using
454
+ * the `track` function.
455
+ * @see {@link track}
456
+ */
457
+ export declare function untrack<TNode>(hNode: HNode<TNode>): void;
458
+ /**
459
+ * Creates a reusable callback for a complete render operation, including reactive reads, nested
460
+ * mounts and batch commits. Each invocation defers conflicting unmounts until the outermost render
461
+ * finishes, preserves the caller's reactive tracking, and returns the block's result unchanged.
462
+ *
463
+ * Deferred teardown errors are reported by the outermost render, after all requests are processed.
464
+ */
465
+ export declare function willMount<TNode, TArgs extends ArgsMax3, TResult>(hGroup: MountingGroup<TNode>, block: (...args: TArgs) => TResult): (...args: TArgs) => TResult;
466
+ /**
467
+ * Mounts JSX into a group that is not already mounted. When rendering into an externally owned
468
+ * batch, enclose the complete operation (including the commit and `flush`) in {@link willMount}.
469
+ */
470
+ export declare function mount<TNode>(jsx: any, hParent: MountingGroup<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, nRealParent: TNode, isBatch: boolean): void;
471
+ /**
472
+ * Marks the provided hGroup and all of its descendants as mounted and dispatches notifications
473
+ * where appropriate.
474
+ *
475
+ * Normally this happens automatically as part of calling {@link mount}, but it is necessary to
476
+ * flush manually when rendering into a batch. Batch owners are responsible for calling this
477
+ * function once the batch has been committed.
478
+ */
479
+ export declare function flush<TNode>(hGroup: MountingGroup<TNode>): void;
480
+ /**
481
+ * Unmounts the contents of a MountingGroup from the node tree. The group itself, though empty,
482
+ * remains usable and can be remounted later.
483
+ *
484
+ * If teardown would interrupt an active render, it is deferred until the outermost render
485
+ * operation finishes. Any teardown errors are then reported by that operation.
486
+ */
487
+ export declare function unmount<TNode>(hGroup: MountingGroup<TNode>): void;
488
+ /**
489
+ * Mounts components described by JSX to the specified location in the node tree.
490
+ */
491
+ export declare function mountJsx<TNode>(jsx: any, hParent: HNode<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, nRealParent: TNode, isBatch: boolean): void;
492
+ /**
493
+ * Inserts a native node and adds it to the tracking hierarchy. Necessary to preserve render order.
494
+ * Returns the newly created tracking node, or null when tracking is skipped. Only a direct child
495
+ * of hParent is used as a tracking insertion point; an outer anchor means appending within hParent.
496
+ * Batched native insertions append, while hBefore still determines the tracking position.
497
+ * Should only be called by component handlers!
498
+ */
499
+ export declare function insert<TNode>(nNode: TNode, children: any, hParent: HNode<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, isBatch: boolean, forceTrack: true): NativeNode<TNode>;
500
+ export declare function insert<TNode>(nNode: TNode, children: any, hParent: HNode<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, isBatch: boolean, forceTrack?: boolean): NativeNode<TNode> | null;
189
501
  //#endregion
190
502
  //#region src/Component.d.ts
191
503
  /**
@@ -202,7 +514,7 @@ type PropsOf<T> = T extends Component<infer TProps> ? TProps : unknown;
202
514
  interface DataTemplate<TData> {
203
515
  (data: TData): JsxResult;
204
516
  }
205
- declare function component<TPropsArg extends [{}]>(block: (...args: TPropsArg) => JsxResult, devId?: string): (...args: [props: JsxProps<TPropsArg[0]>]) => JsxResult;
517
+ export declare function component<TPropsArg extends [{}]>(block: (...args: TPropsArg) => JsxResult, devId?: string): (...args: [props: JsxProps<TPropsArg[0]>]) => JsxResult;
206
518
  /**
207
519
  * Infers the props object for use with JSX. Because Pyxis always supplies components with child
208
520
  * arrays (or tuples), the type needs to be adjusted to reflect the internal mechanics.
@@ -222,23 +534,32 @@ type JsxProps<T> = { readonly [K in keyof T]: K extends "children" ? JsxChildren
222
534
  */
223
535
  type JsxChildrenProp<T> = T extends readonly [any, any, ...any[]] ? T extends readonly [...infer C] ? readonly [...C] : T : T extends readonly [infer SC] ? SC : T extends readonly (infer C)[] ? readonly C[] | C : T;
224
536
  /**
225
- * Primitive types accepted to render as text.
537
+ * Primitive values (or Atoms of such primitives) accepted as text children. Nil and boolean values
538
+ * do not render any text.
226
539
  */
227
- type JsxText = MaybeReadAtom<Nil<string | number | boolean | bigint>>;
540
+ type JsxText = MaybeAtom<Nil<string | number | boolean | bigint>>;
228
541
  /**
229
542
  * Describes the objects returned by JSX factories.
230
543
  *
231
- * Pyxis uses very lightweight factories returning the props object directly,
232
- * adding a few extra props:
233
- *
234
- * - S_COMPONENT ... hidden, contains a reference to the ComponentHandler function
235
- * - S_TAG_NAME ... hidden, specifies the tag name, only populated for native elements
236
- * - children ... always present and always an array, empty array for childless components
544
+ * Pyxis uses lightweight factories returning the props object directly, only adding a few extra
545
+ * symbol-keyed props.
237
546
  */
238
547
  interface JsxObject {
239
548
  [propName: string]: unknown;
549
+ /** specifies the ComponentHandler function used to render this object */
550
+ readonly [S_COMPONENT]: ComponentHandler;
551
+ /** specifies the native element tag name, only populated for native elements */
552
+ readonly [S_TAG_NAME]?: string;
553
+ /** holds source code location of individual JSX nodes, only populated in dev mode */
554
+ readonly [S_DEV_INFO]?: JsxDevSourceInfo;
555
+ /** always present and always an array, empty array for childless components */
240
556
  readonly children: readonly unknown[];
241
557
  }
558
+ interface JsxDevSourceInfo {
559
+ readonly fileName: string;
560
+ readonly lineNumber: number;
561
+ readonly columnNumber: number;
562
+ }
242
563
  /**
243
564
  * Union of all admissible values within JSX.
244
565
  */
@@ -253,6 +574,22 @@ type JsxChildren = JsxResult | readonly JsxChildren[];
253
574
  type WithChildren<T extends PropsType> = T & {
254
575
  children?: JsxChildren;
255
576
  };
577
+ /**
578
+ * A handler function rendering a specific Component type. This is the real shape of Pyxis
579
+ * components used internally by the framework. `hBefore` is a tracked native anchor. When
580
+ * `isBatch` is true, native insertions append while `hBefore` still determines the position in the
581
+ * tracking hierarchy.
582
+ */
583
+ interface ComponentHandler {
584
+ <TNode>(jsx: JsxObject, hParent: HNode<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, nRealParent: TNode, isBatch: boolean): void;
585
+ }
586
+ declare global {
587
+ namespace JSX {
588
+ interface ElementChildrenAttribute {
589
+ children: {};
590
+ }
591
+ }
592
+ }
256
593
  //#endregion
257
594
  //#region src/component/Fragment.d.ts
258
595
  interface FragmentProps {
@@ -261,38 +598,40 @@ interface FragmentProps {
261
598
  /**
262
599
  * The built-in Fragment Component wrapping multiple Components.
263
600
  */
264
- declare function Fragment(props: JsxProps<FragmentProps>): JsxResult;
601
+ export declare function Fragment(props: JsxProps<FragmentProps>): JsxResult;
265
602
  //#endregion
266
603
  //#region src/data/ListDelta.d.ts
267
- declare enum ChangeKind {
268
- Change = 1,
269
- Insert = 2,
270
- Remove = 3,
271
- Clear = 4
272
- }
604
+ export declare const LC_CHANGE = 1;
605
+ export declare const LC_INSERT = 2;
606
+ export declare const LC_REMOVE = 3;
607
+ export declare const LC_CLEAR = 4;
273
608
  interface ListDelta<T> {
274
- readonly changes: ListChange<T>[];
275
- lengthChange: number;
609
+ /** raw snapshot of the List as observed at the time this ListDelta was emitted */
610
+ readonly snapshot: readonly T[];
611
+ /** changes made to the List since its last update */
612
+ readonly changes: readonly ListChange<T>[];
613
+ /** the relative change of the List size (its item count) */
614
+ readonly relSize: number;
276
615
  }
277
616
  type ListChange<T> = ListItemChanged<T> | ListItemInserted<T> | ListItemRemoved<T> | ListCleared;
278
617
  interface ListItemChanged<T> {
279
- kind: ChangeKind.Change;
618
+ kind: typeof LC_CHANGE;
280
619
  index: number;
281
620
  oldItem: T;
282
621
  newItem: T;
283
622
  }
284
623
  interface ListItemInserted<T> {
285
- kind: ChangeKind.Insert;
624
+ kind: typeof LC_INSERT;
286
625
  index: number;
287
626
  newItem: T;
288
627
  }
289
628
  interface ListItemRemoved<T> {
290
- kind: ChangeKind.Remove;
629
+ kind: typeof LC_REMOVE;
291
630
  index: number;
292
631
  oldItem: T;
293
632
  }
294
633
  interface ListCleared {
295
- kind: ChangeKind.Clear;
634
+ kind: typeof LC_CLEAR;
296
635
  index: number;
297
636
  }
298
637
  interface Equals<T> {
@@ -303,31 +642,54 @@ interface Equals<T> {
303
642
  interface ReadonlyList<T> extends Iterable<T>, DependencyList {
304
643
  /**
305
644
  * Gets the size of this List.
645
+ *
306
646
  * Reactive in effects and derivations.
307
647
  */
308
648
  size(): number;
309
649
  /**
310
650
  * Gets the item at the specified index. Return undefined when outside of the List's bounds.
651
+ *
311
652
  * Reactive in effects and derivations.
312
653
  */
313
654
  get(index: number): T | undefined;
314
655
  /**
315
- * Gets a set of changes made to this List within the current tick. Returns null when no changes
316
- * were made.
317
- * Reactive in effects and derivations.
656
+ * Gets a boolean indicating whether changes have been made to this List that have not yet been
657
+ * delivered to its observers.
658
+ *
659
+ * Non-reactive in effects and derivations.
318
660
  */
319
- delta(): ListDelta<T> | null;
661
+ dirty(): boolean;
320
662
  /**
321
- * Gets the underlying array of items. The array is read-only, mutating it will cause observers
322
- * to go out of sync.
663
+ * Registers a callback to run whenever one or more changes are made to this List. The callback
664
+ * receives a ListDelta object describing all changes made since the last notification.
665
+ *
323
666
  * Non-reactive in effects and derivations.
324
667
  */
668
+ delta(block: (delta: ListDelta<T>) => void, lifecycle?: Lifecycle): void;
669
+ /**
670
+ * Gets the underlying array of items of this List. The array is read-only, but may change when
671
+ * the List itself is mutated.
672
+ *
673
+ * Non-reactive in effects and derivations.
674
+ *
675
+ * *Mutating the array directly (e.g. in unchecked JS code) will cause any and all observers to
676
+ * go out of sync, breaking the rendered state in unpredictable ways!*
677
+ */
325
678
  raw(): readonly T[];
326
679
  /**
327
- * Runs the provided callback for each item of this List.
680
+ * Runs a block of code for each item of this List.
681
+ *
328
682
  * Reactive in effects and derivations.
329
683
  */
330
- forEach(callback: (item: T, index: number) => void, thisArg?: any): void;
684
+ forEach(block: (item: T, index: number) => void): void;
685
+ /**
686
+ * Runs a block of code with a stable, immutable snapshot of the items within this List. The
687
+ * List itself may be mutated as a result of running this code, but the provided snapshot will
688
+ * not reflect any such changes.
689
+ *
690
+ * Non-reactive in effects and derivations.
691
+ */
692
+ stable<R>(block: (snapshot: readonly T[]) => R): R;
331
693
  }
332
694
  interface List<T> extends ReadonlyList<T> {
333
695
  /**
@@ -387,36 +749,37 @@ interface List<T> extends ReadonlyList<T> {
387
749
  * Creates an empty List. This List emits deltas with each mutation which can be observed by
388
750
  * Components to efficiently update the rendered state.
389
751
  */
390
- declare function listOf<T>(): List<T>;
391
- declare function listOf<T>(source: Nil<never>, lifecycle?: Lifecycle, devId?: string): List<T>;
752
+ export declare function listOf<T>(): List<T>;
753
+ export declare function listOf<T>(source: Nil<never>, lifecycle?: Lifecycle, devId?: string): List<T>;
392
754
  /**
393
755
  * Creates a List initialized with items copied from the provided Iterable. This List emits deltas
394
756
  * with each mutation which can be observed by Components to efficiently update the rendered state.
395
757
  */
396
- declare function listOf<T>(source: Iterable<T>, lifecycle?: Lifecycle, devId?: string): List<T>;
758
+ export declare function listOf<T>(source: Iterable<T>, lifecycle?: Lifecycle, devId?: string): List<T>;
397
759
  /**
398
760
  * Synchronizes the provided List with the given data source. After this operation, the list will
399
761
  * contain an exact copy of the source.
400
762
  *
401
- * Note: This function is separated instead of being a List method since the underlying diff
402
- * algorithm (Myers) is a relatively large chunk of code which would otherwise always get included
403
- * into bundled builds. This way, tools like Terser can eliminate the extra code when unused.
763
+ * Note: This function is separated instead of being a List method as the underlying diff algorithm
764
+ * (Myers) is a relatively large chunk of code which would otherwise always get bundled into
765
+ * applications. This way, tools like Terser can easily eliminate the extra code when unused.
404
766
  */
405
- declare function sync<T>(list: List<T>, source: readonly T[], eq?: Equals<T>): void;
767
+ export declare function sync<T>(list: List<T>, source: Iterable<T>, eq?: Equals<T>): void;
406
768
  //#endregion
407
769
  //#region src/data/ProxyAtom.d.ts
408
- interface ProxyAtom<T> extends Atom<T> {
770
+ interface ProxyAtom<T> extends WriteAtom<T> {
409
771
  /**
410
772
  * Binds this ProxyAtom to a new value. If it is an Atom, the proxy will mirror it, otherwise it
411
773
  * will be a read-only atom with a static value until rebound.
774
+ * Binding a proxy to itself throws in development and is ignored in production.
412
775
  */
413
776
  use(value: MaybeAtom<T>): void;
414
777
  }
415
778
  /**
416
779
  * Creates a ProxyAtom bound to the provided initial value. If it is an Atom, the proxy will mirror
417
- * it, otherwise it will be a read-only atom with a static value until rebound.
780
+ * it, otherwise it will be a read-only atom with a static value until rebound via its `use` method.
418
781
  */
419
- declare function proxyOf<T>(initialValue: MaybeAtom<T>, lifecycle?: Lifecycle): ProxyAtom<T>;
782
+ export declare function proxyOf<T>(initialValue: MaybeAtom<T>, lifecycle?: Lifecycle): ProxyAtom<T>;
420
783
  type Proxied<T, P extends readonly (keyof T)[]> = {
421
784
  readonly proxied: T;
422
785
  } & { readonly [K in P[number]]: ProxyAtom<T[K] extends MaybeAtom<infer V> ? V : T[K]>; };
@@ -429,163 +792,18 @@ interface RemountIteratorProps<T> {
429
792
  }
430
793
  interface ProxyIteratorProps<T, P extends readonly (keyof T)[]> {
431
794
  source: ReadonlyList<T>;
432
- proxy: P;
795
+ proxy: P & ("proxied" extends P[number] ? never : unknown);
433
796
  children: [template: DataTemplate<Proxied<T, P>>];
434
797
  }
435
798
  /**
436
799
  * The built-in Iterator Component efficiently rendering collections of items
437
800
  * based on updates from a Pyxis `list`.
438
801
  */
439
- declare function Iterator<T>(props: JsxProps<RemountIteratorProps<T>>): JsxResult;
440
- declare function Iterator<T, P extends readonly (keyof T)[]>(props: JsxProps<ProxyIteratorProps<T, P>>): JsxResult;
441
- //#endregion
442
- //#region src/data/Scheduler.d.ts
443
- /**
444
- * A function able to schedule a callback to be executed at a later time, e.g. `queueMicrotask`.
445
- * The function must guarantee that the callback will be eventually executed.
446
- */
447
- interface TickFn {
448
- (onTick: () => void): void;
449
- }
450
- /**
451
- * Runs a block of code on the next tick of the scheduler, synchronized with other updates. If a
452
- * tick is not currently pending, a new one is scheduled.
453
- */
454
- declare function tick(block: () => void, lifecycle?: Lifecycle): void;
455
- /**
456
- * Runs a block of code after the next tick of the scheduler, once all regular updates finished.
457
- * If a tick is not currently pending, a new one is scheduled.
458
- */
459
- declare function tock(block: () => void, lifecycle?: Lifecycle): void;
460
- //#endregion
461
- //#region src/Adapter.d.ts
462
- interface Adapter<TNode, TIntrinsicElements extends ElementsType = ElementsType> {
463
- /**
464
- * Carries information about the available intrinsic elements when using this Adapter.
465
- * @deprecated **Type only, does not exist at runtime!**
466
- */
467
- readonly $elements?: TIntrinsicElements;
468
- /**
469
- * A function able to schedule a callback to be executed at a later time, e.g. `queueMicrotask`.
470
- * The function must guarantee that the callback will be eventually executed.
471
- */
472
- readonly tick: TickFn;
473
- /**
474
- * Creates a native (intrinsic) element node by its name.
475
- */
476
- readonly element: (name: string) => TNode;
477
- /**
478
- * Creates or updates a text node. In both cases the node is returned.
479
- */
480
- readonly text: (value: string, node: TNode | null) => TNode;
481
- /**
482
- * Creates a marker node used to preserve a position within the node tree.
483
- */
484
- readonly marker: (comment?: string) => TNode;
485
- /**
486
- * Creates a batch to which nodes can be inserted "offline," without causing any updates. The
487
- * batch is later inserted all at once using the `insert` function, causing only a single
488
- * update.
489
- *
490
- * Adapters may omit this function when batching is not supported.
491
- */
492
- readonly batch?: () => TNode;
493
- /**
494
- * Inserts the given `node` as a child of the `parent`. If `before` is provided, the child will
495
- * be inserted just before the referenced node, otherwise the child is inserted as the new last
496
- * child.
497
- */
498
- readonly insert: (node: TNode, parent: TNode, before: TNode | null) => void;
499
- /**
500
- * Removes a node from the hierarchy.
501
- */
502
- readonly remove: (node: TNode) => void;
503
- /**
504
- * Sets a named property of the given node.
505
- */
506
- readonly set: (node: TNode, prop: string, value: any) => void;
507
- }
508
- interface Extension<TNode, TExtensionKey extends string = string, TIntrinsicElements extends ElementsType = ElementsType, TExtendedIntrinsicElements extends ElementsType = ElementsType> {
509
- /**
510
- * Infers prop types to decorate existing types with extensions.
511
- * Type only, this call signature does not exist at runtime!
512
- */
513
- (extensionKey: TExtensionKey, intrinsicElements: TIntrinsicElements): TExtendedIntrinsicElements;
514
- /**
515
- * Sets a named extension property of the given node.
516
- */
517
- readonly set: (node: TNode, prop: string, value: any, group: MountingGroup<TNode>) => void;
518
- }
519
- type ExtensionsType<TNode> = { [_ in string]?: Extension<TNode>; };
520
- type ExtensionProps<TExtensionKey extends string, TProps extends PropsType> = { readonly [TExtPropKey in `${TExtensionKey}:${keyof TProps & string}`]?: (TExtPropKey extends `${TExtensionKey}:${infer TPropKey}` ? TProps[TPropKey] : never); };
521
- //#endregion
522
- //#region src/Renderer.d.ts
523
- interface Renderer<TNode, TIntrinsicElements extends ElementsType = ElementsType> {
524
- /**
525
- * Carries information about the available intrinsic elements when using this Renderer.
526
- * @deprecated **Type only, does not exist at runtime!**
527
- */
528
- readonly $elements?: TIntrinsicElements;
529
- mount: (root: TNode, jsx: JsxResult) => void;
530
- unmount: () => void;
531
- }
532
- type ElementsOf<TRenderer> = TRenderer extends {
533
- readonly $elements?: infer TElements;
534
- } ? TElements : {};
535
- interface MountingGroup<TNode> extends Lifecycle, Hierarchy<TNode> {
536
- readonly $isGroup: true;
537
- readonly $isNative?: never;
538
- /** the Adapter rendering this MountingGroup */
539
- readonly adapter: Adapter<TNode>;
540
- }
541
- interface NativeNode<TNode> extends Hierarchy<TNode> {
542
- readonly $isNative: true;
543
- readonly $isGroup?: never;
544
- readonly $nn: TNode;
545
- }
546
- interface Hierarchy<TNode> {}
547
- type HNode<TNode> = MountingGroup<TNode> | NativeNode<TNode>;
548
- /**
549
- * Creates a sub-group within the provided MountingGroup. Needed whenever a subtree needs to mount
550
- * or unmount dynamically.
551
- */
552
- declare function fork<TNode>(hParent: HNode<TNode>, hBefore?: HNode<TNode> | null): MountingGroup<TNode>;
553
- /**
554
- * Adds a HNode to the hierarchy.
555
- */
556
- declare function track<TNode>(hNode: HNode<TNode>, hParent: HNode<TNode>, hBefore?: HNode<TNode> | null): void;
557
- /**
558
- * Removes a HNode from the tracking hierarchy.
559
- */
560
- declare function untrack<TNode>(hNode: HNode<TNode>): void;
561
- /**
562
- * Mounts a MountingGroup to the specified location in the node tree. If the group is already
563
- * mounted (i.e. its native nodes are already rendered somewhere), it is moved to the new location
564
- * without re-mounting Pyxis components.
565
- *
566
- * Note that for successfully moving a group within the tree, you should first `untrack` the group,
567
- * then re-`track` it to the new location and only then call `mount` to commit the move.
568
- * @see {@link track}
569
- * @see {@link untrack}
570
- */
571
- declare function mount<TNode>(jsx: any, hGroup: MountingGroup<TNode>, nUsedParent: TNode, nRealParent: TNode, nBefore: TNode | null, isBatch: boolean): void;
572
- /**
573
- * Unmounts the contents of a MountingGroup from the node tree. The group itself, though empty,
574
- * remains usable and can be remounted later.
575
- */
576
- declare function unmount<TNode>(group: MountingGroup<TNode>): void;
577
- /**
578
- * Mounts components described by the JsxResult to the specified location in the node tree.
579
- */
580
- declare function mountJsx<TNode>(jsx: any, hParent: HNode<TNode>, nUsedParent: TNode, nRealParent: TNode, nBefore: TNode | null, isBatch: boolean): void;
581
- /**
582
- * Inserts a native node and adds it to the tracking hierarchy. Necessary to preserve render order.
583
- * Should only be called by component handlers!
584
- */
585
- declare function insert<TNode>(nNode: TNode, children: any, hParent: HNode<TNode>, nUsedParent: TNode, nBefore: TNode | null, isBatch: boolean): void;
802
+ export declare function Iterator<T>(props: JsxProps<RemountIteratorProps<T>>): JsxResult;
803
+ export declare function Iterator<T, P extends readonly (keyof T)[]>(props: JsxProps<ProxyIteratorProps<T, P>>): JsxResult;
586
804
  //#endregion
587
805
  //#region src/component/Native.d.ts
588
- declare function Native<TNode>(jsx: JsxObject, hParent: HNode<TNode>, nUsedParent: TNode, _nRealParent: TNode, nBefore: TNode | null, isBatch: boolean): void;
806
+ export declare function Native<TNode>(jsx: JsxObject, hParent: HNode<TNode>, hBefore: HNode<TNode> | null, nUsedParent: TNode, _nRealParent: TNode, isBatch: boolean): TNode;
589
807
  //#endregion
590
808
  //#region src/component/Show.d.ts
591
809
  interface ShowProps {
@@ -596,145 +814,225 @@ interface ShowDataProps<T> {
596
814
  when?: MaybeAtom<boolean>;
597
815
  proxy?: never;
598
816
  data: MaybeAtom<T>;
599
- children: [template: DataTemplate<T> | ReadAtom<Nil<DataTemplate<T>>>];
817
+ children: [template: DataTemplate<T> | Atom<Nil<DataTemplate<T>>>];
600
818
  }
601
819
  interface ShowProxyDataProps<T, P extends readonly (keyof T)[]> {
602
820
  when?: MaybeAtom<boolean>;
603
- proxy: P;
821
+ proxy: P & ("proxied" extends P[number] ? never : unknown);
604
822
  data: MaybeAtom<T>;
605
- children: [template: DataTemplate<Proxied<T, P>> | ReadAtom<Nil<DataTemplate<Proxied<T, P>>>>];
823
+ children: [template: DataTemplate<Proxied<T, P>> | Atom<Nil<DataTemplate<Proxied<T, P>>>>];
606
824
  }
607
825
  /**
608
826
  * The built-in Show Component dynamically mounting and unmounting a Template
609
827
  * based on a reactive condition result.
610
828
  */
611
- declare function Show(props: JsxProps<ShowProps>): JsxResult;
612
- declare function Show<T>(props: JsxProps<ShowDataProps<T>>): JsxResult;
613
- declare function Show<T, P extends readonly (keyof T)[]>(props: JsxProps<ShowProxyDataProps<T, P>>): JsxResult;
829
+ export declare function Show(props: JsxProps<ShowProps>): JsxResult;
830
+ export declare function Show<T>(props: JsxProps<ShowDataProps<T>>): JsxResult;
831
+ export declare function Show<T, P extends readonly (keyof T)[]>(props: JsxProps<ShowProxyDataProps<T, P>>): JsxResult;
614
832
  //#endregion
615
833
  //#region src/data/Context.d.ts
616
834
  /**
617
- * Describes a Context distributing data throughout the Component hierarchy.
618
- * @see {@link createContext}
835
+ * Describes a Context propagating data throughout the Component hierarchy.
836
+ * @see {@link contextOf}
619
837
  */
620
838
  interface Context<T> {
621
839
  /**
622
- * A fake property kept for TypeScript to properly type-check Context compatibility.
840
+ * Carries typings of the data propagated by this Context. Typed as a function to enforce
841
+ * correct variance of the generic value type.
623
842
  * @deprecated **Type only, does not exist at runtime!**
624
843
  */
625
- readonly $contract?: (value: T) => void;
844
+ readonly $contract?: (value: T) => T;
626
845
  }
627
846
  /**
628
- * Creates a typed Context that can be used to propagate observable data throughout entire component
629
- * trees without "prop drilling."
630
- * @see {@link context}
847
+ * Creates a typed Context allowing propagation of observable data throughout entire component trees
848
+ * without "prop drilling."
631
849
  */
632
- declare function createContext<T>(devId?: string): Context<T>;
633
- interface ContextAtom<T> extends Atom<T> {
634
- $dep?: Nil<Dependency>;
635
- $ancestor?: Nil<Atom<T>>;
636
- $value?: T;
637
- }
850
+ export declare function contextOf<T>(devId?: string): Context<T>;
851
+ /**
852
+ * Augments the current Component to act as a host (aka provider) of the given Context. Returns a
853
+ * mutable Atom carrying the contextual value propagated to all descendant Components that consume
854
+ * the Context.
855
+ *
856
+ * When a default value is specified, it will immediately be used as the hosted value, overriding
857
+ * any value hosted by ancestors of this Component.
858
+ *
859
+ * Without a default value specified, the Context initializes as "transparent," forwarding values
860
+ * hosted by ancestors of this Component. Once the returned Atom is written into for the first time,
861
+ * it breaks this link and begins hosting the new value from that point onwards. In forwarding mode,
862
+ * if no ancestor hosts the Context, the value is not well defined and reading the Atom fails until
863
+ * at least one of the hosts define a value.
864
+ *
865
+ * Descendants of this Component are able to consume the hosted value via `contextual(context)`
866
+ * receiving a readonly Atom.
867
+ *
868
+ * Note that due to how JavaScript arguments are handled, `undefined` is always treated as no
869
+ * default provided, even if it is an allowed value of the Context. To explicitly initialize hosts
870
+ * to the literal value `undefined`, you need to write the Atom separately, e.g.:
871
+ *
872
+ * ```ts
873
+ * const MyContext = contextOf<number | undefined>();
874
+ *
875
+ * // ...then, within a component:
876
+ * const value = host(MyContext);
877
+ * write(value, undefined);
878
+ * ```
879
+ * @see {@link contextual}
880
+ */
881
+ export declare function host<C>(context: C, defaultValue?: C extends Context<infer T> ? T : never, lifecycle?: Lifecycle, devId?: string): C extends Context<infer T> ? WriteAtom<T> : never;
638
882
  /**
639
- * Gets a consumer Atom for the given Context. This atom will be read-only.
883
+ * Gets a readonly Atom carrying the value inherited from the nearest ancestor of the current
884
+ * Component hosting the specified Context. This call fails if no ancestor is hosting the Context.
640
885
  * @see {@link host}
641
886
  */
642
- declare function consumerOf<T>(context: Context<T>): Atom<T> | null;
887
+ export declare function contextual<T>(context: Context<T>): Atom<T>;
888
+ //#endregion
889
+ //#region src/data/Derivation.d.ts
890
+ /**
891
+ * Holds a value derived from values of other Atoms, managing reactions to their changes.
892
+ * Derivations are read-only. Use the `read` function to access its value.
893
+ * @see {@link read}
894
+ */
895
+ interface Derivation<T = unknown> extends Atom<T> {}
643
896
  /**
644
- * Marks the current component as a host for the given context. Returns a mutable ContextAtom;
645
- * Values written to it will be propagated to any descendant component that consumes the context via
646
- * `consumerOf(context)`.
647
- * @see {@link consumerOf}
897
+ * Creates a Derivation - an Atom with its value computed from other Atoms. The block runs once
898
+ * eagerly to compute the initial value, then re-runs within scheduler ticks whenever its source
899
+ * Atoms change. Observers are only notified if the new value differs from the previous.
648
900
  */
649
- declare function host<C>(context: C, defaultValue?: C extends Context<infer T> ? T : never, devId?: string): C extends Context<infer T> ? ContextAtom<T> : never;
901
+ export declare function derived<T>(block: () => T, lifecycle?: Lifecycle): Derivation<T>;
650
902
  //#endregion
651
903
  //#region src/data/Effect.d.ts
652
904
  interface EffectBlock {
653
905
  (): (() => void) | void;
654
906
  }
655
- interface Effect<T> {}
656
907
  /**
657
908
  * Creates an Effect - a block of logic executed each time any of the Atoms accessed within it
658
- * change. The block is first synchronously executed when the Effect is created.
909
+ * change. The block is first synchronously executed when the Effect is created. Atoms may be
910
+ * written or even created within the block, but note that writing an Atom this Effect depends on
911
+ * may cause an infinite update loop when the state doesn't converge to a point where no more
912
+ * re-runs of this Effect are required.
659
913
  *
660
- * If a teardown callback is returned, it will be run before the next effect re-run, or on component
661
- * unmount.
914
+ * When a teardown callback is returned, it will be run before the next re-run of this Effect, or
915
+ * once the enclosing Component unmounts, whichever comes first.
662
916
  */
663
- declare function effect(block: EffectBlock, lifecycle?: Lifecycle): void;
917
+ export declare function effect(block: EffectBlock, lifecycle?: Lifecycle): void;
664
918
  /**
665
919
  * Runs a block of code removed from any effects. Accessing atoms within this block will be ignored
666
920
  * by any effect that may otherwise be observing this code.
667
921
  */
668
- declare function noEffect<T>(block: () => T): T;
669
- //#endregion
670
- //#region src/data/Derivation.d.ts
671
- /**
672
- * Holds a value derived from values of other Atoms, managing reactions to their changes.
673
- * Derivations are read-only. Use the `read` function to access its value.
674
- * @see {@link read}
675
- */
676
- interface Derivation<T = unknown> extends Atom<T>, Effect<T> {}
677
- /**
678
- * Creates a Derivation - an Atom with its value computed from other Atoms. The block runs once
679
- * eagerly to compute the initial value, then re-runs within scheduler ticks whenever its source
680
- * Atoms change. Observers are only notified if the new value differs from the previous.
681
- */
682
- declare function derived<T>(block: () => T, lifecycle?: Lifecycle): Derivation<T>;
922
+ export declare function noEffect<TArgs extends ArgsMax3, TReturn>(block: (...args: TArgs) => TReturn, ...args: TArgs): TReturn;
683
923
  //#endregion
684
924
  //#region src/extension/RefExtension.d.ts
685
- interface RefExtensionType {
686
- <TExtensionKey extends string, TElements extends ElementsType>(extensionKey: TExtensionKey, elements: TElements): { [TElementName in keyof TElements]: TElements[TElementName] & ExtensionProps<TExtensionKey, {
687
- readonly atom?: Atom<NodeType<TElements[TElementName]> | null>;
688
- readonly call?: RefFn<NodeType<TElements[TElementName]>>;
689
- }>; };
690
- set: (node: any, prop: string, value: any, group?: MountingGroup<any>) => void;
925
+ interface RefPropMapping extends ExtensionPropMapping<unknown> {
926
+ extension: RefProps<this["node"]>;
927
+ }
928
+ interface RefProps<TNode> {
929
+ readonly atom?: WriteAtom<TNode | null>;
930
+ readonly call?: RefFn<TNode>;
691
931
  }
692
932
  interface RefFn<TNode> {
693
- (node: TNode | null): void;
933
+ (node: TNode): (() => void) | void;
694
934
  }
695
935
  /**
696
- * Extension adding direct reference access to any element. Recommended prefix:
697
- * `"ref"`
936
+ * Extension adding direct reference access to any element. Recommended prefix: `"ref"`
937
+ *
938
+ * References can be stored into Atoms:
698
939
  *
699
- * References can be stored into atoms:
700
940
  * ```tsx
701
- * const wrapperRef = atomOf<HTMLDivElement>();
941
+ * const wrapperRef = atomOf<HTMLDivElement | null>(null);
702
942
  * <div ref:atom={wrapperRef} />
703
943
  * ```
704
- * or handled with a custom callback:
944
+ *
945
+ * The Atom will be set to the referenced node once it mounts. Later, when the node unmounts, the
946
+ * Atom is set back to `null`.
947
+ *
948
+ * References can also be received via callbacks:
949
+ *
705
950
  * ```tsx
706
- * const onWrapperRef = (node: HTMLDivElement) => { ... };
951
+ * const onWrapperRef = (node: HTMLDivElement) => {
952
+ * // ...
953
+ * };
954
+ *
707
955
  * <div ref:call={onWrapperRef} />
708
956
  * ```
957
+ *
958
+ * Ref callbacks are only called when the node mounts, they never receive `null`. Instead,
959
+ * unmounted nodes may be handled by returning a teardown callback.
709
960
  */
710
- declare const RefExtension: RefExtensionType;
961
+ export declare const RefExtension: Extension<any, RefPropMapping>;
711
962
  //#endregion
712
- //#region src/support/text.d.ts
963
+ //#region src/support/common.d.ts
713
964
  /**
714
- * A template literal tag that automatically wraps each substitution in a `read` call.
715
- * @see {@link read}
965
+ * Invokes a {@link Callback} passing stored arguments and forwarding its return value.
716
966
  */
717
- declare function reads(strings: TemplateStringsArray, ...values: JsxText[]): string;
967
+ export declare function invoke<TArgs extends ArgsMax3, TReturn>(callback: Callback<TArgs, TReturn>): TReturn;
968
+ //#endregion
969
+ //#region src/support/atoms.d.ts
718
970
  /**
719
- * A template literal tag that automatically wraps each substitution in a `peek` call.
720
- * @see {@link peek}
971
+ * A template string tag that creates a Derivation Atom from the tagged template. The derivation
972
+ * automatically observes any Atoms among substitutions and updates the resulting string whenever
973
+ * one or more of these Atoms change.
974
+ *
975
+ * Substitutions use String conversion; Failed conversions get replaced with `[error]`. Ideally,
976
+ * you'd want to make sure `String(yourValue)` never fails.
721
977
  */
722
- declare function peeks(strings: TemplateStringsArray, ...values: JsxText[]): string;
723
- //#endregion
724
- //#region src/Builder.d.ts
725
- interface PyxisBuilder<TNode, TIntrinsicElements extends ElementsType> {
726
- build: () => Renderer<TNode, TIntrinsicElements>;
727
- extend: <TExtensionKey extends string, TExtendedIntrinsicElements extends ElementsType>(extensionKey: TExtensionKey, extension: (extensionKey: TExtensionKey, intrinsicElements: TIntrinsicElements) => TExtendedIntrinsicElements) => PyxisBuilder<TNode, Merged<TExtendedIntrinsicElements>>;
728
- }
729
- type MergeIntersection<T> = { [K in keyof T]: T[K]; } & {};
730
- type Merged<T> = { [K in keyof T]: MergeIntersection<T[K]>; };
731
- declare function pyxis<TNode, TIntrinsicElements extends ElementsType>(adapter: Adapter<TNode, TIntrinsicElements>): PyxisBuilder<TNode, TIntrinsicElements>;
978
+ export declare function text(strings: TemplateStringsArray, ...values: unknown[]): Derivation<string>;
979
+ /**
980
+ * Creates a callback wrapping a call to the {@link write} function. Useful for decluttering inline
981
+ * event handlers in JSX templates.
982
+ * @see {@link write}
983
+ */
984
+ export declare function writes<A>(input: A, value: A extends WriteAtom<infer T> ? T : never, force?: boolean): () => void;
985
+ /**
986
+ * Creates a callback wrapping a call to the {@link update} function. Useful for decluttering inline
987
+ * event handlers in JSX templates.
988
+ * @see {@link update}
989
+ */
990
+ export declare function updates<A>(input: A, transform: A extends WriteAtom<infer T> ? (value: T) => T : never, force?: boolean): () => void;
991
+ /**
992
+ * Extracts the type of value represented by the given type, unwrapping Atoms if they're part of the
993
+ * type.
994
+ */
995
+ type ValueType<T> = T extends Atom<infer V> ? V : T;
996
+ /**
997
+ * Infers an object with its fields' values wrapped in Atoms. Optionally, if a specific TKeys union
998
+ * is provided, only select fields will be wrapped.
999
+ */
1000
+ type AtomsOf<TData extends { readonly [K in string]: any; }, TKeys extends (keyof TData & (string | number)) | undefined = undefined> = (undefined extends TKeys ? { [K in keyof TData as K extends string | number ? K : never]: undefined extends TData[K] ? MaybeWriteAtom<ValueType<TData[K]>> : WriteAtom<ValueType<TData[K]>>; } : Flatten<({ [K in TKeys & keyof TData & (string | number)]-?: WriteAtom<ValueType<TData[K]>>; } & Omit<Pick<TData, keyof TData & (string | number)>, TKeys & keyof TData>)>);
1001
+ /**
1002
+ * Creates a new data object mapped from the one provided, with its fields' values wrapped in
1003
+ * mutable Atoms. Optionally, a tuple of keys can be given to only wrap the select fields, copying
1004
+ * others as-is.
1005
+ */
1006
+ export declare function atomsOf<TData extends { readonly [K in string]: any; }>(data: TData, lifecycle?: Lifecycle): AtomsOf<TData>;
1007
+ export declare function atomsOf<TData extends { readonly [K in string]: any; }, const TKeys extends readonly (keyof TData & (string | number))[]>(data: TData, keys: TKeys & (number extends TKeys["length"] ? never : unknown), lifecycle?: Lifecycle): AtomsOf<TData, TKeys[number]>;
1008
+ /**
1009
+ * Assigns values taken from the provided data object to the store (typically previously created
1010
+ * via {@link atomsOf}). Optionally, a tuple of keys can be given to treat select fields as
1011
+ * guaranteed Atoms while copying others as-is. Typically, you'd pass the same keys tuple to both
1012
+ * `atomsOf` and later `assign` calls.
1013
+ */
1014
+ export declare function assign<TData extends { readonly [K in string]: any; }, TStore extends AtomsOf<TData>>(store: TStore, data: TData, lifecycle?: Lifecycle): TStore;
1015
+ export declare function assign<TData extends { readonly [K in string]: any; }, const TKeys extends readonly (keyof TData & (string | number))[], TStore extends AtomsOf<TData, TKeys[number]>>(store: TStore, data: TData, keys: TKeys & (number extends TKeys["length"] ? never : unknown), lifecycle?: Lifecycle): TStore;
732
1016
  //#endregion
733
1017
  //#region src/jsx.d.ts
734
- declare function jsx(tagName: string, props: PropsType, key?: any): JsxResult;
735
- declare function jsx<TProps extends PropsType>(component: Component<TProps>, props: TProps, key?: any): JsxResult;
736
- declare function jsxs(tagName: string, props: PropsType, key?: any): JsxResult;
737
- declare function jsxs<TProps extends PropsType>(component: Component<TProps>, props: TProps, key?: any): JsxResult;
1018
+ export declare function jsx(tagName: string, props: PropsType, key?: any): JsxResult;
1019
+ export declare function jsx<TProps extends PropsType>(component: Component<TProps>, props: TProps, key?: any): JsxResult;
1020
+ export declare function jsxs(tagName: string, props: PropsType, key?: any): JsxResult;
1021
+ export declare function jsxs<TProps extends PropsType>(component: Component<TProps>, props: TProps, key?: any): JsxResult;
1022
+ //#endregion
1023
+ //#region src/RendererBuilder.d.ts
1024
+ interface RendererBuilder<TNode, TElements extends ElementsType, TUsedPrefixes extends string = never> {
1025
+ create: () => Renderer<TNode, TElements>;
1026
+ extend: <TPrefix extends string, TExtension extends Extension<TNode>>(prefix: TPrefix & (TPrefix extends TUsedPrefixes ? never : unknown), extension: TExtension) => RendererBuilder<TNode, ExtendedElements<TNode, TElements, TExtension, TPrefix>, TUsedPrefixes | TPrefix>;
1027
+ }
1028
+ type ExtendedElements<TNode, TElements extends ElementsType, TExtension extends Extension<TNode>, TPrefix extends string> = (TExtension extends {
1029
+ readonly $mapping?: infer TMapping extends ExtensionPropMapping<unknown>;
1030
+ } ? { [TElementName in keyof TElements]: ((TMapping & {
1031
+ node: NodeType<TElements[TElementName]>;
1032
+ name: TElementName;
1033
+ })["extension"] extends (infer TExtensionProps extends PropsType) ? [keyof TExtensionProps] extends [never] ? TElements[TElementName] : Flatten<TElements[TElementName] & PrefixedProps<TExtensionProps, TPrefix>> : TElements[TElementName]); } : TElements);
1034
+ type PrefixedProps<TProps extends PropsType, TPrefix extends string> = { readonly [TPrefixed in `${TPrefix}:${keyof TProps & string}`]?: (TPrefixed extends `${TPrefix}:${infer TName extends (keyof TProps & string)}` ? TProps[TName] : never); };
1035
+ export declare function renderer<TNode, TElements extends ElementsType>(adapter: Adapter<TNode, TElements>): RendererBuilder<TNode, TElements, never>;
738
1036
  //#endregion
739
- export { type Adapter, type Atom, ChangeKind, type Component, type Context, type DataTemplate, type Derivation, type EffectBlock, type ElementsOf, type ElementsType, type Equals, type Extension, type ExtensionProps, type ExtensionsType, Fragment, type FragmentProps, type HNode, Iterator, type JsxChildren, type JsxChildrenProp, type JsxObject, type JsxProps, type JsxResult, type JsxText, type Lifecycle, type List, type ListChange, type ListCleared, type ListDelta, type ListItemChanged, type ListItemInserted, type ListItemRemoved, type MaybeAtom, type MaybeReadAtom, type MountBlock, type MountingGroup, Native, type Nil, type NodeType, type PropsOf, type PropsType, type Proxied, type ProxyAtom, type ProxyIteratorProps, type PyxisBuilder, type ReadAtom, type ReadonlyList, RefExtension, type RefExtensionType, type RefFn, type RemountIteratorProps, type Renderer, type S_ATOM, type S_NODE_TYPE, Show, type ShowProps, type TickFn, type UnmountBlock, type WithChildren, atomOf, bind, component, consumerOf, createContext, derived, effect, fork, getLifecycle, host, insert, isAtom, jsx, jsxs, listOf, mount, mountJsx, mounted, noEffect, peek, peeks, proxyOf, pyxis, read, reads, sync, tick, tock, track, unmount, unmounted, untrack, update, withLifecycle, write };
1037
+ export type { Adapter, ArgsMax3, Atom, AtomsOf, Callback, Component, ComponentHandler, Context, DataTemplate, Dependency, DependencyList, Derivation, EffectBlock, ElemName, ElementsOf, ElementsType, Equals, Extension, ExtensionPropMapping, ExtensionsType, Flatten, FragmentProps, HNode, JsxChildren, JsxChildrenProp, JsxDevSourceInfo, JsxObject, JsxProps, JsxResult, JsxText, Lifecycle, List, ListChange, ListCleared, ListDelta, ListItemChanged, ListItemInserted, ListItemRemoved, MaybeAtom, MaybeWriteAtom, MountBlock, MountingGroup, Nil, NodeType, PropsOf, PropsType, Proxied, ProxyAtom, ProxyIteratorProps, ReadonlyList, RefFn, RemountIteratorProps, Renderer, RendererBuilder, S_ELEM_NAME, S_NODE_TYPE, ShowDataProps, ShowProps, ShowProxyDataProps, TickFn, UnmountBlock, ValueType, WithChildren, WriteAtom };
740
1038
  //# sourceMappingURL=core.d.ts.map