@calmdown/pyxis 1.0.0-rc.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/dist/core-dev.d.ts +787 -0
- package/dist/core-dev.js +1828 -0
- package/dist/core-dev.js.map +1 -0
- package/dist/core.d.ts +737 -0
- package/dist/core.js +2 -0
- package/dist/core.js.map +1 -0
- package/dist/jsx-dev-runtime.d.ts +29 -0
- package/dist/jsx-dev-runtime.js +10 -0
- package/dist/jsx-runtime.d.ts +1 -0
- package/dist/jsx-runtime.js +1 -0
- package/dist/main.d.ts +65 -0
- package/dist/main.js +28 -0
- package/package.json +32 -0
package/dist/core-dev.js
ADDED
|
@@ -0,0 +1,1828 @@
|
|
|
1
|
+
//#region src/dev/ComponentRegistry.ts
|
|
2
|
+
var ComponentRegistry = class {
|
|
3
|
+
components = /* @__PURE__ */ new Map();
|
|
4
|
+
isPendingUpdate = false;
|
|
5
|
+
on(id, fn) {
|
|
6
|
+
const entry = this.components.get(id);
|
|
7
|
+
if (!entry) throw new Error(`no component was registered under "${id}"`);
|
|
8
|
+
const listener = {
|
|
9
|
+
fn,
|
|
10
|
+
entry
|
|
11
|
+
};
|
|
12
|
+
if (entry.lt) {
|
|
13
|
+
entry.lt.ln = listener;
|
|
14
|
+
listener.lp = entry.lt;
|
|
15
|
+
} else entry.lh = listener;
|
|
16
|
+
entry.lt = listener;
|
|
17
|
+
fn(entry.component);
|
|
18
|
+
return listener;
|
|
19
|
+
}
|
|
20
|
+
off(listener) {
|
|
21
|
+
const { entry } = listener;
|
|
22
|
+
if (listener.lp) listener.lp.ln = listener.ln;
|
|
23
|
+
else if (entry.lh === listener) entry.lh = listener.ln;
|
|
24
|
+
if (listener.ln) listener.ln.lp = listener.lp;
|
|
25
|
+
else if (entry.lt === listener) entry.lt = listener.lp;
|
|
26
|
+
listener.lp = null;
|
|
27
|
+
listener.ln = null;
|
|
28
|
+
}
|
|
29
|
+
subscribe(id, fn) {
|
|
30
|
+
const listener = this.on(id, fn);
|
|
31
|
+
return () => this.off(listener);
|
|
32
|
+
}
|
|
33
|
+
upsert(id, component) {
|
|
34
|
+
const entry = this.components.get(id);
|
|
35
|
+
if (!entry) {
|
|
36
|
+
this.components.set(id, {
|
|
37
|
+
component,
|
|
38
|
+
dirty: false
|
|
39
|
+
});
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
entry.component = component;
|
|
43
|
+
entry.dirty = true;
|
|
44
|
+
if (!this.isPendingUpdate) {
|
|
45
|
+
queueMicrotask(this.update);
|
|
46
|
+
this.isPendingUpdate = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
update = () => {
|
|
50
|
+
this.isPendingUpdate = false;
|
|
51
|
+
this.components.forEach((entry) => {
|
|
52
|
+
if (!entry.dirty) return;
|
|
53
|
+
let current = entry.lh;
|
|
54
|
+
let next;
|
|
55
|
+
while (current) {
|
|
56
|
+
next = current.ln;
|
|
57
|
+
current.fn(entry.component);
|
|
58
|
+
current = next;
|
|
59
|
+
}
|
|
60
|
+
entry.dirty = false;
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
//#endregion
|
|
66
|
+
//#region src/dev/StateRegistry.ts
|
|
67
|
+
var StateRegistry = class {
|
|
68
|
+
state = /* @__PURE__ */ new WeakMap();
|
|
69
|
+
preserve(handle, devId, value) {
|
|
70
|
+
if (!handle || !devId) return;
|
|
71
|
+
let map = this.state.get(handle);
|
|
72
|
+
if (!map) this.state.set(handle, map = {});
|
|
73
|
+
map[devId] = value;
|
|
74
|
+
}
|
|
75
|
+
restore(handle, devId, block) {
|
|
76
|
+
if (!handle || !devId) return;
|
|
77
|
+
const map = this.state.get(handle);
|
|
78
|
+
if (!map || !Object.hasOwn(map, devId)) return;
|
|
79
|
+
return block ? block(map[devId]) : map[devId];
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
//#region src/dev/PyxisHotReload.ts
|
|
85
|
+
globalThis.__PYXIS_HMR__ = {
|
|
86
|
+
component: new ComponentRegistry(),
|
|
87
|
+
state: new StateRegistry()
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
//#endregion
|
|
91
|
+
//#region src/support/common.ts
|
|
92
|
+
function invoke(callback) {
|
|
93
|
+
return callback.$fn(callback.$a0, callback.$a1);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//#endregion
|
|
97
|
+
//#region src/data/Lifecycle.ts
|
|
98
|
+
/**
|
|
99
|
+
* Registers a callback to run just after the current Component has mounted.
|
|
100
|
+
*
|
|
101
|
+
* If a teardown callback is returned, it will be run just before the Component unmounts (equivalent
|
|
102
|
+
* to adding a separate `unmounted` block).
|
|
103
|
+
* @see {@link unmounted}
|
|
104
|
+
*/
|
|
105
|
+
function mounted(block, lifecycle = getLifecycle()) {
|
|
106
|
+
onMounted(lifecycle, {
|
|
107
|
+
$fn: invokeMountedCallback,
|
|
108
|
+
$a0: lifecycle,
|
|
109
|
+
$a1: block
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
/** @internal */
|
|
113
|
+
function onMounted(lifecycle, callback) {
|
|
114
|
+
(lifecycle.$onMount ??= []).push(callback);
|
|
115
|
+
}
|
|
116
|
+
function invokeMountedCallback(lifecycle, block) {
|
|
117
|
+
const dispose = block();
|
|
118
|
+
if (dispose) onUnmounted(lifecycle, { $fn: dispose });
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Registers a callback to run once the current Component is just about to unmount.
|
|
122
|
+
* @see {@link mounted}
|
|
123
|
+
*/
|
|
124
|
+
function unmounted(block, lifecycle = getLifecycle()) {
|
|
125
|
+
onUnmounted(lifecycle, { $fn: block });
|
|
126
|
+
}
|
|
127
|
+
/** @internal */
|
|
128
|
+
function onUnmounted(lifecycle, callback) {
|
|
129
|
+
(lifecycle.$onUnmount ??= []).push(callback);
|
|
130
|
+
}
|
|
131
|
+
let $currentLifecycle = null;
|
|
132
|
+
/**
|
|
133
|
+
* Gets the Lifecycle of the calling component.
|
|
134
|
+
*/
|
|
135
|
+
function getLifecycle() {
|
|
136
|
+
if (!$currentLifecycle) throw new Error("Cannot get current lifecycle. Are you creating an Atom outside of a Component?");
|
|
137
|
+
return $currentLifecycle;
|
|
138
|
+
}
|
|
139
|
+
/** @internal */
|
|
140
|
+
function setLifecycle(lifecycle) {
|
|
141
|
+
const previous = $currentLifecycle;
|
|
142
|
+
$currentLifecycle = lifecycle;
|
|
143
|
+
return previous;
|
|
144
|
+
}
|
|
145
|
+
function withLifecycle(lifecycle, block, arg) {
|
|
146
|
+
const previousLifecycle = $currentLifecycle;
|
|
147
|
+
$currentLifecycle = lifecycle;
|
|
148
|
+
try {
|
|
149
|
+
return block(arg);
|
|
150
|
+
} finally {
|
|
151
|
+
$currentLifecycle = previousLifecycle;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
//#endregion
|
|
156
|
+
//#region src/data/Dependency.ts
|
|
157
|
+
function bind(lifecycle, target, block) {
|
|
158
|
+
link(lifecycle, target, { $fn: block });
|
|
159
|
+
block();
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Links a Dependency to an Atom and Lifecycle.
|
|
163
|
+
* @internal
|
|
164
|
+
*/
|
|
165
|
+
function link(lifecycle, target, dep) {
|
|
166
|
+
if (target.$dt) {
|
|
167
|
+
target.$dt.$an = dep;
|
|
168
|
+
dep.$ap = target.$dt;
|
|
169
|
+
} else target.$dh = dep;
|
|
170
|
+
dep.$target = target;
|
|
171
|
+
target.$dt = dep;
|
|
172
|
+
if (lifecycle.$dt) {
|
|
173
|
+
lifecycle.$dt.$ln = dep;
|
|
174
|
+
dep.$lp = lifecycle.$dt;
|
|
175
|
+
} else lifecycle.$dh = dep;
|
|
176
|
+
dep.$lifecycle = lifecycle;
|
|
177
|
+
lifecycle.$dt = dep;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Unlinks a Dependency from the Atom and Lifecycle it has been linked to.
|
|
181
|
+
* @internal
|
|
182
|
+
*/
|
|
183
|
+
function unlink(dep) {
|
|
184
|
+
const target = dep.$target;
|
|
185
|
+
if (!target) return;
|
|
186
|
+
if (dep.$ap) dep.$ap.$an = dep.$an;
|
|
187
|
+
else if (target.$dh === dep) target.$dh = dep.$an;
|
|
188
|
+
if (dep.$an) dep.$an.$ap = dep.$ap;
|
|
189
|
+
else if (target.$dt === dep) target.$dt = dep.$ap;
|
|
190
|
+
dep.$target = null;
|
|
191
|
+
dep.$ap = null;
|
|
192
|
+
dep.$an = null;
|
|
193
|
+
const lifecycle = dep.$lifecycle;
|
|
194
|
+
if (dep.$lp) dep.$lp.$ln = dep.$ln;
|
|
195
|
+
else if (lifecycle.$dh === dep) lifecycle.$dh = dep.$ln;
|
|
196
|
+
if (dep.$ln) dep.$ln.$lp = dep.$lp;
|
|
197
|
+
else if (lifecycle.$dt === dep) lifecycle.$dt = dep.$lp;
|
|
198
|
+
dep.$lifecycle = null;
|
|
199
|
+
dep.$lp = null;
|
|
200
|
+
dep.$ln = null;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Unlinks all Dependencies managed by the given Lifecycle.
|
|
204
|
+
* @internal
|
|
205
|
+
*/
|
|
206
|
+
function unlinkAll(lifecycle) {
|
|
207
|
+
let dep = lifecycle.$dh;
|
|
208
|
+
let atom;
|
|
209
|
+
let next;
|
|
210
|
+
while (dep) {
|
|
211
|
+
atom = dep.$target;
|
|
212
|
+
if (dep.$ap) dep.$ap.$an = dep.$an;
|
|
213
|
+
else if (atom.$dh === dep) atom.$dh = dep.$an;
|
|
214
|
+
if (dep.$an) dep.$an.$ap = dep.$ap;
|
|
215
|
+
else if (atom.$dt === dep) atom.$dt = dep.$ap;
|
|
216
|
+
next = dep.$ln;
|
|
217
|
+
dep.$lifecycle = null;
|
|
218
|
+
dep.$target = null;
|
|
219
|
+
dep.$ap = null;
|
|
220
|
+
dep.$an = null;
|
|
221
|
+
dep.$lp = null;
|
|
222
|
+
dep.$ln = null;
|
|
223
|
+
dep = next;
|
|
224
|
+
}
|
|
225
|
+
lifecycle.$dh = null;
|
|
226
|
+
lifecycle.$dt = null;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
//#endregion
|
|
230
|
+
//#region src/data/Scheduler.ts
|
|
231
|
+
/** @internal */
|
|
232
|
+
function createScheduler(tick) {
|
|
233
|
+
let isPending = false;
|
|
234
|
+
const ticks = [];
|
|
235
|
+
const tocks = [];
|
|
236
|
+
const scheduler = {
|
|
237
|
+
$epoch: 1,
|
|
238
|
+
$onTick: ticks,
|
|
239
|
+
$onTock: tocks,
|
|
240
|
+
$scheduleTick: () => {
|
|
241
|
+
if (isPending) return;
|
|
242
|
+
isPending = true;
|
|
243
|
+
tick(update);
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
const update = () => {
|
|
247
|
+
try {
|
|
248
|
+
let index = 0;
|
|
249
|
+
let callback;
|
|
250
|
+
for (; index < ticks.length; index += 1) {
|
|
251
|
+
callback = ticks[index];
|
|
252
|
+
if (callback.$life === callback.$lifecycle.$life) {
|
|
253
|
+
callback.$re = scheduler.$epoch;
|
|
254
|
+
invoke(callback);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
for (index = 0; index < tocks.length; index += 1) {
|
|
258
|
+
callback = tocks[index];
|
|
259
|
+
if (callback.$life === callback.$lifecycle.$life) {
|
|
260
|
+
callback.$re = scheduler.$epoch;
|
|
261
|
+
invoke(callback);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} finally {
|
|
265
|
+
isPending = false;
|
|
266
|
+
ticks.length = 0;
|
|
267
|
+
tocks.length = 0;
|
|
268
|
+
scheduler.$epoch += 1;
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
return scheduler;
|
|
272
|
+
}
|
|
273
|
+
function schedule(lifecycle, queue, callback) {
|
|
274
|
+
const scheduler = lifecycle.$scheduler;
|
|
275
|
+
if (callback.$se === scheduler.$epoch) {
|
|
276
|
+
if (callback.$re === scheduler.$epoch) throw new Error("Refusing to re-schedule an update after it already executed, as it may cause an infinite loop. Are you mutating an Atom inside an effect that observes it?");
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
callback.$lifecycle = lifecycle;
|
|
280
|
+
callback.$life = lifecycle.$life;
|
|
281
|
+
callback.$se = scheduler.$epoch;
|
|
282
|
+
queue.push(callback);
|
|
283
|
+
scheduler.$scheduleTick();
|
|
284
|
+
}
|
|
285
|
+
/** @internal */
|
|
286
|
+
function scheduleTick(lifecycle, callback) {
|
|
287
|
+
schedule(lifecycle, lifecycle.$scheduler.$onTick, callback);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Runs a block of code on the next tick of the scheduler, synchronized with other updates. If a
|
|
291
|
+
* tick is not currently pending, a new one is scheduled.
|
|
292
|
+
*/
|
|
293
|
+
function tick(block, lifecycle = getLifecycle()) {
|
|
294
|
+
schedule(lifecycle, lifecycle.$scheduler.$onTick, { $fn: block });
|
|
295
|
+
}
|
|
296
|
+
/** @internal */
|
|
297
|
+
function scheduleTock(lifecycle, callback) {
|
|
298
|
+
schedule(lifecycle, lifecycle.$scheduler.$onTock, callback);
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Runs a block of code after the next tick of the scheduler, once all regular updates finished.
|
|
302
|
+
* If a tick is not currently pending, a new one is scheduled.
|
|
303
|
+
*/
|
|
304
|
+
function tock(block, lifecycle = getLifecycle()) {
|
|
305
|
+
schedule(lifecycle, lifecycle.$scheduler.$onTock, { $fn: block });
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
//#endregion
|
|
309
|
+
//#region src/data/Effect.ts
|
|
310
|
+
/**
|
|
311
|
+
* Creates an Effect - a block of logic executed each time any of the Atoms accessed within it
|
|
312
|
+
* change. The block is first synchronously executed when the Effect is created.
|
|
313
|
+
*
|
|
314
|
+
* If a teardown callback is returned, it will be run before the next effect re-run, or on component
|
|
315
|
+
* unmount.
|
|
316
|
+
*/
|
|
317
|
+
function effect(block, lifecycle = getLifecycle()) {
|
|
318
|
+
runEffect({
|
|
319
|
+
$lifecycle: lifecycle,
|
|
320
|
+
$life: lifecycle.$life,
|
|
321
|
+
$block: block,
|
|
322
|
+
$react: scheduleEffect,
|
|
323
|
+
$cycle: 0
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
function scheduleEffect(effect, cycle) {
|
|
327
|
+
if (effect.$cycle > cycle) {
|
|
328
|
+
unlink(this);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
scheduleTick(effect.$lifecycle, effect.$resolve ??= {
|
|
332
|
+
$fn: runEffect,
|
|
333
|
+
$a0: effect
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
function runEffect(effect) {
|
|
337
|
+
if (effect.$life !== effect.$lifecycle.$life) return;
|
|
338
|
+
effect.$dispose?.();
|
|
339
|
+
effect.$dispose = resolve(effect);
|
|
340
|
+
if (!effect.$tracksUnmount && effect.$dispose) {
|
|
341
|
+
effect.$tracksUnmount = true;
|
|
342
|
+
onUnmounted(effect.$lifecycle, {
|
|
343
|
+
$fn: teardownEffect,
|
|
344
|
+
$a0: effect
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
function teardownEffect(effect) {
|
|
349
|
+
effect.$dispose?.();
|
|
350
|
+
effect.$dispose = null;
|
|
351
|
+
}
|
|
352
|
+
let $currentEffect = null;
|
|
353
|
+
/**
|
|
354
|
+
* Resolves an Effect: runs user logic tracking accessed Atoms and updating dependency links.
|
|
355
|
+
* Returned value is forwarded.
|
|
356
|
+
* @internal
|
|
357
|
+
*/
|
|
358
|
+
function resolve(effect) {
|
|
359
|
+
effect.$deps ??= /* @__PURE__ */ new WeakMap();
|
|
360
|
+
effect.$cycle += 1;
|
|
361
|
+
const previousEffect = $currentEffect;
|
|
362
|
+
const previousLifecycle = setLifecycle(effect.$lifecycle);
|
|
363
|
+
$currentEffect = effect;
|
|
364
|
+
try {
|
|
365
|
+
return effect.$block();
|
|
366
|
+
} finally {
|
|
367
|
+
setLifecycle(previousLifecycle);
|
|
368
|
+
$currentEffect = previousEffect;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Reports an Atom has been accessed. Does nothing if not within an Effect.
|
|
373
|
+
* @internal
|
|
374
|
+
*/
|
|
375
|
+
function reportAccess(atom) {
|
|
376
|
+
if (!$currentEffect || $currentEffect.$life !== $currentEffect.$lifecycle.$life) return;
|
|
377
|
+
let dep = $currentEffect.$deps.get(atom);
|
|
378
|
+
if (dep) {
|
|
379
|
+
dep.$a1 = $currentEffect.$cycle;
|
|
380
|
+
if (!dep.$lifecycle) link($currentEffect.$lifecycle, atom, dep);
|
|
381
|
+
} else {
|
|
382
|
+
link($currentEffect.$lifecycle, atom, dep = {
|
|
383
|
+
$fn: $currentEffect.$react,
|
|
384
|
+
$a0: $currentEffect,
|
|
385
|
+
$a1: $currentEffect.$cycle
|
|
386
|
+
});
|
|
387
|
+
$currentEffect.$deps.set(atom, dep);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Asserts that the current code is not running within an effect block.
|
|
392
|
+
* Only used in development; In production, this function should be removed by the bundler.
|
|
393
|
+
*/
|
|
394
|
+
function __DEV__assertNotEffect() {
|
|
395
|
+
if ($currentEffect && $currentEffect.$lifecycle === getLifecycle() && $currentEffect.$life === $currentEffect.$lifecycle.$life) throw new Error("Attempt to create an Atom inside an effect block.");
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
//#endregion
|
|
399
|
+
//#region src/data/Atom.ts
|
|
400
|
+
/**
|
|
401
|
+
* Pyxis Atom type guard marker.
|
|
402
|
+
*/
|
|
403
|
+
const S_ATOM = Symbol.for("pyxis:atom");
|
|
404
|
+
function atomOf(initialValue, lifecycle = getLifecycle()) {
|
|
405
|
+
__DEV__assertNotEffect();
|
|
406
|
+
if (isAtom(initialValue)) return initialValue;
|
|
407
|
+
const atom = {
|
|
408
|
+
[S_ATOM]: true,
|
|
409
|
+
$value: initialValue,
|
|
410
|
+
$tracksValue: true,
|
|
411
|
+
$lifecycle: lifecycle,
|
|
412
|
+
$lastValue: initialValue,
|
|
413
|
+
get: getValue$1,
|
|
414
|
+
set: setValue$2
|
|
415
|
+
};
|
|
416
|
+
{
|
|
417
|
+
const devId = arguments[2];
|
|
418
|
+
atom.$devId = devId;
|
|
419
|
+
globalThis.__PYXIS_HMR__.state.restore(lifecycle, devId, (value) => {
|
|
420
|
+
atom.$value = value;
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
return atom;
|
|
424
|
+
}
|
|
425
|
+
function getValue$1() {
|
|
426
|
+
return this.$value;
|
|
427
|
+
}
|
|
428
|
+
function setValue$2(value) {
|
|
429
|
+
if (Object.is(this.$value, value)) return false;
|
|
430
|
+
this.$value = value;
|
|
431
|
+
globalThis.__PYXIS_HMR__.state.preserve(this.$lifecycle, this.$devId, value);
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
function isAtom(input) {
|
|
435
|
+
return input !== null && typeof input === "object" && input[S_ATOM] === true;
|
|
436
|
+
}
|
|
437
|
+
function read(input) {
|
|
438
|
+
if (isAtom(input)) {
|
|
439
|
+
reportAccess(input);
|
|
440
|
+
return input.get();
|
|
441
|
+
}
|
|
442
|
+
return input;
|
|
443
|
+
}
|
|
444
|
+
function peek(input) {
|
|
445
|
+
if (isAtom(input)) return input.get();
|
|
446
|
+
return input;
|
|
447
|
+
}
|
|
448
|
+
function write(input, value, force = false) {
|
|
449
|
+
if (isAtom(input)) {
|
|
450
|
+
if (input.set(value) || force) {
|
|
451
|
+
input.$force ||= force;
|
|
452
|
+
scheduleTick(input.$lifecycle, input.$notify ??= {
|
|
453
|
+
$fn: notify$1,
|
|
454
|
+
$a0: input
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
return input.get();
|
|
458
|
+
}
|
|
459
|
+
return input;
|
|
460
|
+
}
|
|
461
|
+
function update(input, transform, force = false) {
|
|
462
|
+
if (isAtom(input)) {
|
|
463
|
+
if (input.set(transform(input.get())) || force) {
|
|
464
|
+
input.$force ||= force;
|
|
465
|
+
scheduleTick(input.$lifecycle, input.$notify ??= {
|
|
466
|
+
$fn: notify$1,
|
|
467
|
+
$a0: input
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
return input.get();
|
|
471
|
+
}
|
|
472
|
+
return input;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Notifies the dependencies of an Atom.
|
|
476
|
+
* @internal
|
|
477
|
+
*/
|
|
478
|
+
function notify$1(input) {
|
|
479
|
+
if (input.$tracksValue) {
|
|
480
|
+
const newValue = input.get();
|
|
481
|
+
if (Object.is(input.$lastValue, newValue) && !input.$force) return;
|
|
482
|
+
input.$lastValue = newValue;
|
|
483
|
+
}
|
|
484
|
+
input.$force = false;
|
|
485
|
+
let current = input.$dh;
|
|
486
|
+
let next;
|
|
487
|
+
while (current) {
|
|
488
|
+
next = current.$an;
|
|
489
|
+
invoke(current);
|
|
490
|
+
current = next;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
//#endregion
|
|
495
|
+
//#region src/component/Text.ts
|
|
496
|
+
function Text(jsx, hParent, nUsedParent, _nRealParent, nBefore, isBatch) {
|
|
497
|
+
const { adapter } = hParent.$ng;
|
|
498
|
+
let node = null;
|
|
499
|
+
if (isAtom(jsx)) bind(hParent.$ng, jsx, () => {
|
|
500
|
+
node = adapter.text(jsx.get()?.toString() ?? "", node);
|
|
501
|
+
});
|
|
502
|
+
else node = adapter.text(jsx.toString(), null);
|
|
503
|
+
insert(node, null, hParent, nUsedParent, nBefore, isBatch);
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
//#endregion
|
|
507
|
+
//#region src/data/Context.ts
|
|
508
|
+
function createContext() {
|
|
509
|
+
let $symbol = Symbol();
|
|
510
|
+
{
|
|
511
|
+
const devId = arguments[0];
|
|
512
|
+
$symbol = globalThis.__PYXIS_HMR__.state.restore(createContext, devId) ?? $symbol;
|
|
513
|
+
globalThis.__PYXIS_HMR__.state.preserve(createContext, devId, $symbol);
|
|
514
|
+
}
|
|
515
|
+
return { $symbol };
|
|
516
|
+
}
|
|
517
|
+
let $currentContainer;
|
|
518
|
+
let $isNewContainer = false;
|
|
519
|
+
/** @internal */
|
|
520
|
+
function getContextContainer() {
|
|
521
|
+
return $currentContainer;
|
|
522
|
+
}
|
|
523
|
+
/** @internal */
|
|
524
|
+
function setContextContainer(container) {
|
|
525
|
+
$currentContainer = container;
|
|
526
|
+
$isNewContainer = false;
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Gets a consumer Atom for the given Context. This atom will be read-only.
|
|
530
|
+
* @see {@link host}
|
|
531
|
+
*/
|
|
532
|
+
function consumerOf(context) {
|
|
533
|
+
__DEV__assertNotEffect();
|
|
534
|
+
const { $symbol } = context;
|
|
535
|
+
let ptr = $currentContainer;
|
|
536
|
+
let atom;
|
|
537
|
+
while (ptr && !(atom = ptr[$symbol])) ptr = ptr.$parent;
|
|
538
|
+
return atom ?? null;
|
|
539
|
+
}
|
|
540
|
+
function host(context, defaultValue) {
|
|
541
|
+
__DEV__assertNotEffect();
|
|
542
|
+
if (!$isNewContainer || !$currentContainer) {
|
|
543
|
+
$isNewContainer = true;
|
|
544
|
+
$currentContainer = { $parent: $currentContainer };
|
|
545
|
+
}
|
|
546
|
+
const lifecycle = getLifecycle();
|
|
547
|
+
{
|
|
548
|
+
const devId = arguments[2];
|
|
549
|
+
globalThis.__PYXIS_HMR__.state.restore(lifecycle, devId, (value) => {
|
|
550
|
+
defaultValue = value;
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
const localAtom = {
|
|
554
|
+
[S_ATOM]: true,
|
|
555
|
+
$lifecycle: lifecycle,
|
|
556
|
+
$tracksValue: true,
|
|
557
|
+
$value: defaultValue,
|
|
558
|
+
get: getLocalValue,
|
|
559
|
+
set: setValue$1
|
|
560
|
+
};
|
|
561
|
+
if (defaultValue === void 0) {
|
|
562
|
+
const ancestorAtom = consumerOf(context);
|
|
563
|
+
if (ancestorAtom) {
|
|
564
|
+
localAtom.get = getAncestorValue;
|
|
565
|
+
localAtom.$ancestor = ancestorAtom;
|
|
566
|
+
link(lifecycle, ancestorAtom, localAtom.$dep = {
|
|
567
|
+
$fn: notify$1,
|
|
568
|
+
$a0: localAtom
|
|
569
|
+
});
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
localAtom.$devId = arguments[2];
|
|
573
|
+
if (Object.hasOwn($currentContainer, context.$symbol)) throw new Error("Component declares multiple hosts of the same Context.");
|
|
574
|
+
$currentContainer[context.$symbol] = localAtom;
|
|
575
|
+
return localAtom;
|
|
576
|
+
}
|
|
577
|
+
function getAncestorValue() {
|
|
578
|
+
return this.$ancestor.get();
|
|
579
|
+
}
|
|
580
|
+
function getLocalValue() {
|
|
581
|
+
return this.$value;
|
|
582
|
+
}
|
|
583
|
+
function setValue$1(value) {
|
|
584
|
+
let oldValue;
|
|
585
|
+
if (this.$ancestor) {
|
|
586
|
+
oldValue = this.$ancestor.get();
|
|
587
|
+
unlink(this.$dep);
|
|
588
|
+
this.$dep = null;
|
|
589
|
+
this.$ancestor = null;
|
|
590
|
+
this.get = getLocalValue;
|
|
591
|
+
} else oldValue = this.$value;
|
|
592
|
+
this.$value = value;
|
|
593
|
+
globalThis.__PYXIS_HMR__.state.preserve(this.$lifecycle, this.$devId, value);
|
|
594
|
+
return !Object.is(oldValue, value);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
//#endregion
|
|
598
|
+
//#region src/Renderer.ts
|
|
599
|
+
/** @internal */
|
|
600
|
+
const S_COMPONENT = Symbol.for("pyxis:component");
|
|
601
|
+
/** @internal */
|
|
602
|
+
function createRenderer(adapter, extensions) {
|
|
603
|
+
const hGroup = {
|
|
604
|
+
adapter,
|
|
605
|
+
mounted: false,
|
|
606
|
+
$isGroup: true,
|
|
607
|
+
$scheduler: createScheduler(adapter.tick),
|
|
608
|
+
$extensions: extensions,
|
|
609
|
+
$life: 1,
|
|
610
|
+
$pg: null,
|
|
611
|
+
$ng: null,
|
|
612
|
+
unmount: () => unmount(hGroup),
|
|
613
|
+
mount: (nRoot, jsx) => {
|
|
614
|
+
hGroup.$nn = nRoot;
|
|
615
|
+
const isBatch = Boolean(adapter.batch);
|
|
616
|
+
const nParent = isBatch ? adapter.batch() : nRoot;
|
|
617
|
+
mount(jsx, hGroup, nParent, nRoot, null, isBatch);
|
|
618
|
+
if (isBatch) adapter.insert(nParent, nRoot, null);
|
|
619
|
+
}
|
|
620
|
+
};
|
|
621
|
+
hGroup.$ng = hGroup;
|
|
622
|
+
globalThis.__PYXIS_ROOT__ ??= hGroup;
|
|
623
|
+
return hGroup;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Creates a sub-group within the provided MountingGroup. Needed whenever a subtree needs to mount
|
|
627
|
+
* or unmount dynamically.
|
|
628
|
+
*/
|
|
629
|
+
function fork(hParent, hBefore = null) {
|
|
630
|
+
const ng = hParent.$ng;
|
|
631
|
+
const hGroup = {
|
|
632
|
+
adapter: ng.adapter,
|
|
633
|
+
mounted: false,
|
|
634
|
+
$isGroup: true,
|
|
635
|
+
$scheduler: ng.$scheduler,
|
|
636
|
+
$extensions: ng.$extensions,
|
|
637
|
+
$life: 1,
|
|
638
|
+
$context: getContextContainer(),
|
|
639
|
+
$pg: ng,
|
|
640
|
+
$ng: null
|
|
641
|
+
};
|
|
642
|
+
hGroup.$ng = hGroup;
|
|
643
|
+
hGroup.$nn = hParent.$nn;
|
|
644
|
+
track(hGroup, hParent, hBefore);
|
|
645
|
+
return hGroup;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Adds a HNode to the hierarchy.
|
|
649
|
+
*/
|
|
650
|
+
function track(hNode, hParent, hBefore = null) {
|
|
651
|
+
if (hBefore?.$pg === hParent) if (hBefore.$hp) {
|
|
652
|
+
hNode.$hp = hBefore.$hp;
|
|
653
|
+
hNode.$hn = hBefore;
|
|
654
|
+
hBefore.$hp.$hn = hNode;
|
|
655
|
+
hBefore.$hp = hNode;
|
|
656
|
+
} else {
|
|
657
|
+
hNode.$hp = null;
|
|
658
|
+
hNode.$hn = hParent.$hh;
|
|
659
|
+
if (hParent.$hh === hBefore) hBefore.$hp = hNode;
|
|
660
|
+
hParent.$hh = hNode;
|
|
661
|
+
}
|
|
662
|
+
else {
|
|
663
|
+
if (hParent.$ht) {
|
|
664
|
+
hParent.$ht.$hn = hNode;
|
|
665
|
+
hNode.$hp = hParent.$ht;
|
|
666
|
+
} else hParent.$hh = hNode;
|
|
667
|
+
hParent.$ht = hNode;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
/**
|
|
671
|
+
* Removes a HNode from the tracking hierarchy.
|
|
672
|
+
*/
|
|
673
|
+
function untrack(hNode) {
|
|
674
|
+
if (hNode.$hp) hNode.$hp.$hn = hNode.$hn;
|
|
675
|
+
else if (hNode.$pg?.$hh === hNode) hNode.$pg.$hh = hNode.$hn;
|
|
676
|
+
if (hNode.$hn) hNode.$hn.$hp = hNode.$hp;
|
|
677
|
+
else if (hNode.$pg?.$ht === hNode) hNode.$pg.$ht = hNode.$hp;
|
|
678
|
+
hNode.$hp = null;
|
|
679
|
+
hNode.$hn = null;
|
|
680
|
+
}
|
|
681
|
+
/**
|
|
682
|
+
* Mounts a MountingGroup to the specified location in the node tree. If the group is already
|
|
683
|
+
* mounted (i.e. its native nodes are already rendered somewhere), it is moved to the new location
|
|
684
|
+
* without re-mounting Pyxis components.
|
|
685
|
+
*
|
|
686
|
+
* Note that for successfully moving a group within the tree, you should first `untrack` the group,
|
|
687
|
+
* then re-`track` it to the new location and only then call `mount` to commit the move.
|
|
688
|
+
* @see {@link track}
|
|
689
|
+
* @see {@link untrack}
|
|
690
|
+
*/
|
|
691
|
+
function mount(jsx, hGroup, nUsedParent, nRealParent, nBefore, isBatch) {
|
|
692
|
+
if (hGroup.mounted) {
|
|
693
|
+
reinsertNodes(hGroup, nUsedParent, nBefore);
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
const previousLifecycle = setLifecycle(hGroup);
|
|
697
|
+
setContextContainer(hGroup.$context);
|
|
698
|
+
try {
|
|
699
|
+
mountJsx(jsx, hGroup, nUsedParent, nRealParent, nBefore, isBatch);
|
|
700
|
+
} finally {
|
|
701
|
+
setLifecycle(previousLifecycle);
|
|
702
|
+
hGroup.mounted = true;
|
|
703
|
+
if (hGroup.$pg?.mounted !== false) notifyMounted(hGroup);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
/**
|
|
707
|
+
* Only used by `mount`, do not call directly.
|
|
708
|
+
*
|
|
709
|
+
* Recursively (dept-first) runs components' `mounted` callbacks.
|
|
710
|
+
* @see {@link mount}
|
|
711
|
+
* @internal
|
|
712
|
+
*/
|
|
713
|
+
function notifyMounted(hNode) {
|
|
714
|
+
let current = hNode.$hh;
|
|
715
|
+
while (current) {
|
|
716
|
+
notifyMounted(current);
|
|
717
|
+
current = current.$hn;
|
|
718
|
+
}
|
|
719
|
+
let callbacks;
|
|
720
|
+
if (hNode.$isGroup && hNode.mounted && (callbacks = hNode.$onMount)) {
|
|
721
|
+
const previousLifecycle = setLifecycle(hNode);
|
|
722
|
+
try {
|
|
723
|
+
callbacks.forEach(invoke);
|
|
724
|
+
} finally {
|
|
725
|
+
callbacks.length = 0;
|
|
726
|
+
setLifecycle(previousLifecycle);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
/**
|
|
731
|
+
* Only used by `mount`, do not call directly.
|
|
732
|
+
*
|
|
733
|
+
* Re-inserts native nodes of the given group to the specified location in the native tree. Only
|
|
734
|
+
* moves the uppermost nodes - any children should move implicitly with them.
|
|
735
|
+
* @see {@link mount}
|
|
736
|
+
* @internal
|
|
737
|
+
*/
|
|
738
|
+
function reinsertNodes(hGroup, nParent, nBefore) {
|
|
739
|
+
const { adapter } = hGroup;
|
|
740
|
+
let current = hGroup.$hh;
|
|
741
|
+
while (current) {
|
|
742
|
+
if (current.$isNative) adapter.insert(current.$nn, nParent, nBefore);
|
|
743
|
+
else reinsertNodes(current, nParent, nBefore);
|
|
744
|
+
current = current.$hn;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
function unmount(hNode, top = true) {
|
|
748
|
+
if (hNode.$isGroup) {
|
|
749
|
+
if (hNode.mounted) {
|
|
750
|
+
let callbacks;
|
|
751
|
+
if (callbacks = hNode.$onUnmount) {
|
|
752
|
+
const previousLifecycle = setLifecycle(hNode);
|
|
753
|
+
try {
|
|
754
|
+
callbacks.forEach(invoke);
|
|
755
|
+
} finally {
|
|
756
|
+
callbacks.length = 0;
|
|
757
|
+
setLifecycle(previousLifecycle);
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
hNode.mounted = false;
|
|
761
|
+
hNode.$life += 1;
|
|
762
|
+
}
|
|
763
|
+
unlinkAll(hNode);
|
|
764
|
+
}
|
|
765
|
+
const { adapter } = hNode.$ng;
|
|
766
|
+
let current = hNode.$hh;
|
|
767
|
+
let next;
|
|
768
|
+
while (current) {
|
|
769
|
+
if (current.$isNative && top) {
|
|
770
|
+
adapter.remove(current.$nn);
|
|
771
|
+
unmount(current, false);
|
|
772
|
+
} else unmount(current, top);
|
|
773
|
+
next = current.$hn;
|
|
774
|
+
current.$hp = null;
|
|
775
|
+
current.$hn = null;
|
|
776
|
+
current = next;
|
|
777
|
+
}
|
|
778
|
+
hNode.$hh = null;
|
|
779
|
+
hNode.$ht = null;
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Mounts components described by the JsxResult to the specified location in the node tree.
|
|
783
|
+
*/
|
|
784
|
+
function mountJsx(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch) {
|
|
785
|
+
switch (typeof jsx) {
|
|
786
|
+
case "object":
|
|
787
|
+
if (jsx === null) break;
|
|
788
|
+
if (Array.isArray(jsx)) {
|
|
789
|
+
const { length } = jsx;
|
|
790
|
+
let index = 0;
|
|
791
|
+
for (; index < length; index += 1) mountJsx(jsx[index], hParent, nUsedParent, nRealParent, nBefore, isBatch);
|
|
792
|
+
break;
|
|
793
|
+
}
|
|
794
|
+
if (!isAtom(jsx)) {
|
|
795
|
+
jsx[S_COMPONENT]?.(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch);
|
|
796
|
+
break;
|
|
797
|
+
}
|
|
798
|
+
case "string":
|
|
799
|
+
case "number":
|
|
800
|
+
case "boolean":
|
|
801
|
+
case "bigint":
|
|
802
|
+
Text(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch);
|
|
803
|
+
break;
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* Inserts a native node and adds it to the tracking hierarchy. Necessary to preserve render order.
|
|
808
|
+
* Should only be called by component handlers!
|
|
809
|
+
*/
|
|
810
|
+
function insert(nNode, children, hParent, nUsedParent, nBefore, isBatch) {
|
|
811
|
+
let hNative = hParent;
|
|
812
|
+
if (hNative.$isGroup) {
|
|
813
|
+
let hBefore = null;
|
|
814
|
+
if (nBefore) {
|
|
815
|
+
let current = hParent.$ht;
|
|
816
|
+
while (current) {
|
|
817
|
+
if (current.$isNative && current.$nn === nBefore) {
|
|
818
|
+
hBefore = current;
|
|
819
|
+
break;
|
|
820
|
+
}
|
|
821
|
+
current = current.$hp;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
track(hNative = {
|
|
825
|
+
$isNative: true,
|
|
826
|
+
$pg: hNative,
|
|
827
|
+
$ng: hNative,
|
|
828
|
+
$nn: nNode
|
|
829
|
+
}, hParent, hBefore);
|
|
830
|
+
}
|
|
831
|
+
mountJsx(children, hNative, nNode, nNode, null, isBatch);
|
|
832
|
+
hParent.$ng.adapter.insert(nNode, nUsedParent, nBefore);
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
//#endregion
|
|
836
|
+
//#region src/component/Fragment.ts
|
|
837
|
+
function Fragment(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch) {
|
|
838
|
+
mountJsx(jsx.children, hParent, nUsedParent, nRealParent, nBefore, isBatch);
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
//#endregion
|
|
842
|
+
//#region src/data/ListDelta.ts
|
|
843
|
+
/** @internal */
|
|
844
|
+
const LC_CHANGE = 1;
|
|
845
|
+
/** @internal */
|
|
846
|
+
const LC_INSERT = 2;
|
|
847
|
+
/** @internal */
|
|
848
|
+
const LC_REMOVE = 3;
|
|
849
|
+
/** @internal */
|
|
850
|
+
const LC_CLEAR = 4;
|
|
851
|
+
let ChangeKind = /* @__PURE__ */ function(ChangeKind) {
|
|
852
|
+
ChangeKind[ChangeKind["Change"] = 1] = "Change";
|
|
853
|
+
ChangeKind[ChangeKind["Insert"] = 2] = "Insert";
|
|
854
|
+
ChangeKind[ChangeKind["Remove"] = 3] = "Remove";
|
|
855
|
+
ChangeKind[ChangeKind["Clear"] = 4] = "Clear";
|
|
856
|
+
return ChangeKind;
|
|
857
|
+
}({});
|
|
858
|
+
/** @internal */
|
|
859
|
+
function createDelta() {
|
|
860
|
+
return {
|
|
861
|
+
changes: [],
|
|
862
|
+
lengthChange: 0
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
/** @internal */
|
|
866
|
+
function itemChanged({ changes: $changes }, at, oldItem, newItem) {
|
|
867
|
+
const ci = binarySearch($changes, at, latest);
|
|
868
|
+
if (ci < 0) $changes.splice(~ci, 0, {
|
|
869
|
+
kind: 1,
|
|
870
|
+
index: at,
|
|
871
|
+
oldItem,
|
|
872
|
+
newItem
|
|
873
|
+
});
|
|
874
|
+
else {
|
|
875
|
+
const current = $changes[ci];
|
|
876
|
+
switch (current.kind) {
|
|
877
|
+
case 1:
|
|
878
|
+
case 2:
|
|
879
|
+
current.newItem = newItem;
|
|
880
|
+
break;
|
|
881
|
+
case 3:
|
|
882
|
+
$changes.splice(ci + 1, 0, {
|
|
883
|
+
kind: 1,
|
|
884
|
+
index: at,
|
|
885
|
+
oldItem,
|
|
886
|
+
newItem
|
|
887
|
+
});
|
|
888
|
+
break;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
/** @internal */
|
|
893
|
+
function itemInserted(delta, at, item) {
|
|
894
|
+
const { changes: $changes } = delta;
|
|
895
|
+
let ci = binarySearch($changes, at, earliest);
|
|
896
|
+
if (ci < 0) {
|
|
897
|
+
ci = ~ci;
|
|
898
|
+
$changes.splice(ci, 0, {
|
|
899
|
+
kind: 2,
|
|
900
|
+
index: at,
|
|
901
|
+
newItem: item
|
|
902
|
+
});
|
|
903
|
+
} else {
|
|
904
|
+
const current = $changes[ci];
|
|
905
|
+
switch (current.kind) {
|
|
906
|
+
case 1:
|
|
907
|
+
case 2:
|
|
908
|
+
$changes.splice(ci, 0, {
|
|
909
|
+
kind: 2,
|
|
910
|
+
index: at,
|
|
911
|
+
newItem: item
|
|
912
|
+
});
|
|
913
|
+
break;
|
|
914
|
+
case 3:
|
|
915
|
+
current.kind = 1;
|
|
916
|
+
current.newItem = item;
|
|
917
|
+
break;
|
|
918
|
+
}
|
|
919
|
+
}
|
|
920
|
+
const { length } = $changes;
|
|
921
|
+
while (++ci < length) $changes[ci].index += 1;
|
|
922
|
+
delta.lengthChange += 1;
|
|
923
|
+
}
|
|
924
|
+
/** @internal */
|
|
925
|
+
function itemRemoved(delta, at, item) {
|
|
926
|
+
const { changes: $changes } = delta;
|
|
927
|
+
let ci = binarySearch($changes, at, latest);
|
|
928
|
+
if (ci < 0) {
|
|
929
|
+
ci = ~ci;
|
|
930
|
+
$changes.splice(ci, 0, {
|
|
931
|
+
kind: 3,
|
|
932
|
+
index: at,
|
|
933
|
+
oldItem: item
|
|
934
|
+
});
|
|
935
|
+
} else {
|
|
936
|
+
const current = $changes[ci];
|
|
937
|
+
switch (current.kind) {
|
|
938
|
+
case 1:
|
|
939
|
+
current.kind = 3;
|
|
940
|
+
current.newItem = void 0;
|
|
941
|
+
break;
|
|
942
|
+
case 2:
|
|
943
|
+
$changes.splice(ci--, 1);
|
|
944
|
+
break;
|
|
945
|
+
case 3:
|
|
946
|
+
$changes.splice(++ci, 0, {
|
|
947
|
+
kind: 3,
|
|
948
|
+
index: at,
|
|
949
|
+
oldItem: item
|
|
950
|
+
});
|
|
951
|
+
break;
|
|
952
|
+
}
|
|
953
|
+
}
|
|
954
|
+
const { length } = $changes;
|
|
955
|
+
while (++ci < length) $changes[ci].index -= 1;
|
|
956
|
+
delta.lengthChange -= 1;
|
|
957
|
+
}
|
|
958
|
+
/** @internal */
|
|
959
|
+
function listCleared(delta, count) {
|
|
960
|
+
const { changes: $changes } = delta;
|
|
961
|
+
$changes.length = 0;
|
|
962
|
+
$changes.push({
|
|
963
|
+
kind: 4,
|
|
964
|
+
index: -1
|
|
965
|
+
});
|
|
966
|
+
delta.lengthChange -= count;
|
|
967
|
+
}
|
|
968
|
+
/** @internal */
|
|
969
|
+
function listSynced(delta, oldState, newState, eq) {
|
|
970
|
+
let index = 0;
|
|
971
|
+
let N = oldState.length;
|
|
972
|
+
let M = newState.length;
|
|
973
|
+
while (index < N && index < M && eq(oldState[index], newState[index])) index += 1;
|
|
974
|
+
if (index === N && index === M) return;
|
|
975
|
+
while (N > index && M > index && eq(oldState[N - 1], newState[M - 1])) {
|
|
976
|
+
N -= 1;
|
|
977
|
+
M -= 1;
|
|
978
|
+
}
|
|
979
|
+
const Z = (Math.min(N, M) + 1) * 2;
|
|
980
|
+
const L = N + M;
|
|
981
|
+
const state = {
|
|
982
|
+
$eq: eq,
|
|
983
|
+
$list0: oldState,
|
|
984
|
+
$list1: newState,
|
|
985
|
+
$index0: index,
|
|
986
|
+
$index1: index,
|
|
987
|
+
$N: N,
|
|
988
|
+
$M: M,
|
|
989
|
+
$Z: Z,
|
|
990
|
+
$c: 0,
|
|
991
|
+
$buffer: new (L <= 255 ? Uint8Array : L <= 65535 ? Uint16Array : Uint32Array)(Z + Z),
|
|
992
|
+
$stack: [],
|
|
993
|
+
$stackTop: 0,
|
|
994
|
+
$pxs: -1,
|
|
995
|
+
$pxe: -1,
|
|
996
|
+
$pys: -1,
|
|
997
|
+
$pye: -1,
|
|
998
|
+
$oxs: -1,
|
|
999
|
+
$oxe: -1,
|
|
1000
|
+
$oys: -1,
|
|
1001
|
+
$oye: -1
|
|
1002
|
+
};
|
|
1003
|
+
let offset = 0;
|
|
1004
|
+
let rs, re, is, ie, r, i;
|
|
1005
|
+
do {
|
|
1006
|
+
myersDiff(state);
|
|
1007
|
+
if (state.$c === 1) {
|
|
1008
|
+
rs = state.$oxs;
|
|
1009
|
+
re = state.$oxe;
|
|
1010
|
+
is = state.$oys;
|
|
1011
|
+
ie = state.$oye;
|
|
1012
|
+
} else if (state.$pxs >= 0) {
|
|
1013
|
+
rs = state.$pxs;
|
|
1014
|
+
re = state.$pxe;
|
|
1015
|
+
is = state.$pys;
|
|
1016
|
+
ie = state.$pye;
|
|
1017
|
+
} else break;
|
|
1018
|
+
for (r = rs; r < re; r += 1) itemRemoved(delta, rs + offset, oldState[r]);
|
|
1019
|
+
for (i = is; i < ie; i += 1) {
|
|
1020
|
+
itemInserted(delta, rs + offset, newState[i]);
|
|
1021
|
+
offset += 1;
|
|
1022
|
+
}
|
|
1023
|
+
offset -= re - rs;
|
|
1024
|
+
} while (state.$c < 2);
|
|
1025
|
+
}
|
|
1026
|
+
const latest = (changes, index, mid, _min, max) => {
|
|
1027
|
+
let i = mid;
|
|
1028
|
+
while (++i < max && changes[i].index === index);
|
|
1029
|
+
return i - 1;
|
|
1030
|
+
};
|
|
1031
|
+
const earliest = (changes, index, mid, min, _max) => {
|
|
1032
|
+
let i = mid;
|
|
1033
|
+
while (--i >= min && changes[i].index === index);
|
|
1034
|
+
return i + 1;
|
|
1035
|
+
};
|
|
1036
|
+
function binarySearch(changes, index, bias) {
|
|
1037
|
+
let min = 0;
|
|
1038
|
+
let max = changes.length;
|
|
1039
|
+
let mid;
|
|
1040
|
+
let tmp;
|
|
1041
|
+
while (min < max) {
|
|
1042
|
+
mid = min + max >>> 1;
|
|
1043
|
+
tmp = changes[mid].index;
|
|
1044
|
+
if (index < tmp) max = mid;
|
|
1045
|
+
else if (index > tmp) min = mid + 1;
|
|
1046
|
+
else return bias(changes, index, mid, min, max);
|
|
1047
|
+
}
|
|
1048
|
+
return ~min;
|
|
1049
|
+
}
|
|
1050
|
+
function myersDiff(state) {
|
|
1051
|
+
const { $list0, $list1, $buffer, $stack, $eq } = state;
|
|
1052
|
+
let { $index0, $index1, $N, $M, $Z, $c, $stackTop } = state;
|
|
1053
|
+
let W, L, parity, offsetX, offsetY, z, h, hMax, k, kMin, kMax, gkm, gkp, u, v, x, y, pkm, pkp, sx;
|
|
1054
|
+
while (true) switch ($c) {
|
|
1055
|
+
case 0:
|
|
1056
|
+
Z_block: while ($N > 0 && $M > 0) {
|
|
1057
|
+
W = $N - $M;
|
|
1058
|
+
L = $N + $M;
|
|
1059
|
+
parity = L & 1;
|
|
1060
|
+
offsetX = $index0 + $N - 1;
|
|
1061
|
+
offsetY = $index1 + $M - 1;
|
|
1062
|
+
hMax = (L + parity) / 2;
|
|
1063
|
+
$buffer.fill(0, 0, $Z + $Z);
|
|
1064
|
+
h_loop: for (h = 0; h <= hMax; h += 1) {
|
|
1065
|
+
kMin = 2 * Math.max(0, h - $M) - h;
|
|
1066
|
+
kMax = h - 2 * Math.max(0, h - $N);
|
|
1067
|
+
for (k = kMin; k <= kMax; k += 2) {
|
|
1068
|
+
gkm = $buffer[k - 1 - $Z * Math.floor((k - 1) / $Z)];
|
|
1069
|
+
gkp = $buffer[k + 1 - $Z * Math.floor((k + 1) / $Z)];
|
|
1070
|
+
u = k === -h || k !== h && gkm < gkp ? gkp : gkm + 1;
|
|
1071
|
+
v = u - k;
|
|
1072
|
+
x = u;
|
|
1073
|
+
y = v;
|
|
1074
|
+
while (x < $N && y < $M && $eq($list0[$index0 + x], $list1[$index1 + y])) {
|
|
1075
|
+
x += 1;
|
|
1076
|
+
y += 1;
|
|
1077
|
+
}
|
|
1078
|
+
$buffer[k - $Z * Math.floor(k / $Z)] = x;
|
|
1079
|
+
if (parity === 1 && (z = W - k) >= 1 - h && z < h && x + $buffer[$Z + z - $Z * Math.floor(z / $Z)] >= $N) if (h > 1 || x !== u) {
|
|
1080
|
+
$stack[$stackTop++] = $index0 + x;
|
|
1081
|
+
$stack[$stackTop++] = $index1 + y;
|
|
1082
|
+
$stack[$stackTop++] = $N - x;
|
|
1083
|
+
$stack[$stackTop++] = $M - y;
|
|
1084
|
+
$N = u;
|
|
1085
|
+
$M = v;
|
|
1086
|
+
$Z = 2 * (Math.min($N, $M) + 1);
|
|
1087
|
+
continue Z_block;
|
|
1088
|
+
} else break h_loop;
|
|
1089
|
+
}
|
|
1090
|
+
for (k = kMin; k <= kMax; k += 2) {
|
|
1091
|
+
pkm = $buffer[$Z + k - 1 - $Z * Math.floor((k - 1) / $Z)];
|
|
1092
|
+
pkp = $buffer[$Z + k + 1 - $Z * Math.floor((k + 1) / $Z)];
|
|
1093
|
+
u = k === -h || k !== h && pkm < pkp ? pkp : pkm + 1;
|
|
1094
|
+
v = u - k;
|
|
1095
|
+
x = u;
|
|
1096
|
+
y = v;
|
|
1097
|
+
while (x < $N && y < $M && $eq($list0[offsetX - x], $list1[offsetY - y])) {
|
|
1098
|
+
x += 1;
|
|
1099
|
+
y += 1;
|
|
1100
|
+
}
|
|
1101
|
+
$buffer[$Z + k - $Z * Math.floor(k / $Z)] = x;
|
|
1102
|
+
if (parity === 0 && (z = W - k) >= -h && z <= h && x + $buffer[z - $Z * Math.floor(z / $Z)] >= $N) if (h > 0 || x !== u) {
|
|
1103
|
+
$stack[$stackTop++] = $index0 + $N - u;
|
|
1104
|
+
$stack[$stackTop++] = $index1 + $M - v;
|
|
1105
|
+
$stack[$stackTop++] = u;
|
|
1106
|
+
$stack[$stackTop++] = v;
|
|
1107
|
+
$N = $N - x;
|
|
1108
|
+
$M = $M - y;
|
|
1109
|
+
$Z = 2 * (Math.min($N, $M) + 1);
|
|
1110
|
+
continue Z_block;
|
|
1111
|
+
} else break h_loop;
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
if ($N === $M) continue;
|
|
1115
|
+
if ($M > $N) {
|
|
1116
|
+
$index0 += $N;
|
|
1117
|
+
$index1 += $N;
|
|
1118
|
+
$M -= $N;
|
|
1119
|
+
$N = 0;
|
|
1120
|
+
} else {
|
|
1121
|
+
$index0 += $M;
|
|
1122
|
+
$index1 += $M;
|
|
1123
|
+
$N -= $M;
|
|
1124
|
+
$M = 0;
|
|
1125
|
+
}
|
|
1126
|
+
break;
|
|
1127
|
+
}
|
|
1128
|
+
if ($N + $M !== 0) if (state.$pxe === $index0 || state.$pye === $index1) {
|
|
1129
|
+
state.$pxe = $index0 + $N;
|
|
1130
|
+
state.$pye = $index1 + $M;
|
|
1131
|
+
} else {
|
|
1132
|
+
sx = state.$pxs;
|
|
1133
|
+
state.$oxs = state.$pxs;
|
|
1134
|
+
state.$oxe = state.$pxe;
|
|
1135
|
+
state.$oys = state.$pys;
|
|
1136
|
+
state.$oye = state.$pye;
|
|
1137
|
+
state.$pxs = $index0;
|
|
1138
|
+
state.$pxe = $index0 + $N;
|
|
1139
|
+
state.$pys = $index1;
|
|
1140
|
+
state.$pye = $index1 + $M;
|
|
1141
|
+
if (sx >= 0) {
|
|
1142
|
+
state.$index0 = $index0;
|
|
1143
|
+
state.$index1 = $index1;
|
|
1144
|
+
state.$N = $N;
|
|
1145
|
+
state.$M = $M;
|
|
1146
|
+
state.$Z = $Z;
|
|
1147
|
+
state.$stackTop = $stackTop;
|
|
1148
|
+
state.$c = 1;
|
|
1149
|
+
return;
|
|
1150
|
+
}
|
|
1151
|
+
}
|
|
1152
|
+
case 1:
|
|
1153
|
+
if ($stackTop === 0) {
|
|
1154
|
+
state.$c = 2;
|
|
1155
|
+
return;
|
|
1156
|
+
}
|
|
1157
|
+
$M = $stack[--$stackTop];
|
|
1158
|
+
$N = $stack[--$stackTop];
|
|
1159
|
+
$index1 = $stack[--$stackTop];
|
|
1160
|
+
$index0 = $stack[--$stackTop];
|
|
1161
|
+
$Z = 2 * (Math.min($N, $M) + 1);
|
|
1162
|
+
$c = 0;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
|
|
1166
|
+
//#endregion
|
|
1167
|
+
//#region src/data/ProxyAtom.ts
|
|
1168
|
+
/**
|
|
1169
|
+
* Creates a ProxyAtom bound to the provided initial value. If it is an Atom, the proxy will mirror
|
|
1170
|
+
* it, otherwise it will be a read-only atom with a static value until rebound.
|
|
1171
|
+
*/
|
|
1172
|
+
function proxyOf(initialValue, lifecycle = getLifecycle()) {
|
|
1173
|
+
__DEV__assertNotEffect();
|
|
1174
|
+
const self = {
|
|
1175
|
+
[S_ATOM]: true,
|
|
1176
|
+
$lifecycle: lifecycle,
|
|
1177
|
+
use,
|
|
1178
|
+
get: getStaticValue
|
|
1179
|
+
};
|
|
1180
|
+
self.use(initialValue, false);
|
|
1181
|
+
return self;
|
|
1182
|
+
}
|
|
1183
|
+
function use(value, canNotify = true) {
|
|
1184
|
+
if (this.$dep) unlink(this.$dep);
|
|
1185
|
+
const oldValue = this.get();
|
|
1186
|
+
if (isAtom(value)) {
|
|
1187
|
+
this.$bound = value;
|
|
1188
|
+
this.$value = null;
|
|
1189
|
+
this.get = getBoundValue;
|
|
1190
|
+
this.set = setBoundValue;
|
|
1191
|
+
link(this.$lifecycle, value, this.$dep ??= {
|
|
1192
|
+
$fn: notify$1,
|
|
1193
|
+
$a0: this
|
|
1194
|
+
});
|
|
1195
|
+
} else {
|
|
1196
|
+
this.$bound = null;
|
|
1197
|
+
this.$value = value;
|
|
1198
|
+
this.get = getStaticValue;
|
|
1199
|
+
this.set = setStaticValue;
|
|
1200
|
+
}
|
|
1201
|
+
if (canNotify && !Object.is(oldValue, this.get())) scheduleTick(this.$lifecycle, this.$notify ??= {
|
|
1202
|
+
$fn: notify$1,
|
|
1203
|
+
$a0: this
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
1206
|
+
function getBoundValue() {
|
|
1207
|
+
return this.$bound.get();
|
|
1208
|
+
}
|
|
1209
|
+
function setBoundValue(value) {
|
|
1210
|
+
const atom = this.$bound;
|
|
1211
|
+
if (atom.set(value)) scheduleTick(atom.$lifecycle, atom.$notify ??= {
|
|
1212
|
+
$fn: notify$1,
|
|
1213
|
+
$a0: atom
|
|
1214
|
+
});
|
|
1215
|
+
return false;
|
|
1216
|
+
}
|
|
1217
|
+
function getStaticValue() {
|
|
1218
|
+
return this.$value;
|
|
1219
|
+
}
|
|
1220
|
+
function setStaticValue() {
|
|
1221
|
+
return false;
|
|
1222
|
+
}
|
|
1223
|
+
const EMPTY_SOURCE = {};
|
|
1224
|
+
/**
|
|
1225
|
+
* Copies select keys from a data object into a new object where values are all wrapped in
|
|
1226
|
+
* ProxyAtoms and can be updated later.
|
|
1227
|
+
* @see {@link updateProxy}
|
|
1228
|
+
* @internal
|
|
1229
|
+
**/
|
|
1230
|
+
function createProxy(lifecycle, data, keys) {
|
|
1231
|
+
const source = isObject(data) ? data : EMPTY_SOURCE;
|
|
1232
|
+
const proxy = {};
|
|
1233
|
+
const { length } = keys;
|
|
1234
|
+
let index = 0;
|
|
1235
|
+
let key;
|
|
1236
|
+
for (; index < length; index += 1) {
|
|
1237
|
+
key = keys[index];
|
|
1238
|
+
proxy[key] = proxyOf(source[key], lifecycle);
|
|
1239
|
+
}
|
|
1240
|
+
proxy.proxied = data;
|
|
1241
|
+
return proxy;
|
|
1242
|
+
}
|
|
1243
|
+
/**
|
|
1244
|
+
* Updates the values proxied by a previously created proxy object. The keys array must be the same
|
|
1245
|
+
* as was used during creation (or a subset).
|
|
1246
|
+
* @see {@link createProxy}
|
|
1247
|
+
* @internal
|
|
1248
|
+
**/
|
|
1249
|
+
function updateProxy(proxy, data, keys) {
|
|
1250
|
+
const source = isObject(data) ? data : EMPTY_SOURCE;
|
|
1251
|
+
const { length } = keys;
|
|
1252
|
+
proxy.proxied = data;
|
|
1253
|
+
let index = 0;
|
|
1254
|
+
let key;
|
|
1255
|
+
for (; index < length; index += 1) {
|
|
1256
|
+
key = keys[index];
|
|
1257
|
+
proxy[key].use(source[key]);
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
function isObject(value) {
|
|
1261
|
+
return value !== null && typeof value === "object";
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
//#endregion
|
|
1265
|
+
//#region src/component/Iterator.ts
|
|
1266
|
+
function Iterator(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch) {
|
|
1267
|
+
const source = jsx.source;
|
|
1268
|
+
const proxyKeys = jsx.proxy;
|
|
1269
|
+
const isProxy = proxyKeys !== void 0;
|
|
1270
|
+
const template = jsx.children[0];
|
|
1271
|
+
const hGroup = fork(hParent);
|
|
1272
|
+
const { adapter } = hGroup;
|
|
1273
|
+
const shouldBatch = Boolean(adapter.batch);
|
|
1274
|
+
const nListEndMarker = adapter.marker("/Iterator");
|
|
1275
|
+
let items;
|
|
1276
|
+
let skipDelta = Boolean(source.$delta);
|
|
1277
|
+
const onDelta = () => {
|
|
1278
|
+
if (skipDelta) {
|
|
1279
|
+
skipDelta = false;
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
const { changes, lengthChange } = source.$delta;
|
|
1283
|
+
const cMax = changes.length;
|
|
1284
|
+
const iMax = items.length + lengthChange;
|
|
1285
|
+
const newItems = new Array(iMax);
|
|
1286
|
+
const pending = [];
|
|
1287
|
+
let recycled = [];
|
|
1288
|
+
let item;
|
|
1289
|
+
let inserted = 0;
|
|
1290
|
+
let ci = 0;
|
|
1291
|
+
let oi = 0;
|
|
1292
|
+
let ni = 0;
|
|
1293
|
+
let change;
|
|
1294
|
+
let ref;
|
|
1295
|
+
let tmp;
|
|
1296
|
+
let isLocalBatch = false;
|
|
1297
|
+
let nBatchParent = nRealParent;
|
|
1298
|
+
let nBatchBefore = null;
|
|
1299
|
+
for (; ci < cMax; ci += 1) {
|
|
1300
|
+
change = changes[ci];
|
|
1301
|
+
while (ni < change.index) newItems[ni++] = items[oi++];
|
|
1302
|
+
switch (change.kind) {
|
|
1303
|
+
case 1:
|
|
1304
|
+
item = newItems[ni++] = items[oi++];
|
|
1305
|
+
if (isProxy) updateProxy(item.$data, change.newItem, proxyKeys);
|
|
1306
|
+
else {
|
|
1307
|
+
unmount(item);
|
|
1308
|
+
ref = items[oi]?.$marker ?? nListEndMarker;
|
|
1309
|
+
insert(item.$marker, null, item, nRealParent, ref, false);
|
|
1310
|
+
mount(withLifecycle(item, template, item.$data = change.newItem), item, nRealParent, nRealParent, ref, false);
|
|
1311
|
+
}
|
|
1312
|
+
break;
|
|
1313
|
+
case 2:
|
|
1314
|
+
if (!isProxy || inserted < lengthChange) {
|
|
1315
|
+
item = newItems[ni++] = fork(hGroup, items[oi]);
|
|
1316
|
+
item.$marker = adapter.marker("IteratorItem");
|
|
1317
|
+
item.$data = isProxy ? createProxy(item, change.newItem, proxyKeys) : change.newItem;
|
|
1318
|
+
inserted += 1;
|
|
1319
|
+
ref = items[oi]?.$marker ?? nListEndMarker;
|
|
1320
|
+
if (!isLocalBatch) if (shouldBatch) {
|
|
1321
|
+
isLocalBatch = true;
|
|
1322
|
+
nBatchParent = adapter.batch();
|
|
1323
|
+
nBatchBefore = null;
|
|
1324
|
+
} else nBatchBefore = ref;
|
|
1325
|
+
insert(item.$marker, null, item, nBatchParent, nBatchBefore, isLocalBatch);
|
|
1326
|
+
mount(withLifecycle(item, template, item.$data), item, nBatchParent, nRealParent, nBatchBefore, isLocalBatch);
|
|
1327
|
+
if (isLocalBatch && (inserted >= lengthChange || !(tmp = changes[ci + 1]) || tmp.kind !== 2 || tmp.index !== ni)) {
|
|
1328
|
+
adapter.insert(nBatchParent, nRealParent, ref);
|
|
1329
|
+
nBatchParent = nRealParent;
|
|
1330
|
+
isLocalBatch = false;
|
|
1331
|
+
}
|
|
1332
|
+
} else pending.push({
|
|
1333
|
+
$index: ni++,
|
|
1334
|
+
$item: change.newItem
|
|
1335
|
+
});
|
|
1336
|
+
break;
|
|
1337
|
+
case 3:
|
|
1338
|
+
item = items[oi++];
|
|
1339
|
+
if (isProxy) recycled.push(item);
|
|
1340
|
+
else unmount(item);
|
|
1341
|
+
untrack(item);
|
|
1342
|
+
break;
|
|
1343
|
+
case 4:
|
|
1344
|
+
if (isProxy) {
|
|
1345
|
+
recycled = items;
|
|
1346
|
+
recycled.forEach(untrack);
|
|
1347
|
+
oi = items.length;
|
|
1348
|
+
} else while (oi < items.length) {
|
|
1349
|
+
item = items[oi++];
|
|
1350
|
+
unmount(item);
|
|
1351
|
+
untrack(item);
|
|
1352
|
+
}
|
|
1353
|
+
break;
|
|
1354
|
+
}
|
|
1355
|
+
}
|
|
1356
|
+
while (ni < iMax) newItems[ni++] = items[oi++];
|
|
1357
|
+
let pi = pending.length - 1;
|
|
1358
|
+
let ri = recycled.length - 1;
|
|
1359
|
+
while (pi >= 0) {
|
|
1360
|
+
tmp = pending[pi--];
|
|
1361
|
+
item = newItems[tmp.$index] = recycled[ri--];
|
|
1362
|
+
updateProxy(item.$data, tmp.$item, proxyKeys);
|
|
1363
|
+
track(item, hGroup, ref = newItems[tmp.$index + 1]);
|
|
1364
|
+
mount(withLifecycle(item, template, item.$data), item, nRealParent, nRealParent, ref?.$marker ?? nListEndMarker, false);
|
|
1365
|
+
}
|
|
1366
|
+
while (ri >= 0) {
|
|
1367
|
+
item = recycled[ri--];
|
|
1368
|
+
unmount(item);
|
|
1369
|
+
untrack(item);
|
|
1370
|
+
}
|
|
1371
|
+
items = newItems;
|
|
1372
|
+
};
|
|
1373
|
+
link(hGroup, source, { $fn: onDelta });
|
|
1374
|
+
{
|
|
1375
|
+
let nBatchParent = nUsedParent;
|
|
1376
|
+
let nBatchBefore = nBefore;
|
|
1377
|
+
const isLocalBatch = shouldBatch && !isBatch && source.$items.length > 0;
|
|
1378
|
+
if (isLocalBatch) {
|
|
1379
|
+
nBatchParent = adapter.batch();
|
|
1380
|
+
nBatchBefore = null;
|
|
1381
|
+
}
|
|
1382
|
+
const isAnyBatch = isLocalBatch || isBatch;
|
|
1383
|
+
items = source.$items.map((data) => {
|
|
1384
|
+
const item = fork(hGroup);
|
|
1385
|
+
item.$marker = adapter.marker("IteratorItem");
|
|
1386
|
+
item.$data = isProxy ? createProxy(item, data, proxyKeys) : data;
|
|
1387
|
+
insert(item.$marker, null, item, nBatchParent, nBatchBefore, isAnyBatch);
|
|
1388
|
+
mount(withLifecycle(item, template, item.$data), item, nBatchParent, nRealParent, nBatchBefore, isAnyBatch);
|
|
1389
|
+
return item;
|
|
1390
|
+
});
|
|
1391
|
+
insert(nListEndMarker, null, hGroup, nBatchParent, nBatchBefore, isAnyBatch);
|
|
1392
|
+
if (isLocalBatch) adapter.insert(nBatchParent, nUsedParent, nBefore);
|
|
1393
|
+
}
|
|
1394
|
+
mount(null, hGroup, nUsedParent, nRealParent, nBefore, isBatch);
|
|
1395
|
+
}
|
|
1396
|
+
|
|
1397
|
+
//#endregion
|
|
1398
|
+
//#region src/component/Native.ts
|
|
1399
|
+
const RE_EXT = /^([^:]+?):(.+)$/;
|
|
1400
|
+
/** @internal */
|
|
1401
|
+
const S_TAG_NAME = Symbol.for("pyxis:tagName");
|
|
1402
|
+
function Native(jsx, hParent, nUsedParent, _nRealParent, nBefore, isBatch) {
|
|
1403
|
+
const hGroup = hParent.$ng;
|
|
1404
|
+
const { adapter, $extensions } = hGroup;
|
|
1405
|
+
const nNode = adapter.element(jsx[S_TAG_NAME]);
|
|
1406
|
+
let name;
|
|
1407
|
+
let match;
|
|
1408
|
+
let value;
|
|
1409
|
+
for (name in jsx) {
|
|
1410
|
+
match = RE_EXT.exec(name);
|
|
1411
|
+
value = jsx[name];
|
|
1412
|
+
if (match) $extensions[match[1]]?.set(nNode, match[2], value, hGroup);
|
|
1413
|
+
else if (name !== "children") if (isAtom(value)) {
|
|
1414
|
+
const prop = name;
|
|
1415
|
+
const atom = value;
|
|
1416
|
+
bind(hGroup, atom, () => {
|
|
1417
|
+
adapter.set(nNode, prop, atom.get());
|
|
1418
|
+
});
|
|
1419
|
+
} else adapter.set(nNode, name, value);
|
|
1420
|
+
}
|
|
1421
|
+
insert(nNode, jsx.children, hParent, nUsedParent, nBefore, isBatch);
|
|
1422
|
+
}
|
|
1423
|
+
|
|
1424
|
+
//#endregion
|
|
1425
|
+
//#region src/component/Show.ts
|
|
1426
|
+
function Show(jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch) {
|
|
1427
|
+
const when = jsx.when;
|
|
1428
|
+
if (!isAtom(when) && when === false) return;
|
|
1429
|
+
const { children, data } = jsx;
|
|
1430
|
+
const proxyKeys = jsx.proxy;
|
|
1431
|
+
const template = Object.hasOwn(jsx, "data") ? children[0] : () => children;
|
|
1432
|
+
let dataOrProxy = data;
|
|
1433
|
+
if (proxyKeys) if (isAtom(data)) {
|
|
1434
|
+
dataOrProxy = createProxy(hParent.$ng, data.get(), proxyKeys);
|
|
1435
|
+
link(hParent.$ng, data, { $fn: () => {
|
|
1436
|
+
updateProxy(dataOrProxy, data.get(), proxyKeys);
|
|
1437
|
+
} });
|
|
1438
|
+
} else dataOrProxy = createProxy(hParent.$ng, data, proxyKeys);
|
|
1439
|
+
const adapter = hParent.$ng.adapter;
|
|
1440
|
+
const shouldBatch = Boolean(adapter.batch);
|
|
1441
|
+
if (!(isAtom(when) || isAtom(template) || !proxyKeys && isAtom(data))) {
|
|
1442
|
+
const isLocalBatch = shouldBatch && !isBatch;
|
|
1443
|
+
let nBatchParent = nUsedParent;
|
|
1444
|
+
let nBatchBefore = nBefore;
|
|
1445
|
+
if (isLocalBatch) {
|
|
1446
|
+
nBatchParent = adapter.batch();
|
|
1447
|
+
nBatchBefore = null;
|
|
1448
|
+
}
|
|
1449
|
+
mountJsx(template(dataOrProxy), hParent, nBatchParent, nRealParent, nBatchBefore, isLocalBatch || isBatch);
|
|
1450
|
+
if (isLocalBatch) adapter.insert(nBatchParent, nUsedParent, nBefore);
|
|
1451
|
+
return;
|
|
1452
|
+
}
|
|
1453
|
+
const hGroup = fork(hParent);
|
|
1454
|
+
let nMarker = nBefore;
|
|
1455
|
+
effect(() => {
|
|
1456
|
+
if (read(when) === false) return;
|
|
1457
|
+
const isLocalBatch = shouldBatch && !isBatch;
|
|
1458
|
+
let nBatchParent = nUsedParent;
|
|
1459
|
+
let nBatchBefore = nMarker;
|
|
1460
|
+
if (isLocalBatch) {
|
|
1461
|
+
nBatchParent = adapter.batch();
|
|
1462
|
+
nBatchBefore = null;
|
|
1463
|
+
}
|
|
1464
|
+
mount(withLifecycle(hGroup, read(template), read(dataOrProxy)), hGroup, nBatchParent, nRealParent, nBatchBefore, isLocalBatch || isBatch);
|
|
1465
|
+
if (isLocalBatch) adapter.insert(nBatchParent, nUsedParent, nMarker);
|
|
1466
|
+
return () => unmount(hGroup);
|
|
1467
|
+
}, hParent.$ng);
|
|
1468
|
+
nMarker = adapter.marker("/Show");
|
|
1469
|
+
insert(nMarker, null, hParent, nUsedParent, nBefore, isBatch);
|
|
1470
|
+
isBatch = false;
|
|
1471
|
+
nUsedParent = nRealParent;
|
|
1472
|
+
}
|
|
1473
|
+
|
|
1474
|
+
//#endregion
|
|
1475
|
+
//#region src/data/Derivation.ts
|
|
1476
|
+
/**
|
|
1477
|
+
* Creates a Derivation - an Atom with its value computed from other Atoms. The block runs once
|
|
1478
|
+
* eagerly to compute the initial value, then re-runs within scheduler ticks whenever its source
|
|
1479
|
+
* Atoms change. Observers are only notified if the new value differs from the previous.
|
|
1480
|
+
*/
|
|
1481
|
+
function derived(block, lifecycle = getLifecycle()) {
|
|
1482
|
+
__DEV__assertNotEffect();
|
|
1483
|
+
const atom = {
|
|
1484
|
+
[S_ATOM]: true,
|
|
1485
|
+
$dirty: false,
|
|
1486
|
+
$value: null,
|
|
1487
|
+
$tracksValue: true,
|
|
1488
|
+
$lifecycle: lifecycle,
|
|
1489
|
+
$life: lifecycle.$life,
|
|
1490
|
+
$lastValue: null,
|
|
1491
|
+
$cycle: 0,
|
|
1492
|
+
$block: block,
|
|
1493
|
+
$react: scheduleNotify,
|
|
1494
|
+
get: getValue,
|
|
1495
|
+
set: setValue
|
|
1496
|
+
};
|
|
1497
|
+
const value = resolve(atom);
|
|
1498
|
+
atom.$value = value;
|
|
1499
|
+
atom.$lastValue = value;
|
|
1500
|
+
return atom;
|
|
1501
|
+
}
|
|
1502
|
+
function scheduleNotify(derivation, cycle) {
|
|
1503
|
+
if (derivation.$life !== derivation.$lifecycle.$life || derivation.$cycle > cycle) {
|
|
1504
|
+
unlink(this);
|
|
1505
|
+
return;
|
|
1506
|
+
}
|
|
1507
|
+
derivation.$dirty = true;
|
|
1508
|
+
scheduleTick(derivation.$lifecycle, derivation.$notify ??= {
|
|
1509
|
+
$fn: notify$1,
|
|
1510
|
+
$a0: derivation
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
function getValue() {
|
|
1514
|
+
if (this.$dirty && this.$life === this.$lifecycle.$life) {
|
|
1515
|
+
this.$value = resolve(this);
|
|
1516
|
+
this.$dirty = false;
|
|
1517
|
+
}
|
|
1518
|
+
return this.$value;
|
|
1519
|
+
}
|
|
1520
|
+
function setValue() {
|
|
1521
|
+
return false;
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
//#endregion
|
|
1525
|
+
//#region src/data/List.ts
|
|
1526
|
+
function listOf(source, lifecycle = getLifecycle()) {
|
|
1527
|
+
{
|
|
1528
|
+
__DEV__assertNotEffect();
|
|
1529
|
+
const devId = arguments[2];
|
|
1530
|
+
globalThis.__PYXIS_HMR__.state.restore(lifecycle, devId, (value) => {
|
|
1531
|
+
if (Array.isArray(value)) source = value;
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
const list = {
|
|
1535
|
+
$lifecycle: lifecycle,
|
|
1536
|
+
$items: source ? Array.from(source) : [],
|
|
1537
|
+
$delta: null,
|
|
1538
|
+
[Symbol.iterator]: getIterator,
|
|
1539
|
+
size,
|
|
1540
|
+
get,
|
|
1541
|
+
delta,
|
|
1542
|
+
raw,
|
|
1543
|
+
forEach,
|
|
1544
|
+
set,
|
|
1545
|
+
clear,
|
|
1546
|
+
insertAt,
|
|
1547
|
+
insertFirst,
|
|
1548
|
+
insertLast,
|
|
1549
|
+
remove,
|
|
1550
|
+
removeAt,
|
|
1551
|
+
removeFirst,
|
|
1552
|
+
removeLast
|
|
1553
|
+
};
|
|
1554
|
+
list.$devId = arguments[2];
|
|
1555
|
+
return list;
|
|
1556
|
+
}
|
|
1557
|
+
/**
|
|
1558
|
+
* Synchronizes the provided List with the given data source. After this operation, the list will
|
|
1559
|
+
* contain an exact copy of the source.
|
|
1560
|
+
*
|
|
1561
|
+
* Note: This function is separated instead of being a List method since the underlying diff
|
|
1562
|
+
* algorithm (Myers) is a relatively large chunk of code which would otherwise always get included
|
|
1563
|
+
* into bundled builds. This way, tools like Terser can eliminate the extra code when unused.
|
|
1564
|
+
*/
|
|
1565
|
+
function sync(list, source, eq = defaultEquals) {
|
|
1566
|
+
const oldState = list.$items;
|
|
1567
|
+
list.$items = source.slice();
|
|
1568
|
+
listSynced(list.$delta ??= createDelta(), oldState, source, eq);
|
|
1569
|
+
listMutated(list);
|
|
1570
|
+
}
|
|
1571
|
+
function size() {
|
|
1572
|
+
reportAccess(this);
|
|
1573
|
+
return this.$items.length;
|
|
1574
|
+
}
|
|
1575
|
+
function get(index) {
|
|
1576
|
+
reportAccess(this);
|
|
1577
|
+
return this.$items[index];
|
|
1578
|
+
}
|
|
1579
|
+
function delta() {
|
|
1580
|
+
reportAccess(this);
|
|
1581
|
+
return this.$delta;
|
|
1582
|
+
}
|
|
1583
|
+
function raw() {
|
|
1584
|
+
reportAccess(this);
|
|
1585
|
+
return this.$items;
|
|
1586
|
+
}
|
|
1587
|
+
function forEach(callback, thisArg) {
|
|
1588
|
+
reportAccess(this);
|
|
1589
|
+
this.$items.forEach(callback, thisArg);
|
|
1590
|
+
}
|
|
1591
|
+
function getIterator() {
|
|
1592
|
+
reportAccess(this);
|
|
1593
|
+
return this.$items[Symbol.iterator]();
|
|
1594
|
+
}
|
|
1595
|
+
function set(index, newItem) {
|
|
1596
|
+
assertIndex(this, index);
|
|
1597
|
+
const oldItem = this.$items[index];
|
|
1598
|
+
if (Object.is(newItem, oldItem)) return;
|
|
1599
|
+
this.$items[index] = newItem;
|
|
1600
|
+
if (this.$dh) {
|
|
1601
|
+
itemChanged(this.$delta ??= createDelta(), index, oldItem, newItem);
|
|
1602
|
+
listMutated(this);
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
function clear() {
|
|
1606
|
+
const count = this.$items.length;
|
|
1607
|
+
this.$items.length = 0;
|
|
1608
|
+
if (this.$dh) {
|
|
1609
|
+
listCleared(this.$delta ??= createDelta(), count);
|
|
1610
|
+
listMutated(this);
|
|
1611
|
+
}
|
|
1612
|
+
}
|
|
1613
|
+
function insertAt(index, item) {
|
|
1614
|
+
const { $items } = this;
|
|
1615
|
+
if (index === $items.length) $items.push(item);
|
|
1616
|
+
else {
|
|
1617
|
+
assertIndex(this, index);
|
|
1618
|
+
this.$items.splice(index, 0, item);
|
|
1619
|
+
}
|
|
1620
|
+
if (this.$dh) {
|
|
1621
|
+
itemInserted(this.$delta ??= createDelta(), index, item);
|
|
1622
|
+
listMutated(this);
|
|
1623
|
+
}
|
|
1624
|
+
}
|
|
1625
|
+
function insertFirst(item) {
|
|
1626
|
+
this.insertAt(0, item);
|
|
1627
|
+
}
|
|
1628
|
+
function insertLast(item) {
|
|
1629
|
+
this.insertAt(this.$items.length, item);
|
|
1630
|
+
}
|
|
1631
|
+
function remove(item) {
|
|
1632
|
+
const index = this.$items.indexOf(item);
|
|
1633
|
+
if (index === -1) return false;
|
|
1634
|
+
this.removeAt(index);
|
|
1635
|
+
return true;
|
|
1636
|
+
}
|
|
1637
|
+
function removeAt(index) {
|
|
1638
|
+
assertIndex(this, index);
|
|
1639
|
+
const item = this.$items.splice(index, 1)[0];
|
|
1640
|
+
if (this.$dh) {
|
|
1641
|
+
itemRemoved(this.$delta ??= createDelta(), index, item);
|
|
1642
|
+
listMutated(this);
|
|
1643
|
+
}
|
|
1644
|
+
return item;
|
|
1645
|
+
}
|
|
1646
|
+
function removeFirst() {
|
|
1647
|
+
return this.$items.length > 0 ? this.removeAt(0) : void 0;
|
|
1648
|
+
}
|
|
1649
|
+
function removeLast() {
|
|
1650
|
+
const { length } = this.$items;
|
|
1651
|
+
return length > 0 ? this.removeAt(length - 1) : void 0;
|
|
1652
|
+
}
|
|
1653
|
+
function assertIndex(list, index) {
|
|
1654
|
+
if (index >= list.$items.length || index < 0) throw new RangeError("list index out of bounds");
|
|
1655
|
+
}
|
|
1656
|
+
function defaultEquals(item0, item1) {
|
|
1657
|
+
return Object.is(item0, item1);
|
|
1658
|
+
}
|
|
1659
|
+
function listMutated(list) {
|
|
1660
|
+
globalThis.__PYXIS_HMR__.state.preserve(list.$lifecycle, list.$devId, list.$items);
|
|
1661
|
+
scheduleTick(list.$lifecycle, list.$notify ??= {
|
|
1662
|
+
$fn: notify,
|
|
1663
|
+
$a0: list
|
|
1664
|
+
});
|
|
1665
|
+
scheduleTock(list.$lifecycle, list.$cleanup ??= {
|
|
1666
|
+
$fn: cleanup,
|
|
1667
|
+
$a0: list
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1670
|
+
function notify(list) {
|
|
1671
|
+
let current = list.$dh;
|
|
1672
|
+
let next;
|
|
1673
|
+
while (current) {
|
|
1674
|
+
next = current.$an;
|
|
1675
|
+
invoke(current);
|
|
1676
|
+
current = next;
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
function cleanup(list) {
|
|
1680
|
+
list.$delta = null;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
//#endregion
|
|
1684
|
+
//#region src/extension/RefExtension.ts
|
|
1685
|
+
/**
|
|
1686
|
+
* Extension adding direct reference access to any element. Recommended prefix:
|
|
1687
|
+
* `"ref"`
|
|
1688
|
+
*
|
|
1689
|
+
* References can be stored into atoms:
|
|
1690
|
+
* ```tsx
|
|
1691
|
+
* const wrapperRef = atomOf<HTMLDivElement>();
|
|
1692
|
+
* <div ref:atom={wrapperRef} />
|
|
1693
|
+
* ```
|
|
1694
|
+
* or handled with a custom callback:
|
|
1695
|
+
* ```tsx
|
|
1696
|
+
* const onWrapperRef = (node: HTMLDivElement) => { ... };
|
|
1697
|
+
* <div ref:call={onWrapperRef} />
|
|
1698
|
+
* ```
|
|
1699
|
+
*/
|
|
1700
|
+
const RefExtension = { set: (node, kind, value) => {
|
|
1701
|
+
let method;
|
|
1702
|
+
switch (kind) {
|
|
1703
|
+
case "atom":
|
|
1704
|
+
if (!isAtom(value)) return;
|
|
1705
|
+
method = refAtom;
|
|
1706
|
+
break;
|
|
1707
|
+
case "call":
|
|
1708
|
+
if (typeof value !== "function") return;
|
|
1709
|
+
method = refCall;
|
|
1710
|
+
break;
|
|
1711
|
+
default: return;
|
|
1712
|
+
}
|
|
1713
|
+
const lifecycle = getLifecycle();
|
|
1714
|
+
onMounted(lifecycle, {
|
|
1715
|
+
$fn: method,
|
|
1716
|
+
$a0: value,
|
|
1717
|
+
$a1: node
|
|
1718
|
+
});
|
|
1719
|
+
onUnmounted(lifecycle, {
|
|
1720
|
+
$fn: method,
|
|
1721
|
+
$a0: value,
|
|
1722
|
+
$a1: null
|
|
1723
|
+
});
|
|
1724
|
+
} };
|
|
1725
|
+
function refAtom(atom, node) {
|
|
1726
|
+
atom.set(node);
|
|
1727
|
+
}
|
|
1728
|
+
function refCall(setter, node) {
|
|
1729
|
+
setter(node);
|
|
1730
|
+
}
|
|
1731
|
+
|
|
1732
|
+
//#endregion
|
|
1733
|
+
//#region src/support/text.ts
|
|
1734
|
+
function tag(access, strings, values) {
|
|
1735
|
+
const { length } = values;
|
|
1736
|
+
let index = 0;
|
|
1737
|
+
let text = strings[0];
|
|
1738
|
+
while (index < length) text += access(values[index]) + strings[++index];
|
|
1739
|
+
return text;
|
|
1740
|
+
}
|
|
1741
|
+
/**
|
|
1742
|
+
* A template literal tag that automatically wraps each substitution in a `read` call.
|
|
1743
|
+
* @see {@link read}
|
|
1744
|
+
*/
|
|
1745
|
+
function reads(strings, ...values) {
|
|
1746
|
+
return tag(read, strings, values);
|
|
1747
|
+
}
|
|
1748
|
+
/**
|
|
1749
|
+
* A template literal tag that automatically wraps each substitution in a `peek` call.
|
|
1750
|
+
* @see {@link peek}
|
|
1751
|
+
*/
|
|
1752
|
+
function peeks(strings, ...values) {
|
|
1753
|
+
return tag(peek, strings, values);
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1756
|
+
//#endregion
|
|
1757
|
+
//#region src/Builder.ts
|
|
1758
|
+
function pyxis(adapter) {
|
|
1759
|
+
const extensions = {};
|
|
1760
|
+
const builder = {
|
|
1761
|
+
build: () => createRenderer(adapter, extensions),
|
|
1762
|
+
extend: (extensionKey, extension) => {
|
|
1763
|
+
extensions[extensionKey] = extension;
|
|
1764
|
+
return builder;
|
|
1765
|
+
}
|
|
1766
|
+
};
|
|
1767
|
+
return builder;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
//#endregion
|
|
1771
|
+
//#region src/Component.ts
|
|
1772
|
+
function component(block) {
|
|
1773
|
+
let devId;
|
|
1774
|
+
devId = arguments[1];
|
|
1775
|
+
devId && globalThis.__PYXIS_HMR__.component.upsert(devId, block);
|
|
1776
|
+
return (jsx, hParent, nUsedParent, nRealParent, nBefore, isBatch) => {
|
|
1777
|
+
const context = getContextContainer();
|
|
1778
|
+
try {
|
|
1779
|
+
{
|
|
1780
|
+
if (!import.meta.hot || !devId) {
|
|
1781
|
+
setContextContainer(context);
|
|
1782
|
+
mountJsx(block(jsx), hParent, nUsedParent, nRealParent, nBefore, isBatch);
|
|
1783
|
+
return;
|
|
1784
|
+
}
|
|
1785
|
+
const hGroup = fork(hParent);
|
|
1786
|
+
const nMarker = hGroup.adapter.marker(`/${devId}`);
|
|
1787
|
+
insert(nMarker, null, hParent, nUsedParent, nBefore, isBatch);
|
|
1788
|
+
unmounted(globalThis.__PYXIS_HMR__.component.subscribe(devId, (impl) => {
|
|
1789
|
+
unmount(hGroup);
|
|
1790
|
+
mount({
|
|
1791
|
+
...jsx,
|
|
1792
|
+
[S_COMPONENT]: (() => mountJsx(impl(jsx), hGroup, nUsedParent, nRealParent, nMarker, isBatch))
|
|
1793
|
+
}, hGroup, nUsedParent, nRealParent, nMarker, isBatch);
|
|
1794
|
+
}));
|
|
1795
|
+
nUsedParent = nRealParent;
|
|
1796
|
+
isBatch = false;
|
|
1797
|
+
}
|
|
1798
|
+
} finally {
|
|
1799
|
+
setContextContainer(context);
|
|
1800
|
+
}
|
|
1801
|
+
};
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
//#endregion
|
|
1805
|
+
//#region src/jsx.ts
|
|
1806
|
+
const EMPTY_ARRAY = Object.freeze([]);
|
|
1807
|
+
function jsx(componentOrTagName, props, key) {
|
|
1808
|
+
const { children } = props;
|
|
1809
|
+
props.children = children === void 0 ? EMPTY_ARRAY : Array.isArray(children) ? children : [children];
|
|
1810
|
+
props.key ??= key;
|
|
1811
|
+
if (typeof componentOrTagName === "string") {
|
|
1812
|
+
props[S_COMPONENT] = Native;
|
|
1813
|
+
props[S_TAG_NAME] = componentOrTagName;
|
|
1814
|
+
} else props[S_COMPONENT] = componentOrTagName;
|
|
1815
|
+
return props;
|
|
1816
|
+
}
|
|
1817
|
+
function jsxs(componentOrTagName, props, key) {
|
|
1818
|
+
props.key ??= key;
|
|
1819
|
+
if (typeof componentOrTagName === "string") {
|
|
1820
|
+
props[S_COMPONENT] = Native;
|
|
1821
|
+
props[S_TAG_NAME] = componentOrTagName;
|
|
1822
|
+
} else props[S_COMPONENT] = componentOrTagName;
|
|
1823
|
+
return props;
|
|
1824
|
+
}
|
|
1825
|
+
|
|
1826
|
+
//#endregion
|
|
1827
|
+
export { ChangeKind, Fragment, Iterator, Native, RefExtension, Show, atomOf, bind, component, consumerOf, createContext, derived, effect, fork, getLifecycle, host, insert, isAtom, jsx, jsxs, listOf, mount, mountJsx, mounted, peek, peeks, proxyOf, pyxis, read, reads, sync, tick, tock, track, unmount, unmounted, untrack, update, withLifecycle, write };
|
|
1828
|
+
//# sourceMappingURL=core-dev.js.map
|