@expressive/dom 0.2.0 → 0.4.0

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.js CHANGED
@@ -1,240 +1,11 @@
1
- import { a as untrack, c as release, d as transition, f as unschedule, i as track, l as schedule, n as latest, o as afterFlush, r as same, s as claim$1, u as settle$1 } from "./chunk-hot-gq8TyYJV.js";
2
- import { a as vnode, i as isVNode, n as childrenOf, r as createPortal, t as PORTAL } from "./chunk-vnode-CzmFSz5_.js";
1
+ import { a as untrack, c as dispose, d as claim$1, f as release, h as transition, i as track, l as enter, m as settle$1, n as latest, o as call, p as schedule, r as same, s as commit, u as afterFlush } from "./chunk-hot-9LhRiwFx.js";
2
+ import { a as createElement, i as childrenOf, n as PORTAL, o as isVNode, r as Portal, s as vnode, t as Fragment } from "./chunk-vnode-wpCWQ_Zg.js";
3
3
  import "./jsx-runtime.js";
4
- import { Component, Context, State, has, map, unbind } from "@expressive/mvc";
4
+ import { Component, Context, Model, has, map, unbind } from "@expressive/mvc";
5
5
  import { watch } from "@expressive/mvc/observable";
6
- import { Fragment } from "@expressive/mvc/runtime";
6
+ import { Fragment as Fragment$1 } from "@expressive/mvc/jsx-runtime";
7
7
 
8
- //#region src/adapter.ts
9
- let current;
10
- let collecting;
11
- function enter(scope, render) {
12
- const parent = current;
13
- const releases = collecting;
14
- const next = [];
15
- current = scope;
16
- collecting = next;
17
- scope.childContext = scope.context;
18
- scope.useIndex = 0;
19
- try {
20
- const output = render();
21
- if (scope.kind == "function" && scope.useIndex !== scope.uses.length) {
22
- if (!scope.hot) throw new Error("State.use() calls must keep the same order on every function-component render.");
23
- truncate(scope, scope.useIndex);
24
- }
25
- return output;
26
- } finally {
27
- scope.hot = void 0;
28
- current = parent;
29
- collecting = releases;
30
- scope.subscriptions.forEach((release) => release());
31
- scope.subscriptions = next;
32
- }
33
- }
34
- function dispose(scope) {
35
- scope.active = false;
36
- unschedule(scope);
37
- scope.subscriptions.forEach((release) => release());
38
- scope.subscriptions = [];
39
- truncate(scope, 0);
40
- }
41
- /** Destroy the `State.use()` slots of a scope from `index` on. */
42
- function truncate(scope, index) {
43
- for (let i = scope.uses.length - 1; i >= index; i--) {
44
- const slot = scope.uses[i];
45
- slot.release();
46
- if (typeof slot.cleanup == "function") slot.cleanup();
47
- slot.context.pop();
48
- slot.instance.set(null);
49
- }
50
- scope.uses.length = index;
51
- }
52
- function commit(scope) {
53
- for (const slot of scope.uses) if (!slot.mounted) {
54
- slot.mounted = true;
55
- slot.cleanup = slot.instance.mount?.();
56
- }
57
- }
58
- function requireScope() {
59
- if (!current) throw new Error("State.get() and State.use() may only run while @expressive/dom is rendering.");
60
- return current;
61
- }
62
- function tracked(target, required) {
63
- const scope = requireScope();
64
- let proxy = target;
65
- let first = true;
66
- const release = watch(target, (next) => {
67
- proxy = next;
68
- if (!first && scope.active) schedule(scope);
69
- first = false;
70
- }, required, transition);
71
- collecting.push(release);
72
- return proxy;
73
- }
74
- State.get = function get(argument) {
75
- const scope = requireScope();
76
- const instance = scope.childContext.get(this, argument === false ? false : true);
77
- if (!instance) return void 0;
78
- const proxy = tracked(instance, argument === true);
79
- if (typeof argument != "function") return proxy;
80
- const refresh = ((action) => {
81
- if (typeof action == "function") action = action();
82
- schedule(scope);
83
- return action instanceof Promise ? action.finally(() => schedule(scope)) : void 0;
84
- });
85
- return argument.call(proxy, proxy, refresh) ?? null;
86
- };
87
- State.use = function use(...args) {
88
- const scope = requireScope();
89
- if (scope.kind != "function") throw new Error("State.use() is only available at the top level of a function component.");
90
- const index = scope.useIndex++;
91
- let slot = scope.uses[index];
92
- if (slot && slot.Type !== this) {
93
- if (!scope.hot) throw new Error("State.use() calls must keep the same order on every function-component render.");
94
- truncate(scope, index);
95
- slot = void 0;
96
- }
97
- if (!slot) {
98
- let instance;
99
- const assign = (value) => typeof value == "object" && value && instance.set(value);
100
- let apply = (...values) => Promise.all(values.flat().map(assign));
101
- instance = new this((self) => {
102
- const own = self;
103
- if (typeof own.use == "function") {
104
- apply = own.use.bind(own);
105
- apply(...args);
106
- return;
107
- }
108
- return args;
109
- });
110
- const context = scope.childContext.push(instance);
111
- slot = {
112
- Type: this,
113
- context,
114
- instance,
115
- proxy: instance,
116
- release: void 0,
117
- apply
118
- };
119
- let first = true;
120
- slot.release = watch(instance, (proxy) => {
121
- slot.proxy = proxy;
122
- if (!first && scope.active) schedule(scope);
123
- first = false;
124
- }, void 0, transition);
125
- slot.apply = apply;
126
- scope.uses.push(slot);
127
- } else slot.apply(...args);
128
- scope.childContext = slot.context;
129
- return slot.proxy;
130
- };
131
- Object.defineProperty(Component, "use", {
132
- configurable: true,
133
- value() {
134
- throw new Error(`${this} is a Component - render it instead of calling use().`);
135
- }
136
- });
137
- Component.on({
138
- type(type) {
139
- subcomponents(type.prototype);
140
- },
141
- before(self) {
142
- subcomponents(self);
143
- }
144
- });
145
- function subcomponents(target) {
146
- for (const key of Object.getOwnPropertyNames(target)) {
147
- if (!/^[A-Z]/.test(key)) continue;
148
- const { value } = Object.getOwnPropertyDescriptor(target, key);
149
- if (typeof value != "function") continue;
150
- Object.defineProperty(target, key, {
151
- configurable: true,
152
- get() {
153
- const owner = this.is;
154
- let render = unbind(value);
155
- const Subcomponent = (props) => render.call(tracked(owner), props);
156
- Object.defineProperty(owner, key, {
157
- configurable: true,
158
- get: () => Subcomponent,
159
- set(next) {
160
- render = next;
161
- }
162
- });
163
- return Subcomponent;
164
- },
165
- set(next) {
166
- Object.defineProperty(this, key, {
167
- value: next,
168
- writable: true,
169
- enumerable: true,
170
- configurable: true
171
- });
172
- subcomponents(this);
173
- }
174
- });
175
- }
176
- }
177
-
178
- //#endregion
179
- //#region src/context.ts
180
- function Consumer(props) {
181
- return props.for.get((value) => props.children(value));
182
- }
183
- function Provider(_props) {
184
- throw new Error("Provider must be rendered by @expressive/dom.");
185
- }
186
- function provide(context, props) {
187
- const { for: input, is, children: _children, fallback: _fallback, name: _name, ...rest } = props;
188
- const mount = [];
189
- let single;
190
- const solo = State.is(input) || input instanceof State;
191
- context.set(input || {}, (state, owned) => {
192
- if (solo) single = state;
193
- is?.(state);
194
- if (owned) {
195
- let cleanup;
196
- mount.push(() => {
197
- cleanup = state.mount?.();
198
- });
199
- return () => cleanup?.();
200
- }
201
- });
202
- if (solo && !single) {
203
- const Type = input instanceof State ? input.constructor : input;
204
- single = context.get(Type, false);
205
- }
206
- if (single && Object.keys(rest).length) single.set(rest);
207
- return () => mount.forEach((commit) => commit());
208
- }
209
-
210
- //#endregion
211
- //#region src/lazy.ts
212
- function lazy(load) {
213
- let pending;
214
- let resolved;
215
- let rejected;
216
- let failed = false;
217
- return function Lazy(props) {
218
- if (failed) throw rejected;
219
- if (resolved) return vnode(resolved, props);
220
- if (!pending) pending = load().then((module) => {
221
- const output = typeof module == "function" ? module : module?.default;
222
- if (typeof output != "function") {
223
- failed = true;
224
- rejected = /* @__PURE__ */ new Error("lazy() loader resolved no component.");
225
- return;
226
- }
227
- resolved = output;
228
- }, (error) => {
229
- failed = true;
230
- rejected = error;
231
- });
232
- throw pending;
233
- };
234
- }
235
-
236
- //#endregion
237
- //#region src/css.ts
8
+ //#region src/style/css.ts
238
9
  const unitless = /* @__PURE__ */ new Map();
239
10
  let probe;
240
11
  /**
@@ -287,7 +58,7 @@ const css = {
287
58
  };
288
59
 
289
60
  //#endregion
290
- //#region src/appearance-protocol.ts
61
+ //#region src/style/protocol.ts
291
62
  const registrations = /* @__PURE__ */ new WeakMap();
292
63
  const tokens = /* @__PURE__ */ new WeakMap();
293
64
  let root;
@@ -334,7 +105,7 @@ function appearanceToken(value) {
334
105
  }
335
106
 
336
107
  //#endregion
337
- //#region src/appearance.ts
108
+ //#region src/style/appearance.ts
338
109
  const bases = /* @__PURE__ */ new WeakMap();
339
110
  const chains = /* @__PURE__ */ new WeakMap();
340
111
  const contexts = /* @__PURE__ */ new WeakMap();
@@ -561,7 +332,7 @@ function isObject(value) {
561
332
  }
562
333
 
563
334
  //#endregion
