@storve/core 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.
Files changed (196) hide show
  1. package/CHANGELOG.md +151 -0
  2. package/benchmarks/run.ts +102 -0
  3. package/benchmarks/week2.md +9 -0
  4. package/benchmarks/week2.ts +64 -0
  5. package/benchmarks/week4.md +13 -0
  6. package/benchmarks/week4.ts +178 -0
  7. package/benchmarks/week5.md +15 -0
  8. package/benchmarks/week5.ts +184 -0
  9. package/coverage/coverage-summary.json +31 -0
  10. package/dist/adapters/indexedDB.cjs +2 -0
  11. package/dist/adapters/indexedDB.cjs.map +1 -0
  12. package/dist/adapters/indexedDB.mjs +2 -0
  13. package/dist/adapters/indexedDB.mjs.map +1 -0
  14. package/dist/adapters/localStorage.cjs +2 -0
  15. package/dist/adapters/localStorage.cjs.map +1 -0
  16. package/dist/adapters/localStorage.mjs +2 -0
  17. package/dist/adapters/localStorage.mjs.map +1 -0
  18. package/dist/adapters/memory.cjs +2 -0
  19. package/dist/adapters/memory.cjs.map +1 -0
  20. package/dist/adapters/memory.mjs +2 -0
  21. package/dist/adapters/memory.mjs.map +1 -0
  22. package/dist/adapters/sessionStorage.cjs +2 -0
  23. package/dist/adapters/sessionStorage.cjs.map +1 -0
  24. package/dist/adapters/sessionStorage.mjs +2 -0
  25. package/dist/adapters/sessionStorage.mjs.map +1 -0
  26. package/dist/async-entry.d.ts +7 -0
  27. package/dist/async-entry.d.ts.map +1 -0
  28. package/dist/async.cjs +2 -0
  29. package/dist/async.cjs.map +1 -0
  30. package/dist/async.d.ts +52 -0
  31. package/dist/async.d.ts.map +1 -0
  32. package/dist/async.mjs +2 -0
  33. package/dist/async.mjs.map +1 -0
  34. package/dist/batch.d.ts +12 -0
  35. package/dist/batch.d.ts.map +1 -0
  36. package/dist/compose.d.ts +7 -0
  37. package/dist/compose.d.ts.map +1 -0
  38. package/dist/computed-entry.d.ts +7 -0
  39. package/dist/computed-entry.d.ts.map +1 -0
  40. package/dist/computed.cjs +2 -0
  41. package/dist/computed.cjs.map +1 -0
  42. package/dist/computed.d.ts +56 -0
  43. package/dist/computed.d.ts.map +1 -0
  44. package/dist/computed.mjs +2 -0
  45. package/dist/computed.mjs.map +1 -0
  46. package/dist/devtools/history.d.ts +51 -0
  47. package/dist/devtools/history.d.ts.map +1 -0
  48. package/dist/devtools/index.d.ts +5 -0
  49. package/dist/devtools/index.d.ts.map +1 -0
  50. package/dist/devtools/redux-bridge.d.ts +21 -0
  51. package/dist/devtools/redux-bridge.d.ts.map +1 -0
  52. package/dist/devtools/snapshots.d.ts +32 -0
  53. package/dist/devtools/snapshots.d.ts.map +1 -0
  54. package/dist/devtools/withDevtools.d.ts +17 -0
  55. package/dist/devtools/withDevtools.d.ts.map +1 -0
  56. package/dist/devtools.cjs +2 -0
  57. package/dist/devtools.cjs.map +1 -0
  58. package/dist/devtools.mjs +2 -0
  59. package/dist/devtools.mjs.map +1 -0
  60. package/dist/extensions/noop.d.ts +2 -0
  61. package/dist/extensions/noop.d.ts.map +1 -0
  62. package/dist/index.cjs +2 -0
  63. package/dist/index.cjs.js +118 -0
  64. package/dist/index.cjs.js.map +1 -0
  65. package/dist/index.cjs.map +1 -0
  66. package/dist/index.d.ts +5 -0
  67. package/dist/index.d.ts.map +1 -0
  68. package/dist/index.esm.js +116 -0
  69. package/dist/index.esm.js.map +1 -0
  70. package/dist/index.mjs +2 -0
  71. package/dist/index.mjs.map +1 -0
  72. package/dist/persist/adapters/indexedDB.d.ts +12 -0
  73. package/dist/persist/adapters/indexedDB.d.ts.map +1 -0
  74. package/dist/persist/adapters/localStorage.d.ts +11 -0
  75. package/dist/persist/adapters/localStorage.d.ts.map +1 -0
  76. package/dist/persist/adapters/memory.d.ts +11 -0
  77. package/dist/persist/adapters/memory.d.ts.map +1 -0
  78. package/dist/persist/adapters/sessionStorage.d.ts +11 -0
  79. package/dist/persist/adapters/sessionStorage.d.ts.map +1 -0
  80. package/dist/persist/debounce.d.ts +12 -0
  81. package/dist/persist/debounce.d.ts.map +1 -0
  82. package/dist/persist/hydrate.d.ts +15 -0
  83. package/dist/persist/hydrate.d.ts.map +1 -0
  84. package/dist/persist/index.d.ts +34 -0
  85. package/dist/persist/index.d.ts.map +1 -0
  86. package/dist/persist/serialize.d.ts +28 -0
  87. package/dist/persist/serialize.d.ts.map +1 -0
  88. package/dist/persist.cjs +2 -0
  89. package/dist/persist.cjs.map +1 -0
  90. package/dist/persist.mjs +2 -0
  91. package/dist/persist.mjs.map +1 -0
  92. package/dist/proxy.d.ts +2 -0
  93. package/dist/proxy.d.ts.map +1 -0
  94. package/dist/registry-D3X0HSbl.js +26 -0
  95. package/dist/registry-D3X0HSbl.js.map +1 -0
  96. package/dist/registry-RDjbeJdx.js +29 -0
  97. package/dist/registry-RDjbeJdx.js.map +1 -0
  98. package/dist/registry-qtr1UpFU.js +2 -0
  99. package/dist/registry-qtr1UpFU.js.map +1 -0
  100. package/dist/registry-zaKZ1P-s.js +2 -0
  101. package/dist/registry-zaKZ1P-s.js.map +1 -0
  102. package/dist/registry.d.ts +54 -0
  103. package/dist/registry.d.ts.map +1 -0
  104. package/dist/signals/createSignal.d.ts +19 -0
  105. package/dist/signals/createSignal.d.ts.map +1 -0
  106. package/dist/signals/index.d.ts +20 -0
  107. package/dist/signals/index.d.ts.map +1 -0
  108. package/dist/signals/useSignal.d.ts +11 -0
  109. package/dist/signals/useSignal.d.ts.map +1 -0
  110. package/dist/signals.cjs +2 -0
  111. package/dist/signals.cjs.map +1 -0
  112. package/dist/signals.mjs +2 -0
  113. package/dist/signals.mjs.map +1 -0
  114. package/dist/stats.html +4949 -0
  115. package/dist/store.d.ts +12 -0
  116. package/dist/store.d.ts.map +1 -0
  117. package/dist/sync/channel.d.ts +7 -0
  118. package/dist/sync/channel.d.ts.map +1 -0
  119. package/dist/sync/index.d.ts +3 -0
  120. package/dist/sync/index.d.ts.map +1 -0
  121. package/dist/sync/protocol.d.ts +22 -0
  122. package/dist/sync/protocol.d.ts.map +1 -0
  123. package/dist/sync/withSync.d.ts +17 -0
  124. package/dist/sync/withSync.d.ts.map +1 -0
  125. package/dist/sync.cjs +2 -0
  126. package/dist/sync.cjs.map +1 -0
  127. package/dist/sync.mjs +2 -0
  128. package/dist/sync.mjs.map +1 -0
  129. package/dist/types.d.ts +134 -0
  130. package/dist/types.d.ts.map +1 -0
  131. package/package.json +91 -0
  132. package/rollup.config.mjs +44 -0
  133. package/src/async-entry.ts +6 -0
  134. package/src/async.ts +240 -0
  135. package/src/batch.ts +33 -0
  136. package/src/compose.ts +50 -0
  137. package/src/computed-entry.ts +6 -0
  138. package/src/computed.ts +187 -0
  139. package/src/devtools/history.ts +103 -0
  140. package/src/devtools/index.ts +5 -0
  141. package/src/devtools/redux-bridge.ts +70 -0
  142. package/src/devtools/snapshots.ts +54 -0
  143. package/src/devtools/withDevtools.ts +196 -0
  144. package/src/extensions/noop.ts +12 -0
  145. package/src/index.ts +4 -0
  146. package/src/persist/adapters/indexedDB.ts +114 -0
  147. package/src/persist/adapters/localStorage.ts +28 -0
  148. package/src/persist/adapters/memory.ts +26 -0
  149. package/src/persist/adapters/sessionStorage.ts +28 -0
  150. package/src/persist/debounce.ts +28 -0
  151. package/src/persist/hydrate.ts +60 -0
  152. package/src/persist/index.ts +141 -0
  153. package/src/persist/serialize.ts +60 -0
  154. package/src/proxy.ts +87 -0
  155. package/src/registry.ts +67 -0
  156. package/src/signals/createSignal.ts +81 -0
  157. package/src/signals/index.ts +20 -0
  158. package/src/signals/useSignal.ts +18 -0
  159. package/src/store.ts +250 -0
  160. package/src/sync/channel.ts +15 -0
  161. package/src/sync/index.ts +3 -0
  162. package/src/sync/protocol.ts +18 -0
  163. package/src/sync/withSync.ts +147 -0
  164. package/src/types.ts +159 -0
  165. package/tests/async.test.ts +1100 -0
  166. package/tests/batch.test.ts +41 -0
  167. package/tests/compose.test.ts +209 -0
  168. package/tests/computed.test.ts +867 -0
  169. package/tests/devtools.test.ts +1039 -0
  170. package/tests/integration/persist.integration.test.ts +258 -0
  171. package/tests/integration/signals.integration.test.ts +309 -0
  172. package/tests/integration.test.ts +278 -0
  173. package/tests/persist/adapters/indexedDB.adapter.test.ts +185 -0
  174. package/tests/persist/adapters/localStorage.adapter.test.ts +105 -0
  175. package/tests/persist/adapters/memory.adapter.test.ts +112 -0
  176. package/tests/persist/adapters/sessionStorage.adapter.test.ts +128 -0
  177. package/tests/persist/debounce.test.ts +121 -0
  178. package/tests/persist/hydrate.test.ts +120 -0
  179. package/tests/persist/migrate.test.ts +208 -0
  180. package/tests/persist/persist.test.ts +357 -0
  181. package/tests/persist/serialize.test.ts +128 -0
  182. package/tests/proxy.test.ts +473 -0
  183. package/tests/registry.test.ts +67 -0
  184. package/tests/signals/derived.test.ts +244 -0
  185. package/tests/signals/inference.test.ts +108 -0
  186. package/tests/signals/signal.test.ts +348 -0
  187. package/tests/signals/useSignal.test.tsx +275 -0
  188. package/tests/store.test.ts +482 -0
  189. package/tests/stress.test.ts +268 -0
  190. package/tests/sync.test.ts +576 -0
  191. package/tests/types.test.ts +32 -0
  192. package/tests/v0.3.test.ts +813 -0
  193. package/tree-shake-test.js +1 -0
  194. package/tsconfig.json +15 -0
  195. package/vitest.config.ts +22 -0
  196. package/vitest_play.ts +7 -0
