@choksheak/react-utils 0.1.5 → 0.1.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 (58) hide show
  1. package/docs/assets/navigation.js +1 -1
  2. package/docs/assets/search.js +1 -1
  3. package/docs/classes/sharedQuery.SharedQuery.html +15 -0
  4. package/docs/classes/sharedState.SharedState.html +8 -0
  5. package/docs/classes/sharedState.SharedStateConfig.html +7 -6
  6. package/docs/classes/utils_storage.InMemoryStorageAdapter.html +9 -0
  7. package/docs/classes/utils_storage.IndexedDbAdapter.html +9 -0
  8. package/docs/classes/utils_storage.LocalStorageAdapter.html +9 -0
  9. package/docs/functions/sharedQuery.sharedQuery.html +5 -0
  10. package/docs/functions/sharedQuery.useQuery.html +4 -0
  11. package/docs/functions/sharedState.sharedState.html +2 -2
  12. package/docs/functions/sharedState.useSharedState.html +2 -2
  13. package/docs/functions/sharedState.useSharedStateSetter.html +2 -2
  14. package/docs/functions/sharedState.useSharedStateValue.html +2 -2
  15. package/docs/functions/utils_storage.getStorageAdapter.html +1 -0
  16. package/docs/functions/utils_stringify.stringifyDeterministicForKeys.html +7 -0
  17. package/docs/modules/sharedQuery.html +1 -0
  18. package/docs/modules/sharedState.html +1 -1
  19. package/docs/modules/utils_storage.html +1 -0
  20. package/docs/modules/utils_stringify.html +1 -0
  21. package/docs/modules.html +1 -1
  22. package/docs/types/sharedQuery.FetchFn.html +1 -0
  23. package/docs/types/sharedQuery.FetchedData.html +3 -0
  24. package/docs/types/sharedQuery.QueryStateValue.html +4 -0
  25. package/docs/types/sharedQuery.SharedQueryOptions.html +1 -0
  26. package/docs/types/sharedQuery.SharedQueryState.html +3 -0
  27. package/docs/types/sharedState.SharedStateOptions.html +1 -0
  28. package/docs/types/utils_storage.StorageAdapter.html +5 -0
  29. package/docs/types/utils_storage.StorageOptions.html +5 -0
  30. package/docs/variables/fetcher.fetcher.html +1 -1
  31. package/docs/variables/fetcher.fetcherWithRetries.html +1 -1
  32. package/package.json +9 -6
  33. package/sharedQuery.d.mts +61 -0
  34. package/sharedQuery.d.ts +58 -0
  35. package/sharedQuery.js +471 -0
  36. package/sharedQuery.mjs +444 -0
  37. package/sharedState.d.mts +22 -16
  38. package/sharedState.d.ts +20 -15
  39. package/sharedState.js +157 -85
  40. package/sharedState.mjs +156 -85
  41. package/src/sharedQuery.ts +303 -0
  42. package/src/sharedState.ts +75 -137
  43. package/src/utils/storage.ts +197 -0
  44. package/src/utils/stringify.test.ts +38 -0
  45. package/src/utils/stringify.ts +49 -0
  46. package/utils/storage.d.mts +46 -0
  47. package/utils/storage.d.ts +44 -0
  48. package/utils/storage.js +162 -0
  49. package/utils/storage.mjs +134 -0
  50. package/utils/stringify.d.mts +12 -0
  51. package/utils/stringify.d.ts +10 -0
  52. package/utils/stringify.js +58 -0
  53. package/utils/stringify.mjs +33 -0
  54. package/utils/stringify.test.d.mts +2 -0
  55. package/utils/stringify.test.d.ts +2 -0
  56. package/utils/stringify.test.js +64 -0
  57. package/utils/stringify.test.mjs +81 -0
  58. package/docs/types/sharedState.SharedState.html +0 -6
