Skip to content

Commit 0f89cb4

Browse files
committed
5.0.6
1 parent 362424e commit 0f89cb4

5 files changed

Lines changed: 66 additions & 89 deletions

File tree

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
{
22
"name": "uhtml",
3-
"version": "5.0.5",
3+
"version": "5.0.6",
44
"type": "module",
55
"scripts": {
66
"build": "npm run types && npm run build:js",
7-
"build:js": "npm test && npm run build:prod && npm run build:dev && npm run size",
7+
"build:js": "rm -rf dist && npm test && npm run build:prod && npm run build:dev && npm run size",
88
"build:dev": "sed -i 's/false/true/' src/debug.js && rollup -c build/dev.js",
99
"build:prod": "sed -i 's/true/false/' src/debug.js && rollup -c build/prod.js",
1010
"coverage": "mkdir -p ./coverage; c8 report --reporter=text-lcov > ./coverage/lcov.info",
1111
"size": "echo \"dom\t\t$(cat dist/prod/dom.js | brotli | wc -c)\"; echo \"json\t\t$(cat dist/prod/json.js | brotli | wc -c)\"; echo \"parser\t\t$(cat dist/prod/parser.js | brotli | wc -c)\"",
1212
"test": "c8 node test/parser.js",
1313
"test:json": "node test/json.js",
1414
"test:all": "npm run test:json && npm run test",
15-
"types": "tsc --allowJs --checkJs --lib dom,esnext --moduleResolution nodenext --module NodeNext --target esnext -d --emitDeclarationOnly --outDir ./types ./src/*.js ./src/*/*.js"
15+
"types": "rm -rf types && tsc --allowJs --checkJs --lib dom,esnext --moduleResolution nodenext --module NodeNext --target esnext -d --emitDeclarationOnly --outDir ./types ./src/*.js ./src/*/*.js"
1616
},
1717
"files": [
1818
"dist",

src/dom/rabbit.js

Lines changed: 58 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//@ts-check
1+
//@ts-nocheck
22

33
import DEBUG from '../debug.js';
44
import errors from '../errors.js';
@@ -19,6 +19,15 @@ import { Signal, _get as getSignal, _set as setSignal } from './signals.js';
1919
*/
2020
export const dom = hole => diffFragment(hole.n ? hole.update(hole) : hole.valueOf(false), 1);
2121

22+
const holed = (prev, current) => {
23+
const changes = [], h = prev.length, l = current.length;
24+
for (let c, p, j = 0, i = 0; i < l; i++) {
25+
c = current[i];
26+
changes[i] = j < h && (p = prev[j++]).t === c.t ? (current[i] = p).update(c) : c.valueOf(false);
27+
}
28+
return changes;
29+
};
30+
2231
/**
2332
* @param {Hole} hole
2433
* @param {unknown} value
@@ -57,13 +66,48 @@ const getHole = (hole, value) => {
5766
hole.update(value);
5867
}
5968
else {
60-
//@ts-ignore
6169
hole.n.replaceWith(dom(value));
6270
hole = value;
6371
}
6472
return hole;
6573
};
6674

75+
const createEffect = (node, value, obj) => {
76+
let signals = [], entry = [COMPONENT, null, obj], bootstrap = true, hole;
77+
effect(() => {
78+
if (bootstrap) {
79+
bootstrap = false;
80+
hole = component(value, obj, signals);
81+
if (!signals.length) signals = children;
82+
if (hole) {
83+
node.replaceWith(dom(hole));
84+
entry[1] = hole;
85+
}
86+
else node.remove();
87+
}
88+
else {
89+
const result = component(value, obj, signals);
90+
if (hole) {
91+
if (DEBUG && !(result instanceof Hole)) throw errors.invalid_component(value);
92+
if (getHole(hole, /** @type {Hole} */(result)) === result) entry[2] = (hole = result);
93+
}
94+
}
95+
});
96+
return entry;
97+
};
98+
99+
const updateRefs = refs => {
100+
for (const node of refs) {
101+
const value = node[ref];
102+
if (typeof value === 'function')
103+
value(node);
104+
else if (value instanceof Signal)
105+
value.value = node;
106+
else if (value)
107+
value.current = node;
108+
}
109+
};
110+
67111
const props = Symbol();
68112
const global = {};
69113