@@ -0,0 +1,15 @@
1
+ import type { PersistAdapter } from './index.js';
2
+ /**
3
+ * Hydrates state from a persistence adapter.
4
+ * Handles reading from the adapter, JSON parsing, version checking, and migration.
5
+ *
6
+ * @template T - The state object type.
7
+ * @param {PersistAdapter} adapter - The persistence adapter to read from.
8
+ * @param {string} key - The unique namespace/key for the store in the adapter.
9
+ * @param {T} currentState - The current store state.
10
+ * @param {number} version - The expected state version.
11
+ * @param {(persisted: Partial<T>, version: number) => Partial<T>} [migrate] - Optional migration function.
12
+ * @returns {Promise<Partial<T>>} A promise that resolves to the hydrated partial state (or an empty object).
13
+ */
14
+ export declare function hydrate<T extends object>(adapter: PersistAdapter, key: string, currentState: T, version: number, migrate?: (persisted: Partial<T>, version: number) => Partial<T>): Promise<Partial<T>>;
15
+ //# sourceMappingURL=hydrate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hydrate.d.ts","sourceRoot":"","sources":["../../src/persist/hydrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAKhD;;;;;;;;;;;GAWG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,MAAM,EAC5C,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,CAAC,EACf,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GAC/D,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAoCrB"}
@@ -0,0 +1,34 @@
1
+ import type { Store, StoreState } from '../types.js';
2
+ /**
3
+ * Core interface for Storve persistence adapters.
4
+ * All adapters must implement these three methods to be compatible.
5
+ * Depending on the underlying storage, methods can be sync or async.
6
+ */
7
+ export interface PersistAdapter {
8
+ getItem(key: string): string | null | Promise<string | null>;
9
+ setItem(key: string, value: string): void | Promise<void>;
10
+ removeItem(key: string): void | Promise<void>;
11
+ }
12
+ /**
13
+ * Options for configuring persistence.
14
+ * @template T - The state type of the store.
15
+ */
16
+ export interface PersistOptions<T> {
17
+ key: string;
18
+ adapter: PersistAdapter;
19
+ pick?: Array<keyof T>;
20
+ version?: number;
21
+ migrate?: (persisted: Partial<T>, version: number) => Partial<T>;
22
+ debounce?: number;
23
+ }
24
+ /**
25
+ * Enhances a Storve store with continuous automatic persistence.
26
+ * Can be called directly or curried for use with compose().
27
+ */
28
+ export declare function withPersist<D extends object>(store: Store<D>, options: PersistOptions<StoreState<D>>): Store<D> & {
29
+ hydrated: Promise<void>;
30
+ };
31
+ export declare function withPersist<D extends object>(options: PersistOptions<StoreState<D>>): (store: Store<D>) => Store<D> & {
32
+ hydrated: Promise<void>;
33
+ };
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/persist/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAKpD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IAC5D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACzD,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,EAAE,cAAc,CAAA;IACvB,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAChE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAmFD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC1C,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GACrC,KAAK,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAA;AAEzC,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,EAC1C,OAAO,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GACrC,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAA"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Returns a new object with only the specified keys from state.
3
+ * If keys is undefine or empty, returns the full state.
4
+ *
5
+ * @template T - The state object type.
6
+ * @param {T} state - The complete state object.
7
+ * @param {Array<keyof T>} [keys] - The keys to pick.
8
+ * @returns {Partial<T> | T} A new object with picked keys, or the original state.
9
+ */
10
+ export declare function pick<T extends object>(state: T, keys?: Array<keyof T>): Partial<T> | T;
11
+ /**
12
+ * Safely stringifies a value to JSON, throwing a clear error if it fails.
13
+ *
14
+ * @param {unknown} value - The object or value to serialize.
15
+ * @returns {string} The JSON string representation.
16
+ * @throws {Error} Throws a detailed error if JSON.stringify fails.
17
+ */
18
+ export declare function toJSON(value: unknown): string;
19
+ /**
20
+ * Safely parses a JSON string, throwing a clear error if parsing fails or if the string is empty/null.
21
+ *
22
+ * @template T - The expected output type.
23
+ * @param {string} raw - The string to parse.
24
+ * @returns {T} The typed parsed JSON object.
25
+ * @throws {Error} Throws if 'raw' is empty or if JSON.parse fails.
26
+ */
27
+ export declare function fromJSON<T>(raw: string): T;
28
+ //# sourceMappingURL=serialize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serialize.d.ts","sourceRoot":"","sources":["../../src/persist/serialize.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,IAAI,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAetF;AAED;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAM7C;AAED;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,CAU1C"}
@@ -0,0 +1,2 @@
1
+ "use strict";function t(t,e){if(void 0===e||0===e.length)return{...t};const r={};for(let n=0;n<e.length;n++){const o=e[n];o in t&&(r[o]=t[o])}return r}function e(t){try{return JSON.stringify(t)}catch(t){throw new Error(`[storve] Failed to serialize state to JSON: ${t instanceof Error?t.message:String(t)}`)}}async function r(t,e,r,n,o){const i=await t.getItem(e);if(!i)return{};let s;try{s=function(t){if(!t)throw new Error("[storve] Cannot parse empty or null/undefined JSON string.");try{return JSON.parse(t)}catch(t){throw new Error(`[storve] Failed to parse JSON state: ${t instanceof Error?t.message:String(t)}`)}}(i)}catch(t){return console.warn(`[storve] Hydration failed for key "${e}":`,t),{}}const c=void 0!==s.__version?s.__version:0;let a;if(c!==n){if(void 0===o)return console.warn(`Storve: persisted state version mismatch (stored: ${c}, expected: ${n}). No migrate function provided — falling back to default state.`),{};a=o(s,c)}else a=s;const u={...a};return delete u.__version,u}function n(t){return null!==t&&"object"==typeof t&&"adapter"in t&&"key"in t}function o(n,o){let i;const s=new Promise(t=>{i=t}),c=void 0!==o.version?o.version:1,a=void 0!==o.debounce?o.debounce:100;r(o.adapter,o.key,n.getState(),c,o.migrate).then(t=>{n.setState(t),i()}).catch(t=>{console.warn(`[storve] withPersist hydrate error for key "${o.key}":`,t),i()});const u=function(t,e){let r;return function(...n){0!==e?(void 0!==r&&clearTimeout(r),r=setTimeout(()=>{t(...n)},e)):t(...n)}}(t=>{const e=o.adapter.setItem(o.key,t);e&&"function"==typeof e.catch&&e.catch(t=>{console.warn(`[storve] Failed to persist state for key "${o.key}":`,t)})},a);let f=e({...o.pick&&o.pick.length>0?t(n.getState(),o.pick):{...n.getState()},__version:c});return n.subscribe(r=>{const n=e({...o.pick&&o.pick.length>0?t(r,o.pick):{...r},__version:c});n!==f&&(f=n,u(n))}),{...n,hydrated:s}}exports.withPersist=function(t,e){if(void 0!==e&&!n(t))return o(t,e);if(n(t))return e=>o(e,t);throw new Error("[storve] Invalid withPersist arguments")};
2
+ //# sourceMappingURL=persist.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.cjs","sources":["../src/persist/serialize.ts","../src/persist/hydrate.ts","../src/persist/index.ts","../src/persist/debounce.ts"],"sourcesContent":[null,null,null,null],"names":["pick","state","keys","undefined","length","result","i","key","toJSON","value","JSON","stringify","err","Error","message","String","async","hydrate","adapter","currentState","version","migrate","raw","getItem","parsed","parse","fromJSON","console","warn","persistedVersion","__version","finalState","cleaned","isPersistOptions","obj","createEnhancedStore","store","options","resolveHydrated","hydrated","Promise","resolve","debounceMs","debounce","getState","then","hydratedState","setState","catch","debouncedWrite","fn","ms","timerId","args","clearTimeout","setTimeout","createDebounce","serialized","setItem","e","lastPersistedSnapshot","subscribe","newState","storeOrOptions"],"mappings":"aASM,SAAUA,EAAuBC,EAAUC,GAC/C,QAAaC,IAATD,GAAsC,IAAhBA,EAAKE,OAC7B,MAAO,IAAKH,GAGd,MAAMI,EAAqB,CAAA,EAE3B,IAAK,IAAIC,EAAI,EAAGA,EAAIJ,EAAKE,OAAQE,IAAK,CACpC,MAAMC,EAAML,EAAKI,GACbC,KAAON,IACTI,EAAOE,GAAON,EAAMM,GAExB,CAEA,OAAOF,CACT,CASM,SAAUG,EAAOC,GACrB,IACE,OAAOC,KAAKC,UAAUF,EACxB,CAAE,MAAOG,GACP,MAAM,IAAIC,MAAM,+CAA+CD,aAAeC,MAAQD,EAAIE,QAAUC,OAAOH,KAC7G,CACF,CCtBOI,eAAeC,EACpBC,EACAX,EACAY,EACAC,EACAC,GAEA,MAAMC,QAAYJ,EAAQK,QAAQhB,GAClC,IAAKe,EACH,MAAO,CAAA,EAGT,IAAIE,EACJ,IACEA,EDkBE,SAAsBF,GAC1B,IAAKA,EACH,MAAM,IAAIT,MAAM,8DAElB,IAEE,OADkBH,KAAKe,MAAMH,EAE/B,CAAE,MAAOV,GACP,MAAM,IAAIC,MAAM,wCAAwCD,aAAeC,MAAQD,EAAIE,QAAUC,OAAOH,KACtG,CACF,CC5Bac,CAA8BJ,EACzC,CAAE,MAAOV,GAEP,OADAe,QAAQC,KAAK,sCAAsCrB,MAASK,GACrD,CAAA,CACT,CAEA,MAAMiB,OAAwC1B,IAArBqB,EAAOM,UAA0BN,EAAOM,UAAY,EAE7E,IAAIC,EAEJ,GAAIF,IAAqBT,EAAS,CAChC,QAAgBjB,IAAZkB,EAMF,OAHAM,QAAQC,KACN,qDAAqDC,gBAA+BT,qEAE/E,GALPW,EAAaV,EAAQG,EAAQK,EAOjC,MACEE,EAAaP,EAIf,MAAMQ,EAA+B,IAAKD,GAG1C,cAFOC,EAAQF,UAERE,CACT,CC7BA,SAASC,EACPC,GAEA,OAAe,OAARA,GAA+B,iBAARA,GAAoB,YAAaA,GAAO,QAASA,CACjF,CAGA,SAASC,EACPC,EACAC,GAEA,IAAIC,EACJ,MAAMC,EAAW,IAAIC,QAAeC,IAClCH,EAAkBG,IAGdrB,OAA8BjB,IAApBkC,EAAQjB,QAAwBiB,EAAQjB,QAAU,EAC5DsB,OAAkCvC,IAArBkC,EAAQM,SAAyBN,EAAQM,SAAW,IAGvE1B,EACEoB,EAAQnB,QACRmB,EAAQ9B,IACR6B,EAAMQ,WACNxB,EACAiB,EAAQhB,SACRwB,KAAMC,IAENV,EAAMW,SAASD,GACfR,MACCU,MAEApC,IACCe,QAAQC,KAAK,+CAA+CS,EAAQ9B,QAASK,GAC7E0B,MAKJ,MAAMW,EC3DF,SAA8CC,EAA0BC,GAC5E,IAAIC,EAEJ,OAAO,YAAYC,GACN,IAAPF,QAKYhD,IAAZiD,GACFE,aAAaF,GAGfA,EAAUG,WAAW,KACnBL,KAAMG,IACLF,IAVDD,KAAMG,EAWV,CACF,CD0CyBG,CAAgBC,IACrC,MAAMpD,EAASgC,EAAQnB,QAAQwC,QAAQrB,EAAQ9B,IAAKkD,GAEhDpD,GAAkC,mBAAjBA,EAAO2C,OAE1B3C,EAAO2C,MAAOW,IACZhC,QAAQC,KAAK,6CAA6CS,EAAQ9B,QAASoD,MAG9EjB,GAMH,IAAIkB,EAAuCpD,EAAO,IAH5B6B,EAAQrC,MAAQqC,EAAQrC,KAAKI,OAAS,EACxDJ,EAAKoC,EAAMQ,WAAYP,EAAQrC,MAC/B,IAAKoC,EAAMQ,YACuDd,UAAWV,IAoBjF,OAjBAgB,EAAMyB,UAAWC,IAEf,MAKML,EAAajD,EAAO,IALX6B,EAAQrC,MAAQqC,EAAQrC,KAAKI,OAAS,EACjDJ,EAAK8D,EAAUzB,EAAQrC,MACvB,IAAK8D,GAG8BhC,UAAWV,IAG9CqC,IAAeG,IAGnBA,EAAwBH,EACxBR,EAAeQ,MAGV,IACFrB,EACHG,WAEJ,qBAeM,SACJwB,EACA1B,GAEA,QAAgBlC,IAAZkC,IACGJ,EAAiB8B,GACpB,OAAO5B,EAAoB4B,EAAgB1B,GAI/C,GAAIJ,EAAiB8B,GACnB,OAAQ3B,GAAoBD,EAAoBC,EAAO2B,GAIzD,MAAM,IAAIlD,MAAM,yCAClB"}
@@ -0,0 +1,2 @@
1
+ function t(t,e){if(void 0===e||0===e.length)return{...t};const r={};for(let n=0;n<e.length;n++){const o=e[n];o in t&&(r[o]=t[o])}return r}function e(t){try{return JSON.stringify(t)}catch(t){throw new Error(`[storve] Failed to serialize state to JSON: ${t instanceof Error?t.message:String(t)}`)}}async function r(t,e,r,n,o){const i=await t.getItem(e);if(!i)return{};let s;try{s=function(t){if(!t)throw new Error("[storve] Cannot parse empty or null/undefined JSON string.");try{return JSON.parse(t)}catch(t){throw new Error(`[storve] Failed to parse JSON state: ${t instanceof Error?t.message:String(t)}`)}}(i)}catch(t){return console.warn(`[storve] Hydration failed for key "${e}":`,t),{}}const a=void 0!==s.__version?s.__version:0;let c;if(a!==n){if(void 0===o)return console.warn(`Storve: persisted state version mismatch (stored: ${a}, expected: ${n}). No migrate function provided — falling back to default state.`),{};c=o(s,a)}else c=s;const u={...c};return delete u.__version,u}function n(t){return null!==t&&"object"==typeof t&&"adapter"in t&&"key"in t}function o(n,o){let i;const s=new Promise(t=>{i=t}),a=void 0!==o.version?o.version:1,c=void 0!==o.debounce?o.debounce:100;r(o.adapter,o.key,n.getState(),a,o.migrate).then(t=>{n.setState(t),i()}).catch(t=>{console.warn(`[storve] withPersist hydrate error for key "${o.key}":`,t),i()});const u=function(t,e){let r;return function(...n){0!==e?(void 0!==r&&clearTimeout(r),r=setTimeout(()=>{t(...n)},e)):t(...n)}}(t=>{const e=o.adapter.setItem(o.key,t);e&&"function"==typeof e.catch&&e.catch(t=>{console.warn(`[storve] Failed to persist state for key "${o.key}":`,t)})},c);let f=e({...o.pick&&o.pick.length>0?t(n.getState(),o.pick):{...n.getState()},__version:a});return n.subscribe(r=>{const n=e({...o.pick&&o.pick.length>0?t(r,o.pick):{...r},__version:a});n!==f&&(f=n,u(n))}),{...n,hydrated:s}}function i(t,e){if(void 0!==e&&!n(t))return o(t,e);if(n(t))return e=>o(e,t);throw new Error("[storve] Invalid withPersist arguments")}export{i as withPersist};
2
+ //# sourceMappingURL=persist.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"persist.mjs","sources":["../src/persist/serialize.ts","../src/persist/hydrate.ts","../src/persist/index.ts","../src/persist/debounce.ts"],"sourcesContent":[null,null,null,null],"names":["pick","state","keys","undefined","length","result","i","key","toJSON","value","JSON","stringify","err","Error","message","String","async","hydrate","adapter","currentState","version","migrate","raw","getItem","parsed","parse","fromJSON","console","warn","persistedVersion","__version","finalState","cleaned","isPersistOptions","obj","createEnhancedStore","store","options","resolveHydrated","hydrated","Promise","resolve","debounceMs","debounce","getState","then","hydratedState","setState","catch","debouncedWrite","fn","ms","timerId","args","clearTimeout","setTimeout","createDebounce","serialized","setItem","e","lastPersistedSnapshot","subscribe","newState","withPersist","storeOrOptions"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function createStateProxy<T extends object>(state: T, onChange: () => void): T;
2
+ //# sourceMappingURL=proxy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"proxy.d.ts","sourceRoot":"","sources":["../src/proxy.ts"],"names":[],"mappings":"AAWA,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,CAAC,CA2EpF"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Extension registry for store plugins.
3
+ * Features register when imported; createStore applies all registered extensions.
4
+ * @internal
5
+ */
6
+ const extensions = [];
7
+ /**
8
+ * Register an extension. Called by feature modules on import (side-effect).
9
+ * @internal
10
+ */
11
+ function registerExtension(ext) {
12
+ if (extensions.some((e) => e.key === ext.key))
13
+ return;
14
+ extensions.push(ext);
15
+ extensions.sort((a, b) => (a.order ?? 99) - (b.order ?? 99));
16
+ }
17
+ /**
18
+ * Get all registered extensions. Used by createStore.
19
+ * @internal
20
+ */
21
+ function getExtensions() {
22
+ return extensions;
23
+ }
24
+
25
+ export { getExtensions as g, registerExtension as r };
26
+ //# sourceMappingURL=registry-D3X0HSbl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-D3X0HSbl.js","sources":["../src/registry.ts"],"sourcesContent":[null],"names":[],"mappings":"AAAA;;;;AAIG;AA6BH,MAAM,UAAU,GAAqB,EAAE;AAEvC;;;AAGG;AACG,SAAU,iBAAiB,CAAC,GAAwC,EAAA;AACtE,IAAA,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC;QAAE;AAC/C,IAAA,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;IACpB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAE,CAAwB,CAAC,KAAK,IAAI,EAAE,KAAM,CAAwB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAChH;AAEA;;;AAGG;SACa,aAAa,GAAA;AACzB,IAAA,OAAO,UAAU;AACrB;;;;"}
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Extension registry for store plugins.
5
+ * Features register when imported; createStore applies all registered extensions.
6
+ * @internal
7
+ */
8
+ const extensions = [];
9
+ /**
10
+ * Register an extension. Called by feature modules on import (side-effect).
11
+ * @internal
12
+ */
13
+ function registerExtension(ext) {
14
+ if (extensions.some((e) => e.key === ext.key))
15
+ return;
16
+ extensions.push(ext);
17
+ extensions.sort((a, b) => (a.order ?? 99) - (b.order ?? 99));
18
+ }
19
+ /**
20
+ * Get all registered extensions. Used by createStore.
21
+ * @internal
22
+ */
23
+ function getExtensions() {
24
+ return extensions;
25
+ }
26
+
27
+ exports.getExtensions = getExtensions;
28
+ exports.registerExtension = registerExtension;
29
+ //# sourceMappingURL=registry-RDjbeJdx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-RDjbeJdx.js","sources":["../src/registry.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAAA;;;;AAIG;AA6BH,MAAM,UAAU,GAAqB,EAAE;AAEvC;;;AAGG;AACG,SAAU,iBAAiB,CAAC,GAAwC,EAAA;AACtE,IAAA,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,GAAG,CAAC;QAAE;AAC/C,IAAA,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC;IACpB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAE,CAAwB,CAAC,KAAK,IAAI,EAAE,KAAM,CAAwB,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AAChH;AAEA;;;AAGG;SACa,aAAa,GAAA;AACzB,IAAA,OAAO,UAAU;AACrB;;;;;"}
@@ -0,0 +1,2 @@
1
+ "use strict";const e=[];exports.getExtensions=function(){return e},exports.registerExtension=function(t){e.some(e=>e.key===t.key)||(e.push(t),e.sort((e,t)=>(e.order??99)-(t.order??99)))};
2
+ //# sourceMappingURL=registry-qtr1UpFU.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-qtr1UpFU.js","sources":["../src/registry.ts"],"sourcesContent":[null],"names":["extensions","ext","some","e","key","push","sort","a","b","order"],"mappings":"aAwCA,MAAMA,EAA+B,oCAiBjC,OAAOA,CACX,4BAZM,SAA4BC,GAC1BD,EAAWE,KAAMC,GAAMA,EAAEC,MAAQH,EAAIG,OACzCJ,EAAWK,KAAKJ,GAChBD,EAAWM,KAAK,CAACC,EAAGC,KAAQD,EAAyBE,OAAS,KAAQD,EAAyBC,OAAS,KAC5G"}
@@ -0,0 +1,2 @@
1
+ const r=[];function o(o){r.some(r=>r.key===o.key)||(r.push(o),r.sort((r,o)=>(r.order??99)-(o.order??99)))}function e(){return r}export{e as g,o as r};
2
+ //# sourceMappingURL=registry-zaKZ1P-s.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-zaKZ1P-s.js","sources":["../src/registry.ts"],"sourcesContent":[null],"names":["extensions","registerExtension","ext","some","e","key","push","sort","a","b","order","getExtensions"],"mappings":"AAwCA,MAAMA,EAA+B,GAM/B,SAAUC,EAAkBC,GAC1BF,EAAWG,KAAMC,GAAMA,EAAEC,MAAQH,EAAIG,OACzCL,EAAWM,KAAKJ,GAChBF,EAAWO,KAAK,CAACC,EAAGC,KAAQD,EAAyBE,OAAS,KAAQD,EAAyBC,OAAS,KAC5G,UAMgBC,IACZ,OAAOX,CACX"}
@@ -0,0 +1,54 @@
1
+ import type { Store } from './types';
2
+ /**
3
+ * Extension registry for store plugins.
4
+ * Features register when imported; createStore applies all registered extensions.
5
+ * @internal
6
+ */
7
+ export interface ProcessDefinitionResult {
8
+ state: Record<string, unknown>;
9
+ engines?: Map<string, unknown>;
10
+ /** Async keys to init after store has setState. Each init receives (onUpdate) => engine. */
11
+ asyncInits?: Array<{
12
+ key: string;
13
+ init: (onUpdate: (state: unknown) => void) => unknown;
14
+ }>;
15
+ readOnlyKeys?: Set<string>;
16
+ /** Called when state changes. Extensions can recompute derived values via setComputed. */
17
+ onStateChanged?: (ctx: {
18
+ changedKeys: Set<string>;
19
+ getState: () => Record<string, unknown>;
20
+ setComputed: (key: string, value: unknown) => void;
21
+ store: unknown;
22
+ }) => void;
23
+ }
24
+ export interface ExtensionContext {
25
+ engines: Map<string, unknown>;
26
+ store: Store<object>;
27
+ definition: object;
28
+ }
29
+ export interface StoreExtension {
30
+ /** Unique key to avoid double registration */
31
+ key: string;
32
+ /** Process definition values before store init. Return modified state + optional metadata. */
33
+ processDefinition?: (definition: Record<string, unknown>) => ProcessDefinitionResult;
34
+ /** Add methods to the store. Called after store is created. */
35
+ extendStore?: (context: ExtensionContext) => Record<string, unknown>;
36
+ }
37
+ /**
38
+ * Register an extension. Called by feature modules on import (side-effect).
39
+ * @internal
40
+ */
41
+ export declare function registerExtension(ext: StoreExtension & {
42
+ order?: number;
43
+ }): void;
44
+ /**
45
+ * Get all registered extensions. Used by createStore.
46
+ * @internal
47
+ */
48
+ export declare function getExtensions(): readonly StoreExtension[];
49
+ /**
50
+ * Clear all extensions. For testing only.
51
+ * @internal
52
+ */
53
+ export declare function __testingOnlyClearExtensions(): void;
54
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAErC;;;;GAIG;AAEH,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,4FAA4F;IAC5F,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,OAAO,CAAA;KAAE,CAAC,CAAC;IAC3F,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,0FAA0F;IAC1F,cAAc,CAAC,EAAE,CAAC,GAAG,EAAE;QACnB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;QACzB,QAAQ,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QACnD,KAAK,EAAE,OAAO,CAAC;KAClB,KAAK,IAAI,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC7B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;CACtB;AAID,MAAM,WAAW,cAAc;IAC3B,8CAA8C;IAC9C,GAAG,EAAE,MAAM,CAAC;IACZ,8FAA8F;IAC9F,iBAAiB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,uBAAuB,CAAC;IACrF,+DAA+D;IAC/D,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACxE;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,cAAc,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAIhF;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,SAAS,cAAc,EAAE,CAEzD;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,IAAI,CAEnD"}
@@ -0,0 +1,19 @@
1
+ import type { Store, StoreState } from '../types';
2
+ import type { Signal } from './index';
3
+ /**
4
+ * Creates a Signal that subscribes to a specific key in a Storve store.
5
+ * Signals provide fine-grained reactivity by only notifying listeners when
6
+ * the specific key's value changes.
7
+ *
8
+ * @example
9
+ * const countSignal = signal(store, 'count');
10
+ */
11
+ export declare function signal<D extends object, K extends keyof StoreState<D>>(store: Store<D>, key: K): Signal<StoreState<D>[K]>;
12
+ /**
13
+ * Creates a derived read-only Signal that transforms a value from the store.
14
+ *
15
+ * @example
16
+ * const doubleSignal = signal(store, 'count', v => v * 2);
17
+ */
18
+ export declare function signal<D extends object, K extends keyof StoreState<D>, R>(store: Store<D>, key: K, transform: (value: StoreState<D>[K]) => R): Signal<R>;
19
+ //# sourceMappingURL=createSignal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createSignal.d.ts","sourceRoot":"","sources":["../../src/signals/createSignal.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,UAAU,CAAC,CAAC,CAAC,EAClE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,GAAG,EAAE,CAAC,GACP,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAE5B;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,MAAM,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EACrE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EACf,GAAG,EAAE,CAAC,EACN,SAAS,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAC1C,MAAM,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * A subscribable reference to a single key in a Storve store.
3
+ * Read-only signals (derived) throw a clear error when set() is called.
4
+ */
5
+ export interface Signal<T> {
6
+ /** Returns the current value of this signal */
7
+ get(): T;
8
+ /**
9
+ * Sets a new value. Throws if called on a derived (read-only) signal.
10
+ * Writes back to the store — the store remains the single source of truth.
11
+ */
12
+ set(value: T | ((prev: T) => T)): void;
13
+ /** Subscribe to value changes. Returns an unsubscribe function. */
14
+ subscribe(listener: (value: T) => void): () => void;
15
+ /** Internal flag — true if this is a derived read-only signal */
16
+ readonly _derived: boolean;
17
+ }
18
+ export { signal } from './createSignal';
19
+ export { useSignal } from './useSignal';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/signals/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,MAAM,CAAC,CAAC;IACrB,+CAA+C;IAC/C,GAAG,IAAI,CAAC,CAAC;IACT;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC;IACvC,mEAAmE;IACnE,SAAS,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;IACpD,iEAAiE;IACjE,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC9B;AAED,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { Signal } from './index';
2
+ /**
3
+ * React hook that subscribes to a Signal and returns its current value.
4
+ * The component re-renders ONLY when this signal's value changes.
5
+ * Unrelated store key changes are completely ignored.
6
+ *
7
+ * @example
8
+ * const count = useSignal(countSignal) // re-renders only when count changes
9
+ */
10
+ export declare function useSignal<T>(signal: Signal<T>): T;
11
+ //# sourceMappingURL=useSignal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSignal.d.ts","sourceRoot":"","sources":["../../src/signals/useSignal.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAMjD"}
@@ -0,0 +1,2 @@
1
+ "use strict";var e=require("react");exports.signal=function(e,t,r){const n=!!r;return new Proxy({get:()=>{const n=e.getState()[t];return r?r(n):n},set(r){if(n)throw new Error("Storve: cannot call set() on a derived signal. Derived signals are read-only.");const s="function"==typeof r?r(e.getState()[t]):r;e.setState({[t]:s})},subscribe(n){let s=r?r(e.getState()[t]):e.getState()[t];return e.subscribe(()=>{const a=r?r(e.getState()[t]):e.getState()[t];Object.is(s,a)||(s=a,n(a))})},_derived:n},{set:(e,t,r)=>"_derived"===t||Reflect.set(e,t,r)})},exports.useSignal=function(t){return e.useSyncExternalStore(e=>t.subscribe(e),()=>t.get(),()=>t.get())};
2
+ //# sourceMappingURL=signals.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.cjs","sources":["../src/signals/createSignal.ts","../src/signals/useSignal.ts"],"sourcesContent":[null,null],"names":["store","key","transform","isDerived","Proxy","get","value","getState","set","Error","next","setState","subscribe","listener","prev","Object","is","_derived","target","prop","Reflect","signal","useSyncExternalStore","onStoreChange"],"mappings":"4DA6BIA,EACAC,EACAC,GAEA,MAAMC,IAAcD,EAuCpB,OAAO,IAAIE,MAhCY,CACnBC,IANQ,KACR,MAAMC,EAAQN,EAAMO,WAAWN,GAC/B,OAAOC,EAAYA,EAAUI,GAASA,GAKtC,GAAAE,CAAIF,GACA,GAAIH,EACA,MAAM,IAAIM,MACN,iFAGR,MAAMC,EACe,mBAAVJ,EACAA,EAAuDN,EAAMO,WAAWN,IACzEK,EACVN,EAAMW,SAAS,CAAEV,CAACA,GAAMS,GAC5B,EACA,SAAAE,CAAUC,GACN,IAAIC,EAAOZ,EACLA,EAAUF,EAAMO,WAAWN,IAC1BD,EAAMO,WAAWN,GAExB,OAAOD,EAAMY,UAAU,KACnB,MAAMF,EAAOR,EACPA,EAAUF,EAAMO,WAAWN,IAC1BD,EAAMO,WAAWN,GAEpBc,OAAOC,GAAGF,EAAMJ,KACpBI,EAAOJ,EACPG,EAASH,KAEjB,EACAO,SAAUd,GAGmB,CAC7BK,IAAG,CAACU,EAAQC,EAAMb,IACD,aAATa,GAGGC,QAAQZ,IAAIU,EAAQC,EAAMb,IAG7C,oBCrEM,SAAuBe,GACzB,OAAOC,EAAAA,qBACFC,GAA8BF,EAAOT,UAAUW,GAChD,IAAMF,EAAOhB,MACb,IAAMgB,EAAOhB,MAErB"}
@@ -0,0 +1,2 @@
1
+ import{useSyncExternalStore as t}from"react";function e(t,e,r){const n=!!r;return new Proxy({get:()=>{const n=t.getState()[e];return r?r(n):n},set(r){if(n)throw new Error("Storve: cannot call set() on a derived signal. Derived signals are read-only.");const s="function"==typeof r?r(t.getState()[e]):r;t.setState({[e]:s})},subscribe(n){let s=r?r(t.getState()[e]):t.getState()[e];return t.subscribe(()=>{const o=r?r(t.getState()[e]):t.getState()[e];Object.is(s,o)||(s=o,n(o))})},_derived:n},{set:(t,e,r)=>"_derived"===e||Reflect.set(t,e,r)})}function r(e){return t(t=>e.subscribe(t),()=>e.get(),()=>e.get())}export{e as signal,r as useSignal};
2
+ //# sourceMappingURL=signals.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.mjs","sources":["../src/signals/createSignal.ts","../src/signals/useSignal.ts"],"sourcesContent":[null,null],"names":["signal","store","key","transform","isDerived","Proxy","get","value","getState","set","Error","next","setState","subscribe","listener","prev","Object","is","_derived","target","prop","Reflect","useSignal","useSyncExternalStore","onStoreChange"],"mappings":"sDA4BgBA,EACZC,EACAC,EACAC,GAEA,MAAMC,IAAcD,EAuCpB,OAAO,IAAIE,MAhCY,CACnBC,IANQ,KACR,MAAMC,EAAQN,EAAMO,WAAWN,GAC/B,OAAOC,EAAYA,EAAUI,GAASA,GAKtC,GAAAE,CAAIF,GACA,GAAIH,EACA,MAAM,IAAIM,MACN,iFAGR,MAAMC,EACe,mBAAVJ,EACAA,EAAuDN,EAAMO,WAAWN,IACzEK,EACVN,EAAMW,SAAS,CAAEV,CAACA,GAAMS,GAC5B,EACA,SAAAE,CAAUC,GACN,IAAIC,EAAOZ,EACLA,EAAUF,EAAMO,WAAWN,IAC1BD,EAAMO,WAAWN,GAExB,OAAOD,EAAMY,UAAU,KACnB,MAAMF,EAAOR,EACPA,EAAUF,EAAMO,WAAWN,IAC1BD,EAAMO,WAAWN,GAEpBc,OAAOC,GAAGF,EAAMJ,KACpBI,EAAOJ,EACPG,EAASH,KAEjB,EACAO,SAAUd,GAGmB,CAC7BK,IAAG,CAACU,EAAQC,EAAMb,IACD,aAATa,GAGGC,QAAQZ,IAAIU,EAAQC,EAAMb,IAG7C,CCrEM,SAAUe,EAAatB,GACzB,OAAOuB,EACFC,GAA8BxB,EAAOa,UAAUW,GAChD,IAAMxB,EAAOM,MACb,IAAMN,EAAOM,MAErB"}