@praxisjs/runtime 0.6.0 → 0.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +21 -0
- package/dist/__tests__/children.test.js +54 -0
- package/dist/__tests__/children.test.js.map +1 -1
- package/dist/__tests__/component.test.js +76 -1
- package/dist/__tests__/component.test.js.map +1 -1
- package/dist/__tests__/dom.test.js +144 -0
- package/dist/__tests__/dom.test.js.map +1 -1
- package/dist/__tests__/portal.test.js +22 -0
- package/dist/__tests__/portal.test.js.map +1 -1
- package/dist/__tests__/remove.test.d.ts +2 -0
- package/dist/__tests__/remove.test.d.ts.map +1 -0
- package/dist/__tests__/remove.test.js +45 -0
- package/dist/__tests__/remove.test.js.map +1 -0
- package/dist/component.d.ts.map +1 -1
- package/dist/component.js +22 -1
- package/dist/component.js.map +1 -1
- package/dist/dom/events.d.ts +1 -1
- package/dist/dom/events.d.ts.map +1 -1
- package/dist/dom/events.js +22 -2
- package/dist/dom/events.js.map +1 -1
- package/dist/dom/props.d.ts.map +1 -1
- package/dist/dom/props.js +28 -5
- package/dist/dom/props.js.map +1 -1
- package/dist/dom/remove.d.ts +2 -0
- package/dist/dom/remove.d.ts.map +1 -0
- package/dist/dom/remove.js +23 -0
- package/dist/dom/remove.js.map +1 -0
- package/dist/portal.d.ts.map +1 -1
- package/dist/portal.js +8 -7
- package/dist/portal.js.map +1 -1
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +6 -10
- package/dist/reactive.js.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/children.test.ts +58 -0
- package/src/__tests__/component.test.ts +85 -1
- package/src/__tests__/dom.test.ts +157 -0
- package/src/__tests__/portal.test.ts +24 -0
- package/src/__tests__/remove.test.ts +51 -0
- package/src/component.ts +23 -1
- package/src/dom/events.ts +25 -3
- package/src/dom/props.ts +30 -5
- package/src/dom/remove.ts +22 -0
- package/src/portal.ts +8 -7
- package/src/reactive.ts +5 -9
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.test.js","sourceRoot":"","sources":["../../src/__tests__/remove.test.ts"],"names":[],"mappings":"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"}
|
package/dist/component.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,KAAK,oBAAoB,EAAG,MAAM,2BAA2B,CAAC;AAKpF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"component.d.ts","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,WAAW,EAAE,KAAK,oBAAoB,EAAG,MAAM,2BAA2B,CAAC;AAKpF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAwBrC,wBAAgB,cAAc,CAC5B,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,WAAW,EAAE,KAAK,GACjB,IAAI,EAAE,CA0DR;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
package/dist/component.js
CHANGED
|
@@ -3,6 +3,27 @@ import { initSlots } from "@praxisjs/decorators";
|
|
|
3
3
|
import { isComponent } from "@praxisjs/shared/internal";
|
|
4
4
|
import { mountChildren } from "./children";
|
|
5
5
|
import { runInScope } from "./context";
|
|
6
|
+
let pendingMounts = [];
|
|
7
|
+
// One shared microtask drains every component mounted in the same synchronous pass, in mount
|
|
8
|
+
// order (children before parents). A throwing onMount is rethrown on its own microtask so it
|
|
9
|
+
// can't stop the others, as it couldn't when each component had a microtask of its own.
|
|
10
|
+
function scheduleMount(run) {
|
|
11
|
+
if (pendingMounts.length === 0) {
|
|
12
|
+
queueMicrotask(() => {
|
|
13
|
+
const queue = pendingMounts;
|
|
14
|
+
pendingMounts = [];
|
|
15
|
+
for (const job of queue) {
|
|
16
|
+
try {
|
|
17
|
+
job();
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
queueMicrotask(() => { throw e; });
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
pendingMounts.push(run);
|
|
26
|
+
}
|
|
6
27
|
export function mountComponent(ctor, props, parentScope) {
|
|
7
28
|
return untrack(() => {
|
|
8
29
|
const scope = parentScope.fork();
|
|
@@ -36,7 +57,7 @@ export function mountComponent(ctor, props, parentScope) {
|
|
|
36
57
|
});
|
|
37
58
|
mountChildren(container, dom, scope);
|
|
38
59
|
container.appendChild(end);
|
|
39
|
-
|
|
60
|
+
scheduleMount(() => {
|
|
40
61
|
if (disposed)
|
|
41
62
|
return;
|
|
42
63
|
setComponentMounted(instance, true);
|
package/dist/component.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,mBAAmB,EACnB,OAAO,GACR,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAA8B,MAAM,2BAA2B,CAAC;AAEpF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAIvC,MAAM,UAAU,cAAc,CAC5B,IAA0B,EAC1B,KAA8B,EAC9B,WAAkB;IAElB,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;QAEjC,sEAAsE;QACtE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,aAAa,EAAE,GAAG,KAAK,CAAC;QAC/C,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,UAAU;YACrC,CAAC,CAAC,KAA0C;YAC5C,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,EAAE,GAAG,aAAa,EAAE,CAAC,CAAC;QAEhD,MAAM,WAAW,GAAG,aAAa,CAAC,QAAQ,CAAC;QAC3C,IAAI,WAAW,IAAI,IAAI,EAAE,CAAC;YACxB,SAAS,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACvD,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QACtD,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAElC,QAAQ,CAAC,aAAa,EAAE,EAAE,CAAC;QAE3B,MAAM,SAAS,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QACpD,SAAS,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAE7B,IAAI,GAAG,GAAyB,IAAI,CAAC;QACrC,UAAU,CAAC,KAAK,EAAE,GAAG,EAAE;YACrB,IAAI,CAAC;gBACH,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YAC1B,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,IAAI,QAAQ,IAAI,IAAI;oBAAE,GAAG,GAAG,QAAQ,CAAC;YACvC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,aAAa,CAAC,SAAS,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QACrC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAE3B,
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../src/component.ts"],"names":[],"mappings":"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"}
|
package/dist/dom/events.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { Scope } from "../scope";
|
|
2
|
-
export declare function addEvent(el: Element, eventName: string, handler: EventListener, scope: Scope): void;
|
|
2
|
+
export declare function addEvent(el: Element, eventName: string, handler: EventListener | EventListenerObject | null | undefined, scope: Scope): void;
|
|
3
3
|
//# sourceMappingURL=events.d.ts.map
|
package/dist/dom/events.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/dom/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/dom/events.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAkBtC,wBAAgB,QAAQ,CACtB,EAAE,EAAE,OAAO,EACX,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,aAAa,GAAG,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAC/D,KAAK,EAAE,KAAK,GACX,IAAI,CAON"}
|
package/dist/dom/events.js
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
+
import { batch } from "@praxisjs/core/internal";
|
|
2
|
+
// One wrapper per handler keeps addEventListener's dedupe of an identical listener intact.
|
|
3
|
+
const batchedHandlers = new WeakMap();
|
|
4
|
+
// Handlers run inside batch() so several signal writes in one event flush their effects once,
|
|
5
|
+
// instead of re-running the same reactive subtree after every write.
|
|
6
|
+
function batched(handler) {
|
|
7
|
+
let wrapper = batchedHandlers.get(handler);
|
|
8
|
+
if (!wrapper) {
|
|
9
|
+
wrapper = function (event) {
|
|
10
|
+
batch(() => { handler.call(this, event); });
|
|
11
|
+
};
|
|
12
|
+
batchedHandlers.set(handler, wrapper);
|
|
13
|
+
}
|
|
14
|
+
return wrapper;
|
|
15
|
+
}
|
|
1
16
|
export function addEvent(el, eventName, handler, scope) {
|
|
2
|
-
|
|
3
|
-
|
|
17
|
+
// Components forward optional handlers (`onSubmit={this.onSubmit}`) as-is, and addEventListener
|
|
18
|
+
// has always treated a missing listener as a no-op.
|
|
19
|
+
if (handler == null)
|
|
20
|
+
return;
|
|
21
|
+
const listener = typeof handler === "function" ? batched(handler) : handler;
|
|
22
|
+
el.addEventListener(eventName, listener);
|
|
23
|
+
scope.add(() => { el.removeEventListener(eventName, listener); });
|
|
4
24
|
}
|
|
5
25
|
//# sourceMappingURL=events.js.map
|
package/dist/dom/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/dom/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/dom/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAC;AAIhD,2FAA2F;AAC3F,MAAM,eAAe,GAAG,IAAI,OAAO,EAAgC,CAAC;AAEpE,8FAA8F;AAC9F,qEAAqE;AACrE,SAAS,OAAO,CAAC,OAAsB;IACrC,IAAI,OAAO,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3C,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,GAAG,UAAyB,KAAK;YACtC,KAAK,CAAC,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC,CAAC;QACF,eAAe,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,EAAW,EACX,SAAiB,EACjB,OAA+D,EAC/D,KAAY;IAEZ,gGAAgG;IAChG,oDAAoD;IACpD,IAAI,OAAO,IAAI,IAAI;QAAE,OAAO;IAC5B,MAAM,QAAQ,GAAG,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC5E,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IACzC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC"}
|
package/dist/dom/props.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/dom/props.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/dom/props.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AA2FtC,wBAAgB,SAAS,CACvB,EAAE,EAAE,OAAO,EACX,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,KAAK,GACX,IAAI,CAwBN"}
|
package/dist/dom/props.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { untrack } from "@praxisjs/core/internal";
|
|
1
2
|
import { EVENT_MAP } from "./constants";
|
|
2
3
|
import { addEvent } from "./events";
|
|
3
4
|
function applyClass(el, value) {
|
|
@@ -42,10 +43,9 @@ function applyAttr(el, key, value) {
|
|
|
42
43
|
el.setAttribute(key, String(value));
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
let target = el;
|
|
46
|
+
const writableCache = new WeakMap();
|
|
47
|
+
function lookupWritable(proto, key) {
|
|
48
|
+
let target = proto;
|
|
49
49
|
while (target) {
|
|
50
50
|
const descriptor = Object.getOwnPropertyDescriptor(target, key);
|
|
51
51
|
if (descriptor) {
|
|
@@ -55,6 +55,27 @@ function hasWritableProperty(el, key) {
|
|
|
55
55
|
}
|
|
56
56
|
return false;
|
|
57
57
|
}
|
|
58
|
+
// Read-only accessors (SVG geometry, `list`, `form`, `part`, `classList`…)
|
|
59
|
+
// must be excluded here or assignment below throws. The prototype walk is cached per
|
|
60
|
+
// prototype because every element of a given tag repeats the same lookups; a property defined on
|
|
61
|
+
// a prototype after its first lookup (e.g. a late polyfill) is therefore not picked up.
|
|
62
|
+
function hasWritableProperty(el, key) {
|
|
63
|
+
const own = Object.getOwnPropertyDescriptor(el, key);
|
|
64
|
+
if (own)
|
|
65
|
+
return own.set !== undefined || own.writable === true;
|
|
66
|
+
const proto = Object.getPrototypeOf(el);
|
|
67
|
+
let keys = writableCache.get(proto);
|
|
68
|
+
if (!keys) {
|
|
69
|
+
keys = new Map();
|
|
70
|
+
writableCache.set(proto, keys);
|
|
71
|
+
}
|
|
72
|
+
let writable = keys.get(key);
|
|
73
|
+
if (writable === undefined) {
|
|
74
|
+
writable = lookupWritable(proto, key);
|
|
75
|
+
keys.set(key, writable);
|
|
76
|
+
}
|
|
77
|
+
return writable;
|
|
78
|
+
}
|
|
58
79
|
function setProp(el, key, value) {
|
|
59
80
|
if (key === "class" || key === "className") {
|
|
60
81
|
applyClass(el, value);
|
|
@@ -77,7 +98,9 @@ export function applyProp(el, key, value, scope) {
|
|
|
77
98
|
if (normalizedKey === "key" || normalizedKey === "children")
|
|
78
99
|
return;
|
|
79
100
|
if (normalizedKey === "ref") {
|
|
80
|
-
|
|
101
|
+
// untracked: a ref callback that reads a signal must not subscribe the enclosing reactive child
|
|
102
|
+
if (typeof value === "function")
|
|
103
|
+
untrack(() => { value(el); });
|
|
81
104
|
return;
|
|
82
105
|
}
|
|
83
106
|
if (normalizedKey in EVENT_MAP) {
|
package/dist/dom/props.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.js","sourceRoot":"","sources":["../../src/dom/props.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAIpC,SAAS,UAAU,CAAC,EAAW,EAAE,KAAc;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,EAAW,EAAE,KAAc;IAC7C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC1C,EAAE,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,EAAiB,CAAC;QACjC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAA+B,CAAC,EAAE,CAAC;YACrE,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACL,MAAM,CAAC,KAA2C,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAW,EAAE,GAAW,EAAE,KAAc;IACzD,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC7D,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;SAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QAC1B,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,gEAAgE;QAChE,EAAE,CAAC,YAAY,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"props.js","sourceRoot":"","sources":["../../src/dom/props.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/dom/remove.ts"],"names":[],"mappings":"AAIA,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAiB/C"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Replaces Range.deleteContents(): creating a Range per removal is several times slower than
|
|
2
|
+
// walking the siblings, and unreachable Ranges stay registered with the document until collected.
|
|
3
|
+
// Walking first → last (rather than only the tracked nodes) also removes anything a nested reactive
|
|
4
|
+
// child inserted between them after mount, which is what the Range used to cover.
|
|
5
|
+
export function removeNodes(nodes) {
|
|
6
|
+
const first = nodes[0];
|
|
7
|
+
const last = nodes[nodes.length - 1];
|
|
8
|
+
const parent = first.parentNode;
|
|
9
|
+
if (parent === null || last.parentNode !== parent) {
|
|
10
|
+
for (const node of nodes)
|
|
11
|
+
node.parentNode?.removeChild(node);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
let node = first;
|
|
15
|
+
while (node) {
|
|
16
|
+
const next = node.nextSibling;
|
|
17
|
+
parent.removeChild(node);
|
|
18
|
+
if (node === last)
|
|
19
|
+
return;
|
|
20
|
+
node = next;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/dom/remove.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,kGAAkG;AAClG,oGAAoG;AACpG,kFAAkF;AAClF,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;IACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC;IAEhC,IAAI,MAAM,KAAK,IAAI,IAAI,IAAI,CAAC,UAAU,KAAK,MAAM,EAAE,CAAC;QAClD,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAC7D,OAAO;IACT,CAAC;IAED,IAAI,IAAI,GAAgB,KAAK,CAAC;IAC9B,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,IAAI,GAAgB,IAAI,CAAC,WAAW,CAAC;QAC3C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,IAAI;YAAE,OAAO;QAC1B,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
package/dist/portal.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../src/portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"portal.d.ts","sourceRoot":"","sources":["../src/portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAOpD,MAAM,WAAW,WAAW;IAC1B,EAAE,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,qBAAa,MAAO,SAAQ,kBAAkB,CAAC,WAAW,CAAC;IACzD,MAAM,CAAC,QAAQ,CAAC,aAAa,EAAG,IAAI,CAAU;IAC9C,MAAM,CAAC,QAAQ,CAAC,aAAa,QAAQ;IAErC,MAAM;CA6BP;AAED,wBAAgB,mBAAmB,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAOhF"}
|
package/dist/portal.js
CHANGED
|
@@ -2,6 +2,7 @@ import { StatelessComponent } from "@praxisjs/core";
|
|
|
2
2
|
import { isServerRenderPass } from "@praxisjs/core/internal";
|
|
3
3
|
import { mountChildren } from "./children";
|
|
4
4
|
import { getCurrentScope } from "./context";
|
|
5
|
+
import { removeNodes } from "./dom/remove";
|
|
5
6
|
export class Portal extends StatelessComponent {
|
|
6
7
|
static __isComponent = true;
|
|
7
8
|
static __isStateless = true;
|
|
@@ -19,16 +20,16 @@ export class Portal extends StatelessComponent {
|
|
|
19
20
|
return null;
|
|
20
21
|
const start = document.createComment("");
|
|
21
22
|
const end = document.createComment("");
|
|
22
|
-
target.
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
// Built off-document and attached once, so the target never sees a half-built subtree.
|
|
24
|
+
const fragment = document.createDocumentFragment();
|
|
25
|
+
fragment.appendChild(start);
|
|
26
|
+
mountChildren(fragment, this.props.children, scope);
|
|
27
|
+
fragment.appendChild(end);
|
|
28
|
+
target.appendChild(fragment);
|
|
25
29
|
scope.add(() => {
|
|
26
30
|
if (!start.parentNode || start.parentNode !== end.parentNode)
|
|
27
31
|
return;
|
|
28
|
-
|
|
29
|
-
range.setStartBefore(start);
|
|
30
|
-
range.setEndAfter(end);
|
|
31
|
-
range.deleteContents();
|
|
32
|
+
removeNodes([start, end]);
|
|
32
33
|
});
|
|
33
34
|
return document.createComment("portal");
|
|
34
35
|
}
|
package/dist/portal.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../src/portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../src/portal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAM3C,MAAM,OAAO,MAAO,SAAQ,kBAA+B;IACzD,MAAM,CAAU,aAAa,GAAG,IAAa,CAAC;IAC9C,MAAM,CAAU,aAAa,GAAG,IAAI,CAAC;IAErC,MAAM;QACJ,0EAA0E;QAC1E,4EAA4E;QAC5E,6EAA6E;QAC7E,8EAA8E;QAC9E,iEAAiE;QACjE,IAAI,kBAAkB,EAAE;YAAE,OAAO,IAAI,CAAC;QAEtC,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAEzB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;QAEvC,uFAAuF;QACvF,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;QACnD,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAC5B,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACpD,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC1B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE7B,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE;YACb,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,KAAK,CAAC,UAAU,KAAK,GAAG,CAAC,UAAU;gBAAE,OAAO;YACrE,WAAW,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC;QAEH,OAAO,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;;AAGH,MAAM,UAAU,mBAAmB,CAAC,EAA4B;IAC9D,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QACf,IAAI,OAAO,QAAQ,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QACjD,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,EAAE,KAAK,QAAQ;QAAE,OAAO,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
package/dist/reactive.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"reactive.d.ts","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAmBhC,wBAAgB,aAAa,CAC3B,MAAM,EAAE,IAAI,EACZ,EAAE,EAAE,MAAM,OAAO,EACjB,WAAW,EAAE,KAAK,GACjB,IAAI,CAwCN"}
|
package/dist/reactive.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { runInScope } from "./context";
|
|
2
|
+
import { removeNodes } from "./dom/remove";
|
|
2
3
|
import { isRecording, registerReactiveNode } from "./hydration-context";
|
|
3
4
|
import { Scope } from "./scope";
|
|
4
5
|
function collectNodes(value, out) {
|
|
@@ -47,16 +48,11 @@ export function mountReactive(parent, fn, parentScope) {
|
|
|
47
48
|
registerReactiveNode(n, newNodes);
|
|
48
49
|
}
|
|
49
50
|
const anchor = end.parentNode ?? parent;
|
|
50
|
-
if (currentNodes.length
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const range = document.createRange();
|
|
56
|
-
range.setStartBefore(currentNodes[0]);
|
|
57
|
-
range.setEndAfter(currentNodes[currentNodes.length - 1]);
|
|
58
|
-
range.deleteContents();
|
|
59
|
-
}
|
|
51
|
+
if (currentNodes.length === 1) {
|
|
52
|
+
anchor.removeChild(currentNodes[0]);
|
|
53
|
+
}
|
|
54
|
+
else if (currentNodes.length > 1) {
|
|
55
|
+
removeNodes(currentNodes);
|
|
60
56
|
}
|
|
61
57
|
if (newNodes.length > 0) {
|
|
62
58
|
anchor.insertBefore(nodesToFragment(newNodes), end);
|
package/dist/reactive.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reactive.js","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC,SAAS,YAAY,CAAC,KAAc,EAAE,GAAW;IAC/C,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,KAAK;QAAE,OAAO;IACrE,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IACvD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAAC,KAAK,MAAM,CAAC,IAAI,KAAK;YAAE,YAAY,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAAC,OAAO;IAAC,CAAC;IAClF,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3D,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACjD,OAAO;IACT,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAa;IACpC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/C,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,aAAa,CAC3B,MAAY,EACZ,EAAiB,EACjB,WAAkB;IAElB,MAAM,GAAG,GAAG,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACvC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAExB,IAAI,YAAY,GAAW,EAAE,CAAC;IAC9B,IAAI,UAAU,GAAG,IAAI,KAAK,EAAE,CAAC;IAE7B,WAAW,CAAC,MAAM,CAAC,GAAG,EAAE;QACtB,UAAU,CAAC,OAAO,EAAE,CAAC;QACrB,UAAU,GAAG,IAAI,KAAK,EAAE,CAAC;QAEzB,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAW,EAAE,CAAC;QAC5B,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAE/B,yEAAyE;QACzE,wEAAwE;QACxE,0EAA0E;QAC1E,sEAAsE;QACtE,gBAAgB;QAChB,IAAI,WAAW,EAAE,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,QAAQ;gBAAE,oBAAoB,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC9D,CAAC;QAED,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,IAAI,MAAM,CAAC;QAExC,IAAI,YAAY,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"reactive.js","sourceRoot":"","sources":["../src/reactive.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@praxisjs/runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
"typescript": "^6.0.3"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"@praxisjs/
|
|
18
|
-
"@praxisjs/
|
|
19
|
-
"@praxisjs/
|
|
17
|
+
"@praxisjs/decorators": "1.7.0",
|
|
18
|
+
"@praxisjs/shared": "0.3.1",
|
|
19
|
+
"@praxisjs/core": "2.2.0"
|
|
20
20
|
},
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "tsc",
|
|
@@ -216,3 +216,61 @@ describe("mountReactive", () => {
|
|
|
216
216
|
document.body.removeChild(parent);
|
|
217
217
|
});
|
|
218
218
|
});
|
|
219
|
+
|
|
220
|
+
describe("fine-grained rows", () => {
|
|
221
|
+
function setup() {
|
|
222
|
+
const ids = signal([1, 2]);
|
|
223
|
+
const titles = signal<Record<number, string>>({ 1: "a", 2: "b" });
|
|
224
|
+
let listRuns = 0;
|
|
225
|
+
const ul = container();
|
|
226
|
+
const scope = new Scope();
|
|
227
|
+
mountChildren(ul, () => {
|
|
228
|
+
listRuns++;
|
|
229
|
+
return ids().map((id) => {
|
|
230
|
+
const li = document.createElement("li");
|
|
231
|
+
mountChildren(li, () => titles()[id], scope);
|
|
232
|
+
return li;
|
|
233
|
+
});
|
|
234
|
+
}, scope);
|
|
235
|
+
return { ids, titles, ul, scope, runs: () => listRuns };
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
it("changing row content updates text in place without re-running the list function", () => {
|
|
239
|
+
const { titles, ul, scope, runs } = setup();
|
|
240
|
+
const rows = [...ul.querySelectorAll("li")];
|
|
241
|
+
titles.set({ 1: "A", 2: "b" });
|
|
242
|
+
expect(runs()).toBe(1);
|
|
243
|
+
expect([...ul.querySelectorAll("li")]).toEqual(rows);
|
|
244
|
+
expect(rows.map((r) => r.textContent)).toEqual(["A", "b"]);
|
|
245
|
+
scope.dispose();
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
it("changing the structure rebuilds the list", () => {
|
|
249
|
+
const { ids, titles, ul, scope, runs } = setup();
|
|
250
|
+
titles.set({ 1: "a", 2: "b", 3: "c" });
|
|
251
|
+
ids.set([1, 2, 3]);
|
|
252
|
+
expect(runs()).toBe(2);
|
|
253
|
+
expect(ul.querySelectorAll("li")).toHaveLength(3);
|
|
254
|
+
scope.dispose();
|
|
255
|
+
});
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
describe("mountReactive multi-node replacement", () => {
|
|
259
|
+
it("removes nodes that were inserted between the tracked ones after mount", () => {
|
|
260
|
+
const toggle = signal(0);
|
|
261
|
+
const parent = container();
|
|
262
|
+
const scope = new Scope();
|
|
263
|
+
let a!: Node;
|
|
264
|
+
mountChildren(parent, () => {
|
|
265
|
+
void toggle();
|
|
266
|
+
a = document.createElement("a");
|
|
267
|
+
return [a, document.createElement("b")];
|
|
268
|
+
}, scope);
|
|
269
|
+
const stray = document.createElement("stray");
|
|
270
|
+
parent.insertBefore(stray, a.nextSibling);
|
|
271
|
+
toggle.set(1);
|
|
272
|
+
expect(parent.contains(stray)).toBe(false);
|
|
273
|
+
expect([...parent.children].map((c) => c.localName)).toEqual(["a", "b"]);
|
|
274
|
+
scope.dispose();
|
|
275
|
+
});
|
|
276
|
+
});
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
// @vitest-environment jsdom
|
|
2
|
-
import { describe, it, expect, vi } from "vitest";
|
|
2
|
+
import { describe, it, expect, vi, afterEach } from "vitest";
|
|
3
3
|
|
|
4
4
|
import { StatefulComponent } from "@praxisjs/core";
|
|
5
5
|
import { getComponentProps } from "@praxisjs/core/internal";
|
|
6
6
|
|
|
7
7
|
import { mountComponent } from "../component";
|
|
8
|
+
import { getCurrentScope } from "../context";
|
|
9
|
+
import { mountElement } from "../element";
|
|
8
10
|
import { Scope } from "../scope";
|
|
9
11
|
|
|
10
12
|
class SimpleComp extends StatefulComponent {
|
|
@@ -295,3 +297,85 @@ describe("mountComponent", () => {
|
|
|
295
297
|
scope.dispose();
|
|
296
298
|
});
|
|
297
299
|
});
|
|
300
|
+
|
|
301
|
+
describe("mountComponent onMount scheduling", () => {
|
|
302
|
+
afterEach(() => {
|
|
303
|
+
vi.unstubAllGlobals();
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
function stubMicrotasks(): Array<() => void> {
|
|
307
|
+
const jobs: Array<() => void> = [];
|
|
308
|
+
vi.stubGlobal("queueMicrotask", (fn: () => void) => { jobs.push(fn); });
|
|
309
|
+
return jobs;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function lifecycleComp(onMount: () => void) {
|
|
313
|
+
return class extends StatefulComponent {
|
|
314
|
+
static __isComponent = true as const;
|
|
315
|
+
static __isStateless = false;
|
|
316
|
+
onMount() { onMount(); }
|
|
317
|
+
render() { return null; }
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
it("drains every component mounted in the same pass with a single microtask, in mount order", () => {
|
|
322
|
+
const jobs = stubMicrotasks();
|
|
323
|
+
const order: string[] = [];
|
|
324
|
+
const scope = new Scope();
|
|
325
|
+
mountComponent(lifecycleComp(() => order.push("a")), {}, scope);
|
|
326
|
+
mountComponent(lifecycleComp(() => order.push("b")), {}, scope);
|
|
327
|
+
expect(jobs).toHaveLength(1);
|
|
328
|
+
jobs.shift()?.();
|
|
329
|
+
expect(order).toEqual(["a", "b"]);
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
it("schedules a new microtask for components mounted after a drain", () => {
|
|
333
|
+
const jobs = stubMicrotasks();
|
|
334
|
+
const onMount = vi.fn();
|
|
335
|
+
const scope = new Scope();
|
|
336
|
+
mountComponent(lifecycleComp(onMount), {}, scope);
|
|
337
|
+
jobs.shift()?.();
|
|
338
|
+
mountComponent(lifecycleComp(onMount), {}, scope);
|
|
339
|
+
expect(jobs).toHaveLength(1);
|
|
340
|
+
jobs.shift()?.();
|
|
341
|
+
expect(onMount).toHaveBeenCalledTimes(2);
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
it("a throwing onMount does not stop the others and is rethrown on its own microtask", () => {
|
|
345
|
+
const jobs = stubMicrotasks();
|
|
346
|
+
const second = vi.fn();
|
|
347
|
+
const scope = new Scope();
|
|
348
|
+
mountComponent(lifecycleComp(() => { throw new Error("mount boom"); }), {}, scope);
|
|
349
|
+
mountComponent(lifecycleComp(second), {}, scope);
|
|
350
|
+
jobs.shift()?.();
|
|
351
|
+
expect(second).toHaveBeenCalledOnce();
|
|
352
|
+
expect(jobs).toHaveLength(1);
|
|
353
|
+
expect(() => { jobs.shift()?.(); }).toThrow("mount boom");
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
it("skips onMount for a component disposed before the drain", () => {
|
|
357
|
+
const jobs = stubMicrotasks();
|
|
358
|
+
const onMount = vi.fn();
|
|
359
|
+
const scope = new Scope();
|
|
360
|
+
mountComponent(lifecycleComp(onMount), {}, scope);
|
|
361
|
+
scope.dispose();
|
|
362
|
+
jobs.shift()?.();
|
|
363
|
+
expect(onMount).not.toHaveBeenCalled();
|
|
364
|
+
});
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
describe("mountComponent with optional event handlers", () => {
|
|
368
|
+
class OptionalHandlers extends StatefulComponent {
|
|
369
|
+
static __isComponent = true as const;
|
|
370
|
+
static __isStateless = false;
|
|
371
|
+
render() {
|
|
372
|
+
return mountElement("form", { onSubmit: undefined, onClick: null, children: "content" }, getCurrentScope());
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
it("renders the element instead of failing when a forwarded handler is not provided", () => {
|
|
377
|
+
const nodes = mountComponent(OptionalHandlers, {}, new Scope());
|
|
378
|
+
const form = nodes.find((n) => n instanceof HTMLFormElement);
|
|
379
|
+
expect(form?.textContent).toBe("content");
|
|
380
|
+
});
|
|
381
|
+
});
|