{"_id":"@byeolnaerim/global-rx-state","_rev":"3-c4f4544ea13cb307ec61b02372b645a1","name":"@byeolnaerim/global-rx-state","dist-tags":{"alpha":"0.0.1","latest":"0.0.3"},"versions":{"0.0.1":{"name":"@byeolnaerim/global-rx-state","version":"0.0.1","keywords":["react","rxjs","state","global-state","react-state","behavior-subject","persistent-state","reducer","indexeddb","localforage"],"author":{"url":"@oozu1994","name":"Joohyoung Kim"},"license":"Apache-2.0","_id":"@byeolnaerim/global-rx-state@0.0.1","maintainers":[{"name":"oozu1994","email":"oozu1994@gmail.com"}],"homepage":"https://byeolnaerim.com","bugs":{"url":"https://github.com/joohyoungkim19940805/global-rx-state/issues"},"dist":{"shasum":"ddf6febc41bb9cd0a9c50c77ad951dabc730c8a0","tarball":"https://registry.npmjs.org/@byeolnaerim/global-rx-state/-/global-rx-state-0.0.1.tgz","fileCount":46,"integrity":"sha512-+KYFWdK9k34CLHoZrE/vgf9vmnpoeWMjWbLpihbEONlqwuyMfOpO+ASmPBLXCn1vwdelabM6IbP3XknE7xFrXQ==","signatures":[{"sig":"MEUCIQDLguDm79GkjJbCde7Psrn0vNjlR9lICX/JChdQQpfw7wIgKv5NQ0QpT5bUAR3zkoCHiabwl/JCCEif8I7PEcprkaY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":72938},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"},"./rx-state":{"types":"./dist/rx-state/index.d.ts","import":"./dist/rx-state/index.js","default":"./dist/rx-state/index.js","require":"./dist/rx-state/index.cjs"},"./rx-reducer":{"types":"./dist/rx-reducer/index.d.ts","import":"./dist/rx-reducer/index.js","default":"./dist/rx-reducer/index.js","require":"./dist/rx-reducer/index.cjs"},"./eslint-rules":{"default":"./eslint-rules/index.cjs","require":"./eslint-rules/index.cjs"},"./package.json":"./package.json","./eslint-rules/no-tuple-global-rx-state-in-function":{"default":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs","require":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs"}},"gitHead":"baa5fb699232da1be90266ba0d1f5aa81be700f2","scripts":{"dev":"tsup --watch","build":"tsup && tsc -p tsconfig.build.json","prepack":"npm run build"},"_npmUser":{"name":"oozu1994","email":"oozu1994@gmail.com"},"overrides":{"esbuild":"0.28.0"},"repository":{"url":"git+https://github.com/joohyoungkim19940805/global-rx-state.git","type":"git"},"_npmVersion":"11.9.0","description":"A tiny global React state primitive powered by RxJS, with named singleton stores, reducer support, and optional persistence.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","dependencies":{"localforage":"^1.10.0"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.2","tsup":"^8.5.1","react":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.7.0","@types/react":"^19.2.15","esbuild-plugin-preserve-directives":"^0.0.11"},"peerDependencies":{"rxjs":">=7","react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/global-rx-state_0.0.1_1779776751743_0.5244528235279098","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@byeolnaerim/global-rx-state","version":"0.0.2","keywords":["react","rxjs","state","global-state","react-state","behavior-subject","persistent-state","reducer","indexeddb","localforage"],"author":{"url":"@oozu1994","name":"Joohyoung Kim"},"license":"Apache-2.0","_id":"@byeolnaerim/global-rx-state@0.0.2","maintainers":[{"name":"oozu1994","email":"oozu1994@gmail.com"}],"homepage":"https://byeolnaerim.com/global-rx-state","bugs":{"url":"https://github.com/joohyoungkim19940805/global-rx-state/issues"},"dist":{"shasum":"ab5c074883090191db1a04e29263b159ffed17aa","tarball":"https://registry.npmjs.org/@byeolnaerim/global-rx-state/-/global-rx-state-0.0.2.tgz","fileCount":46,"integrity":"sha512-HlV7H83PSnDbxjIQayy0qpKILI0x7Ud+2gcQIAN7aFcQ9aArwNGpmkEosW03BX2u4jlSvytENFbRb3AS+VDnww==","signatures":[{"sig":"MEQCIBwc4u7nVVKD7p5c/jYerXTWMhWRIjBpj1d9boCyHo1rAiA/MG77W52W11L7r5f88MD0IEewILvJ8oW8KJOla8ldhw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76009},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js","require":"./dist/index.cjs"},"./rx-state":{"types":"./dist/rx-state/index.d.ts","import":"./dist/rx-state/index.js","default":"./dist/rx-state/index.js","require":"./dist/rx-state/index.cjs"},"./rx-reducer":{"types":"./dist/rx-reducer/index.d.ts","import":"./dist/rx-reducer/index.js","default":"./dist/rx-reducer/index.js","require":"./dist/rx-reducer/index.cjs"},"./eslint-rules":{"default":"./eslint-rules/index.cjs","require":"./eslint-rules/index.cjs"},"./package.json":"./package.json","./eslint-rules/no-tuple-global-rx-state-in-function":{"default":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs","require":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs"}},"gitHead":"bcb56f00f14cfd2d2f6014ea155710dd9ef9f2b5","scripts":{"dev":"tsup --watch","build":"tsup && tsc -p tsconfig.build.json","prepack":"npm run build"},"_npmUser":{"name":"oozu1994","email":"oozu1994@gmail.com"},"overrides":{"esbuild":"0.28.0"},"repository":{"url":"git+https://github.com/joohyoungkim19940805/global-rx-state.git","type":"git"},"_npmVersion":"11.9.0","description":"A tiny global React state primitive powered by RxJS, with named singleton stores, reducer support, and optional persistence.","directories":{},"sideEffects":false,"_nodeVersion":"24.14.0","dependencies":{"localforage":"^1.10.0"},"_hasShrinkwrap":false,"devDependencies":{"rxjs":"^7.8.2","tsup":"^8.5.1","react":"^19.2.6","typescript":"^6.0.3","@types/node":"^25.7.0","@types/react":"^19.2.15","esbuild-plugin-preserve-directives":"^0.0.11"},"peerDependencies":{"rxjs":">=7","react":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/global-rx-state_0.0.2_1779872468968_0.8204076361518018","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@byeolnaerim/global-rx-state","version":"0.0.3","type":"module","license":"Apache-2.0","author":{"name":"Joohyoung Kim","url":"@oozu1994"},"description":"A tiny global React state primitive powered by RxJS, with named singleton stores, reducer support, and optional persistence.","keywords":["react","rxjs","state","global-state","react-state","behavior-subject","persistent-state","reducer","indexeddb","localforage"],"homepage":"https://byeolnaerim.com/global-rx-state","repository":{"type":"git","url":"git+https://github.com/joohyoungkim19940805/global-rx-state.git"},"bugs":{"url":"https://github.com/joohyoungkim19940805/global-rx-state/issues"},"sideEffects":false,"main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs","default":"./dist/index.js"},"./rx-state":{"types":"./dist/rx-state/index.d.ts","import":"./dist/rx-state/index.js","require":"./dist/rx-state/index.cjs","default":"./dist/rx-state/index.js"},"./rx-reducer":{"types":"./dist/rx-reducer/index.d.ts","import":"./dist/rx-reducer/index.js","require":"./dist/rx-reducer/index.cjs","default":"./dist/rx-reducer/index.js"},"./eslint-rules":{"require":"./eslint-rules/index.cjs","default":"./eslint-rules/index.cjs"},"./eslint-rules/no-tuple-global-rx-state-in-function":{"require":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs","default":"./eslint-rules/no-tuple-global-rx-state-in-function.cjs"},"./package.json":"./package.json"},"scripts":{"build":"tsup && tsc -p tsconfig.build.json","dev":"tsup --watch","prepack":"npm run build"},"peerDependencies":{"react":">=18.0.0","rxjs":">=7"},"dependencies":{"localforage":"^1.10.0"},"devDependencies":{"@types/node":"^25.7.0","@types/react":"^19.2.15","esbuild-plugin-preserve-directives":"^0.0.11","react":"^19.2.6","rxjs":"^7.8.2","tsup":"^8.5.1","typescript":"^6.0.3"},"overrides":{"esbuild":"0.28.0"},"gitHead":"e63a83ef8e40e6ce64a38df2ab153de856707ff3","_id":"@byeolnaerim/global-rx-state@0.0.3","_nodeVersion":"24.16.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-eZ9rEIYL48uxyHJCn3oRPy4xXxdePwFToITE5+wxXgLWaeazRTOcLF+Wk5i+ZWFUoHgOb449m8yP/yz/xww2Sw==","shasum":"20372104732cbeb08a56a7201010612c94ed1ac3","tarball":"https://registry.npmjs.org/@byeolnaerim/global-rx-state/-/global-rx-state-0.0.3.tgz","fileCount":46,"unpackedSize":122557,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGyvVKN4KUClCkQjkWVYPOACacDRN76Ln0B9wArWCIMfAiBT+QJbuwIr+mF5fPVpjS4hFoan2PRMlzzyztEkTW57PQ=="}]},"_npmUser":{"name":"oozu1994","email":"oozu1994@gmail.com"},"directories":{},"maintainers":[{"name":"oozu1994","email":"oozu1994@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/global-rx-state_0.0.3_1787293003733_0.15391670811812874"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-26T06:25:51.505Z","modified":"2026-08-21T06:16:44.053Z","0.0.1":"2026-05-26T06:25:51.879Z","0.0.2":"2026-05-27T09:01:09.100Z","0.0.3":"2026-08-21T06:16:43.895Z"},"bugs":{"url":"https://github.com/joohyoungkim19940805/global-rx-state/issues"},"author":{"name":"Joohyoung Kim","url":"@oozu1994"},"license":"Apache-2.0","homepage":"https://byeolnaerim.com/global-rx-state","keywords":["react","rxjs","state","global-state","react-state","behavior-subject","persistent-state","reducer","indexeddb","localforage"],"repository":{"type":"git","url":"git+https://github.com/joohyoungkim19940805/global-rx-state.git"},"description":"A tiny global React state primitive powered by RxJS, with named singleton stores, reducer support, and optional persistence.","maintainers":[{"name":"oozu1994","email":"oozu1994@gmail.com"}],"readme":"# @byeolnaerim/global-rx-state\r\n\r\nA tiny global React state primitive powered by RxJS, with named singleton stores, reducer support, and optional persistence.\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install @byeolnaerim/global-rx-state rxjs react\r\n```\r\n\r\n## Anonymous tuple mode\r\n\r\nAnonymous tuple mode creates a fresh store for each call. Declare it at module top-level and export the returned functions.\r\n\r\n```ts\r\n// ./state\r\nimport { createRxState } from \"@byeolnaerim/global-rx-state\";\r\n\r\nexport const [setCount, getCount, useCount, countSubject, countReady] =\r\n\tcreateRxState(0);\r\n```\r\n\r\nThen import the exported functions from React components.\r\n\r\n```tsx\r\nimport { useCount } from \"./state\";\r\n\r\nexport function Counter() {\r\n\tconst count = useCount();\r\n\treturn <div>{count}</div>;\r\n}\r\n```\r\n\r\nDo not call anonymous tuple mode inside React components or other functions. It creates a new store for each call.\r\n\r\n```tsx\r\nfunction Counter() {\r\n\t// Do not do this.\r\n\tconst [setCount, getCount, useCount] = createRxState(0);\r\n\treturn <div>{useCount()}</div>;\r\n}\r\n```\r\n\r\nAnonymous tuple mode does not accept storage options. It has no stable persistence key and does not generate or use hidden, random keys.\r\n\r\n## Named state mode\r\n\r\nNamed mode uses a global singleton registry keyed by name and storage options.\r\n\r\n```tsx\r\nimport { createRxState } from \"@byeolnaerim/global-rx-state\";\r\n\r\nexport const { setCount, getCount, useCount, countSubject, countReady } =\r\n\tcreateRxState(0, \"count\", { storage: \"auto\" });\r\n\r\n//OR\r\n\r\nfunction A_Component(){\r\n\tconst {setCountInner} = createRxState(0, \"countInner\"{storage:\"auto\"});\r\n\treturn (\r\n\t\t<div>\r\n\t\t\t<button onClick={() => setCountInner((prev) => prev + 1)}>\r\n\t\t\t\t{countInner}\r\n\t\t\t</button>\r\n\t\t</div>\r\n\t);\r\n}\r\n\r\nfunction B_Component(){\r\n\tconst {useCountInner} = createRxState(0, \"countInner\")// is A_Component countInner\r\n\r\n\tconst countInner = useCountInner();\r\n\r\n\treturn (\r\n\t\t<div><span>current count : {countInner}</span></div>\r\n\t)\r\n}\r\n```\r\n\r\nIf storage is omitted, the first registered storage alias for the same name is reused. If no alias exists yet, it defaults to in-memory.\r\n\r\nTo prevent confusion, it is recommended to explicitly specify the storage whenever possible.\r\n\r\n```ts\r\ncreateRxState(0, \"count\", { storage: \"auto\" });\r\ncreateRxState(0, \"count\"); // reuses auto for count\r\n\r\ncreateRxState(0, \"count\", { storage: \"in-memory\" }); // separate store\r\n\r\ncreateRxState(0, \"clickCount\"); // defaults to 'in-memory' if no storage alias exists\r\ncreateRxState(0, \"clickCount\", { storage: \"auto\" }); // separate store\r\n```\r\n\r\n## Named tuple helper\r\n\r\nUse `createRxStateTuple` when you want tuple ergonomics plus named singleton behavior and optional persistence.\r\n\r\nIf you already know the static name, using the named mode is generally more readable.\r\n\r\ncreateRxStateTuple is particularly useful when the name is determined at runtime. For example, you can use it when you need to separate state based on a key that cannot be determined in advance—such as a workspace ID received from a server, a tab name selected by the user, or a route parameter.\r\n\r\n```ts\r\nimport { createRxStateTuple } from \"@byeolnaerim/global-rx-state\";\r\n\r\nexport const [setCount, getCount, useCount, countSubject, countReady] =\r\n\tcreateRxStateTuple(0, \"count\", { storage: \"auto\" });\r\n```\r\n\r\n## Reducer mode\r\n\r\nAnonymous reducer tuple mode is also module-top-level only.\r\n\r\n```ts\r\nimport { createRxReducer } from \"@byeolnaerim/global-rx-state\";\r\n\r\ntype CountAction = { type: \"increment\" } | { type: \"reset\" };\r\n\r\nfunction countReducer(state: number, action: CountAction) {\r\n\tswitch (action.type) {\r\n\t\tcase \"increment\":\r\n\t\t\treturn state + 1;\r\n\t\tcase \"reset\":\r\n\t\t\treturn 0;\r\n\t\tdefault:\r\n\t\t\treturn state;\r\n\t}\r\n}\r\n\r\nexport const [dispatchCount, getCount, useCount] = createRxReducer(\r\n\t0,\r\n\tcountReducer,\r\n);\r\n```\r\n\r\nNamed reducer mode supports persistence.\r\n\r\n```ts\r\nexport const { dispatchCount, getCount, useCount, countSubject, countReady } =\r\n\tcreateRxReducer(0, countReducer, \"count\", { storage: \"auto\" });\r\n```\r\n\r\nNamed reducer tuple helper:\r\n\r\n```ts\r\nexport const [dispatchCount, getCount, useCount, countSubject, countReady] =\r\n\tcreateRxReducerTuple(0, countReducer, \"count\", { storage: \"auto\" });\r\n```\r\n\r\n## Storage\r\n\r\nSupported storage values:\r\n\r\n- `in-memory`\r\n- `auto`\r\n- `indexeddb`\r\n- `websql`\r\n- `localstorage`\r\n- `sessionstorage`\r\n\r\n`auto` uses localForage with this driver order:\r\n\r\n```txt\r\nIndexedDB > WebSQL > localStorage\r\n```\r\n\r\n`ready` is a Promise that resolves after persistent storage hydration finishes. React hooks update automatically after hydration; use `ready` only when code must wait for the restored value before continuing.\r\n\r\n## Storage utilities\r\n\r\nNamed state storage can be checked with three utilities.\r\n\r\n### `hasRxState`\r\n\r\nChecks whether the named state exists in the specified storage configuration.\r\n\r\n```ts\r\nimport { hasRxState } from \"@byeolnaerim/global-rx-state\";\r\n\r\nawait hasRxState(\"count\", { storage: \"auto\" });\r\n// Promise<boolean>\r\n```\r\n\r\n### `findRxStateStorages`\r\n\r\nReturns the concrete storage backends where the named state currently exists. If the same name exists in more than one storage, all matching backends are returned once.\r\n\r\n```ts\r\nimport { findRxStateStorages } from \"@byeolnaerim/global-rx-state\";\r\n\r\nawait findRxStateStorages(\"count\");\r\n// Promise<RxStateResolvedStorage[]>\r\n// e.g. [\"indexeddb\", \"localstorage\"]\r\n```\r\n\r\n### `getRxStateStorageInfo`\r\n\r\nReturns detailed storage information for every matching location. The result is always an array because the same name can exist in multiple storage configurations.\r\n\r\n```ts\r\nimport { getRxStateStorageInfo } from \"@byeolnaerim/global-rx-state\";\r\n\r\nawait getRxStateStorageInfo(\"count\");\r\n\r\nawait getRxStateStorageInfo(\"count\", { storage: \"indexeddb\" });\r\n// Promise<RxStateStorageInfo[]>\r\n```\r\n\r\nEach `RxStateStorageInfo` item contains:\r\n\r\n```ts\r\ninterface RxStateStorageInfo {\r\n\tkey: string;\r\n\tstorageKey: string;\r\n\tfullKey: string;\r\n\tstorage: RxStateResolvedStorage;\r\n\tname: string;\r\n\tstoreName: string;\r\n\tkeyPrefix: string;\r\n}\r\n```\r\n\r\n`storageKey` is the item key used by the storage adapter/localForage instance. `fullKey` is the full flat key when the backend exposes one. `storage` contains the concrete backend, so `auto` is returned as the driver actually selected by localForage.\r\n\r\nThe reducer API provides the same three utilities as `hasRxReducer`, `findRxReducerStorages`, and `getRxReducerStorageInfo`.\r\n\r\n## ESLint rule\r\n\r\nThe package includes a small ESLint rule that prevents anonymous tuple mode inside functions/components.\r\n\r\n```js\r\nconst globalRxState = require(\"@byeolnaerim/global-rx-state/eslint-rules\");\r\n\r\nmodule.exports = {\r\n\tplugins: {\r\n\t\t\"global-rx-state\": globalRxState,\r\n\t},\r\n\trules: {\r\n\t\t\"global-rx-state/no-tuple-global-rx-state-in-function\": \"error\",\r\n\t},\r\n};\r\n```\r\n\r\nFor legacy `.eslintrc` setups, you can also use ESLint `--rulesdir` with `eslint-rules/no-tuple-global-rx-state-in-function.cjs`.\r\n","readmeFilename":"README.md"}