Skip to content

Commit

Permalink
remove client only hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
mayank1513 committed Feb 27, 2024
1 parent 3ba3fcf commit 0634a20
Showing 1 changed file with 22 additions and 17 deletions.
39 changes: 22 additions & 17 deletions lib/r18gs/src/use-rgs.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useSyncExternalStore } from "react";
/* eslint-disable @typescript-eslint/non-nullable-type-assertion-style -- as ! operator is forbidden by eslint*/
import { useSyncExternalStore } from "react";

interface React18GlobalStore {
listeners: (() => void)[];
Expand All @@ -11,7 +12,11 @@ export type SetStateAction<T> = (val: SetterArgType<T>) => void;

declare global {
// eslint-disable-next-line no-var -- var required for global declaration.
var rgs: Record<string, React18GlobalStore>;
var rgs: Record<string, React18GlobalStore | undefined>;
// eslint-disable-next-line no-var -- var required for global declaration.
var setters: Record<string, SetStateAction<unknown> | undefined>;
// eslint-disable-next-line no-var -- var required for global declaration.
var subscribers: Record<string, ((listener: () => void) => () => void) | undefined>;
}

globalThis.rgs = {};
Expand All @@ -28,29 +33,29 @@ globalThis.rgs = {};
* ```
*/
export default function useRGS<T>(key: string, value?: T): [T, (val: SetterArgType<T>) => void] {
const setRGState = useCallback(
(val: SetterArgType<T>) => {
const rgs = globalThis.rgs[key] as React18GlobalStore;
rgs.value = val instanceof Function ? val(rgs.value as T) : val;
for (const listener of rgs.listeners) listener();
},
[key],
);
const subscribe = useCallback(
(listener: () => void) => {
if (!globalThis.subscribers[key]) {

Check failure on line 36 in lib/r18gs/src/use-rgs.ts

View workflow job for this annotation

GitHub Actions / test

tests/use-rgs.test.tsx > React18GlobalStore > check state update to multiple components

TypeError: Cannot read properties of undefined (reading 'count') ❯ Module.useRGS [as default] src/use-rgs.ts:36:18 ❯ Component1 tests/use-rgs.test.tsx:6:28 ❯ renderWithHooks ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:16305:18 ❯ mountIndeterminateComponent ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:20074:13 ❯ beginWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:21587:16 ❯ beginWork$1 ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:27426:14 ❯ performUnitOfWork ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:26560:12 ❯ workLoopSync ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:26466:5 ❯ renderRootSync ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:26434:7 ❯ recoverFromConcurrentError ../../node_modules/.pnpm/[email protected][email protected]/node_modules/react-dom/cjs/react-dom.development.js:25850:20
globalThis.subscribers[key] = (listener: () => void) => {
if (!globalThis.rgs[key]) globalThis.rgs[key] = { listeners: [], value };
const rgs = globalThis.rgs[key] as React18GlobalStore;
rgs.listeners.push(listener);
return () => {
rgs.listeners = rgs.listeners.filter(l => l !== listener);
};
},
[key, value],
);
};
}
const subscribe = globalThis.subscribers[key] as (listener: () => void) => () => void;

if (!globalThis.setters[key]) {
globalThis.setters[key] = val => {
const rgs = globalThis.rgs[key] as React18GlobalStore;
rgs.value = val instanceof Function ? val(rgs.value as T) : val;
for (const listener of rgs.listeners) listener();
};
}
const setRGState = globalThis.setters[key] as SetStateAction<T>;

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access -- temp fix
const getSnapshot = () => (globalThis.rgs[key]?.value ?? value) as T;

const val = useSyncExternalStore<T>(subscribe, getSnapshot, () => value as T);
const val = useSyncExternalStore<T>(subscribe, getSnapshot, getSnapshot);
return [val, setRGState];
}

0 comments on commit 0634a20

Please sign in to comment.