@miaskiewicz/turbo-dom 0.1.23 → 0.1.24
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miaskiewicz/turbo-dom",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.24",
|
|
4
4
|
"description": "Faster, more spec-correct DOM for test runners — native html5ever (Rust/WASM) parser + lazy copy-on-write DOM. A drop-in-style alternative to jsdom/happy-dom for vitest & jest.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -5,23 +5,32 @@ function makeLive(getArray, extra = {}) {
|
|
|
5
5
|
const target = function () {};
|
|
6
6
|
return new Proxy(target, {
|
|
7
7
|
get(_t, key) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
8
|
+
if (typeof key === 'string') {
|
|
9
|
+
// hot path: indexed access coll[i]. A property key starting with a digit
|
|
10
|
+
// is a numeric index — detect via charCode, no regex, no string-compare
|
|
11
|
+
// chain. getArray() is called only when actually needed.
|
|
12
|
+
const c = key.charCodeAt(0);
|
|
13
|
+
if (c >= 48 && c <= 57) return getArray()[+key];
|
|
14
|
+
if (key === 'length') return getArray().length;
|
|
15
|
+
if (key === 'item') return (i) => getArray()[i] ?? null;
|
|
16
|
+
if (key === 'forEach') return (cb, thisArg) => getArray().forEach(cb, thisArg);
|
|
17
|
+
if (key === 'entries') return () => getArray().entries();
|
|
18
|
+
if (key === 'keys') return () => getArray().keys();
|
|
19
|
+
if (key === 'values') return () => getArray()[Symbol.iterator]();
|
|
20
|
+
if (key === 'toString') return () => '[object NodeList]';
|
|
21
|
+
if (key in extra) return extra[key](getArray());
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
if (key === Symbol.iterator) return () => getArray()[Symbol.iterator]();
|
|
19
25
|
return undefined;
|
|
20
26
|
},
|
|
21
27
|
has(_t, key) {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
28
|
+
if (typeof key === 'string') {
|
|
29
|
+
const c = key.charCodeAt(0);
|
|
30
|
+
if (c >= 48 && c <= 57) return +key < getArray().length;
|
|
31
|
+
return key === 'length' || key === 'item' || key === 'forEach' || key in extra;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
25
34
|
},
|
|
26
35
|
ownKeys() {
|
|
27
36
|
const arr = getArray();
|
|
@@ -30,8 +39,11 @@ function makeLive(getArray, extra = {}) {
|
|
|
30
39
|
getOwnPropertyDescriptor(_t, key) {
|
|
31
40
|
const arr = getArray();
|
|
32
41
|
if (key === 'length') return { configurable: true, enumerable: false, value: arr.length };
|
|
33
|
-
if (typeof key === 'string'
|
|
34
|
-
|
|
42
|
+
if (typeof key === 'string') {
|
|
43
|
+
const c = key.charCodeAt(0);
|
|
44
|
+
if (c >= 48 && c <= 57 && +key < arr.length) {
|
|
45
|
+
return { configurable: true, enumerable: true, value: arr[+key] };
|
|
46
|
+
}
|
|
35
47
|
}
|
|
36
48
|
return undefined;
|
|
37
49
|
},
|
package/src/runtime/events.mjs
CHANGED
|
@@ -114,13 +114,16 @@ function normalizeOptions(options) {
|
|
|
114
114
|
|
|
115
115
|
export class EventTarget {
|
|
116
116
|
constructor() {
|
|
117
|
-
// type -> array of { callback, capture, once, passive }
|
|
118
|
-
|
|
117
|
+
// type -> array of { callback, capture, once, passive }. Lazily created on
|
|
118
|
+
// first addEventListener — most inflated nodes never get a listener, so this
|
|
119
|
+
// skips a Map allocation per node (inflation is a top hot path).
|
|
120
|
+
this.__listeners = null;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
addEventListener(type, callback, options) {
|
|
122
124
|
if (callback == null) return;
|
|
123
125
|
const o = normalizeOptions(options);
|
|
126
|
+
if (!this.__listeners) this.__listeners = new Map();
|
|
124
127
|
let list = this.__listeners.get(type);
|
|
125
128
|
if (!list) { list = []; this.__listeners.set(type, list); }
|
|
126
129
|
// dedupe on (callback, capture) per spec
|
|
@@ -129,6 +132,7 @@ export class EventTarget {
|
|
|
129
132
|
}
|
|
130
133
|
|
|
131
134
|
removeEventListener(type, callback, options) {
|
|
135
|
+
if (!this.__listeners) return;
|
|
132
136
|
const o = normalizeOptions(options);
|
|
133
137
|
const list = this.__listeners.get(type);
|
|
134
138
|
if (!list) return;
|
|
Binary file
|