lilact 0.16.3 → 0.17.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/dist/lilact.development.js +101 -38
- package/dist/lilact.development.js.map +3 -3
- package/dist/lilact.development.min.js +16 -16
- package/dist/lilact.development.min.js.map +3 -3
- package/dist/lilact.production.min.js +18 -18
- package/docs/assets/hierarchy.js +1 -1
- package/docs/assets/navigation.js +1 -1
- package/docs/assets/search.js +1 -1
- package/docs/classes/accessories.ErrorBoundary.html +8 -8
- package/docs/classes/accessories.Suspense.html +7 -7
- package/docs/classes/components.Component.html +11 -11
- package/docs/classes/components.HTMLComponent.html +11 -11
- package/docs/classes/components.RootComponent.html +11 -11
- package/docs/functions/components.createComponent.html +1 -1
- package/docs/functions/components.createRoot.html +1 -1
- package/docs/functions/components.render.html +1 -1
- package/docs/functions/hooks.startTransition.html +6 -0
- package/docs/functions/hooks.useActionState.html +1 -1
- package/docs/functions/hooks.useDebugValue.html +5 -0
- package/docs/functions/hooks.useDeferredValue.html +1 -1
- package/docs/functions/hooks.useEffect.html +4 -4
- package/docs/functions/hooks.useImperativeHandle.html +1 -1
- package/docs/functions/hooks.useInsertionEffect.html +5 -0
- package/docs/functions/hooks.useLayoutEffect.html +2 -2
- package/docs/functions/hooks.useMemo.html +3 -3
- package/docs/functions/hooks.useReducer.html +1 -1
- package/docs/functions/misc.Fragment.html +2 -2
- package/docs/functions/misc.deepEqual.html +1 -1
- package/docs/functions/misc.findDOMNode.html +1 -1
- package/docs/functions/misc.forwardRef.html +1 -1
- package/docs/functions/misc.getComponentByPointer.html +1 -1
- package/docs/functions/misc.isAsync.html +1 -1
- package/docs/functions/misc.isClass.html +1 -1
- package/docs/functions/misc.isEmpty.html +1 -1
- package/docs/functions/misc.isError.html +1 -1
- package/docs/functions/misc.isThenable.html +1 -1
- package/docs/functions/{misc.isValidElement.html → misc.isValidComponent.html} +1 -1
- package/docs/functions/misc.shallowEqual.html +1 -1
- package/docs/functions/misc.toBool.html +1 -1
- package/docs/functions/timers.timeoutPromise.html +9 -6
- package/docs/hierarchy.html +1 -1
- package/docs/modules/hooks.html +1 -1
- package/docs/modules/misc.html +1 -1
- package/docs/static/demos/actionstate.jsx +2 -2
- package/docs/static/demos/priorities.jsx +68 -0
- package/docs/static/index.html +1 -0
- package/docs/static/lilact.development.js +101 -38
- package/docs/static/lilact.development.js.map +3 -3
- package/docs/static/lilact.development.min.js +16 -16
- package/docs/static/lilact.development.min.js.map +3 -3
- package/docs/static/lilact.production.min.js +18 -18
- package/docs/variables/misc.Children.html +2 -2
- package/docs/variables/misc.isValidElement.html +7 -0
- package/examples/demos/actionstate.jsx +2 -2
- package/examples/demos/priorities.jsx +68 -0
- package/examples/index.html +1 -0
- package/examples/lilact.development.js +101 -38
- package/examples/lilact.development.js.map +3 -3
- package/examples/lilact.development.min.js +16 -16
- package/examples/lilact.development.min.js.map +3 -3
- package/examples/lilact.production.min.js +18 -18
- package/package.json +1 -1
- package/src/components.jsx +68 -13
- package/src/hooks.jsx +80 -11
- package/src/lilact.jsx +1 -1
- package/src/misc.jsx +9 -5
package/src/components.jsx
CHANGED
|
@@ -94,7 +94,12 @@ class ComponentCache
|
|
|
94
94
|
{
|
|
95
95
|
this.current_map.forEach( (arr)=>{
|
|
96
96
|
arr.slice(arr[IDX]).forEach((ex)=>{
|
|
97
|
-
if(ex.cleanup)
|
|
97
|
+
if(ex.cleanup) {
|
|
98
|
+
ex.cleanup();
|
|
99
|
+
}
|
|
100
|
+
else if(ex.element) {
|
|
101
|
+
ex.element.parentElement.removeChild(ex.element);
|
|
102
|
+
}
|
|
98
103
|
});
|
|
99
104
|
});
|
|
100
105
|
|
|
@@ -716,23 +721,58 @@ function prepareCore(parent, core)
|
|
|
716
721
|
|
|
717
722
|
function doUpdates()
|
|
718
723
|
{
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
let _update_cbs = Lilact.update_cbs;
|
|
722
|
-
let _update_set = Lilact.update_set;
|
|
724
|
+
/*
|
|
725
|
+
Priority:
|
|
723
726
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
+
- Render + enqueue DOM work (runs in the same task where you schedule the update).
|
|
728
|
+
- Apply DOM updates (do this synchronously before you schedule any effects that must happen before paint).
|
|
729
|
+
- Insertion effects (run immediately after DOM is in place, still before paint).
|
|
730
|
+
- Layout effects (run immediately after insertion effects, still before paint).
|
|
731
|
+
- Passive effects (useEffect)
|
|
727
732
|
|
|
728
|
-
|
|
733
|
+
schedule them for after paint using requestAnimationFrame, typically:
|
|
734
|
+
run the “after paint” work in the next frame or in a callback scheduled such that it runs after the browser has performed the paint.
|
|
735
|
+
|
|
736
|
+
|
|
737
|
+
Current task: render → DOM updates → insertion effects → layout effects
|
|
738
|
+
Next paint timing boundary: requestAnimationFrame callback → passive effects (useEffect)
|
|
739
|
+
*/
|
|
740
|
+
|
|
741
|
+
|
|
742
|
+
clearTimeout(Lilact.effect_timeout);
|
|
743
|
+
|
|
744
|
+
const _update_set = Lilact.update_set;
|
|
745
|
+
const _update_cbs = Lilact.update_cbs;
|
|
746
|
+
Lilact.update_set = new Set;
|
|
747
|
+
Lilact.update_cbs = new Set;
|
|
748
|
+
|
|
749
|
+
for(const u of _update_set) u.apply();
|
|
750
|
+
for(const cb of _update_cbs) cb();
|
|
751
|
+
processEffects();
|
|
729
752
|
|
|
730
|
-
for(const u of _update_set) u.apply();
|
|
731
|
-
for(const cb of _update_cbs) cb();
|
|
732
|
-
});
|
|
733
753
|
}
|
|
734
754
|
|
|
735
755
|
|
|
756
|
+
/** @ignore */
|
|
757
|
+
export function processEffects()
|
|
758
|
+
{
|
|
759
|
+
const _insertion_effects = Lilact.insertion_effects;
|
|
760
|
+
const _layout_effects = Lilact.layout_effects;
|
|
761
|
+
const _passive_effects = Lilact.passive_effects;
|
|
762
|
+
|
|
763
|
+
Lilact.insertion_effects = new Set;
|
|
764
|
+
Lilact.layout_effects = new Set;
|
|
765
|
+
Lilact.passive_effects = new Set;
|
|
766
|
+
|
|
767
|
+
for(const ie of _insertion_effects) ie();
|
|
768
|
+
for(const le of _layout_effects) le();
|
|
769
|
+
|
|
770
|
+
requestAnimationFrame(()=>{
|
|
771
|
+
for(const pe of _passive_effects) pe();
|
|
772
|
+
});
|
|
773
|
+
|
|
774
|
+
}
|
|
775
|
+
|
|
736
776
|
function decode(html)
|
|
737
777
|
{
|
|
738
778
|
decode.parser ??= new DOMParser;
|
|
@@ -1049,7 +1089,7 @@ export class RootComponent extends HTMLComponent
|
|
|
1049
1089
|
|
|
1050
1090
|
export function createComponent(entity, props={}, ...children)
|
|
1051
1091
|
{
|
|
1052
|
-
if(
|
|
1092
|
+
if(typeof(entity)!=='string' && typeof(entity)!=='function') {
|
|
1053
1093
|
throw new Error("Invalid entity for createComponent.");
|
|
1054
1094
|
}
|
|
1055
1095
|
|
|
@@ -1141,6 +1181,7 @@ export function render(component, element)
|
|
|
1141
1181
|
return createRoot(element).render(component);
|
|
1142
1182
|
}
|
|
1143
1183
|
|
|
1184
|
+
|
|
1144
1185
|
/** @ignore */
|
|
1145
1186
|
export const createElement = createComponent;
|
|
1146
1187
|
|
|
@@ -1155,6 +1196,18 @@ export let update_cbs = new Set;
|
|
|
1155
1196
|
export let roots = new Set;
|
|
1156
1197
|
/** @ignore */
|
|
1157
1198
|
export let layout_effects = new Set;
|
|
1199
|
+
/** @ignore */
|
|
1200
|
+
export let insertion_effects = new Set;
|
|
1201
|
+
/** @ignore */
|
|
1202
|
+
export let passive_effects = new Set;
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
/** @ignore */
|
|
1206
|
+
export let update_timeout = undefined;
|
|
1207
|
+
/** @ignore */
|
|
1208
|
+
export let effect_timeout = undefined;
|
|
1209
|
+
/** @ignore */
|
|
1210
|
+
export let update_interval_margin = 0;
|
|
1158
1211
|
|
|
1159
1212
|
/** @ignore */
|
|
1160
1213
|
export const special_attributes = new Set([
|
|
@@ -1201,3 +1254,5 @@ export const length_css_attributes_set = new Set([
|
|
|
1201
1254
|
export const boolean_html_attributes_set = new
|
|
1202
1255
|
Set(["disabled", "readOnly", "required", "checked", "multiple",
|
|
1203
1256
|
"hidden","open","loop","muted","controls","playsInline","allowFullScreen"]);
|
|
1257
|
+
|
|
1258
|
+
|
package/src/hooks.jsx
CHANGED
|
@@ -182,12 +182,12 @@ export function useTransition()
|
|
|
182
182
|
|
|
183
183
|
(async function(core, hk, fn) {
|
|
184
184
|
|
|
185
|
-
hk.count
|
|
186
|
-
|
|
187
|
-
if(hk.count===1) {
|
|
185
|
+
if(hk.count===0) {
|
|
188
186
|
core.component.forceUpdate();
|
|
189
187
|
}
|
|
190
188
|
|
|
189
|
+
hk.count++;
|
|
190
|
+
|
|
191
191
|
await fn();
|
|
192
192
|
|
|
193
193
|
hk.count--;
|
|
@@ -269,13 +269,13 @@ export function useRef(initialValue = null)
|
|
|
269
269
|
* Runs an effect synchronously after all DOM mutations but before the browser paints.
|
|
270
270
|
*
|
|
271
271
|
* @param {Function} effect - Effect callback.
|
|
272
|
-
* @param
|
|
272
|
+
* @param deps - Optional dependency list (or an object for shallow comparison) used to determine when to re-run the effect.
|
|
273
273
|
* @returns {void}
|
|
274
274
|
*/
|
|
275
275
|
export function useLayoutEffect(effect, deps=undefined)
|
|
276
276
|
{
|
|
277
277
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
278
|
-
throw new Error("Layout effect dependencies must be an array or omitted.");
|
|
278
|
+
throw new Error("Layout effect dependencies must be an array, object or omitted.");
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
const hk = useHook();
|
|
@@ -290,20 +290,53 @@ export function useLayoutEffect(effect, deps=undefined)
|
|
|
290
290
|
|
|
291
291
|
hk.deps = deps;
|
|
292
292
|
Lilact.layout_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
293
|
-
|
|
293
|
+
|
|
294
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
295
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
294
296
|
}
|
|
295
297
|
|
|
296
298
|
/**
|
|
297
299
|
* Runs a side effect after render commits.
|
|
298
300
|
*
|
|
299
|
-
* @param
|
|
300
|
-
* @param
|
|
301
|
+
* @param effect - Callback invoked.
|
|
302
|
+
* @param deps - Optional dependency list (or an object for shallow comparison) used to determine when to re-run the effect.
|
|
301
303
|
* @returns {void}
|
|
302
304
|
*/
|
|
303
305
|
export function useEffect(effect, deps=undefined)
|
|
304
306
|
{
|
|
305
307
|
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
306
|
-
throw new Error("Effect dependencies must be an array or omitted.");
|
|
308
|
+
throw new Error("Effect dependencies must be an array, object or omitted.");
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
const hk = useHook();
|
|
312
|
+
|
|
313
|
+
if( !isEmpty(hk) ) {
|
|
314
|
+
if(deps!==undefined && hk?.deps!==undefined && shallowEqual(deps, hk.deps)) return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if(hk?.cleanup) {
|
|
318
|
+
hk.cleanup();
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
hk.deps = deps;
|
|
322
|
+
Lilact.passive_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
323
|
+
|
|
324
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
325
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Executes a side effect after the DOM updates have been committed.
|
|
331
|
+
*
|
|
332
|
+
* @param effect - Callback invoked after render commit.
|
|
333
|
+
* @param deps - Optional dependency list (or an object for shallow comparison) used to determine when to re-run the effect.
|
|
334
|
+
* @returns void
|
|
335
|
+
*/
|
|
336
|
+
export function useInsertionEffect(effect, deps=undefined)
|
|
337
|
+
{
|
|
338
|
+
if( deps!==undefined && (typeof(deps)!=='object' || deps.constructor.name!=='Array') ) {
|
|
339
|
+
throw new Error("Insertion effect dependencies must be an array, object, or omitted.");
|
|
307
340
|
}
|
|
308
341
|
|
|
309
342
|
const hk = useHook();
|
|
@@ -317,15 +350,18 @@ export function useEffect(effect, deps=undefined)
|
|
|
317
350
|
}
|
|
318
351
|
|
|
319
352
|
hk.deps = deps;
|
|
320
|
-
Lilact.
|
|
353
|
+
Lilact.insertion_effects.add( ()=>{ hk.cleanup = effect(); });
|
|
321
354
|
|
|
355
|
+
Lilact.clearTimeout( Lilact.effect_timeout );
|
|
356
|
+
Lilact.setTimeout( Lilact.processEffects, 0 );
|
|
322
357
|
}
|
|
323
358
|
|
|
359
|
+
|
|
324
360
|
/**
|
|
325
361
|
* Memoizes a computed value until dependencies change.
|
|
326
362
|
*
|
|
327
363
|
* @param {Function} factory - Function that creates the value.
|
|
328
|
-
* @param
|
|
364
|
+
* @param deps - Optional dependency list (or an object for shallow comparison) used to determine when to re-run the effect.
|
|
329
365
|
* @returns {any} Memoized value.
|
|
330
366
|
*/
|
|
331
367
|
export function useMemo(factory,deps=undefined)
|
|
@@ -487,3 +523,36 @@ export function useImperativeHandle(ref, factory, deps=undefined)
|
|
|
487
523
|
|
|
488
524
|
}
|
|
489
525
|
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* A hook for debug purposes. At the moment it only logs the output, but it can be overrided
|
|
529
|
+
* for each development environment.
|
|
530
|
+
*
|
|
531
|
+
* @param {any} val
|
|
532
|
+
* The debug value.
|
|
533
|
+
* @param {function(): any} formatter
|
|
534
|
+
* Function that creates a representation of the value.
|
|
535
|
+
* @returns {void}
|
|
536
|
+
*/
|
|
537
|
+
export function useDebugValue(val, formatter=(x)=>x)
|
|
538
|
+
{
|
|
539
|
+
if(DEBUG) {
|
|
540
|
+
console.log(formatter(val));
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Schedule a state update as a low-priority transition.
|
|
547
|
+
*
|
|
548
|
+
* Updates triggered inside the transition callback are treated as lower priority than
|
|
549
|
+
* updates outside of it.
|
|
550
|
+
*
|
|
551
|
+
* @param transition - Function that performs the state updates for the transition.
|
|
552
|
+
* @returns void
|
|
553
|
+
*/
|
|
554
|
+
export function startTransition(transition)
|
|
555
|
+
{
|
|
556
|
+
transition();
|
|
557
|
+
}
|
|
558
|
+
|
package/src/lilact.jsx
CHANGED
package/src/misc.jsx
CHANGED
|
@@ -54,10 +54,18 @@ const typeOf = (input) => {
|
|
|
54
54
|
* @param value - Value to inspect.
|
|
55
55
|
* @returns True if the value is a class component; otherwise false.
|
|
56
56
|
*/
|
|
57
|
-
export const
|
|
57
|
+
export const isValidComponent = (value) => {
|
|
58
58
|
return value[CORE]!==undefined || value[TEXT]!==undefined;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Checks whether a value is a Lilact component. It is the same as `isValidComponent`.
|
|
63
|
+
*
|
|
64
|
+
* @param value - Value to inspect.
|
|
65
|
+
* @returns True if the value is a class component; otherwise false.
|
|
66
|
+
*/
|
|
67
|
+
export const isValidElement = isValidComponent
|
|
68
|
+
|
|
61
69
|
/**
|
|
62
70
|
* Utility to find the underlying DOM node for a mounted Lilact component.
|
|
63
71
|
*
|
|
@@ -337,10 +345,6 @@ export function toBool(value) {
|
|
|
337
345
|
|
|
338
346
|
// Internals
|
|
339
347
|
|
|
340
|
-
/** @ignore */
|
|
341
|
-
export let update_timeout = undefined;
|
|
342
|
-
/** @ignore */
|
|
343
|
-
export let update_interval_margin = 0;
|
|
344
348
|
/** @ignore */
|
|
345
349
|
export let id_num = Math.floor(Math.random()*10000);
|
|
346
350
|
/** @ignore */
|