nukejs 0.0.22 → 0.0.23
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/dist/index.d.ts +1 -1
- package/dist/index.js +2 -1
- package/dist/store.d.ts +42 -0
- package/dist/store.js +22 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createStore, useStore } from "./store.js";
|
|
1
|
+
import { createStore, createPersistedStore, useStore } from "./store.js";
|
|
2
2
|
import { useHtml } from "./use-html.js";
|
|
3
3
|
import { default as default2 } from "./use-router.js";
|
|
4
4
|
import { useRequest } from "./use-request.js";
|
|
@@ -11,6 +11,7 @@ export {
|
|
|
11
11
|
default3 as Link,
|
|
12
12
|
ansi,
|
|
13
13
|
c,
|
|
14
|
+
createPersistedStore,
|
|
14
15
|
createStore,
|
|
15
16
|
escapeHtml,
|
|
16
17
|
getDebugLevel,
|
package/dist/store.d.ts
CHANGED
|
@@ -65,6 +65,7 @@ interface StoreEntry<T> {
|
|
|
65
65
|
declare global {
|
|
66
66
|
interface Window {
|
|
67
67
|
__nukeStores?: Map<string, StoreEntry<any>>;
|
|
68
|
+
__nukePersisted?: Set<string>;
|
|
68
69
|
}
|
|
69
70
|
}
|
|
70
71
|
/**
|
|
@@ -80,6 +81,47 @@ declare global {
|
|
|
80
81
|
* @param initialState Default state used when the store is first created.
|
|
81
82
|
*/
|
|
82
83
|
export declare function createStore<T extends object>(name: string, initialState: T): Store<T>;
|
|
84
|
+
/**
|
|
85
|
+
* Creates a `Store` that survives full page refreshes by mirroring its state
|
|
86
|
+
* into `localStorage` (or `sessionStorage`).
|
|
87
|
+
*
|
|
88
|
+
* A plain `createStore` only lives in `window.__nukeStores`, which is wiped
|
|
89
|
+
* on every hard reload — fine for SPA navigations, not for data you want to
|
|
90
|
+
* keep around. `createPersistedStore` wraps `createStore` and:
|
|
91
|
+
*
|
|
92
|
+
* 1. On first creation in the browser, reads any previously saved value
|
|
93
|
+
* from storage and applies it via `setState`.
|
|
94
|
+
* 2. Subscribes to the store and writes the new state to storage on every
|
|
95
|
+
* change.
|
|
96
|
+
*
|
|
97
|
+
* `store.initialState` (used by `useStore` as the SSR snapshot) is left
|
|
98
|
+
* untouched as the value you passed in — the persisted value is applied
|
|
99
|
+
* *after* creation via `setState`, not by changing `initialState`. This
|
|
100
|
+
* keeps the server-rendered HTML and the client's first hydration pass in
|
|
101
|
+
* sync (no hydration mismatch); components simply re-render with the
|
|
102
|
+
* persisted value immediately after mount, the same way `useSyncExternalStore`
|
|
103
|
+
* already reconciles store mutations.
|
|
104
|
+
*
|
|
105
|
+
* Because `createStore` itself is idempotent per `name` but storage I/O is
|
|
106
|
+
* not, a `window.__nukePersisted` set guards against re-running the
|
|
107
|
+
* read/subscribe wiring if multiple bundles import the same persisted store.
|
|
108
|
+
*
|
|
109
|
+
* @param name Unique store key — also used to derive the storage key.
|
|
110
|
+
* @param initialState Default state used when nothing is in storage yet.
|
|
111
|
+
* @param options.storage `'local'` (default) or `'session'`.
|
|
112
|
+
* @param options.key Override the storage key (defaults to `nuke-store:${name}`).
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* export const cartStore = createPersistedStore('cart', { items: [], total: 0 })
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* // Cleared when the tab closes, kept across refreshes within the session
|
|
119
|
+
* export const draftStore = createPersistedStore('draft', { text: '' }, { storage: 'session' })
|
|
120
|
+
*/
|
|
121
|
+
export declare function createPersistedStore<T extends object>(name: string, initialState: T, options?: {
|
|
122
|
+
storage?: 'local' | 'session';
|
|
123
|
+
key?: string;
|
|
124
|
+
}): Store<T>;
|
|
83
125
|
/**
|
|
84
126
|
* React hook that subscribes a component to a store.
|
|
85
127
|
*
|
package/dist/store.js
CHANGED
|
@@ -30,6 +30,27 @@ function createStore(name, initialState) {
|
|
|
30
30
|
};
|
|
31
31
|
return { name, initialState, getState, setState, subscribe };
|
|
32
32
|
}
|
|
33
|
+
function createPersistedStore(name, initialState, options) {
|
|
34
|
+
const store = createStore(name, initialState);
|
|
35
|
+
if (typeof window === "undefined") return store;
|
|
36
|
+
const storageKey = options?.key ?? `nuke-store:${name}`;
|
|
37
|
+
const backend = options?.storage === "session" ? window.sessionStorage : window.localStorage;
|
|
38
|
+
if (!window.__nukePersisted) window.__nukePersisted = /* @__PURE__ */ new Set();
|
|
39
|
+
if (window.__nukePersisted.has(storageKey)) return store;
|
|
40
|
+
window.__nukePersisted.add(storageKey);
|
|
41
|
+
try {
|
|
42
|
+
const raw = backend.getItem(storageKey);
|
|
43
|
+
if (raw !== null) store.setState(JSON.parse(raw));
|
|
44
|
+
} catch {
|
|
45
|
+
}
|
|
46
|
+
store.subscribe(() => {
|
|
47
|
+
try {
|
|
48
|
+
backend.setItem(storageKey, JSON.stringify(store.getState()));
|
|
49
|
+
} catch {
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return store;
|
|
53
|
+
}
|
|
33
54
|
function useStore(store, selector) {
|
|
34
55
|
const getSnapshot = selector ? () => selector(store.getState()) : () => store.getState();
|
|
35
56
|
const getServerSnapshot = selector ? () => selector(store.initialState) : () => store.initialState;
|
|
@@ -40,6 +61,7 @@ function useStore(store, selector) {
|
|
|
40
61
|
);
|
|
41
62
|
}
|
|
42
63
|
export {
|
|
64
|
+
createPersistedStore,
|
|
43
65
|
createStore,
|
|
44
66
|
useStore
|
|
45
67
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nukejs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "A minimal, opinionated full-stack React framework on Node.js that server-renders everything and hydrates only interactive parts.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|