564
- //#region src/declarations.ts
335
+ //#region src/style/declarations.ts
565
336
  function applyDeclarations(style, declarations, previous = {}) {
566
337
  const target = style;
567
338
  for (const key of Object.keys({
@@ -580,7 +351,7 @@ function applyDeclarations(style, declarations, previous = {}) {
580
351
  }
581
352
 
582
353
  //#endregion
583
- //#region src/stylesheet.ts
354
+ //#region src/style/stylesheet.ts
584
355
  const sheets = /* @__PURE__ */ new WeakMap();
585
356
  function style(type, rules) {
586
357
  style$1(type, rules);
@@ -632,63 +403,48 @@ function serialize(document, declarations) {
632
403
  }
633
404
 
634
405
  //#endregion
635
- //#region src/render.ts
636
- const roots = /* @__PURE__ */ new WeakMap();
637
- const SVG = "http://www.w3.org/2000/svg";
638
- const dirty = /* @__PURE__ */ new Set();
639
- const stashes = /* @__PURE__ */ new WeakMap();
640
- const CONTROLS = ["checked", "value"];
641
- const ENUMERATED = [
642
- "contentEditable",
643
- "contenteditable",
644
- "draggable",
645
- "spellcheck"
646
- ];
647
- const ALIASES = {
648
- autoFocus: "autofocus",
649
- contentEditable: "contenteditable",
650
- htmlFor: "for"
651
- };
652
- const focusing = [];
653
- const controlled = /* @__PURE__ */ new WeakMap();
654
- const restoring = /* @__PURE__ */ new WeakSet();
655
- let passiveRender = false;
656
- let inserting;
657
- let depth = 0;
658
- let settling = false;
659
- let rendering;
660
- let touched = false;
661
- const observed = /* @__PURE__ */ new WeakMap();
662
- const tickets = /* @__PURE__ */ new WeakMap();
663
- function render(node, container) {
664
- roots.get(container)?.();
665
- container.replaceChildren();
666
- const context = new Context(Context.root);
667
- const fiber = range("fragment", container, null, context);
406
+ //#region src/render/commits.ts
407
+ const DETACHED = /* @__PURE__ */ new WeakMap();
408
+ let batch;
409
+ /** Run `run` once `fiber` is on the page: now, after the current batch, or when its detached root attaches. */
410
+ function inserted(fiber, run) {
411
+ enqueue([fiber, run]);
412
+ }
413
+ /** A fragment whose commits wait until it attaches. */
414
+ function fragment() {
415
+ const root = document.createDocumentFragment();
416
+ DETACHED.set(root, []);
417
+ return root;
418
+ }
419
+ function attach(root) {
420
+ const held = DETACHED.get(root);
421
+ DETACHED.delete(root);
422
+ held?.forEach(enqueue);
423
+ }
424
+ /** Defer commits made during `work` until it returns or throws. */
425
+ function batched(work) {
426
+ if (batch) return work();
427
+ const entries = batch = [];
668
428
  try {
669
- pass(() => {
670
- const appearanceContext = appearanceRoot();
671
- reconcile(fiber, node, context, void 0, appearanceContext ? {
672
- context: appearanceContext,
673
- entries: []
674
- } : void 0);
675
- });
676
- } catch (error) {
677
- unmountFiber(fiber);
678
- context.pop();
679
- throw error;
429
+ return work();
430
+ } finally {
431
+ batch = void 0;
432
+ entries.forEach(deliver);
680
433
  }
681
- let active = true;
682
- const unmount = () => {
683
- if (!active) return;
684
- active = false;
685
- unmountFiber(fiber);
686
- context.pop();
687
- roots.delete(container);
688
- };
689
- roots.set(container, unmount);
690
- return unmount;
691
434
  }
435
+ function enqueue(entry) {
436
+ if (batch) batch.push(entry);
437
+ else deliver(entry);
438
+ }
439
+ function deliver(entry) {
440
+ const [fiber, run] = entry;
441
+ const held = DETACHED.get(fiber.start.getRootNode());
442
+ if (held) held.push(entry);
443
+ else if (!fiber.dead) run();
444
+ }
445
+
446
+ //#endregion
447
+ //#region src/render/fiber.ts
692
448
  function range(kind, parent, before, context) {
693
449
  const start = document.createComment(kind);
694
450
  const end = document.createComment(`/${kind}`);
@@ -714,149 +470,37 @@ function makeScope(kind, context, update) {
714
470
  uses: []
715
471
  };
716
472
  }
717
- function complete(fiber, work) {
718
- try {
719
- work();
720
- } catch (error) {
721
- unmountFiber(fiber);
722
- throw error;
473
+ function moveRange(start, end, target) {
474
+ let node = start;
475
+ while (node) {
476
+ const next = node.nextSibling;
477
+ target.appendChild(node);
478
+ if (node === end) break;
479
+ node = next;
723
480
  }
724
- return fiber;
725
- }
726
- function componentProps(type, props, appearance) {
727
- const context = appearance?.context;
728
- if (!context || typeof type != "function") return {
729
- appearance,
730
- props
731
- };
732
- const value = context.resolve(props);
733
- const entries = appearance.entries;
734
- if (!value) return {
735
- appearance: { entries },
736
- props
737
- };
738
- return {
739
- appearance: {
740
- context: value.context,
741
- entries
742
- },
743
- props: {
744
- ...props,
745
- style: [createAppearanceToken(value), props.style]
746
- }
747
- };
748
481
  }
749
- function mount(value, parent, before, context, boundary, appearance) {
750
- if (typeof value == "string" || typeof value == "number" || typeof value == "bigint") {
751
- const text = document.createTextNode(String(value));
752
- parent.insertBefore(text, before);
753
- return {
754
- kind: "text",
755
- value,
756
- context,
757
- start: text,
758
- end: text,
759
- children: []
760
- };
482
+ function move(fiber, parent, before) {
483
+ if (fiber.start.parentNode === parent && fiber.end.nextSibling === before) return;
484
+ let node = fiber.start;
485
+ while (node) {
486
+ const next = node.nextSibling;
487
+ parent.insertBefore(node, before);
488
+ if (node === fiber.end) break;
489
+ node = next;
761
490
  }
762
- if (value instanceof Component) return mountComponent(value, parent, before, context, boundary, appearance);
763
- if (isCollection(value)) return mountCollection(value, parent, before, context, boundary, appearance);
764
- if (!isVNode(value)) throw new TypeError(`Cannot render ${String(value)}.`);
765
- if (value.type === Fragment) return mountFragment(value, parent, before, context, boundary, appearance);
766
- if (value.type === PORTAL) return mountPortal(value, parent, before, context, boundary, appearance);
767
- if (value.type === Provider) return mountProvider(value, parent, before, context, boundary, appearance);
768
- if (typeof value.type == "string") return mountElement(value, parent, before, context, boundary, appearance);
769
- if (typeof value.type != "function") throw new Error(`Cannot render ${String(value.type)}.`);
770
- if (value.type.prototype instanceof Component) return mountOwnedComponent(value, parent, before, context, boundary, appearance);
771
- return mountFunction(value, parent, before, context, boundary, appearance);
772
- }
773
- function mountFragment(value, parent, before, context, boundary, appearance) {
774
- const fiber = range("fragment", parent, before, context);
775
- fiber.key = value.key;
776
- fiber.type = Fragment;
777
- fiber.appearance = appearance;
778
- return complete(fiber, () => {
779
- reconcile(fiber, value.props.children, context, boundary, appearance);
780
- });
781
- }
782
- function mountFunction(value, parent, before, context, boundary, appearance) {
783
- const fiber = range("function", parent, before, context);
784
- const resolved = componentProps(value.type, value.props, appearance);
785
- fiber.key = value.key;
786
- fiber.type = value.type;
787
- fiber.props = observe(resolved.props);
788
- fiber.boundary = boundary;
789
- fiber.appearance = resolved.appearance;
790
- fiber.scope = makeScope("function", context, (passive) => runFunction(fiber, passive));
791
- fiber.render = () => enter(fiber.scope, () => latest(fiber.type)(fiber.props));
792
- track(fiber.type, fiber.scope);
793
- probing(fiber);
794
- return complete(fiber, () => {
795
- runFunction(fiber, passiveRender);
796
- });
797
- }
798
- function mountOwnedComponent(value, parent, before, context, boundary, appearance) {
799
- const resolved = componentProps(value.type, value.props, appearance);
800
- return mountComponent(new value.type(observe(resolved.props)), parent, before, context, boundary, resolved.appearance, true, value.key);
801
- }
802
- function runFunction(fiber, passive) {
803
- const result = attempt(fiber, passive, fiber.render);
804
- if (result === true) inserted(fiber, () => commit(fiber.scope));
805
- else return result;
806
- }
807
- function probing(fiber) {
808
- const scope = fiber.scope;
809
- scope.empty = () => !fiber.children.length;
810
- scope.probe = () => {
811
- try {
812
- scope.probed = { output: consume(fiber, fiber.render) };
813
- } catch (thrown) {
814
- if (isThenable(thrown)) return thrown;
815
- }
816
- };
817
- }
818
- function mountComponent(instance, parent, before, context, inherited, appearance, owned = false, key) {
819
- const fiber = range("component", parent, before, context);
820
- const childContext = context.push(instance);
821
- const ownBoundary = instance.fallback !== false || instance.catch ? {
822
- catch: instance.catch?.bind(instance),
823
- fallback: () => instance.fallback,
824
- owner: fiber,
825
- parent: inherited
826
- } : inherited;
827
- fiber.boundary = ownBoundary;
828
- if (ownBoundary !== inherited) fiber.ownBoundary = ownBoundary;
829
- fiber.childContext = childContext;
830
- fiber.instance = instance;
831
- fiber.key = owned ? key : instance.key;
832
- fiber.type = instance.constructor;
833
- fiber.props = instance.props;
834
- fiber.owned = owned;
835
- fiber.appearance = appearance;
836
- fiber.scope = makeScope("component", childContext, (passive) => runComponent(fiber, passive));
837
- fiber.render = () => enter(fiber.scope, () => instance.render.call(fiber.value, instance.props));
838
- probing(fiber);
839
- let first = true;
840
- let proxy = instance;
841
- fiber.release = watch(instance, (current, events) => {
842
- const { applied, scope } = fiber;
843
- proxy = current;
844
- fiber.applied = void 0;
845
- if (!first && scope.active) if (applied && events.includes("props")) transition(() => schedule(scope));
846
- else schedule(scope);
847
- first = false;
848
- }, void 0, transition);
849
- Object.defineProperty(fiber, "value", { get: () => proxy });
850
- complete(fiber, () => {
851
- runComponent(fiber, passiveRender);
852
- });
853
- if (owned) inserted(fiber, () => fiber.cleanup = instance.mount?.());
854
- return fiber;
855
491
  }
856
- function runComponent(fiber, passive) {
857
- const result = attempt(fiber, passive, fiber.render);
858
- if (result !== true) return result;
492
+ function removeRange(start, end) {
493
+ let node = start;
494
+ while (true) {
495
+ const next = node.nextSibling;
496
+ node.remove();
497
+ if (node === end) break;
498
+ node = next;
499
+ }
859
500
  }
501
+
502
+ //#endregion
503
+ //#region src/render/collection.ts
860
504
  function mountCollection(value, parent, before, context, boundary, appearance) {
861
505
  const fiber = range("collection", parent, before, context);
862
506
  fiber.source = value;
@@ -880,128 +524,159 @@ function runCollection(fiber, passive) {
880
524
  return value instanceof map.Managed ? [...value.values()] : [...value];
881
525
  });
882
526
  }
883
- function mountProvider(value, parent, before, context, inherited, appearance) {
884
- const fiber = range("provider", parent, before, context);
885
- const childContext = new Context(context);
886
- fiber.key = value.key;
887
- fiber.type = Provider;
888
- fiber.props = value.props;
527
+ function patchCollection(fiber, appearance) {
528
+ if (fiber.appearance === appearance) return;
889
529
  fiber.appearance = appearance;
890
- fiber.childContext = childContext;
891
- const commit = provide(childContext, value.props);
892
- const boundary = value.props.fallback !== void 0 ? {
893
- fallback: () => fiber.props.fallback,
894
- owner: fiber,
895
- parent: inherited
896
- } : inherited;
897
- fiber.boundary = boundary;
898
- if (boundary !== inherited) fiber.ownBoundary = boundary;
899
- complete(fiber, () => {
900
- reconcile(fiber, value.props.children, childContext, boundary, appearance);
530
+ runCollection(fiber, passiveRender);
531
+ }
532
+ function isCollection(value) {
533
+ return value instanceof has.List || value instanceof has.Pool || value instanceof map.Managed;
534
+ }
535
+
536
+ //#endregion
537
+ //#region src/node/loader.ts
538
+ const LOADS = /* @__PURE__ */ new WeakMap();
539
+ function resolve(type, props, run) {
540
+ const load = LOADS.get(type);
541
+ if (load?.resolved) return vnode(load.resolved, props);
542
+ if (load?.failed) {
543
+ LOADS.delete(type);
544
+ throw load.failed.error;
545
+ }
546
+ if (load) throw load.pending;
547
+ const output = run();
548
+ if (!output || typeof output.then != "function") return output;
549
+ const next = {};
550
+ LOADS.set(type, next);
551
+ throw next.pending = output.then((module) => {
552
+ const component = typeof module == "function" ? module : module?.default;
553
+ if (typeof component == "function") next.resolved = component;
554
+ else next.failed = { error: /* @__PURE__ */ new Error("Loader resolved no component.") };
555
+ }, (error) => {
556
+ next.failed = { error };
901
557
  });
902
- commit();
903
- return fiber;
904
558
  }
905
- function mountPortal(value, parent, before, context, boundary, appearance) {
906
- const marker = document.createComment("portal");
907
- const container = value.props.container;
908
- const portalStart = document.createComment("portal-root");
909
- const portalEnd = document.createComment("/portal-root");
910
- parent.insertBefore(marker, before);
911
- container.append(portalStart, portalEnd);
912
- const output = {
913
- kind: "portal",
914
- key: value.key,
915
- type: PORTAL,
916
- props: value.props,
917
- context,
918
- boundary,
559
+
560
+ //#endregion
561
+ //#region src/style/claim.ts
562
+ const tickets = /* @__PURE__ */ new WeakMap();
563
+ function componentProps(type, props, appearance) {
564
+ const context = appearance?.context;
565
+ if (!context || typeof type != "function") return {
919
566
  appearance,
920
- start: marker,
921
- end: marker,
922
- children: [],
923
- portalContainer: container,
924
- portalStart,
925
- portalEnd
567
+ props
568
+ };
569
+ const value = context.resolve(props);
570
+ const entries = appearance.entries;
571
+ if (!value) return {
572
+ appearance: { entries },
573
+ props
574
+ };
575
+ return {
576
+ appearance: {
577
+ context: value.context,
578
+ entries
579
+ },
580
+ props: {
581
+ ...props,
582
+ style: [createAppearanceToken(value), props.style]
583
+ }
926
584
  };
927
- return complete(output, () => {
928
- reconcilePortal(output, value.props.children, context, boundary, appearance);
929
- });
930
585
  }
931
- function mountElement(value, parent, before, context, boundary, appearance) {
932
- const tag = value.type;
933
- let host = parent;
934
- for (let owner = stashes.get(host); owner; owner = stashes.get(host)) host = owner.end.parentNode;
935
- const element = (tag == "svg" || host instanceof SVGElement && host.localName != "foreignObject" ? SVG : void 0) ? document.createElementNS(SVG, tag) : document.createElement(tag);
936
- const fiber = {
937
- kind: "element",
938
- key: value.key,
939
- type: tag,
940
- props: {},
941
- context,
942
- boundary,
943
- start: element,
944
- end: element,
945
- children: [],
946
- events: /* @__PURE__ */ new Map()
586
+ function door(value) {
587
+ const collected = {
588
+ classes: [],
589
+ declarations: {},
590
+ tokens: []
947
591
  };
948
- parent.insertBefore(element, before);
949
- complete(fiber, () => {
950
- patchProps(fiber, value.props, appearance);
592
+ const { classes, declarations, tokens } = collected;
593
+ collect(value, collected, 1);
594
+ if (!classes.length && !tokens.length && !Object.keys(declarations).length) return void 0;
595
+ const key = Object.freeze({});
596
+ tickets.set(key, {
597
+ classes,
598
+ tokens
599
+ });
600
+ return Object.freeze({
601
+ ...declarations,
602
+ [Symbol("style")]: key
951
603
  });
952
- if (value.props.autofocus || value.props.autoFocus) focusing.push(element);
953
- return fiber;
954
604
  }
955
- function pass(work) {
956
- depth++;
957
- try {
958
- return work();
959
- } finally {
960
- if (!--depth) {
961
- settle();
962
- focus();
605
+ function claim(element, appearance, resolved, className, value) {
606
+ const collected = {
607
+ classes: [],
608
+ declarations: {},
609
+ tokens: []
610
+ };
611
+ const entries = appearance?.entries || [];
612
+ let context = appearance?.context;
613
+ let reach = -1;
614
+ if (resolved) collect(createAppearanceToken(resolved), collected, 0);
615
+ appendClasses(collected.classes, className);
616
+ collect(value, collected, 0);
617
+ for (let index = entries.length - 1; index >= 0; index--) collect(entries[index].style, collected, entries[index].hops);
618
+ for (const { appearance, doors } of collected.tokens) {
619
+ for (const block of appearance.blocks || []) collected.classes.push(emitClass(block, doors, element.ownerDocument));
620
+ if (appearance.classes) collected.classes.push(...appearance.classes);
621
+ if (appearance.context && doors >= reach) {
622
+ context = appearance.context;
623
+ reach = doors;
963
624
  }
964
625
  }
626
+ return {
627
+ className: [...new Set(collected.classes)].join(" "),
628
+ context,
629
+ declarations: collected.declarations
630
+ };
965
631
  }
966
- function focus() {
967
- for (const element of focusing.splice(0)) if (element.isConnected) element.focus();
632
+ function applyClaim(element, before, after) {
633
+ const previous = before || {
634
+ className: "",
635
+ declarations: {}
636
+ };
637
+ if (previous.className !== after.className) if (after.className) element.setAttribute("class", after.className);
638
+ else element.removeAttribute("class");
639
+ applyDeclarations(element.style, after.declarations, previous.declarations);
968
640
  }
969
- function attempt(fiber, passive, render) {
970
- const previous = passiveRender;
971
- const scope = fiber.scope;
972
- const probed = scope.probed;
973
- scope.probed = void 0;
974
- passiveRender ||= passive;
975
- if (passive && !depth && !fiber.children.length && !fiber.stash) fiber.staging ||= document.createDocumentFragment();
976
- const outer = inserting;
977
- if (fiber.staging) inserting = fiber.inserted ||= [];
978
- try {
979
- return pass(() => {
980
- try {
981
- reconcile(fiber, probed ? probed.output : consume(fiber, render), scope.childContext, fiber.boundary, renderedAppearance(fiber));
982
- if (fiber.staging) {
983
- const queued = fiber.inserted;
984
- fiber.end.parentNode.insertBefore(fiber.staging, fiber.end);
985
- fiber.staging = fiber.inserted = void 0;
986
- inserting = outer;
987
- queued.forEach((run) => run());
988
- }
989
- if (!fiber.recovering) unwait(fiber);
990
- fiber.retried = void 0;
991
- return true;
992
- } catch (thrown) {
993
- return suspend(fiber, thrown, passive);
994
- }
641
+ function collect(value, collected, doors) {
642
+ if (!value) return;
643
+ const token = appearanceToken(value);
644
+ if (token) {
645
+ collected.tokens.push({
646
+ appearance: token,
647
+ doors
995
648
  });
996
- } finally {
997
- passiveRender = previous;
998
- inserting = outer;
649
+ Object.assign(collected.declarations, token.declarations);
650
+ return;
651
+ }
652
+ if (typeof value == "string") {
653
+ appendClasses(collected.classes, value);
654
+ return;
999
655
  }
656
+ if (Array.isArray(value)) {
657
+ value.forEach((entry) => collect(entry, collected, doors));
658
+ return;
659
+ }
660
+ for (const symbol of Object.getOwnPropertySymbols(value)) {
661
+ const ticket = tickets.get(value[symbol]);
662
+ if (!ticket) continue;
663
+ collected.classes.push(...ticket.classes);
664
+ for (const carried of ticket.tokens) collected.tokens.push({
665
+ appearance: carried.appearance,
666
+ doors: carried.doors + doors
667
+ });
668
+ }
669
+ for (const key of Object.keys(value)) collected.declarations[key] = value[key];
1000
670
  }
1001
- function inserted(fiber, run) {
1002
- if (inserting) inserting.push(() => fiber.dead || run());
1003
- else run();
671
+ function appendClasses(classes, value) {
672
+ if (typeof value == "string") classes.push(...value.split(/\s+/).filter(Boolean));
1004
673
  }
674
+
675
+ //#endregion
676
+ //#region src/render/style.ts
677
+ let rendering;
678
+ let touched = false;
679
+ const observed = /* @__PURE__ */ new WeakMap();
1005
680
  function observe(props) {
1006
681
  if (!("style" in props)) return props;
1007
682
  let output = observed.get(props);
@@ -1024,25 +699,6 @@ function observe(props) {
1024
699
  }
1025
700
  return output;
1026
701
  }
1027
- function door(value) {
1028
- const collected = {
1029
- classes: [],
1030
- declarations: {},
1031
- tokens: []
1032
- };
1033
- const { classes, declarations, tokens } = collected;
1034
- collect(value, collected, 1);
1035
- if (!classes.length && !tokens.length && !Object.keys(declarations).length) return void 0;
1036
- const key = Object.freeze({});
1037
- tickets.set(key, {
1038
- classes,
1039
- tokens
1040
- });
1041
- return Object.freeze({
1042
- ...declarations,
1043
- [Symbol("style")]: key
1044
- });
1045
- }
1046
702
  function consume(fiber, render) {
1047
703
  const previous = rendering;
1048
704
  const read = touched;
@@ -1057,258 +713,68 @@ function consume(fiber, render) {
1057
713
  touched = read;
1058
714
  }
1059
715
  }
1060
- function wait(fiber, boundary) {
1061
- if (fiber.waitingOn !== boundary) unwait(fiber);
1062
- fiber.waitingOn = boundary;
1063
- (boundary.waiting ||= /* @__PURE__ */ new Set()).add(fiber);
1064
- dirty.add(boundary);
1065
- }
1066
- function unwait(fiber) {
1067
- const boundary = fiber.waitingOn;
1068
- if (!boundary) return;
1069
- fiber.waitingOn = void 0;
1070
- boundary.waiting.delete(fiber);
1071
- if (!boundary.owner.dead) dirty.add(boundary);
1072
- }
1073
- function settle() {
1074
- if (settling) return;
1075
- settling = true;
1076
- try {
1077
- for (const boundary of dirty) {
1078
- dirty.delete(boundary);
1079
- const owner = boundary.owner;
1080
- const waiting = boundary.waiting.size > 0;
1081
- if (!owner.dead && waiting != !!owner.stash) waiting ? hide(owner, boundary) : reveal(owner);
1082
- }
1083
- } finally {
1084
- settling = false;
1085
- }
1086
- }
1087
- function hide(owner, boundary) {
1088
- const stash = document.createDocumentFragment();
1089
- for (const child of owner.children) move(child, stash, null);
1090
- owner.portals = portals(owner, []).map((portal) => {
1091
- const content = document.createDocumentFragment();
1092
- moveRange(portal.portalStart, portal.portalEnd, content);
1093
- return [portal, content];
716
+ function renderedAppearance(fiber) {
717
+ if (fiber.kind != "component" && fiber.kind != "function") return fiber.appearance;
718
+ const style = fiber.props?.style;
719
+ const entries = (fiber.appearance?.entries || []).map(({ hops, style }) => ({
720
+ hops: hops + 1,
721
+ style
722
+ }));
723
+ const inherited = fiber.appearance?.context || appearanceRoot();
724
+ const context = enterAppearance(inherited, latest(fiber.type));
725
+ if (context?.base && context !== inherited) entries.push({
726
+ hops: 0,
727
+ style: context.base
1094
728
  });
1095
- stashes.set(stash, owner);
1096
- const context = owner.childContext;
1097
- const placeholder = range("fragment", owner.end.parentNode, owner.end, context);
1098
- owner.stash = stash;
1099
- owner.placeholder = placeholder;
1100
- reconcile(placeholder, boundary.fallback(), context, boundary.parent);
1101
- }
1102
- function reveal(owner) {
1103
- unmountFiber(owner.placeholder);
1104
- owner.end.parentNode.insertBefore(owner.stash, owner.end);
1105
- for (const [portal, content] of owner.portals) if (!portal.dead) portal.portalContainer.append(content);
1106
- owner.portals = void 0;
1107
- owner.placeholder = void 0;
1108
- owner.stash = void 0;
1109
- }
1110
- function portals(fiber, found) {
1111
- for (const child of fiber.children) {
1112
- if (child.kind == "portal") found.push(child);
1113
- portals(child, found);
1114
- }
1115
- return found;
1116
- }
1117
- function moveRange(start, end, target) {
1118
- let node = start;
1119
- while (node) {
1120
- const next = node.nextSibling;
1121
- target.appendChild(node);
1122
- if (node === end) break;
1123
- node = next;
1124
- }
1125
- }
1126
- function suspend(fiber, thrown, passive) {
1127
- const boundary = fiber.boundary;
1128
- if (isThenable(thrown)) {
1129
- if (!boundary) throw thrown;
1130
- if (passive && !fiber.children.length && depth > 1) throw thrown;
1131
- if (!passive) wait(fiber, boundary);
1132
- const scope = fiber.scope;
1133
- let held = scope.holds;
1134
- scope.holds = void 0;
1135
- const clear = () => {
1136
- fiber.suspended.delete(clear);
1137
- release(held);
1138
- held = void 0;
1139
- };
1140
- (fiber.suspended ||= /* @__PURE__ */ new Set()).add(clear);
1141
- const resume = (retry) => {
1142
- fiber.suspended.delete(clear);
1143
- if (!scope.active) return clear();
1144
- if (held) (scope.holds ||= []).push(...held);
1145
- held = void 0;
1146
- retry();
1147
- };
1148
- thrown.then(() => resume(() => passive ? transition(() => schedule(scope)) : schedule(scope)), (error) => resume(() => pass(() => recover(fiber, error, fiber.boundary))));
1149
- return thrown;
1150
- }
1151
- recover(fiber, thrown, fiber.boundary);
1152
- }
1153
- function recover(fiber, thrown, boundary) {
1154
- const error = thrown instanceof Error ? thrown : new Error(String(thrown));
1155
- while (boundary && !boundary.catch) boundary = boundary.parent;
1156
- if (!boundary) throw error;
1157
- const handler = boundary;
1158
- const token = {};
1159
- wait(fiber, handler);
1160
- fiber.recovering = token;
1161
- Promise.resolve(handler.catch(error)).then(() => {
1162
- if (fiber.recovering !== token) return;
1163
- fiber.recovering = void 0;
1164
- if (!fiber.scope.active || fiber.retried) return;
1165
- fiber.retried = true;
1166
- schedule(fiber.scope);
1167
- }, (next) => {
1168
- if (fiber.recovering === token && fiber.scope.active) pass(() => recover(fiber, next, handler.parent));
729
+ if (style && !fiber.consumed && !(fiber.instance && "style" in fiber.instance)) entries.push({
730
+ hops: 0,
731
+ style
1169
732
  });
733
+ return entries.length || context ? {
734
+ context,
735
+ entries
736
+ } : void 0;
1170
737
  }
1171
- function isThenable(value) {
1172
- return !!value && typeof value.then == "function";
1173
- }
1174
- function reconcile(fiber, value, context, boundary, appearance) {
1175
- const detached = fiber.stash || fiber.staging;
1176
- if (detached) reconcileChildren(fiber, detached, null, value, context, boundary, appearance);
1177
- else reconcileChildren(fiber, fiber.end.parentNode, fiber.end, value, context, boundary, appearance);
1178
- }
1179
- function reconcilePortal(fiber, value, context, boundary, appearance) {
1180
- reconcileChildren(fiber, fiber.portalEnd.parentNode, fiber.portalEnd, value, context, boundary, appearance);
1181
- }
1182
- function reconcileChildren(owner, parent, before, value, context, boundary, appearance) {
1183
- const values = childrenOf(value);
1184
- const old = owner.children;
1185
- const keyed = /* @__PURE__ */ new Map();
1186
- const used = /* @__PURE__ */ new Set();
1187
- const next = [];
1188
- for (const child of old) if (child.key !== null && child.key !== void 0) keyed.set(child.key, child);
1189
- try {
1190
- for (let index = 0; index < values.length; index++) {
1191
- const value = source(values[index]);
1192
- const key = keyOf(value);
1193
- let child = key !== null && key !== void 0 ? keyed.get(key) : old[index]?.key == null ? old[index] : void 0;
1194
- if (child && used.has(child)) child = void 0;
1195
- if (child) used.add(child);
1196
- next.push(patch(child, value, parent, before, context, boundary, appearance));
1197
- }
1198
- } catch (error) {
1199
- owner.children = [...next, ...old.filter((child) => !child.dead && !next.includes(child))];
1200
- throw error;
1201
- }
1202
- for (const child of old) if (!used.has(child)) unmountFiber(child);
1203
- let anchor = before;
1204
- for (let index = next.length - 1; index >= 0; index--) {
1205
- move(next[index], parent, anchor);
1206
- anchor = next[index].start;
1207
- }
1208
- owner.children = next;
1209
- }
1210
- function patch(old, value, parent, before, context, boundary, appearance) {
1211
- if (!old || !compatible(old, value)) {
1212
- const next = mount(value, parent, old?.start || before, context, boundary, appearance);
1213
- if (old) unmountFiber(old);
1214
- return next;
1215
- }
1216
- if (old.ownBoundary) old.ownBoundary.parent = boundary;
1217
- old.boundary = old.ownBoundary || boundary;
1218
- if (old.kind == "collection") {
1219
- if (old.appearance !== appearance) {
1220
- old.appearance = appearance;
1221
- runCollection(old, passiveRender);
1222
- }
1223
- return old;
1224
- }
1225
- if (old.kind == "text") {
1226
- const next = String(value);
1227
- if (old.start.nodeValue !== next) old.start.nodeValue = next;
1228
- old.value = value;
1229
- } else if (old.kind == "element") patchProps(old, value.props, appearance);
1230
- else if (old.kind == "fragment") {
1231
- old.context = context;
1232
- old.appearance = appearance;
1233
- reconcile(old, value.props.children, context, old.boundary, appearance);
1234
- } else if (old.kind == "function") {
1235
- const vnode = value;
1236
- const resolved = componentProps(vnode.type, vnode.props, appearance);
1237
- if (old.type !== vnode.type) {
1238
- untrack(old.type, old.scope);
1239
- old.type = vnode.type;
1240
- old.scope.hot = true;
1241
- track(old.type, old.scope);
1242
- }
1243
- old.appearance = resolved.appearance;
1244
- old.props = observe(resolved.props);
1245
- rerun(old, () => runFunction(old, passiveRender));
1246
- } else if (old.kind == "component") {
1247
- const resolved = isVNode(value) ? componentProps(value.type, value.props, appearance) : {
1248
- appearance,
1249
- props: old.instance.props
1250
- };
1251
- old.appearance = resolved.appearance;
1252
- const props = isVNode(value) ? observe(resolved.props) : resolved.props;
1253
- if (isVNode(value) && props !== old.instance.props) {
1254
- if (passiveRender) old.applied = true;
1255
- old.instance.props = props;
1256
- }
1257
- old.props = props;
1258
- rerun(old, () => runComponent(old, passiveRender));
1259
- } else if (old.kind == "provider") {
1260
- old.appearance = appearance;
1261
- old.props = value.props;
1262
- const commit = provide(old.childContext, old.props);
1263
- reconcile(old, old.props.children, old.childContext, old.boundary, appearance);
1264
- commit();
1265
- } else {
1266
- old.appearance = appearance;
1267
- const vnode = value;
1268
- old.props = vnode.props;
1269
- reconcilePortal(old, vnode.props.children, context, old.boundary, appearance);
1270
- }
1271
- return old;
1272
- }
1273
- function rerun(fiber, run) {
1274
- claim$1(fiber.scope);
1275
- run();
1276
- settle$1(fiber.scope);
1277
- }
1278
- function compatible(fiber, value) {
1279
- if (fiber.kind == "text") return [
1280
- "string",
1281
- "number",
1282
- "bigint"
1283
- ].includes(typeof value);
1284
- if (value instanceof Component) return fiber.kind == "component" && fiber.instance === value;
1285
- if (isCollection(value)) return fiber.kind == "collection" && fiber.source === value;
1286
- if (!isVNode(value)) return false;
1287
- if (fiber.key !== value.key || !same(fiber.type, value.type)) return false;
1288
- if (fiber.kind == "portal") return fiber.portalContainer === value.props.container;
1289
- return true;
1290
- }
1291
- function source(value) {
1292
- if (value instanceof Component) return value.is;
1293
- while (isCollection(value) && isCollection(Object.getPrototypeOf(value))) value = Object.getPrototypeOf(value);
1294
- return value;
1295
- }
1296
- function isCollection(value) {
1297
- return value instanceof has.List || value instanceof has.Pool || value instanceof map.Managed;
1298
- }
1299
- function keyOf(value) {
1300
- if (value instanceof Component) return value.key;
1301
- return isVNode(value) ? value.key : void 0;
1302
- }
1303
- function move(fiber, parent, before) {
1304
- if (fiber.start.parentNode === parent && fiber.end.nextSibling === before) return;
1305
- let node = fiber.start;
1306
- while (node) {
1307
- const next = node.nextSibling;
1308
- parent.insertBefore(node, before);
1309
- if (node === fiber.end) break;
1310
- node = next;
1311
- }
738
+
739
+ //#endregion
740
+ //#region src/render/element.ts
741
+ const SVG = "http://www.w3.org/2000/svg";
742
+ const CONTROLS = ["checked", "value"];
743
+ const ENUMERATED = [
744
+ "contentEditable",
745
+ "contenteditable",
746
+ "draggable",
747
+ "spellcheck"
748
+ ];
749
+ const ALIASES = {
750
+ autoFocus: "autofocus",
751
+ contentEditable: "contenteditable",
752
+ htmlFor: "for"
753
+ };
754
+ const controlled = /* @__PURE__ */ new WeakMap();
755
+ const restoring = /* @__PURE__ */ new WeakSet();
756
+ function mountElement(value, parent, before, context, boundary, appearance) {
757
+ const tag = value.type;
758
+ const host = hostOf(parent);
759
+ const element = (tag == "svg" || host instanceof SVGElement && host.localName != "foreignObject" ? SVG : void 0) ? document.createElementNS(SVG, tag) : document.createElement(tag);
760
+ const fiber = {
761
+ kind: "element",
762
+ key: value.key,
763
+ type: tag,
764
+ props: {},
765
+ context,
766
+ boundary,
767
+ start: element,
768
+ end: element,
769
+ children: [],
770
+ events: /* @__PURE__ */ new Map()
771
+ };
772
+ parent.insertBefore(element, before);
773
+ complete(fiber, () => {
774
+ patchProps(fiber, value.props, appearance);
775
+ });
776
+ if (value.props.autofocus || value.props.autoFocus) focusing.push(element);
777
+ return fiber;
1312
778
  }
1313
779
  function patchProps(fiber, next, appearance) {
1314
780
  const element = fiber.start;
@@ -1395,124 +861,505 @@ function patchProp(fiber, element, key, previous, next) {
1395
861
  } catch {}
1396
862
  element.setAttribute(name, next === true ? "" : String(next));
1397
863
  }
1398
- function applyClaim(element, before, after) {
1399
- const previous = before || {
1400
- className: "",
1401
- declarations: {}
1402
- };
1403
- if (previous.className !== after.className) if (after.className) element.setAttribute("class", after.className);
1404
- else element.removeAttribute("class");
1405
- applyDeclarations(element.style, after.declarations, previous.declarations);
864
+ function restoreTarget(event) {
865
+ const element = event.target;
866
+ const fiber = controlled.get(element);
867
+ if (fiber && event.type == settles(fiber.props, element)) queueMicrotask(() => afterFlush(() => restore(fiber)));
1406
868
  }
1407
- function claim(element, appearance, resolved, className, value) {
1408
- const collected = {
1409
- classes: [],
1410
- declarations: {},
1411
- tokens: []
1412
- };
1413
- const entries = appearance?.entries || [];
1414
- let context = appearance?.context;
1415
- let reach = -1;
1416
- if (resolved) collect(createAppearanceToken(resolved), collected, 0);
1417
- appendClasses(collected.classes, className);
1418
- collect(value, collected, 0);
1419
- for (let index = entries.length - 1; index >= 0; index--) collect(entries[index].style, collected, entries[index].hops);
1420
- for (const { appearance, doors } of collected.tokens) {
1421
- for (const block of appearance.blocks || []) collected.classes.push(emitClass(block, doors, element.ownerDocument));
1422
- if (appearance.classes) collected.classes.push(...appearance.classes);
1423
- if (appearance.context && doors >= reach) {
1424
- context = appearance.context;
1425
- reach = doors;
1426
- }
869
+ function settles(props, element) {
870
+ if (props.onInput) return "input";
871
+ if (props.onChange) return "change";
872
+ return element.type == "checkbox" || element.type == "radio" || element.localName == "select" ? "change" : "input";
873
+ }
874
+ function restore(fiber) {
875
+ const element = fiber.start;
876
+ for (const key of CONTROLS) {
877
+ const value = fiber.props[key];
878
+ if (value == null || fiber.dead) continue;
879
+ if (key == "value" ? String(element.value) !== String(value) : element[key] !== value) element[key] = value;
1427
880
  }
1428
- return {
1429
- className: [...new Set(collected.classes)].join(" "),
1430
- context,
1431
- declarations: collected.declarations
1432
- };
1433
881
  }
1434
- function renderedAppearance(fiber) {
1435
- if (fiber.kind != "component" && fiber.kind != "function") return fiber.appearance;
1436
- const style = fiber.props?.style;
1437
- const entries = (fiber.appearance?.entries || []).map(({ hops, style }) => ({
1438
- hops: hops + 1,
1439
- style
1440
- }));
1441
- const inherited = fiber.appearance?.context || appearanceRoot();
1442
- const context = enterAppearance(inherited, latest(fiber.type));
1443
- if (context?.base && context !== inherited) entries.push({
1444
- hops: 0,
1445
- style: context.base
1446
- });
1447
- if (style && !fiber.consumed && !(fiber.instance && "style" in fiber.instance)) entries.push({
1448
- hops: 0,
1449
- style
1450
- });
1451
- return entries.length || context ? {
882
+ function settable(element, key) {
883
+ let target = element;
884
+ let descriptor;
885
+ while (!(descriptor = Object.getOwnPropertyDescriptor(target, key))) target = Object.getPrototypeOf(target);
886
+ return !!(descriptor.set || descriptor.writable);
887
+ }
888
+ function applyRef(ref, value) {
889
+ if (typeof ref == "function") ref(value);
890
+ else if (ref && typeof ref == "object" && "current" in ref) ref.current = value;
891
+ }
892
+ function unmountElement(fiber) {
893
+ applyRef(fiber.props?.ref, null);
894
+ for (const [id, listener] of fiber.events) {
895
+ const [name, capture] = id.split(":");
896
+ fiber.start.removeEventListener(name, listener, capture === "true");
897
+ }
898
+ }
899
+
900
+ //#endregion
901
+ //#region src/render/portal.ts
902
+ function mountPortal(value, parent, before, context, boundary, appearance) {
903
+ const marker = document.createComment("portal");
904
+ const container = target(value.props.into, parent);
905
+ const portalStart = document.createComment("portal-root");
906
+ const portalEnd = document.createComment("/portal-root");
907
+ parent.insertBefore(marker, before);
908
+ container.append(portalStart, portalEnd);
909
+ const output = {
910
+ kind: "portal",
911
+ key: value.key,
912
+ type: PORTAL,
913
+ props: value.props,
1452
914
  context,
1453
- entries
1454
- } : void 0;
915
+ boundary,
916
+ appearance,
917
+ start: marker,
918
+ end: marker,
919
+ children: [],
920
+ portalContainer: container,
921
+ portalStart,
922
+ portalEnd
923
+ };
924
+ return complete(output, () => {
925
+ reconcilePortal(output, value.props.children, context, boundary, appearance);
926
+ });
1455
927
  }
1456
- function collect(value, collected, doors) {
1457
- if (!value) return;
1458
- const token = appearanceToken(value);
1459
- if (token) {
1460
- collected.tokens.push({
1461
- appearance: token,
1462
- doors
1463
- });
1464
- Object.assign(collected.declarations, token.declarations);
1465
- return;
928
+ function target(into, parent) {
929
+ if (typeof into != "string") return into;
930
+ const root = parent.getRootNode();
931
+ const found = [...document.querySelectorAll(into)];
932
+ if (root instanceof DocumentFragment) found.push(...root.querySelectorAll(into));
933
+ if (found.length != 1) throw new Error(`Portal target "${into}" ${found.length ? "is ambiguous" : "was not found"}.`);
934
+ return found[0];
935
+ }
936
+ function reconcilePortal(fiber, value, context, boundary, appearance) {
937
+ reconcileChildren(fiber, fiber.portalEnd.parentNode, fiber.portalEnd, value, context, boundary, appearance);
938
+ }
939
+ function patchPortal(fiber, value, context, appearance) {
940
+ fiber.appearance = appearance;
941
+ fiber.props = value.props;
942
+ reconcilePortal(fiber, value.props.children, context, fiber.boundary, appearance);
943
+ }
944
+ function unmountPortal(fiber) {
945
+ fiber.portalStart.remove();
946
+ fiber.portalEnd.remove();
947
+ }
948
+
949
+ //#endregion
950
+ //#region src/render/reconcile.ts
951
+ function reconcile(fiber, value, context, boundary, appearance) {
952
+ const detached = fiber.stash || fiber.staging;
953
+ if (detached) reconcileChildren(fiber, detached, null, value, context, boundary, appearance);
954
+ else reconcileChildren(fiber, fiber.end.parentNode, fiber.end, value, context, boundary, appearance);
955
+ }
956
+ function reconcileChildren(owner, parent, before, value, context, boundary, appearance) {
957
+ const values = childrenOf(value);
958
+ const old = owner.children;
959
+ const keyed = /* @__PURE__ */ new Map();
960
+ const used = /* @__PURE__ */ new Set();
961
+ const next = [];
962
+ for (const child of old) if (child.key !== null && child.key !== void 0) keyed.set(child.key, child);
963
+ try {
964
+ for (let index = 0; index < values.length; index++) {
965
+ const value = source(values[index]);
966
+ const key = keyOf(value);
967
+ let child = key !== null && key !== void 0 ? keyed.get(key) : old[index]?.key == null ? old[index] : void 0;
968
+ if (child && used.has(child)) child = void 0;
969
+ if (child) used.add(child);
970
+ const fiber = patch(child, value, parent, before, context, boundary, appearance);
971
+ if (fiber !== child) used.delete(child);
972
+ next.push(fiber);
973
+ }
974
+ } catch (error) {
975
+ gather(error, next, old);
976
+ owner.children = [...next, ...old.filter((child) => !child.dead && !next.includes(child))];
977
+ throw error;
1466
978
  }
1467
- if (typeof value == "string") {
1468
- appendClasses(collected.classes, value);
1469
- return;
979
+ for (const child of old) if (!used.has(child)) unmountFiber(child);
980
+ let anchor = before;
981
+ for (let index = next.length - 1; index >= 0; index--) {
982
+ const child = next[index];
983
+ const root = child.start.getRootNode();
984
+ move(child, parent, anchor);
985
+ anchor = child.start;
986
+ if (child.start.getRootNode() !== root) attach(root);
1470
987
  }
1471
- if (Array.isArray(value)) {
1472
- value.forEach((entry) => collect(entry, collected, doors));
1473
- return;
988
+ owner.children = next;
989
+ }
990
+ function patch(old, value, parent, before, context, boundary, appearance) {
991
+ if (!old || !compatible(old, value)) return mount(value, parent, old?.start || before, context, boundary, appearance);
992
+ if (old.ownBoundary) old.ownBoundary.parent = boundary;
993
+ old.boundary = old.ownBoundary || boundary;
994
+ if (old.kind == "collection") patchCollection(old, appearance);
995
+ else if (old.kind == "text") patchText(old, value);
996
+ else if (old.kind == "element") patchProps(old, value.props, appearance);
997
+ else if (old.kind == "fragment") patchFragment(old, value, context, appearance);
998
+ else if (old.kind == "function") patchFunction(old, value, appearance);
999
+ else if (old.kind == "component") patchComponent(old, value, appearance);
1000
+ else patchPortal(old, value, context, appearance);
1001
+ return old;
1002
+ }
1003
+ function compatible(fiber, value) {
1004
+ if (fiber.kind == "text") return [
1005
+ "string",
1006
+ "number",
1007
+ "bigint"
1008
+ ].includes(typeof value);
1009
+ if (renderable(value)) return fiber.kind == "component" && fiber.instance === value;
1010
+ if (isCollection(value)) return fiber.kind == "collection" && fiber.source === value;
1011
+ if (!isVNode(value)) return false;
1012
+ if (fiber.key !== value.key || !same(fiber.type, value.type)) return false;
1013
+ if (fiber.kind == "portal") return fiber.props.into === value.props.into;
1014
+ return true;
1015
+ }
1016
+ function source(value) {
1017
+ if (value instanceof Model) return value.is;
1018
+ while (isCollection(value) && isCollection(Object.getPrototypeOf(value))) value = Object.getPrototypeOf(value);
1019
+ return value;
1020
+ }
1021
+ function keyOf(value) {
1022
+ if (renderable(value)) return value.key;
1023
+ return isVNode(value) ? value.key : void 0;
1024
+ }
1025
+
1026
+ //#endregion
1027
+ //#region src/render/suspense.ts
1028
+ const dirty = /* @__PURE__ */ new Set();
1029
+ const stashes = /* @__PURE__ */ new WeakMap();
1030
+ let holding;
1031
+ let settling = false;
1032
+ function park(fiber) {
1033
+ move(fiber, fragment(), null);
1034
+ }
1035
+ function hold(fiber, error) {
1036
+ if (!holding || error !== holding.thrown) return false;
1037
+ park(fiber);
1038
+ holding.fiber = fiber;
1039
+ return true;
1040
+ }
1041
+ function gather(error, next, old) {
1042
+ if (!holding || error !== holding.thrown) return;
1043
+ for (const fiber of next) if (!old.includes(fiber)) park(fiber);
1044
+ if (holding.fiber) next.push(holding.fiber);
1045
+ holding.fiber = void 0;
1046
+ }
1047
+ function hostOf(parent) {
1048
+ let host = parent;
1049
+ for (let owner = stashes.get(host); owner; owner = stashes.get(host)) host = owner.end.parentNode;
1050
+ return host;
1051
+ }
1052
+ function wait(fiber, boundary) {
1053
+ if (fiber.waitingOn !== boundary) unwait(fiber);
1054
+ fiber.waitingOn = boundary;
1055
+ (boundary.waiting ||= /* @__PURE__ */ new Set()).add(fiber);
1056
+ dirty.add(boundary);
1057
+ }
1058
+ function unwait(fiber) {
1059
+ const boundary = fiber.waitingOn;
1060
+ if (!boundary) return;
1061
+ fiber.waitingOn = void 0;
1062
+ boundary.waiting.delete(fiber);
1063
+ if (!boundary.owner.dead) dirty.add(boundary);
1064
+ }
1065
+ function settle() {
1066
+ if (settling) return;
1067
+ settling = true;
1068
+ try {
1069
+ for (const boundary of dirty) {
1070
+ dirty.delete(boundary);
1071
+ const owner = boundary.owner;
1072
+ const waiting = boundary.waiting.size > 0;
1073
+ if (!owner.dead && waiting != !!owner.stash) waiting ? hide(owner, boundary) : reveal(owner);
1074
+ }
1075
+ } finally {
1076
+ settling = false;
1474
1077
  }
1475
- for (const symbol of Object.getOwnPropertySymbols(value)) {
1476
- const ticket = tickets.get(value[symbol]);
1477
- if (!ticket) continue;
1478
- collected.classes.push(...ticket.classes);
1479
- for (const carried of ticket.tokens) collected.tokens.push({
1480
- appearance: carried.appearance,
1481
- doors: carried.doors + doors
1078
+ }
1079
+ function hide(owner, boundary) {
1080
+ const stash = document.createDocumentFragment();
1081
+ for (const child of owner.children) move(child, stash, null);
1082
+ owner.portals = portals(owner, []).map((portal) => {
1083
+ const content = document.createDocumentFragment();
1084
+ moveRange(portal.portalStart, portal.portalEnd, content);
1085
+ return [portal, content];
1086
+ });
1087
+ stashes.set(stash, owner);
1088
+ const context = owner.childContext;
1089
+ const placeholder = range("fragment", owner.end.parentNode, owner.end, context);
1090
+ owner.stash = stash;
1091
+ owner.placeholder = placeholder;
1092
+ reconcile(placeholder, boundary.fallback(), context, boundary.parent);
1093
+ }
1094
+ function reveal(owner) {
1095
+ unmountFiber(owner.placeholder);
1096
+ owner.end.parentNode.insertBefore(owner.stash, owner.end);
1097
+ for (const [portal, content] of owner.portals) if (!portal.dead) portal.portalContainer.append(content);
1098
+ owner.portals = void 0;
1099
+ owner.placeholder = void 0;
1100
+ owner.stash = void 0;
1101
+ }
1102
+ function portals(fiber, found) {
1103
+ for (const child of fiber.children) {
1104
+ if (child.kind == "portal") found.push(child);
1105
+ portals(child, found);
1106
+ }
1107
+ return found;
1108
+ }
1109
+ function suspend(fiber, thrown, passive, empty) {
1110
+ const boundary = fiber.boundary;
1111
+ if (isThenable(thrown)) {
1112
+ if (!boundary) throw thrown;
1113
+ if (passive && empty && depth > 1) {
1114
+ if (holding?.thrown !== thrown) holding = { thrown };
1115
+ throw thrown;
1116
+ }
1117
+ holding = void 0;
1118
+ if (!passive) wait(fiber, boundary);
1119
+ const scope = fiber.scope;
1120
+ let held = scope.holds;
1121
+ scope.holds = void 0;
1122
+ const clear = () => {
1123
+ fiber.suspended.delete(clear);
1124
+ release(held);
1125
+ held = void 0;
1126
+ };
1127
+ (fiber.suspended ||= /* @__PURE__ */ new Set()).add(clear);
1128
+ const resume = (retry) => {
1129
+ fiber.suspended.delete(clear);
1130
+ if (!scope.active) return clear();
1131
+ if (held) (scope.holds ||= []).push(...held);
1132
+ held = void 0;
1133
+ retry();
1134
+ };
1135
+ thrown.then(() => resume(() => passive ? transition(() => schedule(scope)) : schedule(scope)), (error) => resume(() => pass(() => recover(fiber, error, fiber.boundary))));
1136
+ return thrown;
1137
+ }
1138
+ recover(fiber, thrown, fiber.boundary);
1139
+ }
1140
+ function recover(fiber, thrown, boundary) {
1141
+ const error = thrown instanceof Error ? thrown : new Error(String(thrown));
1142
+ while (boundary && !boundary.catch) boundary = boundary.parent;
1143
+ if (!boundary) throw error;
1144
+ const handler = boundary;
1145
+ const token = {};
1146
+ wait(fiber, handler);
1147
+ fiber.recovering = token;
1148
+ Promise.resolve(handler.catch(error)).then(() => {
1149
+ if (fiber.recovering !== token) return;
1150
+ fiber.recovering = void 0;
1151
+ if (!fiber.scope.active || fiber.retried) return;
1152
+ fiber.retried = true;
1153
+ schedule(fiber.scope);
1154
+ }, (next) => {
1155
+ if (fiber.recovering === token && fiber.scope.active) pass(() => recover(fiber, next, handler.parent));
1156
+ });
1157
+ }
1158
+ function isThenable(value) {
1159
+ return !!value && typeof value.then == "function";
1160
+ }
1161
+
1162
+ //#endregion
1163
+ //#region src/render/component.ts
1164
+ function mountFunction(value, parent, before, context, boundary, appearance) {
1165
+ const fiber = range("function", parent, before, context);
1166
+ const resolved = componentProps(value.type, value.props, appearance);
1167
+ fiber.key = value.key;
1168
+ fiber.type = value.type;
1169
+ fiber.props = observe(resolved.props);
1170
+ fiber.boundary = boundary;
1171
+ fiber.appearance = resolved.appearance;
1172
+ fiber.scope = makeScope("function", context, (passive) => runFunction(fiber, passive));
1173
+ fiber.render = () => enter(fiber.scope, () => {
1174
+ const type = latest(fiber.type);
1175
+ return resolve(type, fiber.props, () => call(type, fiber.props));
1176
+ });
1177
+ track(fiber.type, fiber.scope);
1178
+ probing(fiber);
1179
+ return complete(fiber, () => {
1180
+ runFunction(fiber, passiveRender);
1181
+ });
1182
+ }
1183
+ function mountOwnedComponent(value, parent, before, context, boundary, appearance) {
1184
+ const resolved = componentProps(value.type, value.props, appearance);
1185
+ const Type = value.type;
1186
+ const props = observe(resolved.props);
1187
+ const instance = new Type(props, Type.prototype instanceof Component ? void 0 : () => props.is?.(instance));
1188
+ return mountComponent(instance, parent, before, context, boundary, resolved.appearance, true, value.key, props);
1189
+ }
1190
+ function mountComponent(instance, parent, before, context, inherited, appearance, owned = false, key, props = instance.props) {
1191
+ const fiber = range("component", parent, before, context);
1192
+ const childContext = context.push(instance);
1193
+ const element = owned ? props : {};
1194
+ const fallback = element.fallback !== void 0 ? element.fallback : instance.fallback;
1195
+ const ownBoundary = fallback !== void 0 && fallback !== false || element.catch || instance.catch ? {
1196
+ catch: element.catch || instance.catch ? (error) => {
1197
+ return (owned && fiber.props.catch || instance.catch).call(instance, error, instance);
1198
+ } : void 0,
1199
+ fallback: () => {
1200
+ const placed = owned ? fiber.props.fallback : void 0;
1201
+ return placed !== void 0 ? placed : instance.fallback;
1202
+ },
1203
+ owner: fiber,
1204
+ parent: inherited
1205
+ } : inherited;
1206
+ fiber.boundary = ownBoundary;
1207
+ if (ownBoundary !== inherited) fiber.ownBoundary = ownBoundary;
1208
+ fiber.childContext = childContext;
1209
+ fiber.instance = instance;
1210
+ fiber.key = owned ? key : instance.key;
1211
+ fiber.type = instance.constructor;
1212
+ fiber.props = props;
1213
+ fiber.owned = owned;
1214
+ fiber.appearance = appearance;
1215
+ fiber.scope = makeScope("component", childContext, (passive) => runComponent(fiber, passive));
1216
+ fiber.render = () => enter(fiber.scope, () => {
1217
+ const { render } = fiber.value;
1218
+ return render ? unbind(render).call(fiber.value, fiber.props) : fiber.props.children ?? null;
1219
+ });
1220
+ probing(fiber);
1221
+ let first = true;
1222
+ let proxy = instance;
1223
+ fiber.release = watch(instance, (current, events) => {
1224
+ const { applied, scope } = fiber;
1225
+ proxy = current;
1226
+ fiber.applied = void 0;
1227
+ if (!first && scope.active) if (applied && events.includes("props")) transition(() => schedule(scope));
1228
+ else schedule(scope);
1229
+ first = false;
1230
+ }, void 0, transition);
1231
+ Object.defineProperty(fiber, "value", { get: () => proxy });
1232
+ try {
1233
+ complete(fiber, () => {
1234
+ runComponent(fiber, passiveRender);
1482
1235
  });
1236
+ } finally {
1237
+ if (owned && !fiber.dead) inserted(fiber, () => fiber.cleanup = instance.mount?.());
1483
1238
  }
1484
- for (const key of Object.keys(value)) collected.declarations[key] = value[key];
1239
+ return fiber;
1485
1240
  }
1486
- function appendClasses(classes, value) {
1487
- if (typeof value == "string") classes.push(...value.split(/\s+/).filter(Boolean));
1241
+ function runFunction(fiber, passive) {
1242
+ const result = attempt(fiber, passive, fiber.render);
1243
+ if (result === true) inserted(fiber, () => commit(fiber.scope));
1244
+ else return result;
1488
1245
  }
1489
- function restoreTarget(event) {
1490
- const element = event.target;
1491
- const fiber = controlled.get(element);
1492
- if (fiber && event.type == settles(fiber.props, element)) queueMicrotask(() => afterFlush(() => restore(fiber)));
1246
+ function runComponent(fiber, passive) {
1247
+ const result = attempt(fiber, passive, fiber.render);
1248
+ if (result !== true) return result;
1493
1249
  }
1494
- function settles(props, element) {
1495
- if (props.onInput) return "input";
1496
- if (props.onChange) return "change";
1497
- return element.type == "checkbox" || element.type == "radio" || element.localName == "select" ? "change" : "input";
1250
+ function probing(fiber) {
1251
+ const scope = fiber.scope;
1252
+ scope.empty = () => !fiber.children.length;
1253
+ scope.probe = () => {
1254
+ try {
1255
+ scope.probed = { output: consume(fiber, fiber.render) };
1256
+ } catch (thrown) {
1257
+ if (isThenable(thrown)) return thrown;
1258
+ }
1259
+ };
1498
1260
  }
1499
- function restore(fiber) {
1500
- const element = fiber.start;
1501
- for (const key of CONTROLS) {
1502
- const value = fiber.props[key];
1503
- if (value == null || fiber.dead) continue;
1504
- if (key == "value" ? String(element.value) !== String(value) : element[key] !== value) element[key] = value;
1261
+ function patchFunction(fiber, value, appearance) {
1262
+ const resolved = componentProps(value.type, value.props, appearance);
1263
+ if (fiber.type !== value.type) {
1264
+ untrack(fiber.type, fiber.scope);
1265
+ fiber.type = value.type;
1266
+ fiber.scope.hot = true;
1267
+ track(fiber.type, fiber.scope);
1505
1268
  }
1269
+ fiber.appearance = resolved.appearance;
1270
+ fiber.props = observe(resolved.props);
1271
+ rerun(fiber, () => runFunction(fiber, passiveRender));
1506
1272
  }
1507
- function settable(element, key) {
1508
- let target = element;
1509
- let descriptor;
1510
- while (!(descriptor = Object.getOwnPropertyDescriptor(target, key))) target = Object.getPrototypeOf(target);
1511
- return !!(descriptor.set || descriptor.writable);
1273
+ function patchComponent(fiber, value, appearance) {
1274
+ const resolved = isVNode(value) ? componentProps(value.type, value.props, appearance) : {
1275
+ appearance,
1276
+ props: fiber.props
1277
+ };
1278
+ fiber.appearance = resolved.appearance;
1279
+ const props = isVNode(value) ? observe(resolved.props) : resolved.props;
1280
+ if (isVNode(value) && props !== fiber.props) {
1281
+ const instance = fiber.instance;
1282
+ if (passiveRender) fiber.applied = true;
1283
+ if (instance instanceof Component) instance.props = props;
1284
+ else instance.set(merge(fiber.props, props));
1285
+ }
1286
+ fiber.props = props;
1287
+ rerun(fiber, () => runComponent(fiber, passiveRender));
1512
1288
  }
1513
- function applyRef(ref, value) {
1514
- if (typeof ref == "function") ref(value);
1515
- else if (ref && typeof ref == "object" && "current" in ref) ref.current = value;
1289
+ function rerun(fiber, run) {
1290
+ claim$1(fiber.scope);
1291
+ run();
1292
+ settle$1(fiber.scope);
1293
+ }
1294
+ function unmountComponent(fiber) {
1295
+ if (typeof fiber.cleanup == "function") fiber.cleanup();
1296
+ fiber.childContext?.pop();
1297
+ if (fiber.owned && !fiber.instance.get(null)) fiber.instance.set(null);
1298
+ }
1299
+ function renderable(value) {
1300
+ return value instanceof Model && typeof value.render == "function";
1301
+ }
1302
+ function merge(previous, next) {
1303
+ const output = {};
1304
+ for (const key in previous) output[key] = void 0;
1305
+ return {
1306
+ ...output,
1307
+ ...next
1308
+ };
1309
+ }
1310
+
1311
+ //#endregion
1312
+ //#region src/render/mount.ts
1313
+ function complete(fiber, work) {
1314
+ try {
1315
+ work();
1316
+ } catch (error) {
1317
+ if (!hold(fiber, error)) unmountFiber(fiber);
1318
+ throw error;
1319
+ }
1320
+ return fiber;
1321
+ }
1322
+ function mount(value, parent, before, context, boundary, appearance) {
1323
+ if (typeof value == "string" || typeof value == "number" || typeof value == "bigint") {
1324
+ const text = document.createTextNode(String(value));
1325
+ parent.insertBefore(text, before);
1326
+ return {
1327
+ kind: "text",
1328
+ value,
1329
+ context,
1330
+ start: text,
1331
+ end: text,
1332
+ children: []
1333
+ };
1334
+ }
1335
+ if (renderable(value)) return mountComponent(value, parent, before, context, boundary, appearance);
1336
+ if (isCollection(value)) return mountCollection(value, parent, before, context, boundary, appearance);
1337
+ if (!isVNode(value)) throw new TypeError(`Cannot render ${String(value)}.`);
1338
+ if (value.type === Fragment$1) return mountFragment(value, parent, before, context, boundary, appearance);
1339
+ if (value.type === PORTAL) return mountPortal(value, parent, before, context, boundary, appearance);
1340
+ if (typeof value.type == "string") return mountElement(value, parent, before, context, boundary, appearance);
1341
+ if (typeof value.type != "function") throw new Error(`Cannot render ${String(value.type)}.`);
1342
+ if (value.type.prototype instanceof Model) return mountOwnedComponent(value, parent, before, context, boundary, appearance);
1343
+ return mountFunction(value, parent, before, context, boundary, appearance);
1344
+ }
1345
+ function mountFragment(value, parent, before, context, boundary, appearance) {
1346
+ const fiber = range("fragment", parent, before, context);
1347
+ fiber.key = value.key;
1348
+ fiber.type = Fragment$1;
1349
+ fiber.appearance = appearance;
1350
+ return complete(fiber, () => {
1351
+ reconcile(fiber, value.props.children, context, boundary, appearance);
1352
+ });
1353
+ }
1354
+ function patchText(fiber, value) {
1355
+ const next = String(value);
1356
+ if (fiber.start.nodeValue !== next) fiber.start.nodeValue = next;
1357
+ fiber.value = value;
1358
+ }
1359
+ function patchFragment(fiber, value, context, appearance) {
1360
+ fiber.context = context;
1361
+ fiber.appearance = appearance;
1362
+ reconcile(fiber, value.props.children, context, fiber.boundary, appearance);
1516
1363
  }
1517
1364
  function unmountFiber(fiber) {
1518
1365
  fiber.dead = true;
@@ -1523,34 +1370,91 @@ function unmountFiber(fiber) {
1523
1370
  if (fiber.kind == "function") untrack(fiber.type, fiber.scope);
1524
1371
  if (fiber.scope) dispose(fiber.scope);
1525
1372
  fiber.release?.();
1526
- if (fiber.kind == "element") {
1527
- applyRef(fiber.props?.ref, null);
1528
- for (const [id, listener] of fiber.events) {
1529
- const [name, capture] = id.split(":");
1530
- fiber.start.removeEventListener(name, listener, capture === "true");
1531
- }
1373
+ if (fiber.kind == "element") unmountElement(fiber);
1374
+ else if (fiber.kind == "component") unmountComponent(fiber);
1375
+ else if (fiber.kind == "portal") unmountPortal(fiber);
1376
+ removeRange(fiber.start, fiber.end);
1377
+ }
1378
+
1379
+ //#endregion
1380
+ //#region src/render/render.ts
1381
+ const roots = /* @__PURE__ */ new WeakMap();
1382
+ const focusing = [];
1383
+ let passiveRender = false;
1384
+ let depth = 0;
1385
+ function render(node, container) {
1386
+ roots.get(container)?.();
1387
+ container.replaceChildren();
1388
+ const context = new Context(Context.root);
1389
+ const fiber = range("fragment", container, null, context);
1390
+ try {
1391
+ pass(() => {
1392
+ const appearanceContext = appearanceRoot();
1393
+ reconcile(fiber, node, context, void 0, appearanceContext ? {
1394
+ context: appearanceContext,
1395
+ entries: []
1396
+ } : void 0);
1397
+ });
1398
+ } catch (error) {
1399
+ unmountFiber(fiber);
1400
+ context.pop();
1401
+ throw error;
1532
1402
  }
1533
- if (fiber.kind == "component") {
1534
- if (typeof fiber.cleanup == "function") fiber.cleanup();
1535
- fiber.childContext?.pop();
1536
- if (fiber.owned && !fiber.instance.get(null)) fiber.instance.set(null);
1537
- } else if (fiber.kind == "provider") fiber.childContext?.pop();
1538
- else if (fiber.kind == "portal") {
1539
- fiber.portalStart.remove();
1540
- fiber.portalEnd.remove();
1403
+ let active = true;
1404
+ const unmount = () => {
1405
+ if (!active) return;
1406
+ active = false;
1407
+ unmountFiber(fiber);
1408
+ context.pop();
1409
+ roots.delete(container);
1410
+ };
1411
+ roots.set(container, unmount);
1412
+ return unmount;
1413
+ }
1414
+ function pass(work) {
1415
+ depth++;
1416
+ try {
1417
+ return work();
1418
+ } finally {
1419
+ if (!--depth) {
1420
+ settle();
1421
+ focus();
1422
+ }
1541
1423
  }
1542
- removeRange(fiber.start, fiber.end);
1543
1424
  }
1544
- function removeRange(start, end) {
1545
- let node = start;
1546
- while (true) {
1547
- const next = node.nextSibling;
1548
- node.remove();
1549
- if (node === end) break;
1550
- node = next;
1425
+ function focus() {
1426
+ for (const element of focusing.splice(0)) if (element.isConnected) element.focus();
1427
+ }
1428
+ function attempt(fiber, passive, render) {
1429
+ const previous = passiveRender;
1430
+ const scope = fiber.scope;
1431
+ const probed = scope.probed;
1432
+ const empty = !fiber.children.length;
1433
+ scope.probed = void 0;
1434
+ passiveRender ||= passive;
1435
+ if (passive && !depth && empty && !fiber.stash) fiber.staging ||= fragment();
1436
+ const run = () => pass(() => {
1437
+ try {
1438
+ reconcile(fiber, probed ? probed.output : consume(fiber, render), scope.childContext, fiber.boundary, renderedAppearance(fiber));
1439
+ if (fiber.staging) {
1440
+ fiber.end.parentNode.insertBefore(fiber.staging, fiber.end);
1441
+ attach(fiber.staging);
1442
+ fiber.staging = void 0;
1443
+ }
1444
+ if (!fiber.recovering) unwait(fiber);
1445
+ fiber.retried = void 0;
1446
+ return true;
1447
+ } catch (thrown) {
1448
+ return suspend(fiber, thrown, passive, empty);
1449
+ }
1450
+ });
1451
+ try {
1452
+ return passive ? batched(run) : run();
1453
+ } finally {
1454
+ passiveRender = previous;
1551
1455
  }
1552
1456
  }
1553
1457
 
1554
1458
  //#endregion
1555
- export { Consumer, Provider, createPortal, css, lazy, macro, render, style };
1459
+ export { Fragment, Portal, createElement, css, macro, render, style };
1556
1460
  //# sourceMappingURL=index.js.map