@choksheak/react-utils 0.3.5 → 0.3.7

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 (54) hide show
  1. package/NoSSR.cjs +37 -0
  2. package/NoSSR.d.mts +24 -0
  3. package/NoSSR.d.ts +20 -0
  4. package/NoSSR.min.cjs +2 -0
  5. package/NoSSR.min.cjs.map +1 -0
  6. package/NoSSR.min.mjs +2 -0
  7. package/NoSSR.min.mjs.map +1 -0
  8. package/NoSSR.mjs +12 -0
  9. package/README.md +10 -1
  10. package/fetcher.cjs +3 -3
  11. package/fetcher.d.mts +5 -4
  12. package/fetcher.d.ts +4 -3
  13. package/fetcher.min.cjs +1 -1
  14. package/fetcher.min.cjs.map +1 -1
  15. package/fetcher.min.mjs +1 -1
  16. package/fetcher.min.mjs.map +1 -1
  17. package/fetcher.mjs +2 -2
  18. package/package.json +21 -3
  19. package/sharedQuery.cjs +461 -471
  20. package/sharedQuery.d.mts +64 -61
  21. package/sharedQuery.d.ts +62 -59
  22. package/sharedQuery.min.cjs +1 -1
  23. package/sharedQuery.min.cjs.map +1 -1
  24. package/sharedQuery.min.mjs +1 -1
  25. package/sharedQuery.min.mjs.map +1 -1
  26. package/sharedQuery.mjs +462 -471
  27. package/sharedState.cjs +200 -189
  28. package/sharedState.d.mts +49 -37
  29. package/sharedState.d.ts +46 -35
  30. package/sharedState.min.cjs +1 -1
  31. package/sharedState.min.cjs.map +1 -1
  32. package/sharedState.min.mjs +1 -1
  33. package/sharedState.min.mjs.map +1 -1
  34. package/sharedState.mjs +201 -189
  35. package/storage.cjs +78 -65
  36. package/storage.d.mts +39 -2
  37. package/storage.d.ts +37 -1
  38. package/storage.min.cjs +1 -1
  39. package/storage.min.cjs.map +1 -1
  40. package/storage.min.mjs +1 -1
  41. package/storage.min.mjs.map +1 -1
  42. package/storage.mjs +76 -65
  43. package/stringify.d.mts +9 -0
  44. package/stringify.d.ts +9 -0
  45. package/stringify.min.cjs.map +1 -1
  46. package/stringify.min.mjs.map +1 -1
  47. package/useDeepMemo.cjs +1 -1
  48. package/useDeepMemo.d.mts +11 -0
  49. package/useDeepMemo.d.ts +11 -0
  50. package/useDeepMemo.min.cjs +1 -1
  51. package/useDeepMemo.min.cjs.map +1 -1
  52. package/useDeepMemo.min.mjs +1 -1
  53. package/useDeepMemo.min.mjs.map +1 -1
  54. package/useDeepMemo.mjs +1 -1
package/sharedState.cjs CHANGED
@@ -20,7 +20,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/sharedState.ts
21
21
  var sharedState_exports = {};
