@lunarhue/store 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -10
- package/dist/chunk-GHGDIRN2.js +187 -0
- package/dist/chunk-GHGDIRN2.js.map +1 -0
- package/dist/chunk-TCEPLIBH.js +141 -0
- package/dist/chunk-TCEPLIBH.js.map +1 -0
- package/dist/core/index.d.ts +12 -2
- package/dist/core/index.js +8 -3
- package/dist/core/index.js.map +1 -1
- package/dist/plugins/actions/index.d.ts +45 -1
- package/dist/plugins/actions/index.js.map +1 -1
- package/dist/plugins/persist/index.d.ts +138 -41
- package/dist/plugins/persist/index.js +149 -218
- package/dist/plugins/persist/index.js.map +1 -1
- package/dist/react/index.d.ts +75 -4
- package/dist/react/index.js +1 -1
- package/dist/types-CugArdrs.d.ts +107 -0
- package/package.json +20 -9
- package/dist/chunk-ALACXQX3.js +0 -103
- package/dist/chunk-ALACXQX3.js.map +0 -1
- package/dist/chunk-MIBJNMOV.js +0 -45
- package/dist/chunk-MIBJNMOV.js.map +0 -1
- package/dist/types-BfzW2j9T.d.ts +0 -20
|
@@ -1,47 +1,36 @@
|
|
|
1
|
-
import { createStoreInstance } from '../../chunk-
|
|
2
|
-
import { StoreProvider } from '../../chunk-
|
|
1
|
+
import { createStoreInstance } from '../../chunk-TCEPLIBH.js';
|
|
2
|
+
import { StoreProvider } from '../../chunk-GHGDIRN2.js';
|
|
3
3
|
import { getStoreBuilder } from '../../chunk-PCSRXZL4.js';
|
|
4
|
-
import { useContext, createContext,
|
|
5
|
-
import { jsx
|
|
4
|
+
import { useContext, createContext, useEffectEvent, useEffect } from 'react';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
6
|
|
|
7
7
|
// src/plugins/persist/controller.ts
|
|
8
8
|
var DEFAULT_META = {
|
|
9
|
-
isHydrated: false,
|
|
10
9
|
pending: false,
|
|
11
10
|
persisting: false,
|
|
12
11
|
lastPersistedAt: null,
|
|
13
12
|
error: null
|
|
14
13
|
};
|
|
15
|
-
var nextGeneratedPersistKeyId = 0;
|
|
16
|
-
function getInitialMeta(options) {
|
|
17
|
-
return {
|
|
18
|
-
...DEFAULT_META,
|
|
19
|
-
isHydrated: options?.hydratedOnCreate ?? false
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
14
|
function createPersistController(store, pluginOptions) {
|
|
23
|
-
const meta = createStoreInstance(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
15
|
+
const meta = createStoreInstance({
|
|
16
|
+
initialState: { ...DEFAULT_META },
|
|
17
|
+
readyOnCreate: true
|
|
18
|
+
}).store;
|
|
19
|
+
const state = {
|
|
20
|
+
connected: false,
|
|
21
|
+
runtimeOptions: null,
|
|
22
|
+
subscription: null,
|
|
23
|
+
timer: null,
|
|
24
|
+
pendingTransition: null,
|
|
25
|
+
lastObservedState: store.lifecycle.meta.get().status === "ready" ? store.get() : void 0,
|
|
26
|
+
flushPromise: null
|
|
27
|
+
};
|
|
36
28
|
const clearTimer = () => {
|
|
37
|
-
if (
|
|
29
|
+
if (state.timer === null) {
|
|
38
30
|
return;
|
|
39
31
|
}
|
|
40
|
-
clearTimeout(timer);
|
|
41
|
-
timer = null;
|
|
42
|
-
};
|
|
43
|
-
const updateMeta = (updater) => {
|
|
44
|
-
meta.setState(updater);
|
|
32
|
+
clearTimeout(state.timer);
|
|
33
|
+
state.timer = null;
|
|
45
34
|
};
|
|
46
35
|
const resolveRuntimeOptions = (options) => {
|
|
47
36
|
const onPersist = options.onPersist ?? pluginOptions?.onPersist;
|
|
@@ -51,167 +40,134 @@ function createPersistController(store, pluginOptions) {
|
|
|
51
40
|
);
|
|
52
41
|
}
|
|
53
42
|
return {
|
|
54
|
-
|
|
55
|
-
enabled: options.enabled ?? pluginOptions?.enabled ?? true,
|
|
43
|
+
enabled: options.enabled ?? true,
|
|
56
44
|
delay: options.delay ?? pluginOptions?.delay ?? 0,
|
|
57
|
-
hydrate: options.hydrate ?? pluginOptions?.hydrate,
|
|
58
45
|
onPersist
|
|
59
46
|
};
|
|
60
47
|
};
|
|
61
|
-
const
|
|
62
|
-
currentKey = key;
|
|
63
|
-
queuedTransition = null;
|
|
48
|
+
const resetState = () => {
|
|
64
49
|
clearTimer();
|
|
65
|
-
|
|
66
|
-
lastObservedState = store.get();
|
|
67
|
-
meta.setState(() =>
|
|
50
|
+
state.pendingTransition = null;
|
|
51
|
+
state.lastObservedState = store.lifecycle.meta.get().status === "ready" ? store.get() : void 0;
|
|
52
|
+
meta.setState(() => ({
|
|
53
|
+
...DEFAULT_META
|
|
54
|
+
}));
|
|
68
55
|
};
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
pending: true,
|
|
89
|
-
error: null
|
|
90
|
-
}));
|
|
91
|
-
clearTimer();
|
|
92
|
-
timer = setTimeout(() => {
|
|
93
|
-
void flush();
|
|
94
|
-
}, runtimeOptions.delay);
|
|
95
|
-
});
|
|
56
|
+
const enqueueTransition = (previousState, nextState) => {
|
|
57
|
+
state.pendingTransition = state.pendingTransition ? {
|
|
58
|
+
previousState: state.pendingTransition.previousState,
|
|
59
|
+
nextState
|
|
60
|
+
} : {
|
|
61
|
+
previousState,
|
|
62
|
+
nextState
|
|
63
|
+
};
|
|
64
|
+
meta.setState((prev) => ({
|
|
65
|
+
...prev,
|
|
66
|
+
pending: true,
|
|
67
|
+
error: null
|
|
68
|
+
}));
|
|
69
|
+
};
|
|
70
|
+
const canPersist = () => {
|
|
71
|
+
return state.connected && state.runtimeOptions?.enabled;
|
|
72
|
+
};
|
|
73
|
+
const hasEnabledRuntime = () => {
|
|
74
|
+
return state.runtimeOptions?.enabled;
|
|
96
75
|
};
|
|
97
|
-
const
|
|
98
|
-
|
|
76
|
+
const scheduleFlush = () => {
|
|
77
|
+
clearTimer();
|
|
78
|
+
const delay = state.runtimeOptions?.delay ?? 0;
|
|
79
|
+
state.timer = setTimeout(() => {
|
|
80
|
+
void flush();
|
|
81
|
+
}, delay);
|
|
82
|
+
};
|
|
83
|
+
const persistTransition = async (transition) => {
|
|
84
|
+
const runtimeOptions = state.runtimeOptions;
|
|
85
|
+
if (!runtimeOptions?.enabled) {
|
|
99
86
|
return;
|
|
100
87
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
88
|
+
meta.setState((prev) => ({
|
|
89
|
+
...prev,
|
|
90
|
+
pending: false,
|
|
91
|
+
persisting: true,
|
|
92
|
+
error: null
|
|
93
|
+
}));
|
|
94
|
+
try {
|
|
95
|
+
const nextState = pluginOptions?.serializeState ? pluginOptions.serializeState(transition.nextState) : transition.nextState;
|
|
96
|
+
await runtimeOptions.onPersist({
|
|
97
|
+
previousState: transition.previousState,
|
|
98
|
+
nextState
|
|
99
|
+
});
|
|
100
|
+
meta.setState((prev) => ({
|
|
104
101
|
...prev,
|
|
105
|
-
|
|
102
|
+
persisting: false,
|
|
103
|
+
lastPersistedAt: Date.now(),
|
|
106
104
|
error: null
|
|
107
105
|
}));
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
try {
|
|
111
|
-
await options.hydrate({
|
|
112
|
-
key: options.key,
|
|
113
|
-
store: runtimeStore
|
|
114
|
-
});
|
|
115
106
|
} catch (error) {
|
|
116
|
-
|
|
107
|
+
state.pendingTransition = transition;
|
|
108
|
+
meta.setState((prev) => ({
|
|
117
109
|
...prev,
|
|
110
|
+
pending: true,
|
|
111
|
+
persisting: false,
|
|
118
112
|
error
|
|
119
113
|
}));
|
|
120
114
|
throw error;
|
|
121
115
|
}
|
|
122
116
|
};
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
117
|
+
const drainQueue = async () => {
|
|
118
|
+
clearTimer();
|
|
119
|
+
while (state.pendingTransition) {
|
|
120
|
+
if (!hasEnabledRuntime()) {
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const transition = state.pendingTransition;
|
|
124
|
+
state.pendingTransition = null;
|
|
125
|
+
await persistTransition(transition);
|
|
126
126
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
pending: false,
|
|
138
|
-
persisting: true,
|
|
139
|
-
error: null
|
|
140
|
-
}));
|
|
141
|
-
try {
|
|
142
|
-
const nextState = pluginOptions?.serializeState ? pluginOptions.serializeState(transition.nextState) : transition.nextState;
|
|
143
|
-
await runtimeOptions.onPersist({
|
|
144
|
-
key: resolveKey(runtimeOptions.key),
|
|
145
|
-
previousState: transition.previousState,
|
|
146
|
-
nextState
|
|
147
|
-
});
|
|
148
|
-
updateMeta((prev) => ({
|
|
149
|
-
...prev,
|
|
150
|
-
persisting: false,
|
|
151
|
-
lastPersistedAt: Date.now(),
|
|
152
|
-
error: null
|
|
153
|
-
}));
|
|
154
|
-
} catch (error) {
|
|
155
|
-
queuedTransition = transition;
|
|
156
|
-
updateMeta((prev) => ({
|
|
157
|
-
...prev,
|
|
158
|
-
pending: true,
|
|
159
|
-
persisting: false,
|
|
160
|
-
error
|
|
161
|
-
}));
|
|
162
|
-
throw error;
|
|
163
|
-
}
|
|
127
|
+
};
|
|
128
|
+
const ensureSubscription = () => {
|
|
129
|
+
if (state.subscription) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
state.subscription = store.subscribe((nextState) => {
|
|
133
|
+
const previousState = state.lastObservedState;
|
|
134
|
+
state.lastObservedState = nextState;
|
|
135
|
+
if (!canPersist()) {
|
|
136
|
+
return;
|
|
164
137
|
}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
138
|
+
if (previousState === void 0 || Object.is(previousState, nextState)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
enqueueTransition(previousState, nextState);
|
|
142
|
+
scheduleFlush();
|
|
168
143
|
});
|
|
169
|
-
|
|
144
|
+
};
|
|
145
|
+
const flush = () => {
|
|
146
|
+
if (state.flushPromise) {
|
|
147
|
+
return state.flushPromise;
|
|
148
|
+
}
|
|
149
|
+
state.flushPromise = drainQueue().finally(() => {
|
|
150
|
+
state.flushPromise = null;
|
|
151
|
+
});
|
|
152
|
+
return state.flushPromise;
|
|
170
153
|
};
|
|
171
154
|
return {
|
|
172
155
|
meta,
|
|
173
|
-
connect(
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
resetForKey(resolvedOptions.key);
|
|
178
|
-
}
|
|
179
|
-
isConnected = true;
|
|
156
|
+
connect(_runtimeStore, options) {
|
|
157
|
+
state.runtimeOptions = resolveRuntimeOptions(options);
|
|
158
|
+
resetState();
|
|
159
|
+
state.connected = true;
|
|
180
160
|
ensureSubscription();
|
|
181
|
-
void maybeHydrate(runtimeStore, resolvedOptions).catch(() => {
|
|
182
|
-
});
|
|
183
161
|
return () => {
|
|
184
|
-
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
|
-
isConnected = false;
|
|
162
|
+
state.connected = false;
|
|
188
163
|
clearTimer();
|
|
189
|
-
|
|
164
|
+
meta.setState((prev) => ({
|
|
190
165
|
...prev,
|
|
191
166
|
persisting: false
|
|
192
167
|
}));
|
|
193
168
|
};
|
|
194
169
|
},
|
|
195
|
-
flush
|
|
196
|
-
return flush();
|
|
197
|
-
},
|
|
198
|
-
async hydrate(nextState) {
|
|
199
|
-
clearTimer();
|
|
200
|
-
queuedTransition = null;
|
|
201
|
-
hydrating = true;
|
|
202
|
-
try {
|
|
203
|
-
store.setState(() => nextState);
|
|
204
|
-
lastObservedState = nextState;
|
|
205
|
-
updateMeta((prev) => ({
|
|
206
|
-
...prev,
|
|
207
|
-
isHydrated: true,
|
|
208
|
-
pending: false,
|
|
209
|
-
error: null
|
|
210
|
-
}));
|
|
211
|
-
} finally {
|
|
212
|
-
hydrating = false;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
170
|
+
flush
|
|
215
171
|
};
|
|
216
172
|
}
|
|
217
173
|
|
|
@@ -228,16 +184,10 @@ function persist(options) {
|
|
|
228
184
|
});
|
|
229
185
|
}
|
|
230
186
|
return {
|
|
231
|
-
hydrate(nextState) {
|
|
232
|
-
return controller.hydrate(nextState);
|
|
233
|
-
},
|
|
234
187
|
persist: {
|
|
235
188
|
flush() {
|
|
236
189
|
return controller.flush();
|
|
237
190
|
},
|
|
238
|
-
hydrate(nextState) {
|
|
239
|
-
return controller.hydrate(nextState);
|
|
240
|
-
},
|
|
241
191
|
meta: controller.meta,
|
|
242
192
|
[persistControllerKey]: controller
|
|
243
193
|
}
|
|
@@ -260,27 +210,13 @@ function usePersistentRuntime(store, options) {
|
|
|
260
210
|
}
|
|
261
211
|
await options.onPersist(args);
|
|
262
212
|
});
|
|
263
|
-
const hydrate = useEffectEvent(async (args) => {
|
|
264
|
-
if (!options.hydrate) {
|
|
265
|
-
return;
|
|
266
|
-
}
|
|
267
|
-
await options.hydrate(args);
|
|
268
|
-
});
|
|
269
213
|
useEffect(() => {
|
|
270
214
|
return store.persist[persistControllerKey].connect(store, {
|
|
271
|
-
key: options.key,
|
|
272
215
|
enabled: options.enabled,
|
|
273
216
|
delay: options.delay,
|
|
274
|
-
onPersist: options.onPersist ? (args) => onPersist(args) : void 0
|
|
275
|
-
hydrate: options.hydrate ? (args) => hydrate(args) : void 0
|
|
217
|
+
onPersist: options.onPersist ? (args) => onPersist(args) : void 0
|
|
276
218
|
});
|
|
277
|
-
}, [
|
|
278
|
-
options.delay,
|
|
279
|
-
options.enabled,
|
|
280
|
-
options.key,
|
|
281
|
-
store,
|
|
282
|
-
Boolean(options.hydrate)
|
|
283
|
-
]);
|
|
219
|
+
}, [options.delay, options.enabled, store]);
|
|
284
220
|
return {
|
|
285
221
|
store,
|
|
286
222
|
flush() {
|
|
@@ -299,11 +235,8 @@ function usePersistentStore(builder) {
|
|
|
299
235
|
}
|
|
300
236
|
return contextValue;
|
|
301
237
|
}
|
|
302
|
-
function usePersistenceBoundary(store, {
|
|
303
|
-
flushOnBackground
|
|
304
|
-
flushOnPageHide,
|
|
305
|
-
flushOnUnmount
|
|
306
|
-
}) {
|
|
238
|
+
function usePersistenceBoundary(store, options) {
|
|
239
|
+
const { flushOnUnmount, flushOnPageHide, flushOnBackground } = options;
|
|
307
240
|
useEffect(() => {
|
|
308
241
|
if (!flushOnUnmount) {
|
|
309
242
|
return;
|
|
@@ -336,13 +269,10 @@ function PersistStoreProviderContent({
|
|
|
336
269
|
flushOnPageHide,
|
|
337
270
|
flushOnUnmount,
|
|
338
271
|
children,
|
|
339
|
-
persist: persist2,
|
|
272
|
+
persist: persist2 = {},
|
|
340
273
|
store
|
|
341
274
|
}) {
|
|
342
|
-
const persistentStore = usePersistentRuntime(
|
|
343
|
-
store,
|
|
344
|
-
persist2 ?? {}
|
|
345
|
-
);
|
|
275
|
+
const persistentStore = usePersistentRuntime(store, persist2);
|
|
346
276
|
const Context = getPersistStoreContext(builder);
|
|
347
277
|
usePersistenceBoundary(store, {
|
|
348
278
|
flushOnBackground,
|
|
@@ -353,11 +283,17 @@ function PersistStoreProviderContent({
|
|
|
353
283
|
return /* @__PURE__ */ jsx(Context.Provider, { value: persistentStore, children: content });
|
|
354
284
|
}
|
|
355
285
|
function PersistStoreProvider(props) {
|
|
356
|
-
if (props.builder
|
|
357
|
-
|
|
286
|
+
if (!props.builder) {
|
|
287
|
+
const builder = getStoreBuilder(props.store);
|
|
288
|
+
if (!builder) {
|
|
289
|
+
throw new Error(
|
|
290
|
+
"PersistStoreProvider could not resolve a builder for the provided store. Pass a persisted store created by @lunarhue/store."
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
return /* @__PURE__ */ jsx(StoreProvider, { store: props.store, children: ({ store }) => /* @__PURE__ */ jsx(
|
|
358
294
|
PersistStoreProviderContent,
|
|
359
295
|
{
|
|
360
|
-
builder
|
|
296
|
+
builder,
|
|
361
297
|
store,
|
|
362
298
|
persist: props.persist,
|
|
363
299
|
flushOnUnmount: props.flushOnUnmount,
|
|
@@ -367,16 +303,10 @@ function PersistStoreProvider(props) {
|
|
|
367
303
|
}
|
|
368
304
|
) });
|
|
369
305
|
}
|
|
370
|
-
const
|
|
371
|
-
if (!builder) {
|
|
372
|
-
throw new Error(
|
|
373
|
-
"PersistStoreProvider could not resolve a builder for the provided store. Pass a persisted store created by @lunarhue/store."
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
return /* @__PURE__ */ jsx(StoreProvider, { store: props.store, children: ({ store }) => /* @__PURE__ */ jsx(
|
|
306
|
+
const content = (store) => /* @__PURE__ */ jsx(
|
|
377
307
|
PersistStoreProviderContent,
|
|
378
308
|
{
|
|
379
|
-
builder,
|
|
309
|
+
builder: props.builder,
|
|
380
310
|
store,
|
|
381
311
|
persist: props.persist,
|
|
382
312
|
flushOnUnmount: props.flushOnUnmount,
|
|
@@ -384,23 +314,24 @@ function PersistStoreProvider(props) {
|
|
|
384
314
|
flushOnBackground: props.flushOnBackground,
|
|
385
315
|
children: props.children
|
|
386
316
|
}
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
317
|
+
);
|
|
318
|
+
if ("initialState" in props) {
|
|
319
|
+
const initialState = props.initialState;
|
|
320
|
+
return /* @__PURE__ */ jsx(StoreProvider, { builder: props.builder, initialState, children: ({ store }) => content(store) });
|
|
321
|
+
}
|
|
322
|
+
if (props.loadInitialState) {
|
|
323
|
+
return /* @__PURE__ */ jsx(
|
|
324
|
+
StoreProvider,
|
|
325
|
+
{
|
|
326
|
+
builder: props.builder,
|
|
327
|
+
loadInitialState: props.loadInitialState,
|
|
328
|
+
children: ({ store }) => content(store)
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
return /* @__PURE__ */ jsx(StoreProvider, { builder: props.builder, children: ({ store }) => content(store) });
|
|
402
333
|
}
|
|
403
334
|
|
|
404
|
-
export { PersistStoreProvider,
|
|
335
|
+
export { PersistStoreProvider, persist, usePersistentStore };
|
|
405
336
|
//# sourceMappingURL=index.js.map
|
|
406
337
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/plugins/persist/controller.ts","../../../src/plugins/persist/types.ts","../../../src/plugins/persist/plugin.ts","../../../src/plugins/persist/react.tsx"],"names":["persist"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n PersistController,\n PersistMeta,\n PersistPluginOptions,\n PersistRuntimeOptions,\n PersistedStore,\n} from './types'\nimport type { Store } from '../../core'\nimport { createStoreInstance } from '../../core/store-instance'\n\nconst DEFAULT_META: PersistMeta = {\n isHydrated: false,\n pending: false,\n persisting: false,\n lastPersistedAt: null,\n error: null,\n}\n\nlet nextGeneratedPersistKeyId = 0\n\nfunction getInitialMeta<TState>(\n options?: PersistPluginOptions<TState>,\n): PersistMeta {\n return {\n ...DEFAULT_META,\n isHydrated: options?.hydratedOnCreate ?? false,\n }\n}\n\ntype RuntimeOptions<TState> = Required<\n Omit<PersistRuntimeOptions<TState>, 'hydrate'>\n> & {\n hydrate?: PersistRuntimeOptions<TState>['hydrate']\n}\n\nexport function createPersistController<TState>(\n store: Store<TState>,\n pluginOptions?: PersistPluginOptions<TState>,\n): PersistController<TState> {\n const meta = createStoreInstance(getInitialMeta(pluginOptions)).store\n const fallbackKey = `persist:${++nextGeneratedPersistKeyId}`\n let runtimeOptions: RuntimeOptions<TState> | null = null\n let subscription: { unsubscribe(): void } | null = null\n let timer: ReturnType<typeof setTimeout> | null = null\n let queuedTransition: {\n previousState: TState\n nextState: TState\n } | null = null\n let lastObservedState = store.get()\n let currentKey: string | null = null\n let currentFlushPromise: Promise<void> | null = null\n let hydrating = false\n let isConnected = false\n let hasRequestedHydrationForKey = false\n\n const resolveKey = (key?: string) => key ?? fallbackKey\n\n const clearTimer = () => {\n if (!timer) {\n return\n }\n\n clearTimeout(timer)\n timer = null\n }\n\n const updateMeta = (updater: (prev: PersistMeta) => PersistMeta) => {\n meta.setState(updater)\n }\n\n const resolveRuntimeOptions = (\n options: PersistRuntimeOptions<TState>,\n ): RuntimeOptions<TState> => {\n const onPersist = options.onPersist ?? pluginOptions?.onPersist\n\n if (!onPersist) {\n throw new Error(\n 'Persist runtime requires onPersist to be provided either in persist(...) or at runtime.',\n )\n }\n\n return {\n key: resolveKey(options.key),\n enabled: options.enabled ?? pluginOptions?.enabled ?? true,\n delay: options.delay ?? pluginOptions?.delay ?? 0,\n hydrate: options.hydrate ?? pluginOptions?.hydrate,\n onPersist,\n }\n }\n\n const resetForKey = (key: string) => {\n currentKey = key\n queuedTransition = null\n clearTimer()\n hasRequestedHydrationForKey = false\n lastObservedState = store.get()\n meta.setState(() => getInitialMeta(pluginOptions))\n }\n\n const ensureSubscription = () => {\n if (subscription) {\n return\n }\n\n subscription = store.subscribe((nextState) => {\n const previousState = lastObservedState\n lastObservedState = nextState\n\n if (\n hydrating ||\n !isConnected ||\n !runtimeOptions?.enabled ||\n Object.is(previousState, nextState)\n ) {\n return\n }\n\n queuedTransition = queuedTransition\n ? {\n previousState: queuedTransition.previousState,\n nextState,\n }\n : {\n previousState,\n nextState,\n }\n\n updateMeta((prev) => ({\n ...prev,\n pending: true,\n error: null,\n }))\n\n clearTimer()\n timer = setTimeout(() => {\n void flush()\n }, runtimeOptions.delay)\n })\n }\n\n const maybeHydrate = async (\n runtimeStore: PersistedStore<TState>,\n options: RuntimeOptions<TState>,\n ) => {\n if (!options.enabled || hasRequestedHydrationForKey) {\n return\n }\n\n hasRequestedHydrationForKey = true\n\n if (!options.hydrate) {\n updateMeta((prev) => ({\n ...prev,\n isHydrated: true,\n error: null,\n }))\n return\n }\n\n try {\n await options.hydrate({\n key: options.key,\n store: runtimeStore,\n })\n } catch (error) {\n updateMeta((prev) => ({\n ...prev,\n error,\n }))\n throw error\n }\n }\n\n const flush = (): Promise<void> => {\n if (currentFlushPromise) {\n return currentFlushPromise\n }\n\n const runFlush = async () => {\n clearTimer()\n\n while (queuedTransition) {\n if (!runtimeOptions?.enabled) {\n return\n }\n\n const transition = queuedTransition\n queuedTransition = null\n\n updateMeta((prev) => ({\n ...prev,\n pending: false,\n persisting: true,\n error: null,\n }))\n\n try {\n const nextState = pluginOptions?.serializeState\n ? pluginOptions.serializeState(transition.nextState)\n : transition.nextState\n\n await runtimeOptions.onPersist({\n key: resolveKey(runtimeOptions.key),\n previousState: transition.previousState,\n nextState,\n })\n\n updateMeta((prev) => ({\n ...prev,\n persisting: false,\n lastPersistedAt: Date.now(),\n error: null,\n }))\n } catch (error) {\n queuedTransition = transition\n updateMeta((prev) => ({\n ...prev,\n pending: true,\n persisting: false,\n error,\n }))\n throw error\n }\n }\n }\n\n currentFlushPromise = runFlush().finally(() => {\n currentFlushPromise = null\n })\n\n return currentFlushPromise\n }\n\n return {\n meta,\n connect(runtimeStore, options) {\n const resolvedOptions = resolveRuntimeOptions(options)\n runtimeOptions = resolvedOptions\n\n if (currentKey !== resolvedOptions.key) {\n resetForKey(resolvedOptions.key)\n }\n\n isConnected = true\n ensureSubscription()\n void maybeHydrate(runtimeStore, resolvedOptions).catch(() => {})\n\n return () => {\n if (currentKey !== resolvedOptions.key) {\n return\n }\n\n isConnected = false\n clearTimer()\n updateMeta((prev) => ({\n ...prev,\n persisting: false,\n }))\n }\n },\n flush() {\n return flush()\n },\n async hydrate(nextState) {\n clearTimer()\n queuedTransition = null\n hydrating = true\n\n try {\n store.setState(() => nextState)\n lastObservedState = nextState\n updateMeta((prev) => ({\n ...prev,\n isHydrated: true,\n pending: false,\n error: null,\n }))\n } finally {\n hydrating = false\n }\n },\n }\n}\n","import type { Store, StorePlugin } from '../../core'\n\nexport const persistControllerKey = Symbol('lunarhue.store.persist.controller')\n\nexport type PersistMeta = {\n isHydrated: boolean\n pending: boolean\n persisting: boolean\n lastPersistedAt: number | null\n error: unknown | null\n}\n\nexport type PersistHydrateArgs<TState> = {\n key: string\n store: PersistedStore<TState>\n}\n\nexport type PersistPersistArgs<TState> = {\n key: string\n previousState: TState\n nextState: TState\n}\n\nexport type PersistRuntimeOptions<TState> = {\n key?: string\n enabled?: boolean\n delay?: number\n hydrate?: (args: PersistHydrateArgs<TState>) => Promise<void>\n onPersist?: (args: PersistPersistArgs<TState>) => Promise<void>\n}\n\nexport type PersistPluginOptions<TState> = {\n flushOnDispose?: boolean\n hydratedOnCreate?: boolean\n serializeState?: (state: TState) => TState\n} & Omit<PersistRuntimeOptions<TState>, 'key'>\n\nexport type PersistRuntimeSurface<TState> = {\n flush(): Promise<void>\n hydrate(nextState: TState): Promise<void>\n meta: Store<PersistMeta>\n}\n\nexport type PersistStoreSurface<TState> = {\n hydrate(nextState: TState): Promise<void>\n persist: PersistRuntimeSurface<TState>\n}\n\nexport type PersistController<TState> = {\n meta: Store<PersistMeta>\n connect(\n store: PersistedStore<TState>,\n options: PersistRuntimeOptions<TState>,\n ): () => void\n flush(): Promise<void>\n hydrate(nextState: TState): Promise<void>\n}\n\nexport type InternalPersistStoreSurface<TState> = PersistStoreSurface<TState> & {\n persist: PersistRuntimeSurface<TState> & {\n [persistControllerKey]: PersistController<TState>\n }\n}\n\nexport type PersistedStore<TState, TPlugins = {}> = Store<\n TState,\n TPlugins & PersistStoreSurface<TState>\n>\n\nexport type InternalPersistedStore<TState, TPlugins = {}> = Store<\n TState,\n TPlugins & InternalPersistStoreSurface<TState>\n>\n\nexport type PersistPlugin<TState> = StorePlugin<\n TState,\n any,\n PersistStoreSurface<TState>\n>\n","import { createPersistController } from './controller'\nimport { persistControllerKey } from './types'\n\nimport type { PersistPlugin, PersistPluginOptions } from './types'\n\nexport function persist<TState>(\n options?: PersistPluginOptions<TState>,\n): PersistPlugin<TState> {\n return ({ onDispose, store }) => {\n const controller = createPersistController(store, options)\n\n if (options?.flushOnDispose) {\n onDispose(async () => {\n await controller.flush()\n })\n }\n\n return {\n hydrate(nextState: TState) {\n return controller.hydrate(nextState)\n },\n persist: {\n flush() {\n return controller.flush()\n },\n hydrate(nextState: TState) {\n return controller.hydrate(nextState)\n },\n meta: controller.meta,\n [persistControllerKey]: controller,\n },\n }\n }\n}\n","import {\n createContext,\n type Context,\n type ReactNode,\n useContext,\n useEffect,\n useEffectEvent,\n} from 'react'\n\nimport type { StoreBuilder } from '../../core'\nimport { getStoreBuilder } from '../../core/builder-registry'\nimport { StoreProvider, useSelector } from '../../react'\n\nimport {\n persistControllerKey,\n type InternalPersistedStore,\n type PersistHydrateArgs,\n type PersistMeta,\n type PersistPersistArgs,\n type PersistStoreSurface,\n type PersistRuntimeOptions,\n type PersistedStore,\n} from './types'\n\nexport type PersistentStoreResult<TState, TPlugins = {}> = {\n store: PersistedStore<TState, TPlugins>\n flush(): Promise<void>\n}\n\ntype PersistStoreContext<TState, TPlugins> = Context<\n PersistentStoreResult<TState, TPlugins> | undefined\n>\n\nconst persistContextMap = new WeakMap<\n StoreBuilder<any, any>,\n PersistStoreContext<any, any>\n>()\n\ntype PersistStoreProviderChildren<TState, TPlugins> =\n | ReactNode\n | ((args: PersistentStoreResult<TState, TPlugins>) => ReactNode)\n\ntype BuilderPersistStoreProviderProps<TState, TPlugins> = {\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface<TState>>\n children?: PersistStoreProviderChildren<TState, TPlugins>\n flushOnBackground?: boolean\n flushOnPageHide?: boolean\n flushOnUnmount?: boolean\n persist?: PersistRuntimeOptions<TState>\n store?: never\n}\n\ntype ExternalPersistStoreProviderProps<TState, TPlugins> = {\n builder?: never\n children?: PersistStoreProviderChildren<TState, TPlugins>\n flushOnBackground?: boolean\n flushOnPageHide?: boolean\n flushOnUnmount?: boolean\n persist?: PersistRuntimeOptions<TState>\n store: PersistedStore<TState, TPlugins>\n}\n\nexport type PersistStoreProviderProps<TState, TPlugins = {}> =\n | BuilderPersistStoreProviderProps<TState, TPlugins>\n | ExternalPersistStoreProviderProps<TState, TPlugins>\n\n/**\n * @deprecated Prefer PersistStoreProvider flush options. This boundary remains\n * as a compatibility escape hatch for sub-tree flush behavior.\n */\nexport type PersistenceBoundaryProps<TState> = {\n store: PersistedStore<TState>\n flushOnUnmount?: boolean\n flushOnPageHide?: boolean\n flushOnBackground?: boolean\n children?: ReactNode\n}\n\ntype PersistenceBoundaryOptions = {\n flushOnBackground?: boolean\n flushOnPageHide?: boolean\n flushOnUnmount?: boolean\n}\n\nfunction getPersistStoreContext<TState, TPlugins>(\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface<TState>>,\n): PersistStoreContext<TState, TPlugins> {\n let context = persistContextMap.get(builder)\n\n if (!context) {\n context = createContext<\n PersistentStoreResult<TState, TPlugins> | undefined\n >(undefined)\n persistContextMap.set(builder, context)\n }\n\n return context\n}\n\nfunction usePersistentRuntime<TState, TPlugins = {}>(\n store: InternalPersistedStore<TState, TPlugins>,\n options: PersistRuntimeOptions<TState>,\n): PersistentStoreResult<TState, TPlugins> {\n const onPersist = useEffectEvent(async (args: PersistPersistArgs<TState>) => {\n if (!options.onPersist) {\n return\n }\n\n await options.onPersist(args)\n })\n const hydrate = useEffectEvent(async (args: PersistHydrateArgs<TState>) => {\n if (!options.hydrate) {\n return\n }\n\n await options.hydrate(args)\n })\n\n useEffect(() => {\n return store.persist[persistControllerKey].connect(store, {\n key: options.key,\n enabled: options.enabled,\n delay: options.delay,\n onPersist: options.onPersist ? (args) => onPersist(args) : undefined,\n hydrate: options.hydrate ? (args) => hydrate(args) : undefined,\n })\n }, [\n options.delay,\n options.enabled,\n options.key,\n store,\n Boolean(options.hydrate),\n ])\n\n return {\n store,\n flush() {\n return store.persist.flush()\n },\n }\n}\n\nexport function usePersistentStore<TState, TPlugins>(\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface<TState>>,\n): PersistentStoreResult<TState, TPlugins> {\n const contextValue = useContext(\n getPersistStoreContext<TState, TPlugins>(builder),\n )\n\n if (!contextValue) {\n throw new Error(\n 'usePersistentStore(builder) requires a matching <PersistStoreProvider builder={...}> or <PersistStoreProvider store={...}> ancestor.',\n )\n }\n\n return contextValue\n}\n\nfunction usePersistenceBoundary<TState>(\n store: PersistedStore<TState>,\n {\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n }: PersistenceBoundaryOptions,\n) {\n useEffect(() => {\n if (!flushOnUnmount) {\n return\n }\n\n return () => {\n void store.persist.flush()\n }\n }, [flushOnUnmount, store])\n\n useEffect(() => {\n if (!flushOnPageHide || typeof window === 'undefined') {\n return\n }\n\n const handlePageHide = () => {\n void store.persist.flush()\n }\n\n window.addEventListener('pagehide', handlePageHide)\n\n return () => {\n window.removeEventListener('pagehide', handlePageHide)\n }\n }, [flushOnPageHide, store])\n\n useEffect(() => {\n if (!flushOnBackground) {\n return\n }\n\n // Web has no app background lifecycle equivalent here yet.\n }, [flushOnBackground])\n}\n\ninterface PersistStoreProviderContentProps<TState, TPlugins> {\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface<TState>>\n children?: PersistStoreProviderChildren<TState, TPlugins>\n flushOnBackground?: boolean\n flushOnPageHide?: boolean\n flushOnUnmount?: boolean\n persist?: PersistRuntimeOptions<TState>\n store: InternalPersistedStore<TState, TPlugins>\n}\n\nfunction PersistStoreProviderContent<TState, TPlugins>({\n builder,\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n children,\n persist,\n store,\n}: PersistStoreProviderContentProps<TState, TPlugins>) {\n const persistentStore = usePersistentRuntime<TState, TPlugins>(\n store,\n persist ?? {},\n )\n const Context = getPersistStoreContext<TState, TPlugins>(builder)\n\n usePersistenceBoundary(store, {\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n })\n\n const content =\n typeof children === 'function' ? children(persistentStore) : children\n\n return <Context.Provider value={persistentStore}>{content}</Context.Provider>\n}\n\nexport function PersistStoreProvider<TState, TPlugins = {}>(\n props: PersistStoreProviderProps<TState, TPlugins>,\n) {\n if (props.builder !== undefined) {\n return (\n <StoreProvider builder={props.builder}>\n {({ store }) => (\n <PersistStoreProviderContent\n builder={props.builder}\n store={store as InternalPersistedStore<TState, TPlugins>}\n persist={props.persist}\n flushOnUnmount={props.flushOnUnmount}\n flushOnPageHide={props.flushOnPageHide}\n flushOnBackground={props.flushOnBackground}\n >\n {props.children}\n </PersistStoreProviderContent>\n )}\n </StoreProvider>\n )\n }\n\n const builder = getStoreBuilder(props.store)\n\n if (!builder) {\n throw new Error(\n 'PersistStoreProvider could not resolve a builder for the provided store. Pass a persisted store created by @lunarhue/store.',\n )\n }\n\n return (\n <StoreProvider store={props.store}>\n {({ store }) => (\n <PersistStoreProviderContent\n builder={\n builder as StoreBuilder<\n TState,\n TPlugins & PersistStoreSurface<TState>\n >\n }\n store={store as InternalPersistedStore<TState, TPlugins>}\n persist={props.persist}\n flushOnUnmount={props.flushOnUnmount}\n flushOnPageHide={props.flushOnPageHide}\n flushOnBackground={props.flushOnBackground}\n >\n {props.children}\n </PersistStoreProviderContent>\n )}\n </StoreProvider>\n )\n}\n\n/**\n * @deprecated Prefer PersistStoreProvider flush options. This boundary remains\n * as a compatibility escape hatch for sub-tree flush behavior.\n */\nexport function PersistenceBoundary<TState>({\n children,\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n store,\n}: PersistenceBoundaryProps<TState>) {\n usePersistenceBoundary(store, {\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n })\n\n return <>{children}</>\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/plugins/persist/controller.ts","../../../src/plugins/persist/types.ts","../../../src/plugins/persist/plugin.ts","../../../src/plugins/persist/react.tsx"],"names":["persist"],"mappings":"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","file":"index.js","sourcesContent":["import type {\n PersistController,\n PersistMeta,\n PersistPluginOptions,\n PersistRuntimeOptions,\n} from './types'\nimport type { Store } from '../../core'\nimport { createStoreInstance } from '../../core/store-instance'\n\nconst DEFAULT_META: PersistMeta = {\n pending: false,\n persisting: false,\n lastPersistedAt: null,\n error: null,\n}\n\ntype RuntimeOptions<TState> = Required<PersistRuntimeOptions<TState>>\n\ntype Transition<TState> = {\n previousState: TState\n nextState: TState\n}\n\ntype ControllerState<TState> = {\n connected: boolean\n runtimeOptions: RuntimeOptions<TState> | null\n subscription: { unsubscribe(): void } | null\n timer: ReturnType<typeof setTimeout> | null\n pendingTransition: Transition<TState> | null\n lastObservedState: TState | undefined\n flushPromise: Promise<void> | null\n}\n\nexport function createPersistController<TState>(\n store: Store<TState>,\n pluginOptions?: PersistPluginOptions<TState>,\n): PersistController<TState> {\n const meta = createStoreInstance({\n initialState: { ...DEFAULT_META },\n readyOnCreate: true,\n }).store\n\n const state: ControllerState<TState> = {\n connected: false,\n runtimeOptions: null,\n subscription: null,\n timer: null,\n pendingTransition: null,\n lastObservedState:\n store.lifecycle.meta.get().status === 'ready' ? store.get() : undefined,\n flushPromise: null,\n }\n\n const clearTimer = () => {\n if (state.timer === null) {\n return\n }\n\n clearTimeout(state.timer)\n state.timer = null\n }\n\n const resolveRuntimeOptions = (\n options: PersistRuntimeOptions<TState>,\n ): RuntimeOptions<TState> => {\n const onPersist = options.onPersist ?? pluginOptions?.onPersist\n\n if (!onPersist) {\n throw new Error(\n 'Persist runtime requires onPersist to be provided either in persist(...) or at runtime.',\n )\n }\n\n return {\n enabled: options.enabled ?? true,\n delay: options.delay ?? pluginOptions?.delay ?? 0,\n onPersist,\n }\n }\n\n const resetState = () => {\n clearTimer()\n state.pendingTransition = null\n state.lastObservedState =\n store.lifecycle.meta.get().status === 'ready' ? store.get() : undefined\n\n meta.setState(() => ({\n ...DEFAULT_META,\n }))\n }\n\n const enqueueTransition = (previousState: TState, nextState: TState) => {\n state.pendingTransition = state.pendingTransition\n ? {\n previousState: state.pendingTransition.previousState,\n nextState,\n }\n : {\n previousState,\n nextState,\n }\n\n meta.setState((prev) => ({\n ...prev,\n pending: true,\n error: null,\n }))\n }\n\n const canPersist = () => {\n return state.connected && state.runtimeOptions?.enabled\n }\n\n const hasEnabledRuntime = () => {\n return state.runtimeOptions?.enabled\n }\n\n const scheduleFlush = () => {\n clearTimer()\n\n const delay = state.runtimeOptions?.delay ?? 0\n state.timer = setTimeout(() => {\n void flush()\n }, delay)\n }\n\n const persistTransition = async (transition: Transition<TState>) => {\n const runtimeOptions = state.runtimeOptions\n\n if (!runtimeOptions?.enabled) {\n return\n }\n\n meta.setState((prev) => ({\n ...prev,\n pending: false,\n persisting: true,\n error: null,\n }))\n\n try {\n const nextState = pluginOptions?.serializeState\n ? pluginOptions.serializeState(transition.nextState)\n : transition.nextState\n\n await runtimeOptions.onPersist({\n previousState: transition.previousState,\n nextState,\n })\n\n meta.setState((prev) => ({\n ...prev,\n persisting: false,\n lastPersistedAt: Date.now(),\n error: null,\n }))\n } catch (error) {\n state.pendingTransition = transition\n\n meta.setState((prev) => ({\n ...prev,\n pending: true,\n persisting: false,\n error,\n }))\n\n throw error\n }\n }\n\n const drainQueue = async () => {\n clearTimer()\n\n while (state.pendingTransition) {\n if (!hasEnabledRuntime()) {\n return\n }\n\n const transition = state.pendingTransition\n state.pendingTransition = null\n\n await persistTransition(transition)\n }\n }\n\n const ensureSubscription = () => {\n if (state.subscription) {\n return\n }\n\n state.subscription = store.subscribe((nextState) => {\n const previousState = state.lastObservedState\n state.lastObservedState = nextState\n\n if (!canPersist()) {\n return\n }\n\n if (previousState === undefined || Object.is(previousState, nextState)) {\n return\n }\n\n enqueueTransition(previousState, nextState)\n scheduleFlush()\n })\n }\n\n const flush = (): Promise<void> => {\n if (state.flushPromise) {\n return state.flushPromise\n }\n\n state.flushPromise = drainQueue().finally(() => {\n state.flushPromise = null\n })\n\n return state.flushPromise\n }\n\n return {\n meta,\n connect(_runtimeStore, options) {\n state.runtimeOptions = resolveRuntimeOptions(options)\n\n resetState()\n state.connected = true\n ensureSubscription()\n\n return () => {\n state.connected = false\n clearTimer()\n\n meta.setState((prev) => ({\n ...prev,\n persisting: false,\n }))\n }\n },\n flush,\n }\n}\n","import type { Store, StorePlugin } from '../../core'\n\nexport const persistControllerKey = Symbol('lunarhue.store.persist.controller')\n\n/**\n * Runtime metadata exposed on `store.persist.meta`.\n */\nexport type PersistMeta = {\n /**\n * `true` while a state transition is queued for persistence.\n */\n pending: boolean\n /**\n * `true` while `onPersist` is actively running.\n */\n persisting: boolean\n /**\n * Epoch timestamp in milliseconds of the last successful persist.\n */\n lastPersistedAt: number | null\n /**\n * Last persistence error captured by the controller.\n */\n error: unknown | null\n}\n\n/**\n * State transition passed to `onPersist`.\n */\nexport type PersistPersistArgs<TState> = {\n /**\n * Previously observed runtime store state.\n */\n previousState: TState\n /**\n * Next state being persisted, after optional serialization.\n */\n nextState: TState\n}\n\n/**\n * Runtime persistence configuration passed through `PersistStoreProvider`.\n */\nexport type PersistRuntimeOptions<TState> = {\n /**\n * Enables or disables persistence for the active runtime connection.\n *\n * Defaults to `true`.\n */\n enabled?: boolean\n /**\n * Debounce delay in milliseconds before queued state changes are flushed.\n */\n delay?: number\n /**\n * Persists the latest observed state transition.\n *\n * This must be provided here unless declaration-time plugin options already\n * supply it.\n */\n onPersist?: (args: PersistPersistArgs<TState>) => Promise<void>\n}\n\n/**\n * Declaration-time defaults for the persist plugin.\n *\n * Runtime options may override `delay` and `onPersist`, while `enabled`\n * remains a runtime-only control.\n */\nexport type PersistPluginOptions<TState> = {\n /**\n * Flushes queued persistence work when the runtime store is disposed.\n */\n flushOnDispose?: boolean\n /**\n * Transforms state before `onPersist` receives it.\n */\n serializeState?: (state: TState) => TState\n} & Omit<PersistRuntimeOptions<TState>, 'enabled'>\n\nexport type PersistRuntimeSurface = {\n flush(): Promise<void>\n meta: Store<PersistMeta>\n}\n\nexport type PersistStoreSurface = {\n persist: PersistRuntimeSurface\n}\n\nexport type PersistController<TState> = {\n meta: Store<PersistMeta>\n connect(\n store: PersistedStore<TState>,\n options: PersistRuntimeOptions<TState>,\n ): () => void\n flush(): Promise<void>\n}\n\nexport type InternalPersistStoreSurface<TState> = PersistStoreSurface & {\n persist: PersistRuntimeSurface & {\n [persistControllerKey]: PersistController<TState>\n }\n}\n\n/**\n * Runtime store type produced by a builder extended with {@link persist}.\n *\n * This adds `store.persist.flush()` and `store.persist.meta` to the runtime\n * store surface.\n */\nexport type PersistedStore<TState, TPlugins = {}> = Store<\n TState,\n TPlugins & PersistStoreSurface\n>\n\nexport type InternalPersistedStore<TState, TPlugins = {}> = Store<\n TState,\n TPlugins & InternalPersistStoreSurface<TState>\n>\n\nexport type PersistPlugin<TState> = StorePlugin<\n TState,\n any,\n PersistStoreSurface\n>\n","import { createPersistController } from './controller'\nimport { persistControllerKey } from './types'\n\nimport type { PersistPlugin, PersistPluginOptions } from './types'\n\n/**\n * Attaches persistence metadata and flush controls to `store.persist`.\n *\n * Declaration-time options provide defaults for runtime persistence wiring.\n * `onPersist` may be supplied here or later through `PersistStoreProvider`,\n * but it must exist in one of those places before persistence can run.\n */\nexport function persist<TState>(\n options?: PersistPluginOptions<TState>,\n): PersistPlugin<TState> {\n return ({ onDispose, store }) => {\n const controller = createPersistController(store, options)\n\n if (options?.flushOnDispose) {\n onDispose(async () => {\n await controller.flush()\n })\n }\n\n return {\n persist: {\n flush() {\n return controller.flush()\n },\n meta: controller.meta,\n [persistControllerKey]: controller,\n },\n }\n }\n}\n","import {\n createContext,\n type Context,\n type ReactNode,\n useContext,\n useEffect,\n useEffectEvent,\n} from 'react'\n\nimport type { StoreBuilder, StoreInitialStateLoader } from '../../core'\nimport { getStoreBuilder } from '../../core/builder-registry'\nimport { StoreProvider } from '../../react'\n\nimport {\n persistControllerKey,\n type InternalPersistedStore,\n type PersistPersistArgs,\n type PersistStoreSurface,\n type PersistRuntimeOptions,\n type PersistedStore,\n} from './types'\n\n/**\n * Value returned by {@link usePersistentStore} and the\n * `PersistStoreProvider` render prop.\n */\nexport type PersistentStoreResult<TState, TPlugins = {}> = {\n /**\n * Persist-enabled runtime store instance.\n */\n store: PersistedStore<TState, TPlugins>\n /**\n * Flushes any queued persistence work immediately.\n */\n flush(): Promise<void>\n}\n\n/**\n * Additional flush triggers supported by {@link PersistStoreProvider}.\n */\nexport type PersistenceBoundaryOptions = {\n /**\n * Reserved for non-web background lifecycle support.\n *\n * On web this is currently a no-op.\n */\n flushOnBackground?: boolean\n /**\n * Flushes pending persistence work when the browser fires `pagehide`.\n */\n flushOnPageHide?: boolean\n /**\n * Flushes pending persistence work when the provider unmounts.\n */\n flushOnUnmount?: boolean\n}\ntype PersistStoreContext<TState, TPlugins> = Context<\n PersistentStoreResult<TState, TPlugins> | undefined\n>\n\nconst persistContextMap = new WeakMap<\n StoreBuilder<any, any>,\n PersistStoreContext<any, any>\n>()\n\ntype PersistStoreProviderChildren<TState, TPlugins> =\n | ReactNode\n | ((args: PersistentStoreResult<TState, TPlugins>) => ReactNode)\n\ntype BuilderPersistStoreProviderBaseProps<TState, TPlugins> = {\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface>\n children?: PersistStoreProviderChildren<TState, TPlugins>\n persist?: PersistRuntimeOptions<TState>\n store?: never\n} & PersistenceBoundaryOptions\n\ntype BuilderPersistStoreProviderWithInitialStateProps<TState, TPlugins> =\n BuilderPersistStoreProviderBaseProps<TState, TPlugins> & {\n initialState: TState\n loadInitialState?: never\n }\n\ntype BuilderPersistStoreProviderWithLoadInitialStateProps<TState, TPlugins> =\n BuilderPersistStoreProviderBaseProps<TState, TPlugins> & {\n initialState?: never\n loadInitialState: StoreInitialStateLoader<\n TState,\n TPlugins & PersistStoreSurface\n >\n }\n\ntype BuilderPersistStoreProviderWithDeclaredInitialStateProps<\n TState,\n TPlugins,\n> = BuilderPersistStoreProviderBaseProps<TState, TPlugins> & {\n initialState?: never\n loadInitialState?: never\n}\n\ntype BuilderPersistStoreProviderProps<TState, TPlugins> =\n | BuilderPersistStoreProviderWithDeclaredInitialStateProps<TState, TPlugins>\n | BuilderPersistStoreProviderWithInitialStateProps<TState, TPlugins>\n | BuilderPersistStoreProviderWithLoadInitialStateProps<TState, TPlugins>\n\ntype ExternalPersistStoreProviderProps<TState, TPlugins> = {\n builder?: never\n children?: PersistStoreProviderChildren<TState, TPlugins>\n persist?: PersistRuntimeOptions<TState>\n store: PersistedStore<TState, TPlugins>\n} & PersistenceBoundaryOptions\n\n/**\n * Props for {@link PersistStoreProvider}.\n *\n * Use either `builder` to let the provider create and own the persisted store,\n * or `store` to provide an already-created persisted store. Runtime `persist`\n * options override declaration-time defaults from {@link persist}. Builder\n * usage follows the same initialization rules as {@link StoreProvider}, with\n * optional flush boundaries layered on top.\n */\nexport type PersistStoreProviderProps<TState, TPlugins = {}> =\n | BuilderPersistStoreProviderProps<TState, TPlugins>\n | ExternalPersistStoreProviderProps<TState, TPlugins>\n\nfunction getPersistStoreContext<TState, TPlugins>(\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface>,\n): PersistStoreContext<TState, TPlugins> {\n let context = persistContextMap.get(builder)\n\n if (!context) {\n context = createContext<\n PersistentStoreResult<TState, TPlugins> | undefined\n >(undefined)\n persistContextMap.set(builder, context)\n }\n\n return context\n}\n\nfunction usePersistentRuntime<TState, TPlugins = {}>(\n store: InternalPersistedStore<TState, TPlugins>,\n options: PersistRuntimeOptions<TState>,\n): PersistentStoreResult<TState, TPlugins> {\n const onPersist = useEffectEvent(async (args: PersistPersistArgs<TState>) => {\n if (!options.onPersist) {\n return\n }\n\n await options.onPersist(args)\n })\n\n useEffect(() => {\n return store.persist[persistControllerKey].connect(store, {\n enabled: options.enabled,\n delay: options.delay,\n onPersist: options.onPersist ? (args) => onPersist(args) : undefined,\n })\n }, [options.delay, options.enabled, store])\n\n return {\n store,\n flush() {\n return store.persist.flush()\n },\n }\n}\n\n/**\n * Returns the persistent store context for a builder.\n *\n * This hook requires a matching {@link PersistStoreProvider} ancestor.\n */\nexport function usePersistentStore<TState, TPlugins>(\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface>,\n): PersistentStoreResult<TState, TPlugins> {\n const contextValue = useContext(\n getPersistStoreContext<TState, TPlugins>(builder),\n )\n\n if (!contextValue) {\n throw new Error(\n 'usePersistentStore(builder) requires a matching <PersistStoreProvider builder={...}> or <PersistStoreProvider store={...}> ancestor.',\n )\n }\n\n return contextValue\n}\n\nfunction usePersistenceBoundary<TState>(\n store: PersistedStore<TState>,\n options: PersistenceBoundaryOptions,\n) {\n const { flushOnUnmount, flushOnPageHide, flushOnBackground } = options\n useEffect(() => {\n if (!flushOnUnmount) {\n return\n }\n\n return () => {\n void store.persist.flush()\n }\n }, [flushOnUnmount, store])\n\n useEffect(() => {\n if (!flushOnPageHide || typeof window === 'undefined') {\n return\n }\n\n const handlePageHide = () => {\n void store.persist.flush()\n }\n\n window.addEventListener('pagehide', handlePageHide)\n\n return () => {\n window.removeEventListener('pagehide', handlePageHide)\n }\n }, [flushOnPageHide, store])\n\n useEffect(() => {\n if (!flushOnBackground) {\n return\n }\n\n // Web has no app background lifecycle equivalent here yet.\n }, [flushOnBackground])\n}\n\ninterface PersistStoreProviderContentProps<\n TState,\n TPlugins,\n> extends PersistenceBoundaryOptions {\n builder: StoreBuilder<TState, TPlugins & PersistStoreSurface>\n children?: PersistStoreProviderChildren<TState, TPlugins>\n persist?: PersistRuntimeOptions<TState>\n store: InternalPersistedStore<TState, TPlugins>\n}\n\nfunction PersistStoreProviderContent<TState, TPlugins>({\n builder,\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n children,\n persist = {},\n store,\n}: PersistStoreProviderContentProps<TState, TPlugins>) {\n const persistentStore = usePersistentRuntime<TState, TPlugins>(store, persist)\n const Context = getPersistStoreContext<TState, TPlugins>(builder)\n\n usePersistenceBoundary(store, {\n flushOnBackground,\n flushOnPageHide,\n flushOnUnmount,\n })\n\n const content =\n typeof children === 'function' ? children(persistentStore) : children\n\n return <Context.Provider value={persistentStore}>{content}</Context.Provider>\n}\n\n/**\n * Provides a persisted runtime store to React descendants.\n *\n * This composes the core {@link StoreProvider} and connects persistence\n * runtime options such as `enabled`, `delay`, and `onPersist` for the mounted\n * boundary. On web, `flushOnBackground` is currently accepted but does not\n * perform any additional work.\n */\nexport function PersistStoreProvider<TState, TPlugins = {}>(\n props: PersistStoreProviderProps<TState, TPlugins>,\n) {\n if (!props.builder) {\n const builder = getStoreBuilder(props.store)\n\n if (!builder) {\n throw new Error(\n 'PersistStoreProvider could not resolve a builder for the provided store. Pass a persisted store created by @lunarhue/store.',\n )\n }\n\n return (\n <StoreProvider store={props.store}>\n {({ store }) => (\n <PersistStoreProviderContent\n builder={\n builder as StoreBuilder<TState, TPlugins & PersistStoreSurface>\n }\n store={store as InternalPersistedStore<TState, TPlugins>}\n persist={props.persist}\n flushOnUnmount={props.flushOnUnmount}\n flushOnPageHide={props.flushOnPageHide}\n flushOnBackground={props.flushOnBackground}\n >\n {props.children}\n </PersistStoreProviderContent>\n )}\n </StoreProvider>\n )\n }\n\n const content = (store: PersistedStore<TState, TPlugins>) => (\n <PersistStoreProviderContent\n builder={props.builder}\n store={store as InternalPersistedStore<TState, TPlugins>}\n persist={props.persist}\n flushOnUnmount={props.flushOnUnmount}\n flushOnPageHide={props.flushOnPageHide}\n flushOnBackground={props.flushOnBackground}\n >\n {props.children}\n </PersistStoreProviderContent>\n )\n\n if ('initialState' in props) {\n const initialState = props.initialState as TState\n\n return (\n <StoreProvider builder={props.builder} initialState={initialState}>\n {({ store }) => content(store as PersistedStore<TState, TPlugins>)}\n </StoreProvider>\n )\n }\n\n if (props.loadInitialState) {\n return (\n <StoreProvider\n builder={props.builder}\n loadInitialState={props.loadInitialState}\n >\n {({ store }) => content(store as PersistedStore<TState, TPlugins>)}\n </StoreProvider>\n )\n }\n\n return (\n <StoreProvider builder={props.builder}>\n {({ store }) => content(store as PersistedStore<TState, TPlugins>)}\n </StoreProvider>\n )\n}\n"]}
|