@continuum-js/dom 0.3.0 → 0.3.1
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/index.d.ts +3 -0
- package/dist/index.js +31 -4
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function scope<T>(fn: () => T): {
|
|
|
8
8
|
};
|
|
9
9
|
/** Register a cleanup in the current owner (no-op outside any owner). */
|
|
10
10
|
export declare function onCleanup(fn: () => void): void;
|
|
11
|
+
/** Anything placeable in JSX: nodes, behaviors (live-bound), primitives, arrays. */
|
|
11
12
|
export type Child = Node | Behavior<unknown> | string | number | boolean | null | undefined | Child[];
|
|
12
13
|
type Props = Record<string, unknown> | null;
|
|
13
14
|
/** Fragment marker for `--jsxFragmentFactory Fragment`. */
|
|
@@ -21,10 +22,12 @@ export declare function h(tag: string | Component | typeof Fragment, props: Prop
|
|
|
21
22
|
export declare function dyn<T>(b: Behavior<T>, render: (v: T) => Child): Node;
|
|
22
23
|
/** Keyed list: reuses rows by key, reorders with minimal moves (LIS). */
|
|
23
24
|
export declare function each<T, K>(items: Behavior<T[]>, key: (item: T) => K, render: (item: T) => Child): Node;
|
|
25
|
+
/** A context handle: identity plus the value used when nothing was provided. */
|
|
24
26
|
export interface Context<T> {
|
|
25
27
|
readonly id: symbol;
|
|
26
28
|
readonly defaultValue: T;
|
|
27
29
|
}
|
|
30
|
+
/** Create a context. Provide with `provide`, read with `use`. */
|
|
28
31
|
export declare function createContext<T>(defaultValue: T): Context<T>;
|
|
29
32
|
/** Write a context value into the current owner. */
|
|
30
33
|
export declare function provide<T>(ctx: Context<T>, value: T): void;
|
package/dist/index.js
CHANGED
|
@@ -276,12 +276,30 @@ export function dyn(b, render) {
|
|
|
276
276
|
frag.appendChild(start);
|
|
277
277
|
frag.appendChild(end);
|
|
278
278
|
let current = null;
|
|
279
|
-
|
|
279
|
+
// Level-triggered: render the behavior's CURRENT value, not the delivered
|
|
280
|
+
// occurrence. A listener that runs earlier in the post phase may re-enter
|
|
281
|
+
// with a new moment (e.g. a router redirect); the stale queued delivery
|
|
282
|
+
// then must not clobber the newer render. Deduping by Object.is also makes
|
|
283
|
+
// duplicate deliveries free.
|
|
284
|
+
let hasRendered = false;
|
|
285
|
+
let renderedValue;
|
|
286
|
+
const update = () => {
|
|
287
|
+
const v = b.sampleNoTrans();
|
|
288
|
+
if (hasRendered && Object.is(renderedValue, v))
|
|
289
|
+
return;
|
|
290
|
+
hasRendered = true;
|
|
291
|
+
renderedValue = v;
|
|
280
292
|
if (current) {
|
|
281
293
|
current.dispose();
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
294
|
+
// Sweep the whole live range between the markers: a nested dynamic
|
|
295
|
+
// region at the root of this one may have swapped nodes since build,
|
|
296
|
+
// so the recorded node list can be stale.
|
|
297
|
+
let n = start.nextSibling;
|
|
298
|
+
while (n && n !== end) {
|
|
299
|
+
const next = n.nextSibling;
|
|
300
|
+
n.parentNode?.removeChild(n);
|
|
301
|
+
n = next;
|
|
302
|
+
}
|
|
285
303
|
}
|
|
286
304
|
current = buildScoped(owner, () => render(v));
|
|
287
305
|
const parent = end.parentNode;
|
|
@@ -386,6 +404,7 @@ export function each(items, key, render) {
|
|
|
386
404
|
});
|
|
387
405
|
return frag;
|
|
388
406
|
}
|
|
407
|
+
/** Create a context. Provide with `provide`, read with `use`. */
|
|
389
408
|
export function createContext(defaultValue) {
|
|
390
409
|
return { id: Symbol("context"), defaultValue };
|
|
391
410
|
}
|
|
@@ -480,6 +499,14 @@ export function animationFrames() {
|
|
|
480
499
|
}
|
|
481
500
|
// ---------------------------------------------------------------------------
|
|
482
501
|
// Control-flow components — JSX wrappers over the rendering helpers.
|
|
502
|
+
//
|
|
503
|
+
// The function/component pairing is a deliberate symmetry, not duplication:
|
|
504
|
+
// when(b, then, else) ↔ <Show when={b}> — conditional region
|
|
505
|
+
// dyn(b, render) ↔ <Dynamic of={b}> — switching subtree
|
|
506
|
+
// each(b, by, render) ↔ <Each of={b} by={..}> — keyed list
|
|
507
|
+
// portal(target, ch) ↔ <Portal mount={..}> — render elsewhere
|
|
508
|
+
// Functions compose in plain code (no JSX required); components read better
|
|
509
|
+
// inside markup. Both call the same implementation.
|
|
483
510
|
// ---------------------------------------------------------------------------
|
|
484
511
|
// JSX always delivers children as the rest array; a single render function
|
|
485
512
|
// arrives as `[fn]`. Normalize to a render callback.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@continuum-js/dom",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Continuum DOM renderer — fine-grained bindings, dynamic regions, ownership, context",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@continuum-js/frp": "0.3.
|
|
41
|
+
"@continuum-js/frp": "0.3.1"
|
|
42
42
|
}
|
|
43
43
|
}
|