package/sharedState.js CHANGED
@@ -20,6 +20,7 @@ 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,
23
24
  SharedStateConfig: () => SharedStateConfig,
24
25
  sharedState: () => sharedState,
25
26
  useSharedState: () => useSharedState,
@@ -27,16 +28,119 @@ __export(sharedState_exports, {
27
28
  useSharedStateValue: () => useSharedStateValue
28
29
  });
29
30
  module.exports = __toCommonJS(sharedState_exports);
30
- var import_kvStore = require("@choksheak/ts-utils/kvStore");
31
+ var import_kvStore2 = require("@choksheak/ts-utils/kvStore");
31
32
  var import_timeConstants = require("@choksheak/ts-utils/timeConstants");
32
33
  var import_react = require("react");
34
+
35
+ // src/utils/storage.ts
36
+ var import_kvStore = require("@choksheak/ts-utils/kvStore");
37
+ function getStorageAdapter(options, defaultStoreExpiryMs) {
38
+ const { localStorageKey, indexedDbKey, storeExpiryMs, store } = options ?? {};
39
+ if (store) {
40
+ return store;
41
+ }
42
+ const expiryMs = storeExpiryMs || defaultStoreExpiryMs;
43
+ if (localStorageKey) {
44
+ return new LocalStorageAdapter(localStorageKey, expiryMs);
45
+ }
46
+ if (indexedDbKey) {
47
+ return new IndexedDbAdapter(indexedDbKey, expiryMs);
48
+ }
49
+ return null;
50
+ }
51
+ var LocalStorageAdapter = class {
52
+ constructor(keyPrefix, expiryMs) {
53
+ this.keyPrefix = keyPrefix;
54
+ this.expiryMs = expiryMs;
55
+ }
56
+ save(key, value) {
57
+ if (typeof window === "undefined") return;
58
+ const fullKey = this.keyPrefix + ":" + key;
59
+ window.localStorage.setItem(
60
+ fullKey,
61
+ JSON.stringify({
62
+ value,
63
+ expiresAt: this.expiryMs ? Date.now() + this.expiryMs : 0
64
+ })
65
+ );
66
+ }
67
+ load(key) {
68
+ if (typeof window === "undefined") return void 0;
69
+ const fullKey = this.keyPrefix + ":" + key;
70
+ const raw = window.localStorage.getItem(fullKey);
71
+ if (!raw) return void 0;
72
+ try {
73
+ const box = JSON.parse(raw);
74
+ if (!box || box.expiresAt && Date.now() >= box.expiresAt) {
75
+ window.localStorage.removeItem(fullKey);
76
+ return void 0;
77
+ }
78
+ return box.value;
79
+ } catch {
80
+ window.localStorage.removeItem(fullKey);
81
+ return void 0;
82
+ }
83
+ }
84
+ delete(key) {
85
+ if (typeof window === "undefined") return;
86
+ const fullKey = this.keyPrefix + ":" + key;
87
+ window.localStorage.removeItem(fullKey);
88
+ }
89
+ clear() {
90
+ if (typeof window === "undefined") return;
91
+ for (const key of Object.keys(window.localStorage)) {
92
+ if (key.startsWith(this.keyPrefix)) {
93
+ window.localStorage.removeItem(key);
94
+ }
95
+ }
96
+ }
97
+ };
98
+ var IndexedDbAdapter = class {
99
+ constructor(keyPrefix, expiryMs) {
100
+ this.keyPrefix = keyPrefix;
101
+ this.expiryMs = expiryMs;
102
+ }
103
+ async save(key, value) {
104
+ if (typeof window === "undefined") return;
105
+ const fullKey = this.keyPrefix + ":" + key;
106
+ await import_kvStore.kvStore.set(fullKey, JSON.stringify(value), this.expiryMs);
107
+ }
108
+ async load(key) {
109
+ if (typeof window === "undefined") return void 0;
110
+ const fullKey = this.keyPrefix + ":" + key;
111
+ const raw = await import_kvStore.kvStore.get(fullKey);
112
+ if (raw === void 0) return void 0;
113
+ try {
114
+ return JSON.parse(raw);
115
+ } catch {
116
+ await import_kvStore.kvStore.delete(fullKey);
117
+ return void 0;
118
+ }
119
+ }
120
+ async delete(key) {
121
+ if (typeof window === "undefined") return;
122
+ const fullKey = this.keyPrefix + ":" + key;
123
+ await import_kvStore.kvStore.delete(fullKey);
124
+ }
125
+ async clear() {
126
+ if (typeof window === "undefined") return;
127
+ await import_kvStore.kvStore.forEach(async (k) => {
128
+ if (k.startsWith(this.keyPrefix)) {
129
+ await import_kvStore.kvStore.delete(k);
130
+ }
131
+ });
132
+ }
133
+ };
134
+
135
+ // src/sharedState.ts
33
136
  var SharedStateConfig = class {
34
137
  /**
35
- * Default duration for persistence expiration in milliseconds.
138
+ * Default duration for storage expiration in milliseconds. Initial value
139
+ * is 30 days, but can be changed to anything.
36
140
  */
37
- static defaultPersistExpiryMs = import_timeConstants.MS_PER_DAY;
141
+ static storeExpiryMs = import_timeConstants.MS_PER_DAY * 30;
38
142
  /**
39
- * True to load from persistence only on mount, false (default) to load in
143
+ * True to load from storage only on mount, false (default) to load in
40
144
  * the top level scope when the shared state is defined.
41
145
  */
42
146
  static lazyLoad = false;
@@ -55,6 +159,9 @@ var PubSubStore = class {
55
159
  this.dataByKey.set(key, value);
56
160
  this.notify(key, value, prev);
57
161
  }
162
+ delete(key) {
163
+ this.dataByKey.delete(key);
164
+ }
58
165
  setNoNotify(key, value) {
59
166
  this.dataByKey.set(key, value);
60
167
  }
@@ -84,51 +191,58 @@ var PubSubStore = class {
84
191
  }
85
192
  }