22
22
  __export(sharedState_exports, {
23
- SharedState: () => SharedState,
24
23
  SharedStateConfig: () => SharedStateConfig,
25
24
  configureSharedState: () => configureSharedState,
26
25
  sharedState: () => sharedState,
@@ -43,70 +42,12 @@ function getStorageAdapter(options, defaultStoreExpiryMs) {
43
42
  }
44
43
  if ("persistTo" in store && typeof store.persistTo === "string" && "key" in store && typeof store.key === "string") {
45
44
  const expiryMs = store.expiryMs || defaultStoreExpiryMs;
46
- const isValid = store.isValid;
45
+ const config = { ...store, expiryMs };
47
46
  switch (store.persistTo) {
48
- case "localStorage": {
49
- const adapter = new import_localStore.LocalStore(store.key, {
50
- defaultExpiryMs: expiryMs
51
- });
52
- return {
53
- set: (key, value) => {
54
- if (IS_NOT_BROWSER) return;
55
- adapter.set(key, value);
56
- },
57
- get: (key) => {
58
- if (IS_NOT_BROWSER) return void 0;
59
- const value = adapter.get(key);
60
- if (isValid && !isValid(value)) {
61
- console.warn(
62
- `localStorage adapter: Auto-discard invalid value for ${key}: ${JSON.stringify(value)}`
63
- );
64
- adapter.delete(key);
65
- return void 0;
66
- }
67
- return value;
68
- },
69
- delete: (key) => {
70
- if (IS_NOT_BROWSER) return;
71
- adapter.delete(key);
72
- },
73
- clear: () => {
74
- if (IS_NOT_BROWSER) return;
75
- adapter.clear();
76
- }
77
- };
78
- }
79
- case "indexedDb": {
80
- const keyPrefix = store.key + ":";
81
- const isValid2 = store.isValid;
82
- return {
83
- set: async (key, value) => {
84
- if (IS_NOT_BROWSER) return;
85
- await import_kvStore.kvStore.set(keyPrefix + key, value, expiryMs);
86
- },
87
- get: async (key) => {
88
- if (IS_NOT_BROWSER) return void 0;
89
- const fullKey = keyPrefix + key;
90
- const value = await import_kvStore.kvStore.get(fullKey);
91
- if (isValid2 && !isValid2(value)) {
92
- console.warn(
93
- `indexedDb adapter: Auto-discard invalid value for ${key}: ${JSON.stringify(value)}`
94
- );
95
- await import_kvStore.kvStore.delete(fullKey);
96
- return void 0;
97
- }
98
- return value;
99
- },
100
- delete: async (key) => {
101
- if (IS_NOT_BROWSER) return;
102
- await import_kvStore.kvStore.delete(keyPrefix + key);
103
- },
104
- clear: async () => {
105
- if (IS_NOT_BROWSER) return;
106
- await import_kvStore.kvStore.clear();
107
- }
108
- };
109
- }
47
+ case "localStorage":
48
+ return localStoreAdapter(config);
49
+ case "indexedDb":
50
+ return kvStoreAdapter(config);
110
51
  default:
111
52
  store.persistTo;
112
53
  throw new Error(`Unknown store.adapter ${store.persistTo}`);
@@ -114,6 +55,73 @@ function getStorageAdapter(options, defaultStoreExpiryMs) {
114
55
  }
115
56
  return store;
116
57
  }
58
+ function localStoreAdapter({
59
+ key,
60
+ expiryMs,
61
+ isValid
62
+ }) {
63
+ const adapter = (0, import_localStore.createLocalStore)(key, { defaultExpiryMs: expiryMs });
64
+ return {
65
+ set: (key2, value) => {
66
+ if (IS_NOT_BROWSER) return;
67
+ adapter.set(key2, value);
68
+ },
69
+ get: (key2) => {
70
+ if (IS_NOT_BROWSER) return void 0;
71
+ const value = adapter.get(key2);
72
+ if (isValid && !isValid(value)) {
73
+ console.warn(
74
+ `localStorage adapter: Auto-discard invalid value for ${key2}: ${JSON.stringify(value)}`
75
+ );
76
+ adapter.delete(key2);
77
+ return void 0;
78
+ }
79
+ return value;
80
+ },
81
+ delete: (key2) => {
82
+ if (IS_NOT_BROWSER) return;
83
+ adapter.delete(key2);
84
+ },
85
+ clear: () => {
86
+ if (IS_NOT_BROWSER) return;
87
+ adapter.clear();
88
+ }
89
+ };
90
+ }
91
+ function kvStoreAdapter({
92
+ key,
93
+ expiryMs,
94
+ isValid
95
+ }) {
96
+ const keyPrefix = key + ":";
97
+ return {
98
+ set: async (key2, value) => {
99
+ if (IS_NOT_BROWSER) return;
100
+ await import_kvStore.kvStore.set(keyPrefix + key2, value, expiryMs);
101
+ },
102
+ get: async (key2) => {
103
+ if (IS_NOT_BROWSER) return void 0;
104
+ const fullKey = keyPrefix + key2;
105
+ const value = await import_kvStore.kvStore.get(fullKey);
106
+ if (isValid && !isValid(value)) {
107
+ console.warn(
108
+ `indexedDb adapter: Auto-discard invalid value for ${key2}: ${JSON.stringify(value)}`
109
+ );
110
+ await import_kvStore.kvStore.delete(fullKey);
111
+ return void 0;
112
+ }
113
+ return value;
114
+ },
115
+ delete: async (key2) => {
116
+ if (IS_NOT_BROWSER) return;
117
+ await import_kvStore.kvStore.delete(keyPrefix + key2);
118
+ },
119
+ clear: async () => {
120
+ if (IS_NOT_BROWSER) return;
121
+ await import_kvStore.kvStore.clear();
122
+ }
123
+ };
124
+ }
117
125
 
118
126
  // src/sharedState.ts
119
127
  var SharedStateConfig = {
@@ -131,41 +139,11 @@ var SharedStateConfig = {
131
139
  function configureSharedState(config) {
132
140
  Object.assign(SharedStateConfig, config);
133
141
  }
134
- var PubSubStore = class {
135
- dataByKey = /* @__PURE__ */ new Map();
136
- subscribersByKey = /* @__PURE__ */ new Map();
137
- // This could be undefined if T includes undefined, else it should never
138
- // return undefined because the user has to always specify the default value.
139
- get(key) {
140
- return this.dataByKey.get(key);
141
- }
142
- set(key, value) {
143
- const prev = this.dataByKey.get(key);
144
- if (prev === value) return;
145
- this.dataByKey.set(key, value);
146
- this.notify(key, value, prev);
147
- }
148
- delete(key) {
149
- this.dataByKey.delete(key);
150
- }
151
- setNoNotify(key, value) {
152
- this.dataByKey.set(key, value);
153
- }
154
- // Subscribe to changes of a specific key
155
- subscribe(key, subscriber) {
156
- let subscribers = this.subscribersByKey.get(key);
157
- if (!subscribers) {
158
- subscribers = /* @__PURE__ */ new Set();
159
- this.subscribersByKey.set(key, subscribers);
160
- }
161
- subscribers.add(subscriber);
162
- return () => {
163
- subscribers.delete(subscriber);
164
- if (subscribers.size === 0) this.subscribersByKey.delete(key);
165
- };
166
- }
167
- notify(key, next, prev) {
168
- const subscribers = this.subscribersByKey.get(key);
142
+ function createPubSubStore() {
143
+ const dataByKey = /* @__PURE__ */ new Map();
144
+ const subscribersByKey = /* @__PURE__ */ new Map();
145
+ function notify(key, next, prev) {
146
+ const subscribers = subscribersByKey.get(key);
169
147
  if (!subscribers) return;
170
148
  const copy = Array.from(subscribers.values());
171
149
  for (const subscriber of copy) {
@@ -176,116 +154,149 @@ var PubSubStore = class {
176
154
  }
177
155
  }
178
156
  }
179
- };
180
- var pubSubStore = new PubSubStore();
157
+ return {
158
+ // This could be undefined if T includes undefined, else it should never
159
+ // return undefined because the user has to always specify the default value.
160
+ get(key) {
161
+ return dataByKey.get(key);
162
+ },
163
+ set(key, value) {
164
+ const prev = dataByKey.get(key);
165
+ if (prev === value) return;
166
+ dataByKey.set(key, value);
167
+ notify(key, value, prev);
168
+ },
169
+ delete(key) {
170
+ dataByKey.delete(key);
171
+ },
172
+ setNoNotify(key, value) {
173
+ dataByKey.set(key, value);
174
+ },
175
+ // Subscribe to changes of a specific key
176
+ subscribe(key, subscriber) {
177
+ let subscribers = subscribersByKey.get(key);
178
+ if (!subscribers) {
179
+ subscribers = /* @__PURE__ */ new Set();
180
+ subscribersByKey.set(key, subscribers);
181
+ }
182
+ subscribers.add(subscriber);
183
+ return () => {
184
+ subscribers.delete(subscriber);
185
+ if (subscribers.size === 0) subscribersByKey.delete(key);
186
+ };
187
+ }
188
+ };
189
+ }
190
+ var pubSubStore = createPubSubStore();
181
191
  var STORAGE_KEY = "state";
182
192
  var stateKey = 0;
183
- var SharedState = class {
184
- constructor(defaultValue, options) {
185
- this.defaultValue = defaultValue;
186
- this.pubSubKey = String(stateKey++);
187
- this.storageAdapter = getStorageAdapter(
188
- options,
189
- SharedStateConfig.storeExpiryMs
190
- );
191
- this.setValueBounded = (next) => {
192
- this.setValue(next);
193
- };
194
- pubSubStore.setNoNotify(this.pubSubKey, defaultValue);
195
- const lazyLoad = options?.lazyLoad;
196
- const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
197
- if (!lazy) {
198
- void this.initDefaultValueOnce();
199
- }
200
- }
201
- pubSubKey;
202
- storageAdapter;
203
- setValueBounded;
204
- initStarted = false;
205
- initDone = false;
206
- /** `subscribe` function required by useSyncExternalStore. */
207
- subscribe(subscriber) {
208
- return pubSubStore.subscribe(this.pubSubKey, () => subscriber());
209
- }
210
- /** Returns true if there is a backing store. */
211
- hasStore() {
212
- return Boolean(this.storageAdapter);
213
- }
214
- /**
215
- * Set a value directly into the store. Does nothing if there is no
216
- * backing store.
217
- *
218
- * Warning: If you want to set the value properly, you should use
219
- * `setValue()` instead which also updates the in-memory copy.
220
- */
221
- async setInStore(value) {
222
- return await this.storageAdapter?.set(STORAGE_KEY, value);
223
- }
224
- /**
225
- * Get a value directly from the store. Returns undefined if there is no
226
- * backing store.
227
- */
228
- async getFromStore() {
229
- return await this.storageAdapter?.get(STORAGE_KEY);
230
- }
231
- /**
232
- * Get the value of the shared state.
233
- * `getSnapshot` function — must return same ref if value unchanged.
234
- * Note that this would return the default value if data init from store is
235
- * not completed yet.
236
- */
237
- getSnapshot() {
238
- return pubSubStore.get(this.pubSubKey);
239
- }
240
- /** Set the value of the shared state. */
241
- setValue(next) {
242
- if (typeof next === "function") {
243
- const prev = pubSubStore.get(this.pubSubKey);
244
- next = next(prev);
193
+ function sharedState(defaultValue, options) {
194
+ let readyResolve = () => {
195
+ };
196
+ const readyPromise = new Promise((resolve) => {
197
+ readyResolve = resolve;
198
+ });
199
+ const resolveReadyPromise = readyResolve;
200
+ const pubSubKey = String(stateKey++);
201
+ const storageAdapter = getStorageAdapter(
202
+ options,
203
+ SharedStateConfig.storeExpiryMs
204
+ );
205
+ pubSubStore.setNoNotify(pubSubKey, defaultValue);
206
+ const lazyLoad = options?.lazyLoad;
207
+ const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
208
+ const obj = {
209
+ /** Allow users to await for the completion of data init. */
210
+ readyPromise,
211
+ lazy,
212
+ initStarted: false,
213
+ initDone: false,
214
+ /** `subscribe` function required by useSyncExternalStore. */
215
+ subscribe(subscriber) {
216
+ return pubSubStore.subscribe(pubSubKey, () => subscriber());
217
+ },
218
+ /** Returns true if there is a backing store. */
219
+ hasStore() {
220
+ return Boolean(storageAdapter);
221
+ },
222
+ /**
223
+ * Set a value directly into the store. Does nothing if there is no
224
+ * backing store.
225
+ *
226
+ * Warning: If you want to set the value properly, you should use
227
+ * `setValue()` instead which also updates the in-memory copy.
228
+ */
229
+ async setInStore(value) {
230
+ return await storageAdapter?.set(STORAGE_KEY, value);
231
+ },
232
+ /**
233
+ * Get a value directly from the store. Returns undefined if there is no
234
+ * backing store.
235
+ */
236
+ async getFromStore() {
237
+ return await storageAdapter?.get(STORAGE_KEY);
238
+ },
239
+ /**
240
+ * Get the value of the shared state.
241
+ * `getSnapshot` function — must return same ref if value unchanged.
242
+ * Note that this would return the default value if data init from store is
243
+ * not completed yet.
244
+ */
245
+ getSnapshot() {
246
+ return pubSubStore.get(pubSubKey);
247
+ },
248
+ /** Set the value of the shared state. */
249
+ setValue(next) {
250
+ if (typeof next === "function") {
251
+ const prev = pubSubStore.get(pubSubKey);
252
+ next = next(prev);
253
+ }
254
+ pubSubStore.set(pubSubKey, next);
255
+ void obj.setInStore(next);
256
+ },
257
+ /**
258
+ * Remove the value of the shared state. Actually this just sets the value
259
+ * back to the given default value.
260
+ */
261
+ delete() {
262
+ pubSubStore.set(pubSubKey, defaultValue);
263
+ void storageAdapter?.set(STORAGE_KEY, defaultValue);
264
+ },
265
+ /** Initial default handling. */
266
+ async initDefaultValueOnce() {
267
+ if (obj.initDone || obj.initStarted) return;
268
+ obj.initStarted = true;
269
+ const stored = await obj.getFromStore();
270
+ const value = stored !== void 0 ? stored : defaultValue;
271
+ pubSubStore.set(pubSubKey, value);
272
+ obj.initDone = true;
273
+ resolveReadyPromise();
245
274
  }
246
- pubSubStore.set(this.pubSubKey, next);
247
- void this.setInStore(next);
248
- }
249
- /**
250
- * Remove the value of the shared state. Actually this just sets the value
251
- * back to the given default value.
252
- */
253
- delete() {
254
- pubSubStore.set(this.pubSubKey, this.defaultValue);
255
- void this.storageAdapter?.set(STORAGE_KEY, this.defaultValue);
256
- }
257
- /** Initial default handling. */
258
- async initDefaultValueOnce() {
259
- if (this.initDone || this.initStarted) return;
260
- this.initStarted = true;
261
- const stored = await this.getFromStore();
262
- const value = stored !== void 0 ? stored : this.defaultValue;
263
- pubSubStore.set(this.pubSubKey, value);
264
- this.initDone = true;
275
+ };
276
+ if (!lazy) {
277
+ void obj.initDefaultValueOnce();
265
278
  }
266
- };
267
- function sharedState(defaultValue, options) {
268
- return new SharedState(defaultValue, options);
279
+ return obj;
269
280
  }
270
281
  function useSharedState(state) {
271
- state.initDefaultValueOnce();
282
+ void state.initDefaultValueOnce();
272
283
  const value = (0, import_react.useSyncExternalStore)(
273
284
  (onStoreChange) => state.subscribe(onStoreChange),
274
285
  () => state.getSnapshot(),
275
286
  // getServerSnapshot is needed to prevent SSR dev errors in nextjs.
276
287
  () => state.getSnapshot()
277
288
  );
278
- return [value, state.setValueBounded];
289
+ return [value, state.setValue];
279
290
  }
280
291
  function useSharedStateValue(state) {
281
292
  return useSharedState(state)[0];
282
293
  }
283
294
  function useSharedStateSetter(state) {
284
- return useSharedState(state)[1];
295
+ void state.initDefaultValueOnce();
296
+ return state.setValue;
285
297
  }
286
298
  // Annotate the CommonJS export names for ESM import in node:
287
299
  0 && (module.exports = {
288
- SharedState,
289
300
  SharedStateConfig,
290
301
  configureSharedState,
291
302
  sharedState,
package/sharedState.d.mts CHANGED
@@ -1,18 +1,31 @@
1
- import { Dispatch, SetStateAction } from 'react';
1
+ import { SetStateAction, Dispatch } from 'react';
2
2
  import { StorageOptions } from './storage.mjs';
3
+ import '@choksheak/ts-utils/duration';
3
4
  import '@choksheak/ts-utils/storageAdapter';
4
5
 
5
6
  /**
6
7
  * @packageDocumentation
7
8
  *
8
9
  * The "shared state" is a React state that shares the same value across the
9
- * entire app. It is largely similar to the jotai library, but is much smaller
10
- * and much easier to work with when used for persisting in local storage or
11
- * indexed db, with an automatic expiration for persisted values.
10
+ * entire app. Users declare a shared state constant that can be reused across
11
+ * multiple components with the same underlying value.
12
12
  *
13
- * This library aims to be the shortest, simplest, easiest to use, and most
14
- * efficient implementation of shared global React states with seamless support
15
- * for client persistence.
13
+ * Shared states provide persistence to local storage and/or indexed DB out of
14
+ * the box, by using "@choksheak/ts-utils". Note that no matter if the shared
15
+ * state uses persistence or not, it will always maintain a copy of the state
16
+ * in memory. Persisted values can be configured with an automatic expiration
17
+ * duration.
18
+ *
19
+ * This module is largely similar to the open source "jotai" npm library. You
20
+ * can use shared states to replace "jotai" in your code, and optionally make
21
+ * use of the persistence mechanism. A quick migration guide from jotai is:
22
+ *
23
+ * ```
24
+ * atom() --> sharedState()
25
+ * useAtom() --> useSharedState()
26
+ * useAtomValue() --> useSharedStateValue()
27
+ * useSetAtom() --> useSharedStateSetter()
28
+ * ```
16
29
  *
17
30
  * Example:
18
31
  * ```
@@ -22,7 +35,9 @@ import '@choksheak/ts-utils/storageAdapter';
22
35
  * // The first argument is the default value, which is required.
23
36
  * // The second argument is an options object, and is optional (defaults
24
37
  * // to storing in memory only without any persistence).
25
- * const usersState = sharedState([], { indexedDbKey: "users" });
38
+ * const usersState = sharedState(
39
+ * [], { store: { persistTo: "indexedDb", key: "users" }}
40
+ * );
26
41
  *
27
42
  * export const UsersComponent: React.FC = () => {
28
43
  * // Get both the value and the setter.
@@ -68,19 +83,24 @@ declare function configureSharedState(config: Partial<SharedStateConfig>): void;
68
83
  type SharedStateOptions<T> = {
69
84
  lazyLoad?: boolean;
70
85
  } & StorageOptions<T>;
71
- /** Please use sharedState() instead. */
72
- declare class SharedState<T> {
73
- private readonly defaultValue;
74
- private readonly pubSubKey;
75
- private readonly storageAdapter;
76
- readonly setValueBounded: Dispatch<SetStateAction<T>>;
77
- initStarted: boolean;
78
- initDone: boolean;
79
- constructor(defaultValue: T, options?: SharedStateOptions<T>);
86
+ /**
87
+ * Create a new shared state object. Put this code at the top level scope:
88
+ *
89
+ * Example:
90
+ * ```
91
+ * const counterState = sharedState<number>(0);
92
+ * ```
93
+ */
94
+ declare function sharedState<T>(defaultValue: T, options?: SharedStateOptions<T>): {
95
+ /** Allow users to await for the completion of data init. */
96
+ readonly readyPromise: Promise<void>;
97
+ readonly lazy: boolean;
98
+ readonly initStarted: false;
99
+ readonly initDone: false;
80
100
  /** `subscribe` function required by useSyncExternalStore. */
81
- subscribe(subscriber: () => void): () => void;
101
+ readonly subscribe: (subscriber: () => void) => () => void;
82
102
  /** Returns true if there is a backing store. */
83
- hasStore(): boolean;
103
+ readonly hasStore: () => boolean;
84
104
  /**
85
105
  * Set a value directly into the store. Does nothing if there is no
86
106
  * backing store.
@@ -88,38 +108,30 @@ declare class SharedState<T> {
88
108
  * Warning: If you want to set the value properly, you should use
89
109
  * `setValue()` instead which also updates the in-memory copy.
90
110
  */
91
- setInStore(value: T): Promise<void>;
111
+ readonly setInStore: (value: T) => Promise<void>;
92
112
  /**
93
113
  * Get a value directly from the store. Returns undefined if there is no
94
114
  * backing store.
95
115
  */
96
- getFromStore(): Promise<T | undefined>;
116
+ readonly getFromStore: () => Promise<T | undefined>;
97
117
  /**
98
118
  * Get the value of the shared state.
99
119
  * `getSnapshot` function — must return same ref if value unchanged.
100
120
  * Note that this would return the default value if data init from store is
101
121
  * not completed yet.
102
122
  */
103
- getSnapshot(): T;
123
+ readonly getSnapshot: () => T;
104
124
  /** Set the value of the shared state. */
105
- setValue(next: SetStateAction<T>): void;
125
+ readonly setValue: (next: SetStateAction<T>) => void;
106
126
  /**
107
127
  * Remove the value of the shared state. Actually this just sets the value
108
128
  * back to the given default value.
109
129
  */
110
- delete(): void;
130
+ readonly delete: () => void;
111
131
  /** Initial default handling. */
112
- initDefaultValueOnce(): Promise<void>;
113
- }
114
- /**
115
- * Create a new shared state object. Put this code at the top level scope:
116
- *
117
- * Example:
118
- * ```
119
- * const counterState = sharedState<number>(0);
120
- * ```
121
- */
122
- declare function sharedState<T>(defaultValue: T, options?: SharedStateOptions<T>): SharedState<T>;
132
+ readonly initDefaultValueOnce: () => Promise<void>;
133
+ };
134
+ type SharedState<T> = ReturnType<typeof sharedState<T>>;
123
135
  /**
124
136
  * React hook for subscribing to a key in the global store.
125
137
  *
@@ -146,6 +158,6 @@ declare function useSharedStateValue<T>(state: SharedState<T>): T;
146
158
  * const setCounter = useSharedStateSetter(counterState);
147
159
  * ```
148
160
  */
149
- declare function useSharedStateSetter<T>(state: SharedState<T>): Dispatch<SetStateAction<T>>;
161
+ declare function useSharedStateSetter<T>(state: SharedState<T>): (next: SetStateAction<T>) => void;
150
162
 
151
- export { SharedState, SharedStateConfig, type SharedStateOptions, configureSharedState, sharedState, useSharedState, useSharedStateSetter, useSharedStateValue };
163
+ export { type SharedState, SharedStateConfig, type SharedStateOptions, configureSharedState, sharedState, useSharedState, useSharedStateSetter, useSharedStateValue };