Skip to content

Commit

Permalink
Fix demo
Browse files Browse the repository at this point in the history
  • Loading branch information
JoviDeCroock committed Nov 11, 2024
1 parent 84dcf74 commit 22d61f0
Show file tree
Hide file tree
Showing 7 changed files with 496 additions and 194 deletions.
70 changes: 70 additions & 0 deletions compat/src/hooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useState, useLayoutEffect, useEffect } from 'preact/hooks';
import { is } from './util';

/**
* This is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84
* on a high level this cuts out the warnings, ... and attempts a smaller implementation
* @typedef {{ _value: any; _getSnapshot: () => any }} Store
*/
export function useSyncExternalStore(subscribe, getSnapshot) {
const value = getSnapshot();

/**
* @typedef {{ _instance: Store }} StoreRef
* @type {[StoreRef, (store: StoreRef) => void]}
*/
const [{ _instance }, forceUpdate] = useState({
_instance: { _value: value, _getSnapshot: getSnapshot }
});

useLayoutEffect(() => {
_instance._value = value;
_instance._getSnapshot = getSnapshot;

if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}
}, [subscribe, value, getSnapshot]);

useEffect(() => {
if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}

return subscribe(() => {
if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}
});
}, [subscribe]);

return value;
}

/** @type {(inst: Store) => boolean} */
function didSnapshotChange(inst) {
const latestGetSnapshot = inst._getSnapshot;
const prevValue = inst._value;
try {
const nextValue = latestGetSnapshot();
return !is(prevValue, nextValue);
} catch (error) {
return true;
}
}

export function startTransition(cb) {
cb();
}

export function useDeferredValue(val) {
return val;
}

export function useTransition() {
return [false, startTransition];
}

// TODO: in theory this should be done after a VNode is diffed as we want to insert
// styles/... before it attaches
export const useInsertionEffect = useLayoutEffect;
81 changes: 12 additions & 69 deletions compat/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@ import {
useContext,
useDebugValue
} from 'preact/hooks';
import {
useInsertionEffect,
startTransition,
useDeferredValue,
useSyncExternalStore,
useTransition
} from './hooks';
import { PureComponent } from './PureComponent';
import { memo } from './memo';
import { forwardRef } from './forwardRef';
import { Children } from './Children';
import { Suspense, lazy } from './suspense';
import { SuspenseList } from './suspense-list';
import { createPortal } from './portals';
import { is } from './util';
import {
hydrate,
render,
Expand Down Expand Up @@ -143,77 +149,9 @@ const flushSync = (callback, arg) => callback(arg);
*/
const StrictMode = Fragment;

export function startTransition(cb) {
cb();
}

export function useDeferredValue(val) {
return val;
}

export function useTransition() {
return [false, startTransition];
}

// TODO: in theory this should be done after a VNode is diffed as we want to insert
// styles/... before it attaches
export const useInsertionEffect = useLayoutEffect;

// compat to react-is
export const isElement = isValidElement;

/**
* This is taken from https://github.com/facebook/react/blob/main/packages/use-sync-external-store/src/useSyncExternalStoreShimClient.js#L84
* on a high level this cuts out the warnings, ... and attempts a smaller implementation
* @typedef {{ _value: any; _getSnapshot: () => any }} Store
*/
export function useSyncExternalStore(subscribe, getSnapshot) {
const value = getSnapshot();

/**
* @typedef {{ _instance: Store }} StoreRef
* @type {[StoreRef, (store: StoreRef) => void]}
*/
const [{ _instance }, forceUpdate] = useState({
_instance: { _value: value, _getSnapshot: getSnapshot }
});

useLayoutEffect(() => {
_instance._value = value;
_instance._getSnapshot = getSnapshot;

if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}
}, [subscribe, value, getSnapshot]);

useEffect(() => {
if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}

return subscribe(() => {
if (didSnapshotChange(_instance)) {
forceUpdate({ _instance });
}
});
}, [subscribe]);

return value;
}

/** @type {(inst: Store) => boolean} */
function didSnapshotChange(inst) {
const latestGetSnapshot = inst._getSnapshot;
const prevValue = inst._value;
try {
const nextValue = latestGetSnapshot();
return !is(prevValue, nextValue);
} catch (error) {
return true;
}
}

export * from 'preact/hooks';
export {
version,
Expand All @@ -237,6 +175,11 @@ export {
memo,
forwardRef,
flushSync,
useInsertionEffect,
startTransition,
useDeferredValue,
useSyncExternalStore,
useTransition,
// eslint-disable-next-line camelcase
unstable_batchedUpdates,
StrictMode,
Expand Down
2 changes: 1 addition & 1 deletion demo/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import NestedSuspenseBug from './nested-suspense';
import Contenteditable from './contenteditable';
import { MobXDemo } from './mobx';
import Zustand from './zustand';
import ReduxToolkit from './redux_toolkit';
import ReduxToolkit from './redux-toolkit';

let isBenchmark = /(\/spiral|\/pythagoras|[#&]bench)/g.test(
window.location.href
Expand Down
Loading

0 comments on commit 22d61f0

Please sign in to comment.