78 lines
1.9 KiB
JavaScript
78 lines
1.9 KiB
JavaScript
// @ts-nocheck
|
|
|
|
/**
|
|
* External dependencies
|
|
*/
|
|
import { useEffect } from 'preact/hooks';
|
|
import { effect } from '@preact/signals';
|
|
|
|
const afterNextFrame = ( callback ) => {
|
|
return new Promise( ( resolve ) => {
|
|
const done = () => {
|
|
clearTimeout( timeout );
|
|
window.cancelAnimationFrame( raf );
|
|
setTimeout( () => {
|
|
callback();
|
|
resolve();
|
|
} );
|
|
};
|
|
const timeout = setTimeout( done, 100 );
|
|
const raf = window.requestAnimationFrame( done );
|
|
} );
|
|
};
|
|
|
|
// Using the mangled properties:
|
|
// this.c: this._callback
|
|
// this.x: this._compute
|
|
// https://github.com/preactjs/signals/blob/main/mangle.json
|
|
function createFlusher( compute, notify ) {
|
|
let flush;
|
|
const dispose = effect( function () {
|
|
flush = this.c.bind( this );
|
|
this.x = compute;
|
|
this.c = notify;
|
|
return compute();
|
|
} );
|
|
return { flush, dispose };
|
|
}
|
|
|
|
// Version of `useSignalEffect` with a `useEffect`-like execution. This hook
|
|
// implementation comes from this PR, but we added short-cirtuiting to avoid
|
|
// infinite loops: https://github.com/preactjs/signals/pull/290
|
|
export function useSignalEffect( callback ) {
|
|
useEffect( () => {
|
|
let eff = null;
|
|
let isExecuting = false;
|
|
const notify = async () => {
|
|
if ( eff && ! isExecuting ) {
|
|
isExecuting = true;
|
|
await afterNextFrame( eff.flush );
|
|
isExecuting = false;
|
|
}
|
|
};
|
|
eff = createFlusher( callback, notify );
|
|
return eff.dispose;
|
|
}, [] );
|
|
}
|
|
|
|
// For wrapperless hydration.
|
|
// See https://gist.github.com/developit/f4c67a2ede71dc2fab7f357f39cff28c
|
|
export const createRootFragment = ( parent, replaceNode ) => {
|
|
replaceNode = [].concat( replaceNode );
|
|
const s = replaceNode[ replaceNode.length - 1 ].nextSibling;
|
|
function insert( c, r ) {
|
|
parent.insertBefore( c, r || s );
|
|
}
|
|
return ( parent.__k = {
|
|
nodeType: 1,
|
|
parentNode: parent,
|
|
firstChild: replaceNode[ 0 ],
|
|
childNodes: replaceNode,
|
|
insertBefore: insert,
|
|
appendChild: insert,
|
|
removeChild( c ) {
|
|
parent.removeChild( c );
|
|
},
|
|
} );
|
|
};
|