@expressive/dom 0.0.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/README.md +79 -0
- package/dist/chunk-vnode-DA7cLTKP.js +33 -0
- package/dist/chunk-vnode-DA7cLTKP.js.map +1 -0
- package/dist/chunk-vnode-DHwzzX6t.d.ts +25 -0
- package/dist/index.d.ts +148 -0
- package/dist/index.js +1664 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +9 -0
- package/dist/jsx-dev-runtime.js +11 -0
- package/dist/jsx-dev-runtime.js.map +1 -0
- package/dist/jsx-runtime.d.ts +57 -0
- package/dist/jsx-runtime.js +23 -0
- package/dist/jsx-runtime.js.map +1 -0
- package/package.json +59 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1664 @@
|
|
|
1
|
+
import { a as vnode, i as isVNode, n as childrenOf, r as createPortal, t as PORTAL } from "./chunk-vnode-DA7cLTKP.js";
|
|
2
|
+
import "./jsx-runtime.js";
|
|
3
|
+
import { Component, Context, State, has, map, pending, unbind } from "@expressive/mvc";
|
|
4
|
+
import { watch } from "@expressive/mvc/observable";
|
|
5
|
+
import { Fragment } from "@expressive/mvc/runtime";
|
|
6
|
+
|
|
7
|
+
//#region src/scheduler.ts
|
|
8
|
+
const urgent = /* @__PURE__ */ new Set();
|
|
9
|
+
const passive = /* @__PURE__ */ new Set();
|
|
10
|
+
const after = [];
|
|
11
|
+
let depth$1 = 0;
|
|
12
|
+
let urgentQueued = false;
|
|
13
|
+
let passiveQueued = false;
|
|
14
|
+
function flush(scopes) {
|
|
15
|
+
for (const scope of scopes) {
|
|
16
|
+
scopes.delete(scope);
|
|
17
|
+
scope.queued = void 0;
|
|
18
|
+
let waiting = void 0;
|
|
19
|
+
try {
|
|
20
|
+
waiting = scope.update(false);
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(error);
|
|
23
|
+
}
|
|
24
|
+
settle$1(scope);
|
|
25
|
+
if (!waiting) unblock(scope);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function flushUrgent() {
|
|
29
|
+
urgentQueued = false;
|
|
30
|
+
flush(urgent);
|
|
31
|
+
for (const run of after.splice(0)) run();
|
|
32
|
+
}
|
|
33
|
+
function afterFlush(run) {
|
|
34
|
+
after.push(run);
|
|
35
|
+
if (!urgentQueued) {
|
|
36
|
+
urgentQueued = true;
|
|
37
|
+
queueMicrotask(flushUrgent);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function flushPassive() {
|
|
41
|
+
passiveQueued = false;
|
|
42
|
+
const batch = [...passive].filter((scope) => scope.queued === "passive");
|
|
43
|
+
passive.clear();
|
|
44
|
+
for (const scope of batch) {
|
|
45
|
+
const waiting = scope.probe?.();
|
|
46
|
+
if (waiting) return defer(batch, waiting, scope);
|
|
47
|
+
}
|
|
48
|
+
batch.sort((a, b) => Number(!!b.empty?.()) - Number(!!a.empty?.()));
|
|
49
|
+
for (let index = 0; index < batch.length; index++) {
|
|
50
|
+
const scope = batch[index];
|
|
51
|
+
if (scope.queued !== "passive") continue;
|
|
52
|
+
scope.queued = void 0;
|
|
53
|
+
let waiting = void 0;
|
|
54
|
+
try {
|
|
55
|
+
waiting = scope.update(true);
|
|
56
|
+
} catch (error) {
|
|
57
|
+
console.error(error);
|
|
58
|
+
}
|
|
59
|
+
settle$1(scope);
|
|
60
|
+
if (waiting) return defer(batch.slice(index + 1), waiting, scope);
|
|
61
|
+
unblock(scope);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function defer(scopes, waiting, source) {
|
|
65
|
+
const held = scopes.filter((scope) => scope.queued === "passive");
|
|
66
|
+
for (const scope of held) {
|
|
67
|
+
scope.queued = "deferred";
|
|
68
|
+
scope.probed = void 0;
|
|
69
|
+
}
|
|
70
|
+
const resume = () => {
|
|
71
|
+
for (const scope of held) if (scope.queued === "deferred") {
|
|
72
|
+
scope.queued = void 0;
|
|
73
|
+
transition(() => schedule(scope));
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
(source.blocking ||= []).push(resume);
|
|
77
|
+
waiting.then(resume, resume);
|
|
78
|
+
}
|
|
79
|
+
function unblock(scope) {
|
|
80
|
+
const { blocking } = scope;
|
|
81
|
+
scope.blocking = void 0;
|
|
82
|
+
blocking?.forEach((resume) => resume());
|
|
83
|
+
}
|
|
84
|
+
function release(holds) {
|
|
85
|
+
holds?.forEach((held) => held());
|
|
86
|
+
}
|
|
87
|
+
function settle$1(scope) {
|
|
88
|
+
const { holds } = scope;
|
|
89
|
+
scope.holds = void 0;
|
|
90
|
+
release(holds);
|
|
91
|
+
}
|
|
92
|
+
function schedule(scope) {
|
|
93
|
+
const held = pending();
|
|
94
|
+
if (held) (scope.holds ||= []).push(held);
|
|
95
|
+
scope.probed = void 0;
|
|
96
|
+
if (!depth$1) {
|
|
97
|
+
passive.delete(scope);
|
|
98
|
+
scope.queued = "urgent";
|
|
99
|
+
urgent.add(scope);
|
|
100
|
+
if (!urgentQueued) {
|
|
101
|
+
urgentQueued = true;
|
|
102
|
+
queueMicrotask(flushUrgent);
|
|
103
|
+
}
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
if (scope.queued && scope.queued !== "deferred") return;
|
|
107
|
+
scope.queued = "passive";
|
|
108
|
+
passive.add(scope);
|
|
109
|
+
if (!passiveQueued) {
|
|
110
|
+
passiveQueued = true;
|
|
111
|
+
setTimeout(flushPassive);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function transition(work) {
|
|
115
|
+
depth$1++;
|
|
116
|
+
try {
|
|
117
|
+
work();
|
|
118
|
+
} finally {
|
|
119
|
+
depth$1--;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function claim$1(scope) {
|
|
123
|
+
urgent.delete(scope);
|
|
124
|
+
passive.delete(scope);
|
|
125
|
+
scope.queued = void 0;
|
|
126
|
+
scope.probed = void 0;
|
|
127
|
+
}
|
|
128
|
+
function unschedule(scope) {
|
|
129
|
+
urgent.delete(scope);
|
|
130
|
+
passive.delete(scope);
|
|
131
|
+
scope.queued = void 0;
|
|
132
|
+
scope.probed = void 0;
|
|
133
|
+
settle$1(scope);
|
|
134
|
+
unblock(scope);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
//#endregion
|
|
138
|
+
//#region src/adapter.ts
|
|
139
|
+
let current;
|
|
140
|
+
let collecting;
|
|
141
|
+
function enter(scope, render) {
|
|
142
|
+
const parent = current;
|
|
143
|
+
const releases = collecting;
|
|
144
|
+
const next = [];
|
|
145
|
+
current = scope;
|
|
146
|
+
collecting = next;
|
|
147
|
+
scope.childContext = scope.context;
|
|
148
|
+
scope.useIndex = 0;
|
|
149
|
+
try {
|
|
150
|
+
const output = render();
|
|
151
|
+
if (scope.kind == "function" && scope.useIndex !== scope.uses.length) throw new Error("State.use() calls must keep the same order on every function-component render.");
|
|
152
|
+
return output;
|
|
153
|
+
} finally {
|
|
154
|
+
current = parent;
|
|
155
|
+
collecting = releases;
|
|
156
|
+
scope.subscriptions.forEach((release) => release());
|
|
157
|
+
scope.subscriptions = next;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function dispose(scope) {
|
|
161
|
+
scope.active = false;
|
|
162
|
+
unschedule(scope);
|
|
163
|
+
scope.subscriptions.forEach((release) => release());
|
|
164
|
+
scope.subscriptions = [];
|
|
165
|
+
for (let i = scope.uses.length - 1; i >= 0; i--) {
|
|
166
|
+
const slot = scope.uses[i];
|
|
167
|
+
slot.release();
|
|
168
|
+
if (typeof slot.cleanup == "function") slot.cleanup();
|
|
169
|
+
slot.context.pop();
|
|
170
|
+
slot.instance.set(null);
|
|
171
|
+
}
|
|
172
|
+
scope.uses = [];
|
|
173
|
+
}
|
|
174
|
+
function commit(scope) {
|
|
175
|
+
for (const slot of scope.uses) if (!slot.mounted) {
|
|
176
|
+
slot.mounted = true;
|
|
177
|
+
slot.cleanup = slot.instance.mount?.();
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
function requireScope() {
|
|
181
|
+
if (!current) throw new Error("State.get() and State.use() may only run while @expressive/dom is rendering.");
|
|
182
|
+
return current;
|
|
183
|
+
}
|
|
184
|
+
function tracked(target, required) {
|
|
185
|
+
const scope = requireScope();
|
|
186
|
+
let proxy = target;
|
|
187
|
+
let first = true;
|
|
188
|
+
const release = watch(target, (next) => {
|
|
189
|
+
proxy = next;
|
|
190
|
+
if (!first && scope.active) schedule(scope);
|
|
191
|
+
first = false;
|
|
192
|
+
}, required, transition);
|
|
193
|
+
collecting.push(release);
|
|
194
|
+
return proxy;
|
|
195
|
+
}
|
|
196
|
+
State.get = function get(argument) {
|
|
197
|
+
const scope = requireScope();
|
|
198
|
+
const instance = scope.childContext.get(this, argument === false ? false : true);
|
|
199
|
+
if (!instance) return void 0;
|
|
200
|
+
const proxy = tracked(instance, argument === true);
|
|
201
|
+
if (typeof argument != "function") return proxy;
|
|
202
|
+
const refresh = ((action) => {
|
|
203
|
+
if (typeof action == "function") action = action();
|
|
204
|
+
schedule(scope);
|
|
205
|
+
return action instanceof Promise ? action.finally(() => schedule(scope)) : void 0;
|
|
206
|
+
});
|
|
207
|
+
return argument.call(proxy, proxy, refresh) ?? null;
|
|
208
|
+
};
|
|
209
|
+
State.use = function use(...args) {
|
|
210
|
+
const scope = requireScope();
|
|
211
|
+
if (scope.kind != "function") throw new Error("State.use() is only available at the top level of a function component.");
|
|
212
|
+
const index = scope.useIndex++;
|
|
213
|
+
let slot = scope.uses[index];
|
|
214
|
+
if (slot && slot.Type !== this) throw new Error("State.use() calls must keep the same order on every function-component render.");
|
|
215
|
+
if (!slot) {
|
|
216
|
+
let instance;
|
|
217
|
+
const assign = (value) => typeof value == "object" && value && instance.set(value);
|
|
218
|
+
let apply = (...values) => Promise.all(values.flat().map(assign));
|
|
219
|
+
instance = new this((self) => {
|
|
220
|
+
const own = self;
|
|
221
|
+
if (typeof own.use == "function") {
|
|
222
|
+
apply = own.use.bind(own);
|
|
223
|
+
apply(...args);
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
return args;
|
|
227
|
+
});
|
|
228
|
+
const context = scope.childContext.push(instance);
|
|
229
|
+
slot = {
|
|
230
|
+
Type: this,
|
|
231
|
+
context,
|
|
232
|
+
instance,
|
|
233
|
+
proxy: instance,
|
|
234
|
+
release: void 0,
|
|
235
|
+
apply
|
|
236
|
+
};
|
|
237
|
+
let first = true;
|
|
238
|
+
slot.release = watch(instance, (proxy) => {
|
|
239
|
+
slot.proxy = proxy;
|
|
240
|
+
if (!first && scope.active) schedule(scope);
|
|
241
|
+
first = false;
|
|
242
|
+
}, void 0, transition);
|
|
243
|
+
slot.apply = apply;
|
|
244
|
+
scope.uses.push(slot);
|
|
245
|
+
} else slot.apply(...args);
|
|
246
|
+
scope.childContext = slot.context;
|
|
247
|
+
return slot.proxy;
|
|
248
|
+
};
|
|
249
|
+
Object.defineProperty(Component, "use", {
|
|
250
|
+
configurable: true,
|
|
251
|
+
value() {
|
|
252
|
+
throw new Error(`${this} is a Component - render it instead of calling use().`);
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
Component.on({
|
|
256
|
+
type(type) {
|
|
257
|
+
subcomponents(type.prototype);
|
|
258
|
+
},
|
|
259
|
+
before(self) {
|
|
260
|
+
subcomponents(self, true);
|
|
261
|
+
}
|
|
262
|
+
});
|
|
263
|
+
function subcomponents(target, configurable) {
|
|
264
|
+
for (const key of Object.getOwnPropertyNames(target)) {
|
|
265
|
+
if (!/^[A-Z]/.test(key)) continue;
|
|
266
|
+
const { value } = Object.getOwnPropertyDescriptor(target, key);
|
|
267
|
+
if (typeof value != "function") continue;
|
|
268
|
+
Object.defineProperty(target, key, {
|
|
269
|
+
configurable,
|
|
270
|
+
get() {
|
|
271
|
+
const owner = this.is;
|
|
272
|
+
let render = unbind(value);
|
|
273
|
+
const Subcomponent = (props) => render.call(tracked(owner), props);
|
|
274
|
+
Object.defineProperty(owner, key, {
|
|
275
|
+
configurable: true,
|
|
276
|
+
get: () => Subcomponent,
|
|
277
|
+
set(next) {
|
|
278
|
+
render = next;
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
return Subcomponent;
|
|
282
|
+
},
|
|
283
|
+
set(next) {
|
|
284
|
+
Object.defineProperty(this, key, {
|
|
285
|
+
value: next,
|
|
286
|
+
writable: true,
|
|
287
|
+
enumerable: true,
|
|
288
|
+
configurable: true
|
|
289
|
+
});
|
|
290
|
+
subcomponents(this, true);
|
|
291
|
+
}
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
//#endregion
|
|
297
|
+
//#region src/context.ts
|
|
298
|
+
function Consumer(props) {
|
|
299
|
+
return props.for.get((value) => props.children(value));
|
|
300
|
+
}
|
|
301
|
+
function Provider(_props) {
|
|
302
|
+
throw new Error("Provider must be rendered by @expressive/dom.");
|
|
303
|
+
}
|
|
304
|
+
function provide(context, props) {
|
|
305
|
+
const { for: input, is, children: _children, fallback: _fallback, name: _name, ...rest } = props;
|
|
306
|
+
const mount = [];
|
|
307
|
+
let single;
|
|
308
|
+
const solo = State.is(input) || input instanceof State;
|
|
309
|
+
context.set(input || {}, (state, owned) => {
|
|
310
|
+
if (solo) single = state;
|
|
311
|
+
is?.(state);
|
|
312
|
+
if (owned) {
|
|
313
|
+
let cleanup;
|
|
314
|
+
mount.push(() => {
|
|
315
|
+
cleanup = state.mount?.();
|
|
316
|
+
});
|
|
317
|
+
return () => cleanup?.();
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
if (solo && !single) {
|
|
321
|
+
const Type = input instanceof State ? input.constructor : input;
|
|
322
|
+
single = context.get(Type, false);
|
|
323
|
+
}
|
|
324
|
+
if (single && Object.keys(rest).length) single.set(rest);
|
|
325
|
+
return () => mount.forEach((commit) => commit());
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region src/lazy.ts
|
|
330
|
+
function lazy(load) {
|
|
331
|
+
let pending;
|
|
332
|
+
let resolved;
|
|
333
|
+
let rejected;
|
|
334
|
+
let failed = false;
|
|
335
|
+
return function Lazy(props) {
|
|
336
|
+
if (failed) throw rejected;
|
|
337
|
+
if (resolved) return vnode(resolved, props);
|
|
338
|
+
if (!pending) pending = load().then((module) => {
|
|
339
|
+
const output = typeof module == "function" ? module : module?.default;
|
|
340
|
+
if (typeof output != "function") {
|
|
341
|
+
failed = true;
|
|
342
|
+
rejected = /* @__PURE__ */ new Error("lazy() loader resolved no component.");
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
resolved = output;
|
|
346
|
+
}, (error) => {
|
|
347
|
+
failed = true;
|
|
348
|
+
rejected = error;
|
|
349
|
+
});
|
|
350
|
+
throw pending;
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region src/css.ts
|
|
356
|
+
const unitless = /* @__PURE__ */ new Map();
|
|
357
|
+
let probe;
|
|
358
|
+
/**
|
|
359
|
+
* Does the CSSOM accept a bare number for this property? Probed once with a
|
|
360
|
+
* canonical value; the answer is a property of CSS, not of the value.
|
|
361
|
+
*/
|
|
362
|
+
function bare(property) {
|
|
363
|
+
let known = unitless.get(property);
|
|
364
|
+
if (known === void 0) {
|
|
365
|
+
probe ||= document.createElement("div").style;
|
|
366
|
+
probe[property] = "";
|
|
367
|
+
probe[property] = 1;
|
|
368
|
+
unitless.set(property, known = Boolean(probe[property]));
|
|
369
|
+
}
|
|
370
|
+
return known;
|
|
371
|
+
}
|
|
372
|
+
function sized(property, value) {
|
|
373
|
+
if (Array.isArray(value)) return value.map((entry) => sized(property, entry));
|
|
374
|
+
return typeof value == "number" && value !== 0 && !bare(property) ? `${value}px` : value;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Web macro pack. Register with `macro(css)` to opt into pixel units for
|
|
378
|
+
* numbers and the axis shorthands CSS itself does not provide.
|
|
379
|
+
*/
|
|
380
|
+
const css = {
|
|
381
|
+
"*": (value, key) => ({ [key]: sized(key, value) }),
|
|
382
|
+
mx: (value) => ({
|
|
383
|
+
marginLeft: value,
|
|
384
|
+
marginRight: value
|
|
385
|
+
}),
|
|
386
|
+
my: (value) => ({
|
|
387
|
+
marginTop: value,
|
|
388
|
+
marginBottom: value
|
|
389
|
+
}),
|
|
390
|
+
px: (value) => ({
|
|
391
|
+
paddingLeft: value,
|
|
392
|
+
paddingRight: value
|
|
393
|
+
}),
|
|
394
|
+
py: (value) => ({
|
|
395
|
+
paddingTop: value,
|
|
396
|
+
paddingBottom: value
|
|
397
|
+
}),
|
|
398
|
+
size: (value) => Array.isArray(value) ? {
|
|
399
|
+
width: value[0],
|
|
400
|
+
height: value[1]
|
|
401
|
+
} : {
|
|
402
|
+
width: value,
|
|
403
|
+
height: value
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
//#endregion
|
|
408
|
+
//#region src/appearance-protocol.ts
|
|
409
|
+
const registrations = /* @__PURE__ */ new WeakMap();
|
|
410
|
+
const tokens = /* @__PURE__ */ new WeakMap();
|
|
411
|
+
let root;
|
|
412
|
+
let emitter;
|
|
413
|
+
let rendered = false;
|
|
414
|
+
function registerAppearance(type, enter) {
|
|
415
|
+
registrations.set(type, enter);
|
|
416
|
+
}
|
|
417
|
+
function registerAppearanceRoot(factory) {
|
|
418
|
+
root = factory;
|
|
419
|
+
}
|
|
420
|
+
function registerEmitter(emit) {
|
|
421
|
+
emitter = emit;
|
|
422
|
+
}
|
|
423
|
+
function emitClass(block, depth, document) {
|
|
424
|
+
return emitter(block, depth, document);
|
|
425
|
+
}
|
|
426
|
+
function appearanceRoot() {
|
|
427
|
+
rendered = true;
|
|
428
|
+
return root?.();
|
|
429
|
+
}
|
|
430
|
+
/** Has anything rendered yet - global registration is closed after it has. */
|
|
431
|
+
function appearanceSealed() {
|
|
432
|
+
return rendered;
|
|
433
|
+
}
|
|
434
|
+
function enterAppearance(parent, type) {
|
|
435
|
+
const chain = [];
|
|
436
|
+
let current = type;
|
|
437
|
+
while (current && current !== Function.prototype) {
|
|
438
|
+
const enter = registrations.get(current);
|
|
439
|
+
if (enter) chain.unshift(enter);
|
|
440
|
+
current = Object.getPrototypeOf(current);
|
|
441
|
+
}
|
|
442
|
+
for (const enter of chain) parent = enter(parent);
|
|
443
|
+
return parent;
|
|
444
|
+
}
|
|
445
|
+
function createAppearanceToken(appearance) {
|
|
446
|
+
const token = {};
|
|
447
|
+
tokens.set(token, appearance);
|
|
448
|
+
return token;
|
|
449
|
+
}
|
|
450
|
+
function appearanceToken(value) {
|
|
451
|
+
return value && typeof value == "object" ? tokens.get(value) : void 0;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
//#endregion
|
|
455
|
+
//#region src/appearance.ts
|
|
456
|
+
const bases = /* @__PURE__ */ new WeakMap();
|
|
457
|
+
const chains = /* @__PURE__ */ new WeakMap();
|
|
458
|
+
const contexts = /* @__PURE__ */ new WeakMap();
|
|
459
|
+
const rootScopes = /* @__PURE__ */ new WeakMap();
|
|
460
|
+
const styles = /* @__PURE__ */ new WeakMap();
|
|
461
|
+
const entered = /* @__PURE__ */ new WeakSet();
|
|
462
|
+
const globals = [];
|
|
463
|
+
let globalContext;
|
|
464
|
+
function createStyleScope(parent, value, label, defines) {
|
|
465
|
+
if (!isObject(value)) return parent;
|
|
466
|
+
const cache = parent?.children || rootScopes;
|
|
467
|
+
const cached = cache.get(value);
|
|
468
|
+
if (cached) return cached;
|
|
469
|
+
const own = [];
|
|
470
|
+
const source = {};
|
|
471
|
+
const base = {};
|
|
472
|
+
for (const key of Object.keys(value)) {
|
|
473
|
+
const entry = value[key];
|
|
474
|
+
if (key[0] == "$") throw new Error(`Reserved key "${key}" in style map.`);
|
|
475
|
+
if (key[0] == "_") {
|
|
476
|
+
if (!isObject(entry)) throw new Error(`Rule "${key}" must be an object. Macros are defined by macro().`);
|
|
477
|
+
const name = key.slice(1);
|
|
478
|
+
own.push(name);
|
|
479
|
+
source[name] = entry;
|
|
480
|
+
} else if (defines && typeof entry == "function") {
|
|
481
|
+
own.push(key);
|
|
482
|
+
source[key] = entry;
|
|
483
|
+
} else base[key] = entry;
|
|
484
|
+
}
|
|
485
|
+
const names = parent ? [...parent.names, ...own.filter((name) => !parent.names.includes(name))] : own;
|
|
486
|
+
const rules = Object.create(parent?.rules || null);
|
|
487
|
+
const labels = Object.create(parent?.labels || null);
|
|
488
|
+
const scopeLabel = label || parent?.label || "style";
|
|
489
|
+
for (const name of own) {
|
|
490
|
+
const rule = source[name];
|
|
491
|
+
const inherited = parent?.rules[name];
|
|
492
|
+
rules[name] = isObject(inherited) && isObject(rule) ? {
|
|
493
|
+
...inherited,
|
|
494
|
+
...rule
|
|
495
|
+
} : rule;
|
|
496
|
+
labels[name] = scopeLabel;
|
|
497
|
+
}
|
|
498
|
+
const scope = {
|
|
499
|
+
children: /* @__PURE__ */ new WeakMap(),
|
|
500
|
+
expansions: /* @__PURE__ */ new Map(),
|
|
501
|
+
label: scopeLabel,
|
|
502
|
+
labels,
|
|
503
|
+
names,
|
|
504
|
+
own: base,
|
|
505
|
+
routes: /* @__PURE__ */ new Map(),
|
|
506
|
+
rules
|
|
507
|
+
};
|
|
508
|
+
cache.set(value, scope);
|
|
509
|
+
return scope;
|
|
510
|
+
}
|
|
511
|
+
function createContext(scope) {
|
|
512
|
+
const cached = contexts.get(scope);
|
|
513
|
+
if (cached) return cached;
|
|
514
|
+
const context = {
|
|
515
|
+
scope,
|
|
516
|
+
base: baseToken(scope),
|
|
517
|
+
resolve(props, tag) {
|
|
518
|
+
return resolveAppearance(scope, props, tag);
|
|
519
|
+
}
|
|
520
|
+
};
|
|
521
|
+
contexts.set(scope, context);
|
|
522
|
+
return context;
|
|
523
|
+
}
|
|
524
|
+
function extendContext(parent, maps, label, defines) {
|
|
525
|
+
let scope = parent?.scope;
|
|
526
|
+
const base = { ...scope && bases.get(scope) };
|
|
527
|
+
for (const map of maps) {
|
|
528
|
+
scope = createStyleScope(scope, map, label, defines);
|
|
529
|
+
Object.assign(base, scope.own);
|
|
530
|
+
}
|
|
531
|
+
if (Object.keys(base).length) bases.set(scope, base);
|
|
532
|
+
return createContext(scope);
|
|
533
|
+
}
|
|
534
|
+
function baseToken(scope) {
|
|
535
|
+
const base = bases.get(scope);
|
|
536
|
+
if (!base) return void 0;
|
|
537
|
+
const expansion = expand(scope, base, /* @__PURE__ */ new Map());
|
|
538
|
+
const appearance = {};
|
|
539
|
+
if (Object.keys(expansion.declarations).length) appearance.blocks = [{
|
|
540
|
+
declarations: expansion.declarations,
|
|
541
|
+
name: scope.label,
|
|
542
|
+
ordinal: -1
|
|
543
|
+
}];
|
|
544
|
+
if (expansion.classes.length) appearance.classes = expansion.classes;
|
|
545
|
+
return createAppearanceToken(appearance);
|
|
546
|
+
}
|
|
547
|
+
function style$1(type, rules) {
|
|
548
|
+
if (entered.has(type)) throw new Error("Cannot add styles after a component has rendered.");
|
|
549
|
+
const maps = styles.get(type);
|
|
550
|
+
if (maps) maps.push(rules);
|
|
551
|
+
else {
|
|
552
|
+
const label = type.displayName || type.name;
|
|
553
|
+
styles.set(type, [rules]);
|
|
554
|
+
registerAppearance(type, (parent) => {
|
|
555
|
+
entered.add(type);
|
|
556
|
+
return extendContext(parent, styles.get(type), label);
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
return type;
|
|
560
|
+
}
|
|
561
|
+
function macro$1(rules) {
|
|
562
|
+
for (const key of Object.keys(rules)) if (key[0] != "_" && key[0] != "$" && typeof rules[key] != "function") throw new Error(`Macro "${key}" must be a function. Use "_${key}" to register a rule.`);
|
|
563
|
+
if (appearanceSealed()) throw new Error("Cannot add macros after rendering has started.");
|
|
564
|
+
globals.push(rules);
|
|
565
|
+
globalContext = void 0;
|
|
566
|
+
registerAppearanceRoot(() => globalContext ||= extendContext(void 0, globals, "global", true));
|
|
567
|
+
return rules;
|
|
568
|
+
}
|
|
569
|
+
function createAppearanceRoute(scope, props, tag) {
|
|
570
|
+
if (!scope) return void 0;
|
|
571
|
+
const keys = Object.keys(props).filter((key) => key.startsWith("_")).sort();
|
|
572
|
+
const id = `${tag || ""}\0${keys.join("\0")}`;
|
|
573
|
+
const cached = scope.routes.get(id);
|
|
574
|
+
if (cached) return cached;
|
|
575
|
+
const present = new Set(keys.map((key) => key.slice(1)));
|
|
576
|
+
const flags = [];
|
|
577
|
+
for (const name of scope.names) {
|
|
578
|
+
if (!present.has(name) || name == tag) continue;
|
|
579
|
+
if (isObject(scope.rules[name])) flags.push(name);
|
|
580
|
+
}
|
|
581
|
+
const route = {
|
|
582
|
+
flags,
|
|
583
|
+
scope,
|
|
584
|
+
tag: tag && isObject(scope.rules[tag]) ? tag : void 0
|
|
585
|
+
};
|
|
586
|
+
scope.routes.set(id, route);
|
|
587
|
+
return route;
|
|
588
|
+
}
|
|
589
|
+
function resolveAppearance(scope, props, tag) {
|
|
590
|
+
const route = createAppearanceRoute(scope, props, tag);
|
|
591
|
+
if (!route) return void 0;
|
|
592
|
+
const parts = [];
|
|
593
|
+
const names = route.tag ? [route.tag] : [];
|
|
594
|
+
for (const name of route.flags) if (props[`_${name}`]) names.push(name);
|
|
595
|
+
for (const name of names) parts.push(expandRule(route.scope, name));
|
|
596
|
+
const blocks = parts.flatMap((part) => part.block ? [part.block] : []);
|
|
597
|
+
const classes = parts.flatMap((part) => part.classes);
|
|
598
|
+
let child = route.scope;
|
|
599
|
+
for (const part of parts) for (const nested of part.nested) child = createStyleScope(child, nested, tag ? `${route.scope.label}_${tag}` : route.scope.label);
|
|
600
|
+
if (!blocks.length && !classes.length && child === route.scope) return void 0;
|
|
601
|
+
const appearance = {};
|
|
602
|
+
if (blocks.length) appearance.blocks = blocks;
|
|
603
|
+
if (classes.length) appearance.classes = classes;
|
|
604
|
+
if (child !== route.scope) appearance.context = createContext(child);
|
|
605
|
+
return appearance;
|
|
606
|
+
}
|
|
607
|
+
function expandRule(scope, name) {
|
|
608
|
+
let expansion = scope.expansions.get(name);
|
|
609
|
+
if (!expansion) {
|
|
610
|
+
expansion = expand(scope, scope.rules[name], /* @__PURE__ */ new Map());
|
|
611
|
+
if (Object.keys(expansion.declarations).length) expansion.block = {
|
|
612
|
+
declarations: expansion.declarations,
|
|
613
|
+
name: `${scope.labels[name]}_${name}`,
|
|
614
|
+
ordinal: scope.names.indexOf(name)
|
|
615
|
+
};
|
|
616
|
+
scope.expansions.set(name, expansion);
|
|
617
|
+
}
|
|
618
|
+
return expansion;
|
|
619
|
+
}
|
|
620
|
+
function handlers(scope, name) {
|
|
621
|
+
let known = chains.get(scope);
|
|
622
|
+
if (!known) chains.set(scope, known = /* @__PURE__ */ new Map());
|
|
623
|
+
let chain = known.get(name);
|
|
624
|
+
if (!chain) {
|
|
625
|
+
chain = [];
|
|
626
|
+
for (const key of [name, "*"]) for (let rules = scope.rules; rules; rules = Object.getPrototypeOf(rules)) {
|
|
627
|
+
const own = Object.getOwnPropertyDescriptor(rules, key);
|
|
628
|
+
if (own && typeof own.value == "function") chain.push(own.value);
|
|
629
|
+
}
|
|
630
|
+
known.set(name, chain);
|
|
631
|
+
}
|
|
632
|
+
return chain;
|
|
633
|
+
}
|
|
634
|
+
function expand(scope, value, depths) {
|
|
635
|
+
const output = {
|
|
636
|
+
classes: [],
|
|
637
|
+
declarations: {},
|
|
638
|
+
nested: []
|
|
639
|
+
};
|
|
640
|
+
const nested = {};
|
|
641
|
+
function walk(value, depths) {
|
|
642
|
+
if (!value) return;
|
|
643
|
+
if (typeof value == "string") {
|
|
644
|
+
output.classes.push(...value.split(/\s+/).filter(Boolean));
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
647
|
+
if (Array.isArray(value)) {
|
|
648
|
+
value.forEach((entry) => walk(entry, depths));
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
for (const [name, entry] of Object.entries(value)) {
|
|
652
|
+
if (name[0] == "_") {
|
|
653
|
+
if (isObject(entry)) nested[name] = entry;
|
|
654
|
+
continue;
|
|
655
|
+
}
|
|
656
|
+
const chain = handlers(scope, name);
|
|
657
|
+
const depth = depths.get(name) || 0;
|
|
658
|
+
if (depth < chain.length) {
|
|
659
|
+
if (isPresent(entry)) walk(chain[depth](entry === true ? void 0 : entry, name), new Map(depths).set(name, depth + 1));
|
|
660
|
+
} else output.declarations[name] = terminal(name, entry);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
walk(value, depths);
|
|
664
|
+
if (Object.keys(nested).length) output.nested.push(nested);
|
|
665
|
+
return output;
|
|
666
|
+
}
|
|
667
|
+
function terminal(name, value) {
|
|
668
|
+
if (Array.isArray(value)) return value.join(" ");
|
|
669
|
+
if (typeof value == "function" || isObject(value)) throw new Error(`No macro handles "${name}".`);
|
|
670
|
+
return typeof value == "number" ? String(value) : value;
|
|
671
|
+
}
|
|
672
|
+
function isPresent(value) {
|
|
673
|
+
return value !== false && value !== null && value !== void 0;
|
|
674
|
+
}
|
|
675
|
+
function isObject(value) {
|
|
676
|
+
return !!value && typeof value == "object" && !Array.isArray(value);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
//#endregion
|
|
680
|
+
//#region src/declarations.ts
|
|
681
|
+
function applyDeclarations(style, declarations, previous = {}) {
|
|
682
|
+
const target = style;
|
|
683
|
+
for (const key of Object.keys({
|
|
684
|
+
...previous,
|
|
685
|
+
...declarations
|
|
686
|
+
})) {
|
|
687
|
+
const value = declarations[key];
|
|
688
|
+
if (key.startsWith("--")) {
|
|
689
|
+
style.setProperty(key, value == null ? "" : String(value));
|
|
690
|
+
continue;
|
|
691
|
+
}
|
|
692
|
+
if (typeof value == "number") target[key] = "";
|
|
693
|
+
target[key] = value == null ? "" : value;
|
|
694
|
+
if (typeof value == "number" && value !== 0 && !target[key]) target[key] = `${value}px`;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
//#endregion
|
|
699
|
+
//#region src/stylesheet.ts
|
|
700
|
+
const sheets = /* @__PURE__ */ new WeakMap();
|
|
701
|
+
function style(type, rules) {
|
|
702
|
+
style$1(type, rules);
|
|
703
|
+
registerEmitter(emit);
|
|
704
|
+
return type;
|
|
705
|
+
}
|
|
706
|
+
function macro(rules) {
|
|
707
|
+
macro$1(rules);
|
|
708
|
+
registerEmitter(emit);
|
|
709
|
+
return rules;
|
|
710
|
+
}
|
|
711
|
+
function emit(block, depth, document) {
|
|
712
|
+
let sheet = sheets.get(document);
|
|
713
|
+
if (!sheet?.element.sheet) {
|
|
714
|
+
const element = document.createElement("style");
|
|
715
|
+
element.dataset.expressive = "dom";
|
|
716
|
+
document.head.append(element);
|
|
717
|
+
sheet = {
|
|
718
|
+
element,
|
|
719
|
+
emitted: /* @__PURE__ */ new WeakMap(),
|
|
720
|
+
names: /* @__PURE__ */ new Map(),
|
|
721
|
+
positions: []
|
|
722
|
+
};
|
|
723
|
+
sheets.set(document, sheet);
|
|
724
|
+
}
|
|
725
|
+
let byDepth = sheet.emitted.get(block);
|
|
726
|
+
if (!byDepth) sheet.emitted.set(block, byDepth = /* @__PURE__ */ new Map());
|
|
727
|
+
const cached = byDepth.get(depth);
|
|
728
|
+
if (cached) return cached;
|
|
729
|
+
const css = serialize(document, block.declarations);
|
|
730
|
+
const base = (depth ? `${block.name}-d${depth}` : block.name).replace(/[^\w-]/g, "_");
|
|
731
|
+
let name = base;
|
|
732
|
+
for (let index = 2; sheet.names.has(name) && sheet.names.get(name) !== css; index++) name = `${base}-${index}`;
|
|
733
|
+
if (!sheet.names.has(name)) {
|
|
734
|
+
const { positions } = sheet;
|
|
735
|
+
let at = positions.findIndex(([d, o]) => d > depth || d == depth && o > block.ordinal);
|
|
736
|
+
if (at < 0) at = positions.length;
|
|
737
|
+
sheet.names.set(name, css);
|
|
738
|
+
positions.splice(at, 0, [depth, block.ordinal]);
|
|
739
|
+
sheet.element.sheet.insertRule(`.${name}{${css}}`, at);
|
|
740
|
+
}
|
|
741
|
+
byDepth.set(depth, name);
|
|
742
|
+
return name;
|
|
743
|
+
}
|
|
744
|
+
function serialize(document, declarations) {
|
|
745
|
+
const value = document.createElement("div").style;
|
|
746
|
+
applyDeclarations(value, declarations);
|
|
747
|
+
return value.cssText;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
//#endregion
|
|
751
|
+
//#region src/render.ts
|
|
752
|
+
const roots = /* @__PURE__ */ new WeakMap();
|
|
753
|
+
const SVG = "http://www.w3.org/2000/svg";
|
|
754
|
+
const dirty = /* @__PURE__ */ new Set();
|
|
755
|
+
const stashes = /* @__PURE__ */ new WeakMap();
|
|
756
|
+
const CONTROLS = ["checked", "value"];
|
|
757
|
+
const ENUMERATED = [
|
|
758
|
+
"contentEditable",
|
|
759
|
+
"contenteditable",
|
|
760
|
+
"draggable",
|
|
761
|
+
"spellcheck"
|
|
762
|
+
];
|
|
763
|
+
const ALIASES = {
|
|
764
|
+
autoFocus: "autofocus",
|
|
765
|
+
contentEditable: "contenteditable",
|
|
766
|
+
htmlFor: "for"
|
|
767
|
+
};
|
|
768
|
+
const focusing = [];
|
|
769
|
+
const controlled = /* @__PURE__ */ new WeakMap();
|
|
770
|
+
const restoring = /* @__PURE__ */ new WeakSet();
|
|
771
|
+
let passiveRender = false;
|
|
772
|
+
let inserting;
|
|
773
|
+
let depth = 0;
|
|
774
|
+
let settling = false;
|
|
775
|
+
let rendering;
|
|
776
|
+
let touched = false;
|
|
777
|
+
const observed = /* @__PURE__ */ new WeakMap();
|
|
778
|
+
const tickets = /* @__PURE__ */ new WeakMap();
|
|
779
|
+
function render(node, container) {
|
|
780
|
+
roots.get(container)?.();
|
|
781
|
+
container.replaceChildren();
|
|
782
|
+
const context = new Context(Context.root);
|
|
783
|
+
const fiber = range("fragment", container, null, context);
|
|
784
|
+
try {
|
|
785
|
+
pass(() => {
|
|
786
|
+
const appearanceContext = appearanceRoot();
|
|
787
|
+
reconcile(fiber, node, context, void 0, appearanceContext ? {
|
|
788
|
+
context: appearanceContext,
|
|
789
|
+
entries: []
|
|
790
|
+
} : void 0);
|
|
791
|
+
});
|
|
792
|
+
} catch (error) {
|
|
793
|
+
unmountFiber(fiber);
|
|
794
|
+
context.pop();
|
|
795
|
+
throw error;
|
|
796
|
+
}
|
|
797
|
+
let active = true;
|
|
798
|
+
const unmount = () => {
|
|
799
|
+
if (!active) return;
|
|
800
|
+
active = false;
|
|
801
|
+
unmountFiber(fiber);
|
|
802
|
+
context.pop();
|
|
803
|
+
roots.delete(container);
|
|
804
|
+
};
|
|
805
|
+
roots.set(container, unmount);
|
|
806
|
+
return unmount;
|
|
807
|
+
}
|
|
808
|
+
function range(kind, parent, before, context) {
|
|
809
|
+
const start = document.createComment(kind);
|
|
810
|
+
const end = document.createComment(`/${kind}`);
|
|
811
|
+
parent.insertBefore(start, before);
|
|
812
|
+
parent.insertBefore(end, before);
|
|
813
|
+
return {
|
|
814
|
+
kind,
|
|
815
|
+
context,
|
|
816
|
+
start,
|
|
817
|
+
end,
|
|
818
|
+
children: []
|
|
819
|
+
};
|
|
820
|
+
}
|
|
821
|
+
function makeScope(kind, context, update) {
|
|
822
|
+
return {
|
|
823
|
+
active: true,
|
|
824
|
+
childContext: context,
|
|
825
|
+
context,
|
|
826
|
+
kind,
|
|
827
|
+
subscriptions: [],
|
|
828
|
+
update,
|
|
829
|
+
useIndex: 0,
|
|
830
|
+
uses: []
|
|
831
|
+
};
|
|
832
|
+
}
|
|
833
|
+
function complete(fiber, work) {
|
|
834
|
+
try {
|
|
835
|
+
work();
|
|
836
|
+
} catch (error) {
|
|
837
|
+
unmountFiber(fiber);
|
|
838
|
+
throw error;
|
|
839
|
+
}
|
|
840
|
+
return fiber;
|
|
841
|
+
}
|
|
842
|
+
function componentProps(type, props, appearance) {
|
|
843
|
+
const context = appearance?.context;
|
|
844
|
+
if (!context || typeof type != "function") return {
|
|
845
|
+
appearance,
|
|
846
|
+
props
|
|
847
|
+
};
|
|
848
|
+
const value = context.resolve(props);
|
|
849
|
+
const entries = appearance.entries;
|
|
850
|
+
if (!value) return {
|
|
851
|
+
appearance: { entries },
|
|
852
|
+
props
|
|
853
|
+
};
|
|
854
|
+
return {
|
|
855
|
+
appearance: {
|
|
856
|
+
context: value.context,
|
|
857
|
+
entries
|
|
858
|
+
},
|
|
859
|
+
props: {
|
|
860
|
+
...props,
|
|
861
|
+
style: [createAppearanceToken(value), props.style]
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
function mount(value, parent, before, context, boundary, appearance) {
|
|
866
|
+
if (typeof value == "string" || typeof value == "number" || typeof value == "bigint") {
|
|
867
|
+
const text = document.createTextNode(String(value));
|
|
868
|
+
parent.insertBefore(text, before);
|
|
869
|
+
return {
|
|
870
|
+
kind: "text",
|
|
871
|
+
value,
|
|
872
|
+
context,
|
|
873
|
+
start: text,
|
|
874
|
+
end: text,
|
|
875
|
+
children: []
|
|
876
|
+
};
|
|
877
|
+
}
|
|
878
|
+
if (value instanceof Component) return mountComponent(value, parent, before, context, boundary, appearance);
|
|
879
|
+
if (isCollection(value)) return mountCollection(value, parent, before, context, boundary, appearance);
|
|
880
|
+
if (!isVNode(value)) throw new TypeError(`Cannot render ${String(value)}.`);
|
|
881
|
+
if (value.type === Fragment) return mountFragment(value, parent, before, context, boundary, appearance);
|
|
882
|
+
if (value.type === PORTAL) return mountPortal(value, parent, before, context, boundary, appearance);
|
|
883
|
+
if (value.type === Provider) return mountProvider(value, parent, before, context, boundary, appearance);
|
|
884
|
+
if (typeof value.type == "string") return mountElement(value, parent, before, context, boundary, appearance);
|
|
885
|
+
if (typeof value.type != "function") throw new Error(`Cannot render ${String(value.type)}.`);
|
|
886
|
+
if (value.type.prototype instanceof Component) return mountOwnedComponent(value, parent, before, context, boundary, appearance);
|
|
887
|
+
return mountFunction(value, parent, before, context, boundary, appearance);
|
|
888
|
+
}
|
|
889
|
+
function mountFragment(value, parent, before, context, boundary, appearance) {
|
|
890
|
+
const fiber = range("fragment", parent, before, context);
|
|
891
|
+
fiber.key = value.key;
|
|
892
|
+
fiber.type = Fragment;
|
|
893
|
+
fiber.appearance = appearance;
|
|
894
|
+
return complete(fiber, () => {
|
|
895
|
+
reconcile(fiber, value.props.children, context, boundary, appearance);
|
|
896
|
+
});
|
|
897
|
+
}
|
|
898
|
+
function mountFunction(value, parent, before, context, boundary, appearance) {
|
|
899
|
+
const fiber = range("function", parent, before, context);
|
|
900
|
+
const resolved = componentProps(value.type, value.props, appearance);
|
|
901
|
+
fiber.key = value.key;
|
|
902
|
+
fiber.type = value.type;
|
|
903
|
+
fiber.props = observe(resolved.props);
|
|
904
|
+
fiber.boundary = boundary;
|
|
905
|
+
fiber.appearance = resolved.appearance;
|
|
906
|
+
fiber.scope = makeScope("function", context, (passive) => runFunction(fiber, passive));
|
|
907
|
+
fiber.render = () => enter(fiber.scope, () => fiber.type(fiber.props));
|
|
908
|
+
probing(fiber);
|
|
909
|
+
return complete(fiber, () => {
|
|
910
|
+
runFunction(fiber, passiveRender);
|
|
911
|
+
});
|
|
912
|
+
}
|
|
913
|
+
function mountOwnedComponent(value, parent, before, context, boundary, appearance) {
|
|
914
|
+
const resolved = componentProps(value.type, value.props, appearance);
|
|
915
|
+
return mountComponent(new value.type(observe(resolved.props)), parent, before, context, boundary, resolved.appearance, true, value.key);
|
|
916
|
+
}
|
|
917
|
+
function runFunction(fiber, passive) {
|
|
918
|
+
const result = attempt(fiber, passive, fiber.render);
|
|
919
|
+
if (result === true) inserted(fiber, () => commit(fiber.scope));
|
|
920
|
+
else return result;
|
|
921
|
+
}
|
|
922
|
+
function probing(fiber) {
|
|
923
|
+
const scope = fiber.scope;
|
|
924
|
+
scope.empty = () => !fiber.children.length;
|
|
925
|
+
scope.probe = () => {
|
|
926
|
+
try {
|
|
927
|
+
scope.probed = { output: consume(fiber, fiber.render) };
|
|
928
|
+
} catch (thrown) {
|
|
929
|
+
if (isThenable(thrown)) return thrown;
|
|
930
|
+
}
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
function mountComponent(instance, parent, before, context, inherited, appearance, owned = false, key) {
|
|
934
|
+
const fiber = range("component", parent, before, context);
|
|
935
|
+
const childContext = context.push(instance);
|
|
936
|
+
const ownBoundary = instance.fallback !== false || instance.catch ? {
|
|
937
|
+
catch: instance.catch?.bind(instance),
|
|
938
|
+
fallback: () => instance.fallback,
|
|
939
|
+
owner: fiber,
|
|
940
|
+
parent: inherited
|
|
941
|
+
} : inherited;
|
|
942
|
+
fiber.boundary = ownBoundary;
|
|
943
|
+
if (ownBoundary !== inherited) fiber.ownBoundary = ownBoundary;
|
|
944
|
+
fiber.childContext = childContext;
|
|
945
|
+
fiber.instance = instance;
|
|
946
|
+
fiber.key = owned ? key : instance.key;
|
|
947
|
+
fiber.type = instance.constructor;
|
|
948
|
+
fiber.props = instance.props;
|
|
949
|
+
fiber.owned = owned;
|
|
950
|
+
fiber.appearance = appearance;
|
|
951
|
+
fiber.scope = makeScope("component", childContext, (passive) => runComponent(fiber, passive));
|
|
952
|
+
fiber.render = () => enter(fiber.scope, () => instance.render.call(fiber.value, instance.props));
|
|
953
|
+
probing(fiber);
|
|
954
|
+
let first = true;
|
|
955
|
+
let proxy = instance;
|
|
956
|
+
fiber.release = watch(instance, (current, events) => {
|
|
957
|
+
const { applied, scope } = fiber;
|
|
958
|
+
proxy = current;
|
|
959
|
+
fiber.applied = void 0;
|
|
960
|
+
if (!first && scope.active) if (applied && events.includes("props")) transition(() => schedule(scope));
|
|
961
|
+
else schedule(scope);
|
|
962
|
+
first = false;
|
|
963
|
+
}, void 0, transition);
|
|
964
|
+
Object.defineProperty(fiber, "value", { get: () => proxy });
|
|
965
|
+
complete(fiber, () => {
|
|
966
|
+
runComponent(fiber, passiveRender);
|
|
967
|
+
});
|
|
968
|
+
if (owned) inserted(fiber, () => fiber.cleanup = instance.mount?.());
|
|
969
|
+
return fiber;
|
|
970
|
+
}
|
|
971
|
+
function runComponent(fiber, passive) {
|
|
972
|
+
const result = attempt(fiber, passive, fiber.render);
|
|
973
|
+
if (result !== true) return result;
|
|
974
|
+
}
|
|
975
|
+
function mountCollection(value, parent, before, context, boundary, appearance) {
|
|
976
|
+
const fiber = range("collection", parent, before, context);
|
|
977
|
+
fiber.source = value;
|
|
978
|
+
fiber.value = value;
|
|
979
|
+
fiber.boundary = boundary;
|
|
980
|
+
fiber.appearance = appearance;
|
|
981
|
+
fiber.scope = makeScope("collection", context, (passive) => runCollection(fiber, passive));
|
|
982
|
+
let first = true;
|
|
983
|
+
fiber.release = watch(value, (current) => {
|
|
984
|
+
fiber.value = current;
|
|
985
|
+
if (!first && fiber.scope?.active) schedule(fiber.scope);
|
|
986
|
+
first = false;
|
|
987
|
+
}, void 0, transition);
|
|
988
|
+
return complete(fiber, () => {
|
|
989
|
+
runCollection(fiber, passiveRender);
|
|
990
|
+
});
|
|
991
|
+
}
|
|
992
|
+
function runCollection(fiber, passive) {
|
|
993
|
+
attempt(fiber, passive, () => {
|
|
994
|
+
const value = fiber.value;
|
|
995
|
+
return value instanceof map.Managed ? [...value.values()] : [...value];
|
|
996
|
+
});
|
|
997
|
+
}
|
|
998
|
+
function mountProvider(value, parent, before, context, inherited, appearance) {
|
|
999
|
+
const fiber = range("provider", parent, before, context);
|
|
1000
|
+
const childContext = new Context(context);
|
|
1001
|
+
fiber.key = value.key;
|
|
1002
|
+
fiber.type = Provider;
|
|
1003
|
+
fiber.props = value.props;
|
|
1004
|
+
fiber.appearance = appearance;
|
|
1005
|
+
fiber.childContext = childContext;
|
|
1006
|
+
const commit = provide(childContext, value.props);
|
|
1007
|
+
const boundary = value.props.fallback !== void 0 ? {
|
|
1008
|
+
fallback: () => fiber.props.fallback,
|
|
1009
|
+
owner: fiber,
|
|
1010
|
+
parent: inherited
|
|
1011
|
+
} : inherited;
|
|
1012
|
+
fiber.boundary = boundary;
|
|
1013
|
+
if (boundary !== inherited) fiber.ownBoundary = boundary;
|
|
1014
|
+
complete(fiber, () => {
|
|
1015
|
+
reconcile(fiber, value.props.children, childContext, boundary, appearance);
|
|
1016
|
+
});
|
|
1017
|
+
commit();
|
|
1018
|
+
return fiber;
|
|
1019
|
+
}
|
|
1020
|
+
function mountPortal(value, parent, before, context, boundary, appearance) {
|
|
1021
|
+
const marker = document.createComment("portal");
|
|
1022
|
+
const container = value.props.container;
|
|
1023
|
+
const portalStart = document.createComment("portal-root");
|
|
1024
|
+
const portalEnd = document.createComment("/portal-root");
|
|
1025
|
+
parent.insertBefore(marker, before);
|
|
1026
|
+
container.append(portalStart, portalEnd);
|
|
1027
|
+
const output = {
|
|
1028
|
+
kind: "portal",
|
|
1029
|
+
key: value.key,
|
|
1030
|
+
type: PORTAL,
|
|
1031
|
+
props: value.props,
|
|
1032
|
+
context,
|
|
1033
|
+
boundary,
|
|
1034
|
+
appearance,
|
|
1035
|
+
start: marker,
|
|
1036
|
+
end: marker,
|
|
1037
|
+
children: [],
|
|
1038
|
+
portalContainer: container,
|
|
1039
|
+
portalStart,
|
|
1040
|
+
portalEnd
|
|
1041
|
+
};
|
|
1042
|
+
return complete(output, () => {
|
|
1043
|
+
reconcilePortal(output, value.props.children, context, boundary, appearance);
|
|
1044
|
+
});
|
|
1045
|
+
}
|
|
1046
|
+
function mountElement(value, parent, before, context, boundary, appearance) {
|
|
1047
|
+
const tag = value.type;
|
|
1048
|
+
let host = parent;
|
|
1049
|
+
for (let owner = stashes.get(host); owner; owner = stashes.get(host)) host = owner.end.parentNode;
|
|
1050
|
+
const element = (tag == "svg" || host instanceof SVGElement && host.localName != "foreignObject" ? SVG : void 0) ? document.createElementNS(SVG, tag) : document.createElement(tag);
|
|
1051
|
+
const fiber = {
|
|
1052
|
+
kind: "element",
|
|
1053
|
+
key: value.key,
|
|
1054
|
+
type: tag,
|
|
1055
|
+
props: {},
|
|
1056
|
+
context,
|
|
1057
|
+
boundary,
|
|
1058
|
+
start: element,
|
|
1059
|
+
end: element,
|
|
1060
|
+
children: [],
|
|
1061
|
+
events: /* @__PURE__ */ new Map()
|
|
1062
|
+
};
|
|
1063
|
+
parent.insertBefore(element, before);
|
|
1064
|
+
complete(fiber, () => {
|
|
1065
|
+
patchProps(fiber, value.props, appearance);
|
|
1066
|
+
});
|
|
1067
|
+
if (value.props.autofocus || value.props.autoFocus) focusing.push(element);
|
|
1068
|
+
return fiber;
|
|
1069
|
+
}
|
|
1070
|
+
function pass(work) {
|
|
1071
|
+
depth++;
|
|
1072
|
+
try {
|
|
1073
|
+
return work();
|
|
1074
|
+
} finally {
|
|
1075
|
+
if (!--depth) {
|
|
1076
|
+
settle();
|
|
1077
|
+
focus();
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
function focus() {
|
|
1082
|
+
for (const element of focusing.splice(0)) if (element.isConnected) element.focus();
|
|
1083
|
+
}
|
|
1084
|
+
function attempt(fiber, passive, render) {
|
|
1085
|
+
const previous = passiveRender;
|
|
1086
|
+
const scope = fiber.scope;
|
|
1087
|
+
const probed = scope.probed;
|
|
1088
|
+
scope.probed = void 0;
|
|
1089
|
+
passiveRender ||= passive;
|
|
1090
|
+
if (passive && !depth && !fiber.children.length && !fiber.stash) fiber.staging ||= document.createDocumentFragment();
|
|
1091
|
+
const outer = inserting;
|
|
1092
|
+
if (fiber.staging) inserting = fiber.inserted ||= [];
|
|
1093
|
+
try {
|
|
1094
|
+
return pass(() => {
|
|
1095
|
+
try {
|
|
1096
|
+
reconcile(fiber, probed ? probed.output : consume(fiber, render), scope.childContext, fiber.boundary, renderedAppearance(fiber));
|
|
1097
|
+
if (fiber.staging) {
|
|
1098
|
+
const queued = fiber.inserted;
|
|
1099
|
+
fiber.end.parentNode.insertBefore(fiber.staging, fiber.end);
|
|
1100
|
+
fiber.staging = fiber.inserted = void 0;
|
|
1101
|
+
inserting = outer;
|
|
1102
|
+
queued.forEach((run) => run());
|
|
1103
|
+
}
|
|
1104
|
+
if (!fiber.recovering) unwait(fiber);
|
|
1105
|
+
fiber.retried = void 0;
|
|
1106
|
+
return true;
|
|
1107
|
+
} catch (thrown) {
|
|
1108
|
+
return suspend(fiber, thrown, passive);
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
} finally {
|
|
1112
|
+
passiveRender = previous;
|
|
1113
|
+
inserting = outer;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
function inserted(fiber, run) {
|
|
1117
|
+
if (inserting) inserting.push(() => fiber.dead || run());
|
|
1118
|
+
else run();
|
|
1119
|
+
}
|
|
1120
|
+
function observe(props) {
|
|
1121
|
+
if (!("style" in props)) return props;
|
|
1122
|
+
let output = observed.get(props);
|
|
1123
|
+
if (!output) {
|
|
1124
|
+
const { style } = props;
|
|
1125
|
+
let handle;
|
|
1126
|
+
let resolved = false;
|
|
1127
|
+
output = Object.defineProperty({ ...props }, "style", {
|
|
1128
|
+
enumerable: true,
|
|
1129
|
+
get() {
|
|
1130
|
+
if (rendering === output) touched = true;
|
|
1131
|
+
if (!resolved) {
|
|
1132
|
+
handle = door(style);
|
|
1133
|
+
resolved = true;
|
|
1134
|
+
}
|
|
1135
|
+
return handle;
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
observed.set(props, output);
|
|
1139
|
+
}
|
|
1140
|
+
return output;
|
|
1141
|
+
}
|
|
1142
|
+
function door(value) {
|
|
1143
|
+
const collected = {
|
|
1144
|
+
classes: [],
|
|
1145
|
+
declarations: {},
|
|
1146
|
+
tokens: []
|
|
1147
|
+
};
|
|
1148
|
+
const { classes, declarations, tokens } = collected;
|
|
1149
|
+
collect(value, collected, 1);
|
|
1150
|
+
if (!classes.length && !tokens.length && !Object.keys(declarations).length) return void 0;
|
|
1151
|
+
const key = Object.freeze({});
|
|
1152
|
+
tickets.set(key, {
|
|
1153
|
+
classes,
|
|
1154
|
+
tokens
|
|
1155
|
+
});
|
|
1156
|
+
return Object.freeze({
|
|
1157
|
+
...declarations,
|
|
1158
|
+
[Symbol("style")]: key
|
|
1159
|
+
});
|
|
1160
|
+
}
|
|
1161
|
+
function consume(fiber, render) {
|
|
1162
|
+
const previous = rendering;
|
|
1163
|
+
const read = touched;
|
|
1164
|
+
rendering = fiber.props;
|
|
1165
|
+
touched = false;
|
|
1166
|
+
try {
|
|
1167
|
+
const output = render();
|
|
1168
|
+
fiber.consumed = touched;
|
|
1169
|
+
return output;
|
|
1170
|
+
} finally {
|
|
1171
|
+
rendering = previous;
|
|
1172
|
+
touched = read;
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
function wait(fiber, boundary) {
|
|
1176
|
+
if (fiber.waitingOn !== boundary) unwait(fiber);
|
|
1177
|
+
fiber.waitingOn = boundary;
|
|
1178
|
+
(boundary.waiting ||= /* @__PURE__ */ new Set()).add(fiber);
|
|
1179
|
+
dirty.add(boundary);
|
|
1180
|
+
}
|
|
1181
|
+
function unwait(fiber) {
|
|
1182
|
+
const boundary = fiber.waitingOn;
|
|
1183
|
+
if (!boundary) return;
|
|
1184
|
+
fiber.waitingOn = void 0;
|
|
1185
|
+
boundary.waiting.delete(fiber);
|
|
1186
|
+
if (!boundary.owner.dead) dirty.add(boundary);
|
|
1187
|
+
}
|
|
1188
|
+
function settle() {
|
|
1189
|
+
if (settling) return;
|
|
1190
|
+
settling = true;
|
|
1191
|
+
try {
|
|
1192
|
+
for (const boundary of dirty) {
|
|
1193
|
+
dirty.delete(boundary);
|
|
1194
|
+
const owner = boundary.owner;
|
|
1195
|
+
const waiting = boundary.waiting.size > 0;
|
|
1196
|
+
if (!owner.dead && waiting != !!owner.stash) waiting ? hide(owner, boundary) : reveal(owner);
|
|
1197
|
+
}
|
|
1198
|
+
} finally {
|
|
1199
|
+
settling = false;
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1202
|
+
function hide(owner, boundary) {
|
|
1203
|
+
const stash = document.createDocumentFragment();
|
|
1204
|
+
for (const child of owner.children) move(child, stash, null);
|
|
1205
|
+
owner.portals = portals(owner, []).map((portal) => {
|
|
1206
|
+
const content = document.createDocumentFragment();
|
|
1207
|
+
moveRange(portal.portalStart, portal.portalEnd, content);
|
|
1208
|
+
return [portal, content];
|
|
1209
|
+
});
|
|
1210
|
+
stashes.set(stash, owner);
|
|
1211
|
+
const context = owner.childContext;
|
|
1212
|
+
const placeholder = range("fragment", owner.end.parentNode, owner.end, context);
|
|
1213
|
+
owner.stash = stash;
|
|
1214
|
+
owner.placeholder = placeholder;
|
|
1215
|
+
reconcile(placeholder, boundary.fallback(), context, boundary.parent);
|
|
1216
|
+
}
|
|
1217
|
+
function reveal(owner) {
|
|
1218
|
+
unmountFiber(owner.placeholder);
|
|
1219
|
+
owner.end.parentNode.insertBefore(owner.stash, owner.end);
|
|
1220
|
+
for (const [portal, content] of owner.portals) if (!portal.dead) portal.portalContainer.append(content);
|
|
1221
|
+
owner.portals = void 0;
|
|
1222
|
+
owner.placeholder = void 0;
|
|
1223
|
+
owner.stash = void 0;
|
|
1224
|
+
}
|
|
1225
|
+
function portals(fiber, found) {
|
|
1226
|
+
for (const child of fiber.children) {
|
|
1227
|
+
if (child.kind == "portal") found.push(child);
|
|
1228
|
+
portals(child, found);
|
|
1229
|
+
}
|
|
1230
|
+
return found;
|
|
1231
|
+
}
|
|
1232
|
+
function moveRange(start, end, target) {
|
|
1233
|
+
let node = start;
|
|
1234
|
+
while (node) {
|
|
1235
|
+
const next = node.nextSibling;
|
|
1236
|
+
target.appendChild(node);
|
|
1237
|
+
if (node === end) break;
|
|
1238
|
+
node = next;
|
|
1239
|
+
}
|
|
1240
|
+
}
|
|
1241
|
+
function suspend(fiber, thrown, passive) {
|
|
1242
|
+
const boundary = fiber.boundary;
|
|
1243
|
+
if (isThenable(thrown)) {
|
|
1244
|
+
if (!boundary) throw thrown;
|
|
1245
|
+
if (passive && !fiber.children.length && depth > 1) throw thrown;
|
|
1246
|
+
if (!passive) wait(fiber, boundary);
|
|
1247
|
+
const scope = fiber.scope;
|
|
1248
|
+
let held = scope.holds;
|
|
1249
|
+
scope.holds = void 0;
|
|
1250
|
+
const clear = () => {
|
|
1251
|
+
fiber.suspended.delete(clear);
|
|
1252
|
+
release(held);
|
|
1253
|
+
held = void 0;
|
|
1254
|
+
};
|
|
1255
|
+
(fiber.suspended ||= /* @__PURE__ */ new Set()).add(clear);
|
|
1256
|
+
const resume = (retry) => {
|
|
1257
|
+
fiber.suspended.delete(clear);
|
|
1258
|
+
if (!scope.active) return clear();
|
|
1259
|
+
if (held) (scope.holds ||= []).push(...held);
|
|
1260
|
+
held = void 0;
|
|
1261
|
+
retry();
|
|
1262
|
+
};
|
|
1263
|
+
thrown.then(() => resume(() => passive ? transition(() => schedule(scope)) : schedule(scope)), (error) => resume(() => pass(() => recover(fiber, error, fiber.boundary))));
|
|
1264
|
+
return thrown;
|
|
1265
|
+
}
|
|
1266
|
+
recover(fiber, thrown, fiber.boundary);
|
|
1267
|
+
}
|
|
1268
|
+
function recover(fiber, thrown, boundary) {
|
|
1269
|
+
const error = thrown instanceof Error ? thrown : new Error(String(thrown));
|
|
1270
|
+
while (boundary && !boundary.catch) boundary = boundary.parent;
|
|
1271
|
+
if (!boundary) throw error;
|
|
1272
|
+
const handler = boundary;
|
|
1273
|
+
const token = {};
|
|
1274
|
+
wait(fiber, handler);
|
|
1275
|
+
fiber.recovering = token;
|
|
1276
|
+
Promise.resolve(handler.catch(error)).then(() => {
|
|
1277
|
+
if (fiber.recovering !== token) return;
|
|
1278
|
+
fiber.recovering = void 0;
|
|
1279
|
+
if (!fiber.scope.active || fiber.retried) return;
|
|
1280
|
+
fiber.retried = true;
|
|
1281
|
+
schedule(fiber.scope);
|
|
1282
|
+
}, (next) => {
|
|
1283
|
+
if (fiber.recovering === token && fiber.scope.active) pass(() => recover(fiber, next, handler.parent));
|
|
1284
|
+
});
|
|
1285
|
+
}
|
|
1286
|
+
function isThenable(value) {
|
|
1287
|
+
return !!value && typeof value.then == "function";
|
|
1288
|
+
}
|
|
1289
|
+
function reconcile(fiber, value, context, boundary, appearance) {
|
|
1290
|
+
const detached = fiber.stash || fiber.staging;
|
|
1291
|
+
if (detached) reconcileChildren(fiber, detached, null, value, context, boundary, appearance);
|
|
1292
|
+
else reconcileChildren(fiber, fiber.end.parentNode, fiber.end, value, context, boundary, appearance);
|
|
1293
|
+
}
|
|
1294
|
+
function reconcilePortal(fiber, value, context, boundary, appearance) {
|
|
1295
|
+
reconcileChildren(fiber, fiber.portalEnd.parentNode, fiber.portalEnd, value, context, boundary, appearance);
|
|
1296
|
+
}
|
|
1297
|
+
function reconcileChildren(owner, parent, before, value, context, boundary, appearance) {
|
|
1298
|
+
const values = childrenOf(value);
|
|
1299
|
+
const old = owner.children;
|
|
1300
|
+
const keyed = /* @__PURE__ */ new Map();
|
|
1301
|
+
const used = /* @__PURE__ */ new Set();
|
|
1302
|
+
const next = [];
|
|
1303
|
+
for (const child of old) if (child.key !== null && child.key !== void 0) keyed.set(child.key, child);
|
|
1304
|
+
try {
|
|
1305
|
+
for (let index = 0; index < values.length; index++) {
|
|
1306
|
+
const value = source(values[index]);
|
|
1307
|
+
const key = keyOf(value);
|
|
1308
|
+
let child = key !== null && key !== void 0 ? keyed.get(key) : old[index]?.key == null ? old[index] : void 0;
|
|
1309
|
+
if (child && used.has(child)) child = void 0;
|
|
1310
|
+
if (child) used.add(child);
|
|
1311
|
+
next.push(patch(child, value, parent, before, context, boundary, appearance));
|
|
1312
|
+
}
|
|
1313
|
+
} catch (error) {
|
|
1314
|
+
owner.children = [...next, ...old.filter((child) => !child.dead && !next.includes(child))];
|
|
1315
|
+
throw error;
|
|
1316
|
+
}
|
|
1317
|
+
for (const child of old) if (!used.has(child)) unmountFiber(child);
|
|
1318
|
+
let anchor = before;
|
|
1319
|
+
for (let index = next.length - 1; index >= 0; index--) {
|
|
1320
|
+
move(next[index], parent, anchor);
|
|
1321
|
+
anchor = next[index].start;
|
|
1322
|
+
}
|
|
1323
|
+
owner.children = next;
|
|
1324
|
+
}
|
|
1325
|
+
function patch(old, value, parent, before, context, boundary, appearance) {
|
|
1326
|
+
if (!old || !compatible(old, value)) {
|
|
1327
|
+
const next = mount(value, parent, old?.start || before, context, boundary, appearance);
|
|
1328
|
+
if (old) unmountFiber(old);
|
|
1329
|
+
return next;
|
|
1330
|
+
}
|
|
1331
|
+
if (old.ownBoundary) old.ownBoundary.parent = boundary;
|
|
1332
|
+
old.boundary = old.ownBoundary || boundary;
|
|
1333
|
+
if (old.kind == "collection") {
|
|
1334
|
+
if (old.appearance !== appearance) {
|
|
1335
|
+
old.appearance = appearance;
|
|
1336
|
+
runCollection(old, passiveRender);
|
|
1337
|
+
}
|
|
1338
|
+
return old;
|
|
1339
|
+
}
|
|
1340
|
+
if (old.kind == "text") {
|
|
1341
|
+
const next = String(value);
|
|
1342
|
+
if (old.start.nodeValue !== next) old.start.nodeValue = next;
|
|
1343
|
+
old.value = value;
|
|
1344
|
+
} else if (old.kind == "element") patchProps(old, value.props, appearance);
|
|
1345
|
+
else if (old.kind == "fragment") {
|
|
1346
|
+
old.context = context;
|
|
1347
|
+
old.appearance = appearance;
|
|
1348
|
+
reconcile(old, value.props.children, context, old.boundary, appearance);
|
|
1349
|
+
} else if (old.kind == "function") {
|
|
1350
|
+
const vnode = value;
|
|
1351
|
+
const resolved = componentProps(vnode.type, vnode.props, appearance);
|
|
1352
|
+
old.appearance = resolved.appearance;
|
|
1353
|
+
old.props = observe(resolved.props);
|
|
1354
|
+
rerun(old, () => runFunction(old, passiveRender));
|
|
1355
|
+
} else if (old.kind == "component") {
|
|
1356
|
+
const resolved = isVNode(value) ? componentProps(value.type, value.props, appearance) : {
|
|
1357
|
+
appearance,
|
|
1358
|
+
props: old.instance.props
|
|
1359
|
+
};
|
|
1360
|
+
old.appearance = resolved.appearance;
|
|
1361
|
+
const props = isVNode(value) ? observe(resolved.props) : resolved.props;
|
|
1362
|
+
if (isVNode(value) && props !== old.instance.props) {
|
|
1363
|
+
if (passiveRender) old.applied = true;
|
|
1364
|
+
old.instance.props = props;
|
|
1365
|
+
}
|
|
1366
|
+
old.props = props;
|
|
1367
|
+
rerun(old, () => runComponent(old, passiveRender));
|
|
1368
|
+
} else if (old.kind == "provider") {
|
|
1369
|
+
old.appearance = appearance;
|
|
1370
|
+
old.props = value.props;
|
|
1371
|
+
const commit = provide(old.childContext, old.props);
|
|
1372
|
+
reconcile(old, old.props.children, old.childContext, old.boundary, appearance);
|
|
1373
|
+
commit();
|
|
1374
|
+
} else {
|
|
1375
|
+
old.appearance = appearance;
|
|
1376
|
+
const vnode = value;
|
|
1377
|
+
old.props = vnode.props;
|
|
1378
|
+
reconcilePortal(old, vnode.props.children, context, old.boundary, appearance);
|
|
1379
|
+
}
|
|
1380
|
+
return old;
|
|
1381
|
+
}
|
|
1382
|
+
function rerun(fiber, run) {
|
|
1383
|
+
claim$1(fiber.scope);
|
|
1384
|
+
run();
|
|
1385
|
+
settle$1(fiber.scope);
|
|
1386
|
+
}
|
|
1387
|
+
function compatible(fiber, value) {
|
|
1388
|
+
if (fiber.kind == "text") return [
|
|
1389
|
+
"string",
|
|
1390
|
+
"number",
|
|
1391
|
+
"bigint"
|
|
1392
|
+
].includes(typeof value);
|
|
1393
|
+
if (value instanceof Component) return fiber.kind == "component" && fiber.instance === value;
|
|
1394
|
+
if (isCollection(value)) return fiber.kind == "collection" && fiber.source === value;
|
|
1395
|
+
if (!isVNode(value)) return false;
|
|
1396
|
+
if (fiber.key !== value.key || fiber.type !== value.type) return false;
|
|
1397
|
+
if (fiber.kind == "portal") return fiber.portalContainer === value.props.container;
|
|
1398
|
+
return true;
|
|
1399
|
+
}
|
|
1400
|
+
function source(value) {
|
|
1401
|
+
if (value instanceof Component) return value.is;
|
|
1402
|
+
while (isCollection(value) && isCollection(Object.getPrototypeOf(value))) value = Object.getPrototypeOf(value);
|
|
1403
|
+
return value;
|
|
1404
|
+
}
|
|
1405
|
+
function isCollection(value) {
|
|
1406
|
+
return value instanceof has.List || value instanceof has.Pool || value instanceof map.Managed;
|
|
1407
|
+
}
|
|
1408
|
+
function keyOf(value) {
|
|
1409
|
+
if (value instanceof Component) return value.key;
|
|
1410
|
+
return isVNode(value) ? value.key : void 0;
|
|
1411
|
+
}
|
|
1412
|
+
function move(fiber, parent, before) {
|
|
1413
|
+
if (fiber.start.parentNode === parent && fiber.end.nextSibling === before) return;
|
|
1414
|
+
let node = fiber.start;
|
|
1415
|
+
while (node) {
|
|
1416
|
+
const next = node.nextSibling;
|
|
1417
|
+
parent.insertBefore(node, before);
|
|
1418
|
+
if (node === fiber.end) break;
|
|
1419
|
+
node = next;
|
|
1420
|
+
}
|
|
1421
|
+
}
|
|
1422
|
+
function patchProps(fiber, next, appearance) {
|
|
1423
|
+
const element = fiber.start;
|
|
1424
|
+
const previous = fiber.props;
|
|
1425
|
+
const raw = "dangerouslySetInnerHTML" in next;
|
|
1426
|
+
const resolved = appearance?.context?.resolve(next, fiber.type);
|
|
1427
|
+
if (raw) {
|
|
1428
|
+
for (let index = fiber.children.length - 1; index >= 0; index--) unmountFiber(fiber.children[index]);
|
|
1429
|
+
fiber.children = [];
|
|
1430
|
+
}
|
|
1431
|
+
for (const key of Object.keys({
|
|
1432
|
+
...previous,
|
|
1433
|
+
...next
|
|
1434
|
+
})) {
|
|
1435
|
+
if (key.startsWith("_") || key == "children" || key == "className" || key == "key" || key == "ref" || key == "style" || CONTROLS.includes(key)) continue;
|
|
1436
|
+
if (previous[key] === next[key]) continue;
|
|
1437
|
+
patchProp(fiber, element, key, previous[key], next[key]);
|
|
1438
|
+
}
|
|
1439
|
+
const claimed = claim(element, appearance, resolved, next.className, next.style);
|
|
1440
|
+
applyClaim(element, fiber.claimed, claimed);
|
|
1441
|
+
fiber.claimed = claimed;
|
|
1442
|
+
fiber.props = next;
|
|
1443
|
+
fiber.appearance = appearance;
|
|
1444
|
+
if (!raw) reconcileChildren(fiber, element, null, next.children, fiber.context, fiber.boundary, claimed.context ? {
|
|
1445
|
+
context: claimed.context,
|
|
1446
|
+
entries: []
|
|
1447
|
+
} : void 0);
|
|
1448
|
+
for (const key of CONTROLS) {
|
|
1449
|
+
const value = next[key];
|
|
1450
|
+
const live = element[key];
|
|
1451
|
+
if (value == null || !(key in element) ? previous[key] !== value : key == "value" ? String(live) !== String(value) : live !== value) patchProp(fiber, element, key, previous[key], value);
|
|
1452
|
+
}
|
|
1453
|
+
if (CONTROLS.some((key) => next[key] != null)) {
|
|
1454
|
+
const document = element.ownerDocument;
|
|
1455
|
+
controlled.set(element, fiber);
|
|
1456
|
+
if (!restoring.has(document)) {
|
|
1457
|
+
restoring.add(document);
|
|
1458
|
+
document.addEventListener("input", restoreTarget);
|
|
1459
|
+
document.addEventListener("change", restoreTarget);
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
if (previous.ref !== next.ref) patchProp(fiber, element, "ref", previous.ref, next.ref);
|
|
1463
|
+
}
|
|
1464
|
+
function patchProp(fiber, element, key, previous, next) {
|
|
1465
|
+
if (key == "ref") {
|
|
1466
|
+
applyRef(previous, null);
|
|
1467
|
+
inserted(fiber, () => applyRef(next, element));
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1470
|
+
if (key == "dangerouslySetInnerHTML") {
|
|
1471
|
+
element.innerHTML = next?.__html || "";
|
|
1472
|
+
return;
|
|
1473
|
+
}
|
|
1474
|
+
if (/^on[A-Z]/.test(key)) {
|
|
1475
|
+
const capture = key.endsWith("Capture");
|
|
1476
|
+
const lower = (capture ? key.slice(2, -7) : key.slice(2)).toLowerCase();
|
|
1477
|
+
const name = lower == "doubleclick" ? "dblclick" : lower;
|
|
1478
|
+
const id = `${name}:${capture}`;
|
|
1479
|
+
const current = fiber.events.get(id);
|
|
1480
|
+
if (current) element.removeEventListener(name, current, capture);
|
|
1481
|
+
if (typeof next == "function") {
|
|
1482
|
+
fiber.events.set(id, next);
|
|
1483
|
+
element.addEventListener(name, next, capture);
|
|
1484
|
+
} else fiber.events.delete(id);
|
|
1485
|
+
return;
|
|
1486
|
+
}
|
|
1487
|
+
const name = ALIASES[key] || key;
|
|
1488
|
+
if ((key.startsWith("aria-") || key.startsWith("data-") || ENUMERATED.includes(key)) && next != null) {
|
|
1489
|
+
element.setAttribute(name, String(next));
|
|
1490
|
+
return;
|
|
1491
|
+
}
|
|
1492
|
+
if (next === null || next === void 0 || next === false) {
|
|
1493
|
+
if (key in element && typeof element[key] != "function") try {
|
|
1494
|
+
const current = element[key];
|
|
1495
|
+
element[key] = typeof current == "boolean" ? false : typeof current == "number" ? 0 : "";
|
|
1496
|
+
} catch {}
|
|
1497
|
+
element.removeAttribute(element.namespaceURI === SVG ? name.toLowerCase() : name);
|
|
1498
|
+
element.removeAttribute(name);
|
|
1499
|
+
return;
|
|
1500
|
+
}
|
|
1501
|
+
if (key in element && (element.namespaceURI !== SVG || settable(element, key))) try {
|
|
1502
|
+
element[key] = next;
|
|
1503
|
+
return;
|
|
1504
|
+
} catch {}
|
|
1505
|
+
element.setAttribute(name, next === true ? "" : String(next));
|
|
1506
|
+
}
|
|
1507
|
+
function applyClaim(element, before, after) {
|
|
1508
|
+
const previous = before || {
|
|
1509
|
+
className: "",
|
|
1510
|
+
declarations: {}
|
|
1511
|
+
};
|
|
1512
|
+
if (previous.className !== after.className) if (after.className) element.setAttribute("class", after.className);
|
|
1513
|
+
else element.removeAttribute("class");
|
|
1514
|
+
applyDeclarations(element.style, after.declarations, previous.declarations);
|
|
1515
|
+
}
|
|
1516
|
+
function claim(element, appearance, resolved, className, value) {
|
|
1517
|
+
const collected = {
|
|
1518
|
+
classes: [],
|
|
1519
|
+
declarations: {},
|
|
1520
|
+
tokens: []
|
|
1521
|
+
};
|
|
1522
|
+
const entries = appearance?.entries || [];
|
|
1523
|
+
let context = appearance?.context;
|
|
1524
|
+
let reach = -1;
|
|
1525
|
+
if (resolved) collect(createAppearanceToken(resolved), collected, 0);
|
|
1526
|
+
appendClasses(collected.classes, className);
|
|
1527
|
+
collect(value, collected, 0);
|
|
1528
|
+
for (let index = entries.length - 1; index >= 0; index--) collect(entries[index].style, collected, entries[index].hops);
|
|
1529
|
+
for (const { appearance, doors } of collected.tokens) {
|
|
1530
|
+
for (const block of appearance.blocks || []) collected.classes.push(emitClass(block, doors, element.ownerDocument));
|
|
1531
|
+
if (appearance.classes) collected.classes.push(...appearance.classes);
|
|
1532
|
+
if (appearance.context && doors >= reach) {
|
|
1533
|
+
context = appearance.context;
|
|
1534
|
+
reach = doors;
|
|
1535
|
+
}
|
|
1536
|
+
}
|
|
1537
|
+
return {
|
|
1538
|
+
className: [...new Set(collected.classes)].join(" "),
|
|
1539
|
+
context,
|
|
1540
|
+
declarations: collected.declarations
|
|
1541
|
+
};
|
|
1542
|
+
}
|
|
1543
|
+
function renderedAppearance(fiber) {
|
|
1544
|
+
if (fiber.kind != "component" && fiber.kind != "function") return fiber.appearance;
|
|
1545
|
+
const style = fiber.props?.style;
|
|
1546
|
+
const entries = (fiber.appearance?.entries || []).map(({ hops, style }) => ({
|
|
1547
|
+
hops: hops + 1,
|
|
1548
|
+
style
|
|
1549
|
+
}));
|
|
1550
|
+
const inherited = fiber.appearance?.context || appearanceRoot();
|
|
1551
|
+
const context = enterAppearance(inherited, fiber.type);
|
|
1552
|
+
if (context?.base && context !== inherited) entries.push({
|
|
1553
|
+
hops: 0,
|
|
1554
|
+
style: context.base
|
|
1555
|
+
});
|
|
1556
|
+
if (style && !fiber.consumed && !(fiber.instance && "style" in fiber.instance)) entries.push({
|
|
1557
|
+
hops: 0,
|
|
1558
|
+
style
|
|
1559
|
+
});
|
|
1560
|
+
return entries.length || context ? {
|
|
1561
|
+
context,
|
|
1562
|
+
entries
|
|
1563
|
+
} : void 0;
|
|
1564
|
+
}
|
|
1565
|
+
function collect(value, collected, doors) {
|
|
1566
|
+
if (!value) return;
|
|
1567
|
+
const token = appearanceToken(value);
|
|
1568
|
+
if (token) {
|
|
1569
|
+
collected.tokens.push({
|
|
1570
|
+
appearance: token,
|
|
1571
|
+
doors
|
|
1572
|
+
});
|
|
1573
|
+
Object.assign(collected.declarations, token.declarations);
|
|
1574
|
+
return;
|
|
1575
|
+
}
|
|
1576
|
+
if (typeof value == "string") {
|
|
1577
|
+
appendClasses(collected.classes, value);
|
|
1578
|
+
return;
|
|
1579
|
+
}
|
|
1580
|
+
if (Array.isArray(value)) {
|
|
1581
|
+
value.forEach((entry) => collect(entry, collected, doors));
|
|
1582
|
+
return;
|
|
1583
|
+
}
|
|
1584
|
+
for (const symbol of Object.getOwnPropertySymbols(value)) {
|
|
1585
|
+
const ticket = tickets.get(value[symbol]);
|
|
1586
|
+
if (!ticket) continue;
|
|
1587
|
+
collected.classes.push(...ticket.classes);
|
|
1588
|
+
for (const carried of ticket.tokens) collected.tokens.push({
|
|
1589
|
+
appearance: carried.appearance,
|
|
1590
|
+
doors: carried.doors + doors
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
for (const key of Object.keys(value)) collected.declarations[key] = value[key];
|
|
1594
|
+
}
|
|
1595
|
+
function appendClasses(classes, value) {
|
|
1596
|
+
if (typeof value == "string") classes.push(...value.split(/\s+/).filter(Boolean));
|
|
1597
|
+
}
|
|
1598
|
+
function restoreTarget(event) {
|
|
1599
|
+
const element = event.target;
|
|
1600
|
+
const fiber = controlled.get(element);
|
|
1601
|
+
if (fiber && event.type == settles(fiber.props, element)) queueMicrotask(() => afterFlush(() => restore(fiber)));
|
|
1602
|
+
}
|
|
1603
|
+
function settles(props, element) {
|
|
1604
|
+
if (props.onInput) return "input";
|
|
1605
|
+
if (props.onChange) return "change";
|
|
1606
|
+
return element.type == "checkbox" || element.type == "radio" || element.localName == "select" ? "change" : "input";
|
|
1607
|
+
}
|
|
1608
|
+
function restore(fiber) {
|
|
1609
|
+
const element = fiber.start;
|
|
1610
|
+
for (const key of CONTROLS) {
|
|
1611
|
+
const value = fiber.props[key];
|
|
1612
|
+
if (value == null || fiber.dead) continue;
|
|
1613
|
+
if (key == "value" ? String(element.value) !== String(value) : element[key] !== value) element[key] = value;
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
function settable(element, key) {
|
|
1617
|
+
let target = element;
|
|
1618
|
+
let descriptor;
|
|
1619
|
+
while (!(descriptor = Object.getOwnPropertyDescriptor(target, key))) target = Object.getPrototypeOf(target);
|
|
1620
|
+
return !!(descriptor.set || descriptor.writable);
|
|
1621
|
+
}
|
|
1622
|
+
function applyRef(ref, value) {
|
|
1623
|
+
if (typeof ref == "function") ref(value);
|
|
1624
|
+
else if (ref && typeof ref == "object" && "current" in ref) ref.current = value;
|
|
1625
|
+
}
|
|
1626
|
+
function unmountFiber(fiber) {
|
|
1627
|
+
fiber.dead = true;
|
|
1628
|
+
unwait(fiber);
|
|
1629
|
+
for (let index = fiber.children.length - 1; index >= 0; index--) unmountFiber(fiber.children[index]);
|
|
1630
|
+
if (fiber.placeholder) unmountFiber(fiber.placeholder);
|
|
1631
|
+
fiber.suspended?.forEach((clear) => clear());
|
|
1632
|
+
if (fiber.scope) dispose(fiber.scope);
|
|
1633
|
+
fiber.release?.();
|
|
1634
|
+
if (fiber.kind == "element") {
|
|
1635
|
+
applyRef(fiber.props?.ref, null);
|
|
1636
|
+
for (const [id, listener] of fiber.events) {
|
|
1637
|
+
const [name, capture] = id.split(":");
|
|
1638
|
+
fiber.start.removeEventListener(name, listener, capture === "true");
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
if (fiber.kind == "component") {
|
|
1642
|
+
if (typeof fiber.cleanup == "function") fiber.cleanup();
|
|
1643
|
+
fiber.childContext?.pop();
|
|
1644
|
+
if (fiber.owned && !fiber.instance.get(null)) fiber.instance.set(null);
|
|
1645
|
+
} else if (fiber.kind == "provider") fiber.childContext?.pop();
|
|
1646
|
+
else if (fiber.kind == "portal") {
|
|
1647
|
+
fiber.portalStart.remove();
|
|
1648
|
+
fiber.portalEnd.remove();
|
|
1649
|
+
}
|
|
1650
|
+
removeRange(fiber.start, fiber.end);
|
|
1651
|
+
}
|
|
1652
|
+
function removeRange(start, end) {
|
|
1653
|
+
let node = start;
|
|
1654
|
+
while (true) {
|
|
1655
|
+
const next = node.nextSibling;
|
|
1656
|
+
node.remove();
|
|
1657
|
+
if (node === end) break;
|
|
1658
|
+
node = next;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
//#endregion
|
|
1663
|
+
export { Consumer, Provider, createPortal, css, lazy, macro, render, style };
|
|
1664
|
+
//# sourceMappingURL=index.js.map
|