86
193
  };
87
- var store = new PubSubStore();
194
+ var pubSubStore = new PubSubStore();
195
+ var STORAGE_KEY = "state";
88
196
  var stateKey = 0;
89
- function sharedState(defaultValue, options) {
90
- const { localStorageKey, indexedDbKey, persistExpiryMs, lazyLoad } = options ?? {};
91
- const key = String(stateKey++);
92
- let persistenceAdapter;
93
- const expiryMs = persistExpiryMs ?? SharedStateConfig.defaultPersistExpiryMs;
94
- if (localStorageKey) {
95
- persistenceAdapter = new LocalStorageAdapter(localStorageKey, expiryMs);
96
- } else if (indexedDbKey) {
97
- persistenceAdapter = new IndexedDbAdapter(indexedDbKey, expiryMs);
197
+ var SharedState = class {
198
+ constructor(defaultValue, options) {
199
+ this.defaultValue = defaultValue;
200
+ this.pubSubKey = String(stateKey++);
201
+ this.storageAdapter = getStorageAdapter(options, import_kvStore2.DEFAULT_EXPIRY_DELTA_MS);
202
+ pubSubStore.setNoNotify(this.pubSubKey, defaultValue);
203
+ const lazyLoad = options?.lazyLoad;
204
+ const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
205
+ if (!lazy) {
206
+ void this.initDefaultValueOnce();
207
+ }
98
208
  }
99
- function subscribe(subscriber) {
100
- return store.subscribe(key, () => subscriber());
209
+ pubSubKey;
210
+ storageAdapter;
211
+ initDone = false;
212
+ // `subscribe` function required by useSyncExternalStore
213
+ subscribe(subscriber) {
214
+ return pubSubStore.subscribe(this.pubSubKey, () => subscriber());
101
215
  }
102
- function getSnapshot() {
103
- return store.get(key);
216
+ // Get the value of the shared state.
217
+ // `getSnapshot` function — must return same ref if value unchanged
218
+ getSnapshot() {
219
+ return pubSubStore.get(this.pubSubKey);
104
220
  }
105
- function setValue(next) {
221
+ // Set the value of the shared state.
222
+ setValue(next) {
106
223
  if (typeof next === "function") {
107
- const prev = store.get(key);
224
+ const prev = pubSubStore.get(this.pubSubKey);
108
225
  next = next(prev);
109
226
  }
110
- store.set(key, next);
111
- void persistenceAdapter?.save?.(next);
112
- }
113
- store.setNoNotify(key, defaultValue);
114
- const state = {
115
- subscribe,
116
- getSnapshot,
117
- // initial default handling
118
- initDefaultValueOnce: async () => {
119
- if (state.initDone) return;
120
- state.initDone = true;
121
- const v = await persistenceAdapter?.load?.();
122
- store.set(key, v !== void 0 ? v : defaultValue);
123
- },
124
- initDone: false,
125
- setValue
126
- };
127
- const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
128
- if (!lazy) {
129
- void state.initDefaultValueOnce();
130
- }
131
- return state;
227
+ pubSubStore.set(this.pubSubKey, next);
228
+ void this.storageAdapter?.save(STORAGE_KEY, next);
229
+ }
230
+ // Remove the value of the shared state. Actually this just sets the value
231
+ // back to the given default value.
232
+ delete() {
233
+ pubSubStore.set(this.pubSubKey, this.defaultValue);
234
+ void this.storageAdapter?.save(STORAGE_KEY, this.defaultValue);
235
+ }
236
+ // Initial default handling
237
+ async initDefaultValueOnce() {
238
+ if (this.initDone) return;
239
+ this.initDone = true;
240
+ const v = await this.storageAdapter?.load(STORAGE_KEY);
241
+ pubSubStore.set(this.pubSubKey, v !== void 0 ? v : this.defaultValue);
242
+ }
243
+ };
244
+ function sharedState(defaultValue, options) {
245
+ return new SharedState(defaultValue, options);
132
246
  }
133
247
  function useSharedState(state) {
134
248
  state.initDefaultValueOnce();
@@ -146,51 +260,9 @@ function useSharedStateValue(state) {
146
260
  function useSharedStateSetter(state) {
147
261
  return useSharedState(state)[1];
148
262
  }
149
- var LocalStorageAdapter = class {
150
- constructor(key, expiryMs) {
151
- this.key = key;
152
- this.expiryMs = expiryMs;
153
- }
154
- save(value) {
155
- if (typeof window === "undefined") return;
156
- window.localStorage.setItem(
157
- this.key,
158
- JSON.stringify({
159
- value,
160
- expiresAt: Date.now() + this.expiryMs
161
- })
162
- );
163
- }
164
- load() {
165
- if (typeof window === "undefined") return void 0;
166
- const raw = window.localStorage.getItem(this.key);
167
- if (!raw) return void 0;
168
- const box = JSON.parse(raw);
169
- if (!box || !box?.expiresAt || Date.now() >= box.expiresAt) {
170
- window.localStorage.removeItem(this.key);
171
- return void 0;
172
- }
173
- return box.value;
174
- }
175
- };
176
- var IndexedDbAdapter = class {
177
- constructor(key, expiryMs) {
178
- this.key = key;
179
- this.expiryMs = expiryMs;
180
- }
181
- async save(value) {
182
- if (typeof window === "undefined") return;
183
- await import_kvStore.kvStore.set(this.key, JSON.stringify(value), this.expiryMs);
184
- }
185
- async load() {
186
- if (typeof window === "undefined") return void 0;
187
- const raw = await import_kvStore.kvStore.get(this.key);
188
- if (raw === void 0) return void 0;
189
- return JSON.parse(raw);
190
- }
191
- };
192
263
  // Annotate the CommonJS export names for ESM import in node:
193
264
  0 && (module.exports = {
265
+ SharedState,
194
266
  SharedStateConfig,
195
267
  sharedState,
196
268
  useSharedState,
package/sharedState.mjs CHANGED
@@ -1,14 +1,117 @@
1
1
  // src/sharedState.ts
2
- import { kvStore } from "@choksheak/ts-utils/kvStore";
2
+ import { DEFAULT_EXPIRY_DELTA_MS } from "@choksheak/ts-utils/kvStore";
3
3
  import { MS_PER_DAY } from "@choksheak/ts-utils/timeConstants";
4
4
  import { useSyncExternalStore } from "react";
5
+
6
+ // src/utils/storage.ts
7
+ import { kvStore } from "@choksheak/ts-utils/kvStore";
8
+ function getStorageAdapter(options, defaultStoreExpiryMs) {
9
+ const { localStorageKey, indexedDbKey, storeExpiryMs, store } = options ?? {};
10
+ if (store) {
11
+ return store;
12
+ }
13
+ const expiryMs = storeExpiryMs || defaultStoreExpiryMs;
14
+ if (localStorageKey) {
15
+ return new LocalStorageAdapter(localStorageKey, expiryMs);
16
+ }
17
+ if (indexedDbKey) {
18
+ return new IndexedDbAdapter(indexedDbKey, expiryMs);
19
+ }
20
+ return null;
21
+ }
22
+ var LocalStorageAdapter = class {
23
+ constructor(keyPrefix, expiryMs) {
24
+ this.keyPrefix = keyPrefix;
25
+ this.expiryMs = expiryMs;
26
+ }
27
+ save(key, value) {
28
+ if (typeof window === "undefined") return;
29
+ const fullKey = this.keyPrefix + ":" + key;
30
+ window.localStorage.setItem(
31
+ fullKey,
32
+ JSON.stringify({
33
+ value,
34
+ expiresAt: this.expiryMs ? Date.now() + this.expiryMs : 0
35
+ })
36
+ );
37
+ }
38
+ load(key) {
39
+ if (typeof window === "undefined") return void 0;
40
+ const fullKey = this.keyPrefix + ":" + key;
41
+ const raw = window.localStorage.getItem(fullKey);
42
+ if (!raw) return void 0;
43
+ try {
44
+ const box = JSON.parse(raw);
45
+ if (!box || box.expiresAt && Date.now() >= box.expiresAt) {
46
+ window.localStorage.removeItem(fullKey);
47
+ return void 0;
48
+ }
49
+ return box.value;
50
+ } catch {
51
+ window.localStorage.removeItem(fullKey);
52
+ return void 0;
53
+ }
54
+ }
55
+ delete(key) {
56
+ if (typeof window === "undefined") return;
57
+ const fullKey = this.keyPrefix + ":" + key;
58
+ window.localStorage.removeItem(fullKey);
59
+ }
60
+ clear() {
61
+ if (typeof window === "undefined") return;
62
+ for (const key of Object.keys(window.localStorage)) {
63
+ if (key.startsWith(this.keyPrefix)) {
64
+ window.localStorage.removeItem(key);
65
+ }
66
+ }
67
+ }
68
+ };
69
+ var IndexedDbAdapter = class {
70
+ constructor(keyPrefix, expiryMs) {
71
+ this.keyPrefix = keyPrefix;
72
+ this.expiryMs = expiryMs;
73
+ }
74
+ async save(key, value) {
75
+ if (typeof window === "undefined") return;
76
+ const fullKey = this.keyPrefix + ":" + key;
77
+ await kvStore.set(fullKey, JSON.stringify(value), this.expiryMs);
78
+ }
79
+ async load(key) {
80
+ if (typeof window === "undefined") return void 0;
81
+ const fullKey = this.keyPrefix + ":" + key;
82
+ const raw = await kvStore.get(fullKey);
83
+ if (raw === void 0) return void 0;
84
+ try {
85
+ return JSON.parse(raw);
86
+ } catch {
87
+ await kvStore.delete(fullKey);
88
+ return void 0;
89
+ }
90
+ }
91
+ async delete(key) {
92
+ if (typeof window === "undefined") return;
93
+ const fullKey = this.keyPrefix + ":" + key;
94
+ await kvStore.delete(fullKey);
95
+ }
96
+ async clear() {
97
+ if (typeof window === "undefined") return;
98
+ await kvStore.forEach(async (k) => {
99
+ if (k.startsWith(this.keyPrefix)) {
100
+ await kvStore.delete(k);
101
+ }
102
+ });
103
+ }
104
+ };
105
+
106
+ // src/sharedState.ts
5
107
  var SharedStateConfig = class {
6
108
  /**
7
- * Default duration for persistence expiration in milliseconds.
109
+ * Default duration for storage expiration in milliseconds. Initial value
110
+ * is 30 days, but can be changed to anything.
8
111
  */
9
- static defaultPersistExpiryMs = MS_PER_DAY;
112
+ static storeExpiryMs = MS_PER_DAY * 30;
10
113
  /**
11
- * True to load from persistence only on mount, false (default) to load in
114
+ * True to load from storage only on mount, false (default) to load in
12
115
  * the top level scope when the shared state is defined.
13
116
  */
14
117
  static lazyLoad = false;
@@ -27,6 +130,9 @@ var PubSubStore = class {
27
130
  this.dataByKey.set(key, value);
28
131
  this.notify(key, value, prev);
29
132
  }
133
+ delete(key) {
134
+ this.dataByKey.delete(key);
135
+ }
30
136
  setNoNotify(key, value) {
31
137
  this.dataByKey.set(key, value);
32
138
  }
@@ -56,51 +162,58 @@ var PubSubStore = class {
56
162
  }
57
163
  }
58
164
  };
59
- var store = new PubSubStore();
165
+ var pubSubStore = new PubSubStore();
166
+ var STORAGE_KEY = "state";
60
167
  var stateKey = 0;
61
- function sharedState(defaultValue, options) {
62
- const { localStorageKey, indexedDbKey, persistExpiryMs, lazyLoad } = options ?? {};
63
- const key = String(stateKey++);
64
- let persistenceAdapter;
65
- const expiryMs = persistExpiryMs ?? SharedStateConfig.defaultPersistExpiryMs;
66
- if (localStorageKey) {
67
- persistenceAdapter = new LocalStorageAdapter(localStorageKey, expiryMs);
68
- } else if (indexedDbKey) {
69
- persistenceAdapter = new IndexedDbAdapter(indexedDbKey, expiryMs);
168
+ var SharedState = class {
169
+ constructor(defaultValue, options) {
170
+ this.defaultValue = defaultValue;
171
+ this.pubSubKey = String(stateKey++);
172
+ this.storageAdapter = getStorageAdapter(options, DEFAULT_EXPIRY_DELTA_MS);
173
+ pubSubStore.setNoNotify(this.pubSubKey, defaultValue);
174
+ const lazyLoad = options?.lazyLoad;
175
+ const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
176
+ if (!lazy) {
177
+ void this.initDefaultValueOnce();
178
+ }
70
179
  }
71
- function subscribe(subscriber) {
72
- return store.subscribe(key, () => subscriber());
180
+ pubSubKey;
181
+ storageAdapter;
182
+ initDone = false;
183
+ // `subscribe` function required by useSyncExternalStore
184
+ subscribe(subscriber) {
185
+ return pubSubStore.subscribe(this.pubSubKey, () => subscriber());
73
186
  }
74
- function getSnapshot() {
75
- return store.get(key);
187
+ // Get the value of the shared state.
188
+ // `getSnapshot` function — must return same ref if value unchanged
189
+ getSnapshot() {
190
+ return pubSubStore.get(this.pubSubKey);
76
191
  }
77
- function setValue(next) {
192
+ // Set the value of the shared state.
193
+ setValue(next) {
78
194
  if (typeof next === "function") {
79
- const prev = store.get(key);
195
+ const prev = pubSubStore.get(this.pubSubKey);
80
196
  next = next(prev);
81
197
  }
82
- store.set(key, next);
83
- void persistenceAdapter?.save?.(next);
84
- }
85
- store.setNoNotify(key, defaultValue);
86
- const state = {
87
- subscribe,
88
- getSnapshot,
89
- // initial default handling
90
- initDefaultValueOnce: async () => {
91
- if (state.initDone) return;
92
- state.initDone = true;
93
- const v = await persistenceAdapter?.load?.();
94
- store.set(key, v !== void 0 ? v : defaultValue);
95
- },
96
- initDone: false,
97
- setValue
98
- };
99
- const lazy = lazyLoad !== void 0 ? lazyLoad : SharedStateConfig.lazyLoad;
100
- if (!lazy) {
101
- void state.initDefaultValueOnce();
102
- }
103
- return state;
198
+ pubSubStore.set(this.pubSubKey, next);
199
+ void this.storageAdapter?.save(STORAGE_KEY, next);
200
+ }
201
+ // Remove the value of the shared state. Actually this just sets the value
202
+ // back to the given default value.
203
+ delete() {
204
+ pubSubStore.set(this.pubSubKey, this.defaultValue);
205
+ void this.storageAdapter?.save(STORAGE_KEY, this.defaultValue);
206
+ }
207
+ // Initial default handling
208
+ async initDefaultValueOnce() {
209
+ if (this.initDone) return;
210
+ this.initDone = true;
211
+ const v = await this.storageAdapter?.load(STORAGE_KEY);
212
+ pubSubStore.set(this.pubSubKey, v !== void 0 ? v : this.defaultValue);
213
+ }
214
+ };
215
+ function sharedState(defaultValue, options) {
216
+ return new SharedState(defaultValue, options);
104
217
  }
105
218
  function useSharedState(state) {
106
219
  state.initDefaultValueOnce();
@@ -118,50 +231,8 @@ function useSharedStateValue(state) {
118
231
  function useSharedStateSetter(state) {
119
232
  return useSharedState(state)[1];
120
233
  }
121
- var LocalStorageAdapter = class {
122
- constructor(key, expiryMs) {
123
- this.key = key;
124
- this.expiryMs = expiryMs;
125
- }
126
- save(value) {
127
- if (typeof window === "undefined") return;
128
- window.localStorage.setItem(
129
- this.key,
130
- JSON.stringify({
131
- value,
132
- expiresAt: Date.now() + this.expiryMs
133
- })
134
- );
135
- }
136
- load() {
137
- if (typeof window === "undefined") return void 0;
138
- const raw = window.localStorage.getItem(this.key);
139
- if (!raw) return void 0;
140
- const box = JSON.parse(raw);
141
- if (!box || !box?.expiresAt || Date.now() >= box.expiresAt) {
142
- window.localStorage.removeItem(this.key);
143
- return void 0;
144
- }
145
- return box.value;
146
- }
147
- };
148
- var IndexedDbAdapter = class {
149
- constructor(key, expiryMs) {
150
- this.key = key;
151
- this.expiryMs = expiryMs;
152
- }
153
- async save(value) {
154
- if (typeof window === "undefined") return;
155
- await kvStore.set(this.key, JSON.stringify(value), this.expiryMs);
156
- }
157
- async load() {
158
- if (typeof window === "undefined") return void 0;
159
- const raw = await kvStore.get(this.key);
160
- if (raw === void 0) return void 0;
161
- return JSON.parse(raw);
162
- }
163
- };
164
234
  export {
235
+ SharedState,
165
236
  SharedStateConfig,
166
237
  sharedState,
167
238
  useSharedState,