ilha 0.15.0 → 0.15.2
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/define.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/{mount-qJHX_CfF.js → mount-DKY_jSsG.js} +37 -6
- package/dist/{paint-core-Cw1HbMp6.js → paint-core-B7jENZwS.js} +148 -81
- package/dist/renderer.d.ts +1 -1
- package/dist/renderer.js +1 -1
- package/dist/{runtime-B-sEGtAa.d.ts → runtime-Baq7MtkE.d.ts} +2 -0
- package/package.json +1 -1
package/dist/define.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { C as WatchOnceCleanup, S as WatchContext, _ as ResourceOptions, b as View, c as EventSourceStatus, d as Instruction, g as ResourceFetcher, h as Resource, i as Component, l as Fragment, n as AtomHandle, o as EventSourceFeed, r as AtomOptions, s as EventSourceOptions, t as AtomEquality, v as UnsafeHtml, w as Yielded, x as WatchCallback } from "./types-DsdtZMhG.js";
|
|
2
2
|
import { t as h } from "./vnode-CpSQZnLM.js";
|
|
3
|
-
import { r as watch } from "./runtime-
|
|
3
|
+
import { r as watch } from "./runtime-Baq7MtkE.js";
|
|
4
4
|
import * as Atom from "effect/reactivity/Atom";
|
|
5
5
|
import { Equal } from "effect";
|
|
6
6
|
import * as Effect$1 from "effect/Effect";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as isString, f as errorView, i as Fragment, m as isFunction, t as h } from "./vnode-BHUY61Rm.js";
|
|
2
|
-
import { C as
|
|
3
|
-
import { n as renderToString, t as mount } from "./mount-
|
|
2
|
+
import { C as getFiber, S as closeFiber, _ as isAtomHandle, b as wrapHandle, d as runSetup, f as interpret, g as instr, h as handleOwner, m as batch, n as unsafe, p as atom, v as structuralEqual, w as makeFiber, x as clearFiberView, y as untrack } from "./paint-core-B7jENZwS.js";
|
|
3
|
+
import { n as renderToString, t as mount } from "./mount-DKY_jSsG.js";
|
|
4
4
|
import * as Atom from "effect/reactivity/Atom";
|
|
5
5
|
import * as Effect from "effect/Effect";
|
|
6
6
|
import * as Stream from "effect/Stream";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as isString, c as KEEP, d as defer, g as isObject, m as isFunction, r as isVNode, u as SLOT_ATTR, y as unwrap } from "./vnode-BHUY61Rm.js";
|
|
2
|
-
import {
|
|
2
|
+
import { E as makeRuntime, S as closeFiber, T as makeRootFiber, a as markControlled, c as standInFor, d as runSetup, i as insertRendered, l as bindEvents, o as morphInner, r as committedElement, s as placeChildren, t as createPainter, u as eventTypeFromProp } from "./paint-core-B7jENZwS.js";
|
|
3
3
|
|
|
4
4
|
//#region src/paint.ts
|
|
5
5
|
const noopDisconnect = () => {};
|
|
@@ -30,13 +30,19 @@ const core$1 = createPainter({
|
|
|
30
30
|
reuseNode: (host) => host instanceof Element && host.isConnected ? standInFor(host) : host,
|
|
31
31
|
setFormControl: (el, key, v) => {
|
|
32
32
|
const node = el;
|
|
33
|
+
if (v !== null && v !== void 0) markControlled(el, key);
|
|
33
34
|
if (key === "value") {
|
|
34
|
-
|
|
35
|
+
const text = v === null || v === void 0 ? "" : String(v);
|
|
36
|
+
if (el.localName === "textarea") {
|
|
37
|
+
node.defaultValue = text;
|
|
38
|
+
node.value = text;
|
|
39
|
+
} else if (el.localName === "select") node.value = text;
|
|
40
|
+
else if (v === null || v === void 0) {
|
|
35
41
|
el.removeAttribute("value");
|
|
36
42
|
node.value = "";
|
|
37
43
|
} else {
|
|
38
|
-
el.setAttribute("value",
|
|
39
|
-
node.value =
|
|
44
|
+
el.setAttribute("value", text);
|
|
45
|
+
node.value = text;
|
|
40
46
|
}
|
|
41
47
|
} else if (key === "checked") {
|
|
42
48
|
node.checked = Boolean(v);
|
|
@@ -344,6 +350,26 @@ const bindSsrEvents = (el, props, fiber) => {
|
|
|
344
350
|
el.dataset.ilhaOn = existing ? `${existing},${id}` : id;
|
|
345
351
|
}
|
|
346
352
|
};
|
|
353
|
+
const WHITESPACE_RUN = /\s+/gu;
|
|
354
|
+
/**
|
|
355
|
+
* Mark the first option whose value is `value` selected and clear the rest,
|
|
356
|
+
* as setting a live select's `.value` does. Returns whether one matched.
|
|
357
|
+
*/
|
|
358
|
+
const selectOption = (parent, value, found) => {
|
|
359
|
+
let matched = found;
|
|
360
|
+
for (const child of parent.children) {
|
|
361
|
+
if (child.kind !== "element") continue;
|
|
362
|
+
if (child.localName === "optgroup") matched = selectOption(child, value, matched);
|
|
363
|
+
else if (child.localName === "option") {
|
|
364
|
+
const optionValue = child.getAttribute("value") ?? child.textContent.trim().replaceAll(WHITESPACE_RUN, " ");
|
|
365
|
+
if (!matched && optionValue === value) {
|
|
366
|
+
child.setAttribute("selected", "");
|
|
367
|
+
matched = true;
|
|
368
|
+
} else child.removeAttribute("selected");
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
return matched;
|
|
372
|
+
};
|
|
347
373
|
const core = createPainter({
|
|
348
374
|
appendRoot: (root, node) => ssrAs(root).append(node),
|
|
349
375
|
asElement: (el) => ssrAs(el),
|
|
@@ -370,8 +396,13 @@ const core = createPainter({
|
|
|
370
396
|
},
|
|
371
397
|
reuseNode: (host) => ssrAs(host),
|
|
372
398
|
setFormControl: (el, key, v) => {
|
|
373
|
-
if (key === "value")
|
|
374
|
-
|
|
399
|
+
if (key === "value") {
|
|
400
|
+
const text = String(v ?? "");
|
|
401
|
+
if (el.localName === "textarea") el.textContent = text;
|
|
402
|
+
else if (el.localName === "select") {
|
|
403
|
+
if (v !== null && v !== void 0) selectOption(el, text, false);
|
|
404
|
+
} else el.setAttribute("value", text);
|
|
405
|
+
} else if (v) el.setAttribute(key, "");
|
|
375
406
|
else el.removeAttribute(key);
|
|
376
407
|
},
|
|
377
408
|
setStyle: (el, css) => el.setAttribute("style", css)
|
|
@@ -362,8 +362,10 @@ const subscribeRenderDeps = (fiber, deps, run) => {
|
|
|
362
362
|
const schedule = () => {
|
|
363
363
|
if (scheduled) return;
|
|
364
364
|
scheduled = true;
|
|
365
|
+
const seen = fiber.renderGen;
|
|
365
366
|
fiber.runtime.later(() => {
|
|
366
367
|
scheduled = false;
|
|
368
|
+
if (fiber.renderGen !== seen) return;
|
|
367
369
|
run();
|
|
368
370
|
});
|
|
369
371
|
};
|
|
@@ -507,6 +509,7 @@ const runSetup = (fiber, fn) => {
|
|
|
507
509
|
},
|
|
508
510
|
render: () => {
|
|
509
511
|
if (fiber.closed) return;
|
|
512
|
+
fiber.renderGen = (fiber.renderGen ?? 0) + 1;
|
|
510
513
|
fiber.runtime.begin();
|
|
511
514
|
beginPrimitiveFrame(fiber);
|
|
512
515
|
withTrackGetRun(fiber, () => fn(), ({ value: out, deps }) => {
|
|
@@ -833,6 +836,20 @@ const collectKeys = (parent) => {
|
|
|
833
836
|
}
|
|
834
837
|
return keys;
|
|
835
838
|
};
|
|
839
|
+
/** Rendered elements that carried a non-null form-control prop, per key.
|
|
840
|
+
* `checked={false}`, `selected={false}` and `<select value>` leave no
|
|
841
|
+
* attribute, so presence alone can't tell a controlled render from an
|
|
842
|
+
* uncontrolled one. */
|
|
843
|
+
const controlledBy = {
|
|
844
|
+
checked: /* @__PURE__ */ new WeakSet(),
|
|
845
|
+
selected: /* @__PURE__ */ new WeakSet(),
|
|
846
|
+
value: /* @__PURE__ */ new WeakSet()
|
|
847
|
+
};
|
|
848
|
+
/** Mark a rendered element controlled for `key`: the morph syncs it either way. */
|
|
849
|
+
const markControlled = (el, key) => {
|
|
850
|
+
controlledBy[key].add(el);
|
|
851
|
+
};
|
|
852
|
+
const isControlled = (el, key) => controlledBy[key].has(el);
|
|
836
853
|
const morphInput = (fromEl, toEl) => {
|
|
837
854
|
syncAttributes(fromEl, toEl);
|
|
838
855
|
const from = fromEl;
|
|
@@ -842,7 +859,7 @@ const morphInput = (fromEl, toEl) => {
|
|
|
842
859
|
if (toChecked) fromEl.setAttribute("checked", "");
|
|
843
860
|
else fromEl.removeAttribute("checked");
|
|
844
861
|
}
|
|
845
|
-
if (toChecked && from.checked !== to.checked) from.checked = to.checked;
|
|
862
|
+
if ((toChecked || isControlled(toEl, "checked")) && from.checked !== to.checked) from.checked = to.checked;
|
|
846
863
|
const toValue = toEl.getAttribute("value");
|
|
847
864
|
if (toValue !== fromEl.getAttribute("value")) {
|
|
848
865
|
if (toValue === null) fromEl.removeAttribute("value");
|
|
@@ -854,14 +871,32 @@ const morphTextarea = (fromEl, toEl) => {
|
|
|
854
871
|
syncAttributes(fromEl, toEl);
|
|
855
872
|
const from = fromEl;
|
|
856
873
|
const to = toEl;
|
|
857
|
-
if (to.textContent !== "" || from.textContent !== to.textContent) {
|
|
874
|
+
if (isControlled(toEl, "value") || to.textContent !== "" || from.textContent !== to.textContent) {
|
|
858
875
|
if (from.value !== to.value) from.value = to.value;
|
|
859
876
|
if (from.textContent !== to.textContent) from.textContent = to.textContent;
|
|
860
877
|
}
|
|
861
878
|
};
|
|
879
|
+
const isControlledSelect = (select) => {
|
|
880
|
+
if (isControlled(select, "value")) return true;
|
|
881
|
+
for (const o of select.options) if (isControlled(o, "selected")) return true;
|
|
882
|
+
return false;
|
|
883
|
+
};
|
|
862
884
|
const morphSelect = (fromEl, toEl, api) => {
|
|
863
|
-
const before = /* @__PURE__ */ new Map();
|
|
864
885
|
const fromSelect = fromEl;
|
|
886
|
+
const toSelect = toEl;
|
|
887
|
+
if (isControlledSelect(toSelect)) {
|
|
888
|
+
syncAttributes(fromEl, toEl);
|
|
889
|
+
api.morphChildren(fromEl, toEl);
|
|
890
|
+
const want = toSelect.options;
|
|
891
|
+
let i = 0;
|
|
892
|
+
for (const o of fromSelect.options) {
|
|
893
|
+
const selected = want[i]?.selected ?? false;
|
|
894
|
+
if (o.selected !== selected) o.selected = selected;
|
|
895
|
+
i += 1;
|
|
896
|
+
}
|
|
897
|
+
return;
|
|
898
|
+
}
|
|
899
|
+
const before = /* @__PURE__ */ new Map();
|
|
865
900
|
for (const o of fromSelect.options) before.set(o, {
|
|
866
901
|
attr: o.hasAttribute("selected"),
|
|
867
902
|
live: o.selected
|
|
@@ -1133,36 +1168,26 @@ const elementNs = (lower, parentNs) => {
|
|
|
1133
1168
|
if (parentNs === "http://www.w3.org/2000/svg" || parentNs === "http://www.w3.org/1998/Math/MathML") return parentNs;
|
|
1134
1169
|
};
|
|
1135
1170
|
const canMorphRoot = (root) => typeof Element !== "undefined" && typeof document !== "undefined" && root instanceof Element && root.childNodes.length > 0;
|
|
1171
|
+
/** Close a child hole through the parent's hole list, so it disposes once. */
|
|
1172
|
+
const releaseHole = (fiber, hole) => {
|
|
1173
|
+
const idx = fiber.holes.findIndex((h) => h.holeFiber === hole);
|
|
1174
|
+
if (idx === -1) closeFiber(hole);
|
|
1175
|
+
else {
|
|
1176
|
+
const [removed] = fiber.holes.splice(idx, 1);
|
|
1177
|
+
removed?.dispose();
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1136
1180
|
const sweepComponentSlots = (fiber) => {
|
|
1137
1181
|
const cframe = fiber.componentFrame;
|
|
1138
1182
|
if (!cframe) return;
|
|
1139
1183
|
const { slots } = cframe;
|
|
1140
1184
|
for (let j = cframe.i; j < slots.length; j += 1) {
|
|
1141
1185
|
const s = slots[j];
|
|
1142
|
-
if (s)
|
|
1143
|
-
const { hole } = s;
|
|
1144
|
-
if (!hole.closed) {
|
|
1145
|
-
const idx = fiber.holes.findIndex((h) => h.holeFiber === hole);
|
|
1146
|
-
if (idx === -1) closeFiber(hole);
|
|
1147
|
-
else {
|
|
1148
|
-
const [removed] = fiber.holes.splice(idx, 1);
|
|
1149
|
-
removed?.dispose();
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
}
|
|
1186
|
+
if (s && !s.hole.closed) releaseHole(fiber, s.hole);
|
|
1153
1187
|
slots[j] = void 0;
|
|
1154
1188
|
}
|
|
1155
1189
|
slots.length = cframe.i;
|
|
1156
1190
|
};
|
|
1157
|
-
/** Close a child hole through the parent's hole list, so it disposes once. */
|
|
1158
|
-
const releaseHole = (fiber, hole) => {
|
|
1159
|
-
const idx = fiber.holes.findIndex((h) => h.holeFiber === hole);
|
|
1160
|
-
if (idx === -1) closeFiber(hole);
|
|
1161
|
-
else {
|
|
1162
|
-
const [removed] = fiber.holes.splice(idx, 1);
|
|
1163
|
-
removed?.dispose();
|
|
1164
|
-
}
|
|
1165
|
-
};
|
|
1166
1191
|
/** Close the keyed components the paint that just ran did not reach. */
|
|
1167
1192
|
const sweepKeyedHoles = (fiber) => {
|
|
1168
1193
|
const { keyedHoles, keyedGen } = fiber;
|
|
@@ -1183,6 +1208,61 @@ const pass = (fiber, fn) => {
|
|
|
1183
1208
|
fn();
|
|
1184
1209
|
sweepKeyedHoles(fiber);
|
|
1185
1210
|
};
|
|
1211
|
+
/**
|
|
1212
|
+
* Dispose a hole fiber's child holes before it repaints, except the component
|
|
1213
|
+
* and island holes the repaint can reuse: positional children, keyed
|
|
1214
|
+
* children, and islands. Reuse pushes new props instead of remounting, and the
|
|
1215
|
+
* sweeps that end the paint close whatever it did not reach.
|
|
1216
|
+
*/
|
|
1217
|
+
const keepReusableHoles = (fiber, cframe, frame) => {
|
|
1218
|
+
const kept = /* @__PURE__ */ new Set();
|
|
1219
|
+
for (const s of cframe.slots) if (s && !s.hole.closed) kept.add(s.hole);
|
|
1220
|
+
for (const hole of fiber.keyedHoles?.values() ?? []) if (!hole.closed) kept.add(hole);
|
|
1221
|
+
const keptIslands = new Set(frame.slots);
|
|
1222
|
+
const keep = [];
|
|
1223
|
+
for (const h of fiber.holes) {
|
|
1224
|
+
if (h.holeFiber && kept.has(h.holeFiber) || h.islandSlot && keptIslands.has(h.islandSlot)) {
|
|
1225
|
+
keep.push(h);
|
|
1226
|
+
continue;
|
|
1227
|
+
}
|
|
1228
|
+
h.dispose();
|
|
1229
|
+
}
|
|
1230
|
+
fiber.holes = keep;
|
|
1231
|
+
};
|
|
1232
|
+
/** Shallow equality of two prop bags, children compared item by item. */
|
|
1233
|
+
const sameProps = (prev, next) => {
|
|
1234
|
+
if (!prev) return false;
|
|
1235
|
+
const keys = Object.keys(next);
|
|
1236
|
+
if (keys.length !== Object.keys(prev).length) return false;
|
|
1237
|
+
return keys.every((k) => {
|
|
1238
|
+
const a = prev[k];
|
|
1239
|
+
const b = next[k];
|
|
1240
|
+
if (k === "children" && Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((x, i) => Object.is(x, b[i]));
|
|
1241
|
+
return Object.is(a, b);
|
|
1242
|
+
});
|
|
1243
|
+
};
|
|
1244
|
+
/**
|
|
1245
|
+
* Rerun a reused component hole with new props, in its own fiber. The props
|
|
1246
|
+
* box is updated in place, so every render closure of the hole reads the
|
|
1247
|
+
* latest props, including a self-render queued while an async render ran.
|
|
1248
|
+
*/
|
|
1249
|
+
const rerunHole = (hole, run, props) => {
|
|
1250
|
+
const box = hole.propsBox ?? { current: props };
|
|
1251
|
+
box.current = props;
|
|
1252
|
+
hole.propsBox = box;
|
|
1253
|
+
runSetup(hole, () => run(box.current));
|
|
1254
|
+
};
|
|
1255
|
+
/**
|
|
1256
|
+
* Run a new component hole's first render after the paint that opened it. A
|
|
1257
|
+
* repaint that reached the hole first already rendered it with newer props.
|
|
1258
|
+
*/
|
|
1259
|
+
const mountHoleLater = (fiber, hole, run) => {
|
|
1260
|
+
fiber.runtime.later(() => {
|
|
1261
|
+
const box = hole.propsBox;
|
|
1262
|
+
if (hole.closed || hole.renderGen !== void 0 || !box) return;
|
|
1263
|
+
runSetup(hole, () => run(box.current));
|
|
1264
|
+
});
|
|
1265
|
+
};
|
|
1186
1266
|
const warnedKeys = /* @__PURE__ */ new Set();
|
|
1187
1267
|
const warnDuplicateKey = (key) => {
|
|
1188
1268
|
if (warnedKeys.has(key)) return;
|
|
@@ -1221,10 +1301,6 @@ const styleCss = (v) => {
|
|
|
1221
1301
|
if (isString(v) || isObject(v)) return serializeStyleAttr(v);
|
|
1222
1302
|
return "";
|
|
1223
1303
|
};
|
|
1224
|
-
const isThenable = (value) => {
|
|
1225
|
-
if (!isObject(value) && !isFunction(value)) return false;
|
|
1226
|
-
return isFunction(value.then);
|
|
1227
|
-
};
|
|
1228
1304
|
const writeAttr = (el, k, v) => {
|
|
1229
1305
|
if (v === false || v === null || v === void 0) {
|
|
1230
1306
|
el.removeAttribute(k);
|
|
@@ -1369,18 +1445,7 @@ const createPainter = (ops) => {
|
|
|
1369
1445
|
sweepIslandSlots(fiber);
|
|
1370
1446
|
return;
|
|
1371
1447
|
}
|
|
1372
|
-
|
|
1373
|
-
for (const s of cframe.slots) if (s && !s.hole.closed) kept.add(s.hole);
|
|
1374
|
-
const keptIslands = new Set(frame.slots);
|
|
1375
|
-
const keep = [];
|
|
1376
|
-
for (const h of fiber.holes) {
|
|
1377
|
-
if (h.holeFiber && kept.has(h.holeFiber) || h.islandSlot && keptIslands.has(h.islandSlot)) {
|
|
1378
|
-
keep.push(h);
|
|
1379
|
-
continue;
|
|
1380
|
-
}
|
|
1381
|
-
h.dispose();
|
|
1382
|
-
}
|
|
1383
|
-
fiber.holes = keep;
|
|
1448
|
+
keepReusableHoles(fiber, cframe, frame);
|
|
1384
1449
|
const fresh = api.materialize(view, fiber);
|
|
1385
1450
|
if (canMorphRoot(fiber.root)) {
|
|
1386
1451
|
const tmp = document.createElement("div");
|
|
@@ -1494,18 +1559,10 @@ const createPainter = (ops) => {
|
|
|
1494
1559
|
if (existing) {
|
|
1495
1560
|
const { hole } = existing;
|
|
1496
1561
|
if (existing.type === type && !hole.closed) {
|
|
1497
|
-
hole
|
|
1498
|
-
runSetup(hole, () => run(props));
|
|
1562
|
+
rerunHole(hole, run, props);
|
|
1499
1563
|
return [ops.reuseNode(hole.root)];
|
|
1500
1564
|
}
|
|
1501
|
-
if (!hole.closed)
|
|
1502
|
-
const idx = fiber.holes.findIndex((h) => h.holeFiber === hole);
|
|
1503
|
-
if (idx === -1) closeFiber(hole);
|
|
1504
|
-
else {
|
|
1505
|
-
const [removed] = fiber.holes.splice(idx, 1);
|
|
1506
|
-
removed?.dispose();
|
|
1507
|
-
}
|
|
1508
|
-
}
|
|
1565
|
+
if (!hole.closed) releaseHole(fiber, hole);
|
|
1509
1566
|
}
|
|
1510
1567
|
const { fiber: hole, nodes } = api.openHole(fiber);
|
|
1511
1568
|
hole.propsBox = { current: props };
|
|
@@ -1514,58 +1571,61 @@ const createPainter = (ops) => {
|
|
|
1514
1571
|
hole,
|
|
1515
1572
|
type
|
|
1516
1573
|
};
|
|
1517
|
-
fiber
|
|
1518
|
-
if (hole.closed) return;
|
|
1519
|
-
const box = hole.propsBox;
|
|
1520
|
-
if (!box) return;
|
|
1521
|
-
runSetup(hole, () => run(box.current));
|
|
1522
|
-
});
|
|
1574
|
+
mountHoleLater(fiber, hole, run);
|
|
1523
1575
|
trackHole(fiber, hole, void 0, { keyed: true });
|
|
1524
1576
|
return nodes;
|
|
1525
1577
|
};
|
|
1526
|
-
const
|
|
1527
|
-
|
|
1528
|
-
...view.props,
|
|
1529
|
-
children: view.children
|
|
1530
|
-
};
|
|
1531
|
-
const branded = type;
|
|
1532
|
-
if (branded[ISLAND] === true) return materializeIsland(branded, props, fiber);
|
|
1533
|
-
const k = view.key === null || view.key === void 0 ? void 0 : String(view.key);
|
|
1534
|
-
const reuse = k ? fiber.keyedHoles?.get(k) : void 0;
|
|
1535
|
-
const run = type;
|
|
1578
|
+
const materializeKeyedComponent = ({ run, type, props, key, fiber }) => {
|
|
1579
|
+
let reuse = fiber.keyedHoles?.get(key);
|
|
1536
1580
|
const gen = fiber.keyedGen;
|
|
1537
|
-
if (
|
|
1538
|
-
warnDuplicateKey(
|
|
1581
|
+
if (reuse && !reuse.closed && reuse.keyedSeen === gen) {
|
|
1582
|
+
warnDuplicateKey(key);
|
|
1539
1583
|
return materializeUnkeyedComponent(run, type, props, fiber);
|
|
1540
1584
|
}
|
|
1585
|
+
if (reuse && !reuse.closed && reuse.componentType !== type) {
|
|
1586
|
+
fiber.keyedHoles?.delete(key);
|
|
1587
|
+
releaseHole(fiber, reuse);
|
|
1588
|
+
reuse = void 0;
|
|
1589
|
+
}
|
|
1541
1590
|
if (reuse && !reuse.closed) {
|
|
1542
1591
|
reuse.keyedSeen = gen;
|
|
1543
|
-
if (reuse.propsBox) reuse
|
|
1544
|
-
const next = withFiber(fiber, () => run(reuse.propsBox?.current ?? props));
|
|
1545
|
-
if (next && !isThenable(next) && !isSetupFn(next)) reuse.paint(next);
|
|
1592
|
+
if (!sameProps(reuse.propsBox?.current, props)) rerunHole(reuse, run, props);
|
|
1546
1593
|
return [ops.reuseNode(reuse.root)];
|
|
1547
1594
|
}
|
|
1548
|
-
if (!k) return materializeUnkeyedComponent(run, type, props, fiber);
|
|
1549
1595
|
const { fiber: khole, nodes: knodes } = api.openHole(fiber);
|
|
1550
1596
|
khole.propsBox = { current: props };
|
|
1597
|
+
khole.componentType = type;
|
|
1551
1598
|
khole.keyedSeen = gen;
|
|
1552
|
-
fiber.keyedHoles?.set(
|
|
1553
|
-
fiber
|
|
1554
|
-
if (khole.closed) return;
|
|
1555
|
-
const box = khole.propsBox;
|
|
1556
|
-
if (!box) return;
|
|
1557
|
-
runSetup(khole, () => run(box.current));
|
|
1558
|
-
});
|
|
1599
|
+
fiber.keyedHoles?.set(key, khole);
|
|
1600
|
+
mountHoleLater(fiber, khole, run);
|
|
1559
1601
|
trackHole(fiber, khole, void 0, { keyed: true });
|
|
1560
1602
|
return knodes;
|
|
1561
1603
|
};
|
|
1604
|
+
const materializeComponent = (view, type, fiber) => {
|
|
1605
|
+
const props = {
|
|
1606
|
+
...view.props,
|
|
1607
|
+
children: view.children
|
|
1608
|
+
};
|
|
1609
|
+
const branded = type;
|
|
1610
|
+
if (branded[ISLAND] === true) return materializeIsland(branded, props, fiber);
|
|
1611
|
+
const run = type;
|
|
1612
|
+
if (view.key === null || view.key === void 0) return materializeUnkeyedComponent(run, type, props, fiber);
|
|
1613
|
+
return materializeKeyedComponent({
|
|
1614
|
+
fiber,
|
|
1615
|
+
key: String(view.key),
|
|
1616
|
+
props,
|
|
1617
|
+
run,
|
|
1618
|
+
type
|
|
1619
|
+
});
|
|
1620
|
+
};
|
|
1562
1621
|
const materializeElement = (view, fiber) => {
|
|
1563
1622
|
const tag = view.type;
|
|
1564
1623
|
const lower = tag.toLowerCase();
|
|
1565
1624
|
const ns = elementNs(lower, parentNsOf(fiber.root));
|
|
1566
1625
|
const el = ops.createElement(tag, ns);
|
|
1567
1626
|
if (view.key !== null && view.key !== void 0) el.setAttribute(KEY_ATTR, String(view.key));
|
|
1568
|
-
|
|
1627
|
+
const propsAfterChildren = lower === "select";
|
|
1628
|
+
if (!propsAfterChildren) api.applyProps(el, view.props, fiber);
|
|
1569
1629
|
const childFiber = {
|
|
1570
1630
|
...fiber,
|
|
1571
1631
|
holes: fiber.holes,
|
|
@@ -1573,6 +1633,7 @@ const createPainter = (ops) => {
|
|
|
1573
1633
|
root: ops.asRoot(el)
|
|
1574
1634
|
};
|
|
1575
1635
|
for (const c of view.children) for (const n of api.materialize(c, childFiber)) el.append(n);
|
|
1636
|
+
if (propsAfterChildren) api.applyProps(el, view.props, fiber);
|
|
1576
1637
|
return [el];
|
|
1577
1638
|
};
|
|
1578
1639
|
const materializeVNode = (view, fiber) => {
|
|
@@ -1602,8 +1663,14 @@ const createPainter = (ops) => {
|
|
|
1602
1663
|
const nodes = [];
|
|
1603
1664
|
for (const v of views) {
|
|
1604
1665
|
const reuse = fiber.keyedHoles?.get(String(v.key));
|
|
1605
|
-
|
|
1666
|
+
const reusable = reuse && !reuse.closed && reuse.keyedSeen !== fiber.keyedGen && reuse.componentType === v.type;
|
|
1667
|
+
if (reuse && reusable) {
|
|
1606
1668
|
reuse.keyedSeen = fiber.keyedGen;
|
|
1669
|
+
const props = {
|
|
1670
|
+
...v.props,
|
|
1671
|
+
children: v.children
|
|
1672
|
+
};
|
|
1673
|
+
if (!sameProps(reuse.propsBox?.current, props)) rerunHole(reuse, v.type, props);
|
|
1607
1674
|
nodes.push(ops.asNode(reuse.root));
|
|
1608
1675
|
continue;
|
|
1609
1676
|
}
|
|
@@ -1623,4 +1690,4 @@ const createPainter = (ops) => {
|
|
|
1623
1690
|
};
|
|
1624
1691
|
|
|
1625
1692
|
//#endregion
|
|
1626
|
-
export {
|
|
1693
|
+
export { getFiber as C, makeRuntime as E, closeFiber as S, makeRootFiber as T, isAtomHandle as _, markControlled as a, wrapHandle as b, standInFor as c, runSetup as d, interpret as f, instr as g, handleOwner as h, insertRendered as i, bindEvents as l, batch as m, unsafe as n, morphInner as o, atom as p, committedElement as r, placeChildren as s, createPainter as t, eventTypeFromProp as u, structuralEqual as v, makeFiber as w, clearFiberView as x, untrack as y };
|
package/dist/renderer.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { b as View, i as Component, m as PropValue, p as PropBag, u as IlhaRuntime } from "./types-DsdtZMhG.js";
|
|
2
|
-
import { n as getFiber, t as FiberLocal } from "./runtime-
|
|
2
|
+
import { n as getFiber, t as FiberLocal } from "./runtime-Baq7MtkE.js";
|
|
3
3
|
//#region src/shared.d.ts
|
|
4
4
|
declare const KEEP: unique symbol;
|
|
5
5
|
//#endregion
|
package/dist/renderer.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defer } from "./vnode-BHUY61Rm.js";
|
|
2
|
-
import {
|
|
2
|
+
import { C as getFiber, E as makeRuntime, S as closeFiber, T as makeRootFiber, d as runSetup, l as bindEvents, t as createPainter } from "./paint-core-B7jENZwS.js";
|
|
3
3
|
|
|
4
4
|
//#region src/renderer.ts
|
|
5
5
|
/**
|
|
@@ -78,6 +78,8 @@ interface FiberLocal {
|
|
|
78
78
|
componentFrame?: ComponentFrame;
|
|
79
79
|
componentType?: unknown;
|
|
80
80
|
renderSub?: () => void;
|
|
81
|
+
/** Counts the renders this fiber started; see `subscribeRenderDeps`. */
|
|
82
|
+
renderGen?: number;
|
|
81
83
|
trackRestore?: () => void;
|
|
82
84
|
propsBox?: {
|
|
83
85
|
current: PropBag;
|