@@ -75,10 +119,7 @@ export class Hole {
75119
constructor(template, values) {
76120
this.t = template;
77121
this.v = values;
78-
this.c = children;
79-
/** @type {Node?} */
80122
this.n = null;
81-
/** @type {number} */
82123
this.k = -1;
83124
}
84125

@@ -93,67 +134,37 @@ export class Hole {
93134
let length = values.length;
94135
let changes = children;
95136
let node, prev, refs;
96-
//@ts-ignore
97137
if (DEBUG && length !== updates.length) throw errors.invalid_interpolation(this.t[3], values);
98138
if (0 < length) {
99139
changes = updates.slice(0);
100140
while (length--) {
101-
//@ts-ignore
102141
const [path, update, type] = updates[length];
103142
const value = values[length];
104143
if (prev !== path) {
105144
node = resolve(root, path);
106145
prev = path;
107-
//@ts-ignore
108146
if (DEBUG && !node) throw errors.invalid_path(this.t[3], path);
109147
}
110148
if (type & COMPONENT) {
111149
const obj = node[props] || (node[props] = {});
112150
if (type === COMPONENT) {
113151
for (const { name, value } of node.attributes) obj[name] ??= value;
114152
obj.children ??= [...node.content.childNodes];
115-
//@ts-ignore
116-
let signals = [], bootstrap = true, entry, hole;
117-
effect(() => {
118-
if (bootstrap) {
119-
bootstrap = false;
120-
//@ts-ignore
121-
hole = component(value, obj, signals);
122-
//@ts-ignore
123-
if (!signals.length) signals = children;
124-
if (hole) node.replaceWith(dom(hole));
125-
else node.remove();
126-
//@ts-ignore
127-
changes[length] = (entry = [type, hole, obj]);
128-
}
129-
else {
130-
//@ts-ignore
131-
const result = component(value, obj, signals);
132-
if (hole) {
133-
if (DEBUG && !(result instanceof Hole)) throw errors.invalid_component(value);
134-
if (getHole(hole, /** @type {Hole} */(result)) === result) entry[2] = (hole = result);
135-
}
136-
}
137-
});
153+
changes[length] = createEffect(node, value, obj);
138154
}
139155
else {
140156
update(obj, value);
141-
//@ts-ignore
142157
changes[length] = [type, update, obj];
143158
}
144159
}
145160
else {
146161
let commit = true;
147-
//@ts-ignore
148162
if (DEBUG && (type & ARRAY) && !isArray(value)) throw errors.invalid_interpolation(this.t[3], value);
149163
if (!direct && (type & COMMENT) && !(type & SIGNAL)) {
150164
if (type & ARRAY) {
151165
commit = false;
152-
//@ts-ignore
153-
if (value.length) {
154-
//@ts-ignore
155-
node.before(...(node[nodes] = value[0] instanceof Hole ? value.map(dom) : value));
156-
}
166+
if (value.length)
167+
update(node, value[0] instanceof Hole ? holed(children, value) : value);
157168
}
158169
else if (value instanceof Hole) {
159170
commit = false;
@@ -170,37 +181,19 @@ export class Hole {
170181
update(node, value);
171182
}
172183
}
173-
//@ts-ignore
174184
changes[length] = [type, update, value, node];
175185
if (direct && (type & COMMENT)) node.remove();
176186
}
177187
}
178-
if (refs) {
179-
for (const node of refs) {
180-
const value = node[ref];
181-
if (typeof value === 'function')
182-
value(node);
183-
else if (value instanceof Signal)
184-
value.value = node;
185-
else if (value)
186-
value.current = node;
187-
}
188-
}
188+
if (refs) updateRefs(refs);
189189
}
190190

191191
const { childNodes } = root;
192192
const size = childNodes.length;
193193
const n = size === 1 ? childNodes[0] : (size ? PersistentFragment(root) : root);
194-
if (!direct) {
195-
//@ts-ignore
196-
this.v = children;
197-
this.c = changes;
198-
this.n = n;
199-
if (-1 < this.k) {
200-
//@ts-ignore
201-
keys.set(changes[this.k][2], n, this);
202-
}
203-
}
194+
this.v = changes;
195+
this.n = n;
196+
if (-1 < this.k) keys.set(changes[this.k][2], n, this);
204197
return n;
205198
}
206199

@@ -210,7 +203,7 @@ export class Hole {
210203
*/
211204
update(hole) {
212205
const key = this.k;
213-
const changes = this.c;
206+
const changes = this.v;
214207
const values = hole.v;
215208

216209
if (-1 < key && changes[key][2] !== values[key])
@@ -225,7 +218,6 @@ export class Hole {
225218
if (type & COMPONENT) {
226219
if (type === COMPONENT) {
227220
if (DEBUG && typeof value !== 'function') throw errors.invalid_component(value);
228-
//@ts-ignore
229221
const result = value(prev, global);
230222
if (update) {
231223
if (DEBUG && !(result instanceof Hole)) throw errors.invalid_component(value);
@@ -239,25 +231,14 @@ export class Hole {
239231
if (type & ARRAY) {
240232
if (DEBUG && !isArray(value)) throw errors.invalid_interpolation([], value);
241233
if (type & COMMENT) {
242-
//@ts-ignore
243-
const l = value.length;
244-
const h = prev.length;
245234
// TODO: a smarter differ that does not require 2 loops
246-
//@ts-ignore
247-
if (l && (value[0] instanceof Hole)) {
248-
//@ts-ignore
249-
if (DEBUG && h && !(prev[0] instanceof Hole)) throw errors.invalid_interpolation([], value[0]);
250-
change = [];
251-
//@ts-ignore
252-
for (let c, p, j = 0, i = 0; i < l; i++) {
253-
//@ts-ignore
254-
c = value[i];
255-
//@ts-ignore
256-
change[i] = j < h && (p = prev[j++]).t === c.t ? (value[i] = p).update(c) : dom(c);
235+
if (value.length) {
236+
if (value[0] instanceof Hole) {
237+
if (DEBUG && prev.length && !(prev[0] instanceof Hole)) throw errors.invalid_interpolation([], value[0]);
238+
change = holed(prev, value);
257239
}
258240
}
259241
}
260-
//@ts-ignore
261242
else if ((type & EVENT) && (value[0] === prev[0])) continue;
262243
}
263244
else if (type & COMMENT) {
@@ -270,7 +251,6 @@ export class Hole {
270251
else if (prev instanceof Hole) {
271252
if (DEBUG && !(value instanceof Hole)) throw errors.invalid_interpolation([], value);
272253
value = getHole(prev, /** @type {Hole} */(value));
273-
//@ts-ignore
274254
change = value.n;
275255
}
276256
}

src/dom/update.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Signal } from './signals.js';
1313
import { Unsafe, assign, entries, isArray } from '../utils.js';
1414
import { PersistentFragment, diffFragment, nodes } from './persistent-fragment.js';
1515
import creator from './creator.js';
16-
import domdiff from './diff.js';
16+
import diff from './diff.js';
1717

1818
export const ARRAY = 1 << 0;
1919
export const ARIA = 1 << 1;
@@ -56,7 +56,7 @@ const attribute = name => (node, value) => {
5656
};
5757

5858
const comment_array = (node, value) => {
59-
node[nodes] = domdiff(
59+
node[nodes] = diff(
6060
node[nodes] || children,
6161
value,
6262
diffFragment,

types/dom/rabbit.d.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ export class Hole {
77
constructor(template: [DocumentFragment, unknown[], import("./keyed.js").Keyed?], values: unknown[]);
88
t: [DocumentFragment, unknown[], import("./keyed.js").Keyed?];
99
v: unknown[];
10-
c: readonly any[];
11-
/** @type {Node?} */
12-
n: Node | null;
13-
/** @type {number} */
10+
n: DocumentFragment | ChildNode;
1411
k: number;
1512
/**
1613
* @param {boolean} [direct]

0 commit comments

Comments
 (0)