react-reactive-val 1.0.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/package.json +22 -0
- package/src/index.ts +50 -0
- package/tsconfig.json +28 -0
package/package.json
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
{
|
2
|
+
"name": "react-reactive-val",
|
3
|
+
"version": "1.0.0",
|
4
|
+
"description": "",
|
5
|
+
"main": "dist/index.js",
|
6
|
+
"scripts": {
|
7
|
+
"build": "tsc",
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
9
|
+
},
|
10
|
+
"peerDependencies": {
|
11
|
+
"react": "^19.0.0"
|
12
|
+
},
|
13
|
+
"keywords": [],
|
14
|
+
"author": "Jatin Parate <jatin4228@gmail.com>",
|
15
|
+
"license": "ISC",
|
16
|
+
"type": "commonjs",
|
17
|
+
"devDependencies": {
|
18
|
+
"react": "^19.1.0",
|
19
|
+
"@types/react": "^19.1.0",
|
20
|
+
"typescript": "^5.8.3"
|
21
|
+
}
|
22
|
+
}
|
package/src/index.ts
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
import {
|
2
|
+
type ReactNode,
|
3
|
+
type ReactElement,
|
4
|
+
useSyncExternalStore,
|
5
|
+
memo,
|
6
|
+
useMemo,
|
7
|
+
} from "react";
|
8
|
+
import { jsx } from "react/jsx-runtime";
|
9
|
+
|
10
|
+
export default function useReactiveValue<T extends ReactNode>(initialValue: T) {
|
11
|
+
return useMemo(() => reallyReactiveVal(initialValue), [initialValue]);
|
12
|
+
}
|
13
|
+
|
14
|
+
export const reallyReactiveVal = <T extends ReactNode>(initialValue: T) => {
|
15
|
+
let value: T = initialValue;
|
16
|
+
const onUpdates = new Set<() => void>();
|
17
|
+
|
18
|
+
const Component = memo(function Component() {
|
19
|
+
const currVal = useSyncExternalStore(
|
20
|
+
(listener) => {
|
21
|
+
onUpdates.add(listener);
|
22
|
+
return () => onUpdates.delete(listener);
|
23
|
+
},
|
24
|
+
() => value
|
25
|
+
);
|
26
|
+
|
27
|
+
return currVal;
|
28
|
+
});
|
29
|
+
|
30
|
+
type Updater = T | ((currVal: T) => T);
|
31
|
+
|
32
|
+
function fn<U extends Updater | unknown | undefined>(updater?: U) {
|
33
|
+
if (typeof updater === "undefined") {
|
34
|
+
return jsx(Component, {});
|
35
|
+
}
|
36
|
+
|
37
|
+
// Type narrowing correctly applies here: updater is not undefined
|
38
|
+
value = typeof updater === "function" ? updater(value) : updater;
|
39
|
+
|
40
|
+
onUpdates.forEach((item) => {
|
41
|
+
item();
|
42
|
+
});
|
43
|
+
|
44
|
+
return undefined;
|
45
|
+
}
|
46
|
+
|
47
|
+
return fn as <U extends Updater | unknown | undefined>(
|
48
|
+
updater?: U
|
49
|
+
) => U extends Updater ? undefined : ReactElement;
|
50
|
+
};
|
package/tsconfig.json
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
{
|
2
|
+
"compilerOptions": {
|
3
|
+
"outDir": "./dist",
|
4
|
+
"target": "ES2015",
|
5
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
6
|
+
"allowJs": true,
|
7
|
+
"skipLibCheck": true,
|
8
|
+
"strict": true,
|
9
|
+
"noEmit": false,
|
10
|
+
"esModuleInterop": true,
|
11
|
+
"module": "CommonJS",
|
12
|
+
"moduleResolution": "node",
|
13
|
+
"resolveJsonModule": true,
|
14
|
+
"isolatedModules": true,
|
15
|
+
"jsx": "preserve",
|
16
|
+
"incremental": true,
|
17
|
+
"plugins": [
|
18
|
+
{
|
19
|
+
"name": "next"
|
20
|
+
}
|
21
|
+
],
|
22
|
+
"paths": {
|
23
|
+
"@/*": ["./src/*"]
|
24
|
+
}
|
25
|
+
},
|
26
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
27
|
+
"exclude": ["node_modules"]
|
28
|
+
}
|