everkit-state 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/commonjs/index.js +28 -0
- package/dist/commonjs/index.js.map +1 -0
- package/dist/commonjs/package.json +1 -0
- package/dist/commonjs/preferences.js +55 -0
- package/dist/commonjs/preferences.js.map +1 -0
- package/dist/commonjs/secureStore.js +71 -0
- package/dist/commonjs/secureStore.js.map +1 -0
- package/dist/module/index.js +5 -0
- package/dist/module/index.js.map +1 -0
- package/dist/module/package.json +1 -0
- package/dist/module/preferences.js +49 -0
- package/dist/module/preferences.js.map +1 -0
- package/dist/module/secureStore.js +67 -0
- package/dist/module/secureStore.js.map +1 -0
- package/dist/typescript/commonjs/index.d.ts +3 -0
- package/dist/typescript/commonjs/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/package.json +1 -0
- package/dist/typescript/commonjs/preferences.d.ts +38 -0
- package/dist/typescript/commonjs/preferences.d.ts.map +1 -0
- package/dist/typescript/commonjs/secureStore.d.ts +58 -0
- package/dist/typescript/commonjs/secureStore.d.ts.map +1 -0
- package/dist/typescript/module/index.d.ts +3 -0
- package/dist/typescript/module/index.d.ts.map +1 -0
- package/dist/typescript/module/package.json +1 -0
- package/dist/typescript/module/preferences.d.ts +38 -0
- package/dist/typescript/module/preferences.d.ts.map +1 -0
- package/dist/typescript/module/secureStore.d.ts +58 -0
- package/dist/typescript/module/secureStore.d.ts.map +1 -0
- package/package.json +91 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vladyslav Petrykov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# everkit-state
|
|
2
|
+
|
|
3
|
+
Reusable client-state + persistence primitives for React Native / Expo apps. The storage backend is **injected**, so the core stays pure and testable outside a React Native runtime.
|
|
4
|
+
|
|
5
|
+
## Exports
|
|
6
|
+
|
|
7
|
+
- **`makeSecureStoreAdapter(api)`** → Zustand `StateStorage` — a thin, pass-through bridge from a SecureStore-shaped API (`getItemAsync`/`setItemAsync`/`deleteItemAsync`) to Zustand `persist`. Enforces the load-bearing contract: `getItem` resolves `null` (not `undefined`) on a miss and propagates errors; `removeItem` is idempotent.
|
|
8
|
+
- **`makeSecureJsonStorage(api)`** — `createJSONStorage`-wrapped adapter; what `persist({ storage })` consumes. Lazy, so importing it doesn't touch the native store at boot.
|
|
9
|
+
- **`createPreferencesSlice`** — a composable Zustand slice for the shared persisted shape: `theme` + `hasCompletedOnboarding` (+ setters). Spread into a bound store alongside app-specific runtime fields.
|
|
10
|
+
- **`pickPersistedPreferences(state)`** — `partialize` helper: persists only `theme` + `hasCompletedOnboarding`, dropping actions and foreign fields.
|
|
11
|
+
- **`ThemePreference`** — `'light' | 'dark' | 'system'` (owned here; re-exported by the theme package).
|
|
12
|
+
|
|
13
|
+
## Peer dependencies
|
|
14
|
+
|
|
15
|
+
- `zustand >= 5`
|
|
16
|
+
|
|
17
|
+
## Test
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
npm test # node --require sucrase/register --test "src/**/__tests__/**/*.test.ts"
|
|
21
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
var _secureStore = require("./secureStore.js");
|
|
7
|
+
Object.keys(_secureStore).forEach(function (key) {
|
|
8
|
+
if (key === "default" || key === "__esModule") return;
|
|
9
|
+
if (key in exports && exports[key] === _secureStore[key]) return;
|
|
10
|
+
Object.defineProperty(exports, key, {
|
|
11
|
+
enumerable: true,
|
|
12
|
+
get: function () {
|
|
13
|
+
return _secureStore[key];
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
var _preferences = require("./preferences.js");
|
|
18
|
+
Object.keys(_preferences).forEach(function (key) {
|
|
19
|
+
if (key === "default" || key === "__esModule") return;
|
|
20
|
+
if (key in exports && exports[key] === _preferences[key]) return;
|
|
21
|
+
Object.defineProperty(exports, key, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function () {
|
|
24
|
+
return _preferences[key];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_secureStore","require","Object","keys","forEach","key","exports","defineProperty","enumerable","get","_preferences"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;AAAA,IAAAA,YAAA,GAAAC,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAH,YAAA,EAAAI,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAL,YAAA,CAAAK,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAT,YAAA,CAAAK,GAAA;IAAA;EAAA;AAAA;AACA,IAAAK,YAAA,GAAAT,OAAA;AAAAC,MAAA,CAAAC,IAAA,CAAAO,YAAA,EAAAN,OAAA,WAAAC,GAAA;EAAA,IAAAA,GAAA,kBAAAA,GAAA;EAAA,IAAAA,GAAA,IAAAC,OAAA,IAAAA,OAAA,CAAAD,GAAA,MAAAK,YAAA,CAAAL,GAAA;EAAAH,MAAA,CAAAK,cAAA,CAAAD,OAAA,EAAAD,GAAA;IAAAG,UAAA;IAAAC,GAAA,WAAAA,CAAA;MAAA,OAAAC,YAAA,CAAAL,GAAA;IAAA;EAAA;AAAA","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.createPreferencesSlice = void 0;
|
|
7
|
+
exports.pickPersistedPreferences = pickPersistedPreferences;
|
|
8
|
+
/**
|
|
9
|
+
* User-chosen theme mode. `'system'` defers to the OS appearance. This type
|
|
10
|
+
* is owned here (it backs the persisted preference); the theme-rendering
|
|
11
|
+
* package re-exports it so callers have a single source of truth.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* The slice of app state that is common to every app and persisted across a
|
|
16
|
+
* reload + reboot: the theme preference and the onboarding-completed flag.
|
|
17
|
+
* Apps compose this into their bound store alongside app-specific,
|
|
18
|
+
* runtime-only fields (auth session, bootstrap flags) which are NOT persisted.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Zustand slice creator for the shared preferences. Spread it into a bound
|
|
23
|
+
* store:
|
|
24
|
+
*
|
|
25
|
+
* create<AppState>()(persist((set, get, store) => ({
|
|
26
|
+
* ...createPreferencesSlice(set, get, store),
|
|
27
|
+
* // app-specific, runtime-only fields:
|
|
28
|
+
* session: null,
|
|
29
|
+
* setSession: (session) => set({ session }),
|
|
30
|
+
* }), { name: 'app-store', storage, partialize: pickPersistedPreferences }))
|
|
31
|
+
*/
|
|
32
|
+
const createPreferencesSlice = set => ({
|
|
33
|
+
theme: 'light',
|
|
34
|
+
setTheme: pref => set({
|
|
35
|
+
theme: pref
|
|
36
|
+
}),
|
|
37
|
+
hasCompletedOnboarding: false,
|
|
38
|
+
setHasCompletedOnboarding: value => set({
|
|
39
|
+
hasCompletedOnboarding: value
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* `partialize` helper for `persist`: keep ONLY the persisted preference
|
|
45
|
+
* fields, dropping the action functions and any app-specific runtime fields
|
|
46
|
+
* (e.g. an auth session) that must never be written to disk.
|
|
47
|
+
*/
|
|
48
|
+
exports.createPreferencesSlice = createPreferencesSlice;
|
|
49
|
+
function pickPersistedPreferences(state) {
|
|
50
|
+
return {
|
|
51
|
+
theme: state.theme,
|
|
52
|
+
hasCompletedOnboarding: state.hasCompletedOnboarding
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createPreferencesSlice","set","theme","setTheme","pref","hasCompletedOnboarding","setHasCompletedOnboarding","value","exports","pickPersistedPreferences","state"],"sourceRoot":"../../src","sources":["preferences.ts"],"mappings":";;;;;;;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMA,sBAAgF,GAC3FC,GAAG,KACC;EACJC,KAAK,EAAE,OAAO;EACdC,QAAQ,EAAGC,IAAI,IAAKH,GAAG,CAAC;IAAEC,KAAK,EAAEE;EAAK,CAAC,CAAC;EACxCC,sBAAsB,EAAE,KAAK;EAC7BC,yBAAyB,EAAGC,KAAK,IAAKN,GAAG,CAAC;IAAEI,sBAAsB,EAAEE;EAAM,CAAC;AAC7E,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AAJAC,OAAA,CAAAR,sBAAA,GAAAA,sBAAA;AAKO,SAASS,wBAAwBA,CACtCC,KAAQ,EACoD;EAC5D,OAAO;IAAER,KAAK,EAAEQ,KAAK,CAACR,KAAK;IAAEG,sBAAsB,EAAEK,KAAK,CAACL;EAAuB,CAAC;AACrF","ignoreList":[]}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.makeSecureJsonStorage = makeSecureJsonStorage;
|
|
7
|
+
exports.makeSecureStoreAdapter = makeSecureStoreAdapter;
|
|
8
|
+
var _middleware = require("zustand/middleware");
|
|
9
|
+
/**
|
|
10
|
+
* Pure SecureStore -> Zustand `StateStorage` bridge.
|
|
11
|
+
*
|
|
12
|
+
* Apps persist Zustand stores through a secure key-value store (e.g.
|
|
13
|
+
* `expo-secure-store`) so preferences (theme, onboarding flag, pinned ids)
|
|
14
|
+
* survive a reload AND a device reboot. The wrapping is a one-liner per
|
|
15
|
+
* method, but the contract has two load-bearing rules worth pinning with a
|
|
16
|
+
* test:
|
|
17
|
+
*
|
|
18
|
+
* 1. `getItem` MUST resolve to `null` when the key is missing. Zustand
|
|
19
|
+
* treats `null` as «no persisted state» and falls back to the store's
|
|
20
|
+
* initial state. SecureStore's `getItemAsync` already returns `null`
|
|
21
|
+
* for a missing key, so the adapter just passes it through — but we
|
|
22
|
+
* want a regression guard against accidentally translating that to
|
|
23
|
+
* `undefined`, an empty string, or a thrown error.
|
|
24
|
+
*
|
|
25
|
+
* 2. `removeItem` MUST be idempotent. Logging out clears the persisted
|
|
26
|
+
* slice, and a second logout (or a logout-on-cold-start cleanup pass)
|
|
27
|
+
* MUST NOT throw. SecureStore's `deleteItemAsync` is idempotent, so
|
|
28
|
+
* again the adapter just passes it through.
|
|
29
|
+
*
|
|
30
|
+
* The store API is INJECTED rather than imported, so this module never
|
|
31
|
+
* touches a native module: the production call site passes the real
|
|
32
|
+
* `expo-secure-store` functions in; tests pass an in-memory fake. That keeps
|
|
33
|
+
* the adapter loadable (and testable) in plain Node, outside a React Native
|
|
34
|
+
* runtime.
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The subset of `expo-secure-store` (or any compatible secure key-value
|
|
39
|
+
* store) the adapter depends on. Only the three async functions Zustand's
|
|
40
|
+
* `StateStorage` needs — `setItemAsync`, `getItemAsync`, `deleteItemAsync`.
|
|
41
|
+
* Typed against the platform contract so a future SDK widening of the return
|
|
42
|
+
* type fails compilation here, not at runtime.
|
|
43
|
+
*/
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Build the `StateStorage` Zustand expects from a SecureStore-shaped API.
|
|
47
|
+
*
|
|
48
|
+
* Kept as a thin pass-through on purpose: any logic added here (caching,
|
|
49
|
+
* error swallowing, value transforms) would silently change the persisted
|
|
50
|
+
* shape across all stores. If you need such behaviour, add a SECOND wrapper
|
|
51
|
+
* around this one and document it next to the store that uses it.
|
|
52
|
+
*/
|
|
53
|
+
function makeSecureStoreAdapter(api) {
|
|
54
|
+
return {
|
|
55
|
+
getItem: key => api.getItemAsync(key),
|
|
56
|
+
setItem: (key, value) => api.setItemAsync(key, value),
|
|
57
|
+
removeItem: key => api.deleteItemAsync(key)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* `createJSONStorage`-wrapped adapter — what `persist({ storage })` actually
|
|
63
|
+
* consumes. The factory function is invoked lazily by Zustand on first
|
|
64
|
+
* read/write, so importing this module does NOT touch the secure store at app
|
|
65
|
+
* boot. That matters because a native secure store is unavailable during SSR
|
|
66
|
+
* and during the test runner's module load.
|
|
67
|
+
*/
|
|
68
|
+
function makeSecureJsonStorage(api) {
|
|
69
|
+
return (0, _middleware.createJSONStorage)(() => makeSecureStoreAdapter(api));
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=secureStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_middleware","require","makeSecureStoreAdapter","api","getItem","key","getItemAsync","setItem","value","setItemAsync","removeItem","deleteItemAsync","makeSecureJsonStorage","createJSONStorage"],"sourceRoot":"../../src","sources":["secureStore.ts"],"mappings":";;;;;;;AA4BA,IAAAA,WAAA,GAAAC,OAAA;AA5BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,sBAAsBA,CAACC,GAAmB,EAAgB;EACxE,OAAO;IACLC,OAAO,EAAGC,GAAW,IAAKF,GAAG,CAACG,YAAY,CAACD,GAAG,CAAC;IAC/CE,OAAO,EAAEA,CAACF,GAAW,EAAEG,KAAa,KAAKL,GAAG,CAACM,YAAY,CAACJ,GAAG,EAAEG,KAAK,CAAC;IACrEE,UAAU,EAAGL,GAAW,IAAKF,GAAG,CAACQ,eAAe,CAACN,GAAG;EACtD,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASO,qBAAqBA,CAACT,GAAmB,EAAE;EACzD,OAAO,IAAAU,6BAAiB,EAAC,MAAMX,sBAAsB,CAACC,GAAG,CAAC,CAAC;AAC7D","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,cAAc,kBAAe;AAC7B,cAAc,kBAAe","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* User-chosen theme mode. `'system'` defers to the OS appearance. This type
|
|
5
|
+
* is owned here (it backs the persisted preference); the theme-rendering
|
|
6
|
+
* package re-exports it so callers have a single source of truth.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The slice of app state that is common to every app and persisted across a
|
|
11
|
+
* reload + reboot: the theme preference and the onboarding-completed flag.
|
|
12
|
+
* Apps compose this into their bound store alongside app-specific,
|
|
13
|
+
* runtime-only fields (auth session, bootstrap flags) which are NOT persisted.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Zustand slice creator for the shared preferences. Spread it into a bound
|
|
18
|
+
* store:
|
|
19
|
+
*
|
|
20
|
+
* create<AppState>()(persist((set, get, store) => ({
|
|
21
|
+
* ...createPreferencesSlice(set, get, store),
|
|
22
|
+
* // app-specific, runtime-only fields:
|
|
23
|
+
* session: null,
|
|
24
|
+
* setSession: (session) => set({ session }),
|
|
25
|
+
* }), { name: 'app-store', storage, partialize: pickPersistedPreferences }))
|
|
26
|
+
*/
|
|
27
|
+
export const createPreferencesSlice = set => ({
|
|
28
|
+
theme: 'light',
|
|
29
|
+
setTheme: pref => set({
|
|
30
|
+
theme: pref
|
|
31
|
+
}),
|
|
32
|
+
hasCompletedOnboarding: false,
|
|
33
|
+
setHasCompletedOnboarding: value => set({
|
|
34
|
+
hasCompletedOnboarding: value
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* `partialize` helper for `persist`: keep ONLY the persisted preference
|
|
40
|
+
* fields, dropping the action functions and any app-specific runtime fields
|
|
41
|
+
* (e.g. an auth session) that must never be written to disk.
|
|
42
|
+
*/
|
|
43
|
+
export function pickPersistedPreferences(state) {
|
|
44
|
+
return {
|
|
45
|
+
theme: state.theme,
|
|
46
|
+
hasCompletedOnboarding: state.hasCompletedOnboarding
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createPreferencesSlice","set","theme","setTheme","pref","hasCompletedOnboarding","setHasCompletedOnboarding","value","pickPersistedPreferences","state"],"sourceRoot":"../../src","sources":["preferences.ts"],"mappings":";;AAEA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,sBAAgF,GAC3FC,GAAG,KACC;EACJC,KAAK,EAAE,OAAO;EACdC,QAAQ,EAAGC,IAAI,IAAKH,GAAG,CAAC;IAAEC,KAAK,EAAEE;EAAK,CAAC,CAAC;EACxCC,sBAAsB,EAAE,KAAK;EAC7BC,yBAAyB,EAAGC,KAAK,IAAKN,GAAG,CAAC;IAAEI,sBAAsB,EAAEE;EAAM,CAAC;AAC7E,CAAC,CAAC;;AAEF;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,wBAAwBA,CACtCC,KAAQ,EACoD;EAC5D,OAAO;IAAEP,KAAK,EAAEO,KAAK,CAACP,KAAK;IAAEG,sBAAsB,EAAEI,KAAK,CAACJ;EAAuB,CAAC;AACrF","ignoreList":[]}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Pure SecureStore -> Zustand `StateStorage` bridge.
|
|
5
|
+
*
|
|
6
|
+
* Apps persist Zustand stores through a secure key-value store (e.g.
|
|
7
|
+
* `expo-secure-store`) so preferences (theme, onboarding flag, pinned ids)
|
|
8
|
+
* survive a reload AND a device reboot. The wrapping is a one-liner per
|
|
9
|
+
* method, but the contract has two load-bearing rules worth pinning with a
|
|
10
|
+
* test:
|
|
11
|
+
*
|
|
12
|
+
* 1. `getItem` MUST resolve to `null` when the key is missing. Zustand
|
|
13
|
+
* treats `null` as «no persisted state» and falls back to the store's
|
|
14
|
+
* initial state. SecureStore's `getItemAsync` already returns `null`
|
|
15
|
+
* for a missing key, so the adapter just passes it through — but we
|
|
16
|
+
* want a regression guard against accidentally translating that to
|
|
17
|
+
* `undefined`, an empty string, or a thrown error.
|
|
18
|
+
*
|
|
19
|
+
* 2. `removeItem` MUST be idempotent. Logging out clears the persisted
|
|
20
|
+
* slice, and a second logout (or a logout-on-cold-start cleanup pass)
|
|
21
|
+
* MUST NOT throw. SecureStore's `deleteItemAsync` is idempotent, so
|
|
22
|
+
* again the adapter just passes it through.
|
|
23
|
+
*
|
|
24
|
+
* The store API is INJECTED rather than imported, so this module never
|
|
25
|
+
* touches a native module: the production call site passes the real
|
|
26
|
+
* `expo-secure-store` functions in; tests pass an in-memory fake. That keeps
|
|
27
|
+
* the adapter loadable (and testable) in plain Node, outside a React Native
|
|
28
|
+
* runtime.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
import { createJSONStorage } from 'zustand/middleware';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The subset of `expo-secure-store` (or any compatible secure key-value
|
|
35
|
+
* store) the adapter depends on. Only the three async functions Zustand's
|
|
36
|
+
* `StateStorage` needs — `setItemAsync`, `getItemAsync`, `deleteItemAsync`.
|
|
37
|
+
* Typed against the platform contract so a future SDK widening of the return
|
|
38
|
+
* type fails compilation here, not at runtime.
|
|
39
|
+
*/
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Build the `StateStorage` Zustand expects from a SecureStore-shaped API.
|
|
43
|
+
*
|
|
44
|
+
* Kept as a thin pass-through on purpose: any logic added here (caching,
|
|
45
|
+
* error swallowing, value transforms) would silently change the persisted
|
|
46
|
+
* shape across all stores. If you need such behaviour, add a SECOND wrapper
|
|
47
|
+
* around this one and document it next to the store that uses it.
|
|
48
|
+
*/
|
|
49
|
+
export function makeSecureStoreAdapter(api) {
|
|
50
|
+
return {
|
|
51
|
+
getItem: key => api.getItemAsync(key),
|
|
52
|
+
setItem: (key, value) => api.setItemAsync(key, value),
|
|
53
|
+
removeItem: key => api.deleteItemAsync(key)
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* `createJSONStorage`-wrapped adapter — what `persist({ storage })` actually
|
|
59
|
+
* consumes. The factory function is invoked lazily by Zustand on first
|
|
60
|
+
* read/write, so importing this module does NOT touch the secure store at app
|
|
61
|
+
* boot. That matters because a native secure store is unavailable during SSR
|
|
62
|
+
* and during the test runner's module load.
|
|
63
|
+
*/
|
|
64
|
+
export function makeSecureJsonStorage(api) {
|
|
65
|
+
return createJSONStorage(() => makeSecureStoreAdapter(api));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=secureStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["createJSONStorage","makeSecureStoreAdapter","api","getItem","key","getItemAsync","setItem","value","setItemAsync","removeItem","deleteItemAsync","makeSecureJsonStorage"],"sourceRoot":"../../src","sources":["secureStore.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,iBAAiB,QAA2B,oBAAoB;;AAEzE;AACA;AACA;AACA;AACA;AACA;AACA;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,sBAAsBA,CAACC,GAAmB,EAAgB;EACxE,OAAO;IACLC,OAAO,EAAGC,GAAW,IAAKF,GAAG,CAACG,YAAY,CAACD,GAAG,CAAC;IAC/CE,OAAO,EAAEA,CAACF,GAAW,EAAEG,KAAa,KAAKL,GAAG,CAACM,YAAY,CAACJ,GAAG,EAAEG,KAAK,CAAC;IACrEE,UAAU,EAAGL,GAAW,IAAKF,GAAG,CAACQ,eAAe,CAACN,GAAG;EACtD,CAAC;AACH;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASO,qBAAqBA,CAACT,GAAmB,EAAE;EACzD,OAAOF,iBAAiB,CAAC,MAAMC,sBAAsB,CAACC,GAAG,CAAC,CAAC;AAC7D","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAA;AAC7B,cAAc,eAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { StateCreator } from 'zustand';
|
|
2
|
+
/**
|
|
3
|
+
* User-chosen theme mode. `'system'` defers to the OS appearance. This type
|
|
4
|
+
* is owned here (it backs the persisted preference); the theme-rendering
|
|
5
|
+
* package re-exports it so callers have a single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export type ThemePreference = 'light' | 'dark' | 'system';
|
|
8
|
+
/**
|
|
9
|
+
* The slice of app state that is common to every app and persisted across a
|
|
10
|
+
* reload + reboot: the theme preference and the onboarding-completed flag.
|
|
11
|
+
* Apps compose this into their bound store alongside app-specific,
|
|
12
|
+
* runtime-only fields (auth session, bootstrap flags) which are NOT persisted.
|
|
13
|
+
*/
|
|
14
|
+
export interface PreferencesSlice {
|
|
15
|
+
theme: ThemePreference;
|
|
16
|
+
setTheme: (pref: ThemePreference) => void;
|
|
17
|
+
hasCompletedOnboarding: boolean;
|
|
18
|
+
setHasCompletedOnboarding: (value: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Zustand slice creator for the shared preferences. Spread it into a bound
|
|
22
|
+
* store:
|
|
23
|
+
*
|
|
24
|
+
* create<AppState>()(persist((set, get, store) => ({
|
|
25
|
+
* ...createPreferencesSlice(set, get, store),
|
|
26
|
+
* // app-specific, runtime-only fields:
|
|
27
|
+
* session: null,
|
|
28
|
+
* setSession: (session) => set({ session }),
|
|
29
|
+
* }), { name: 'app-store', storage, partialize: pickPersistedPreferences }))
|
|
30
|
+
*/
|
|
31
|
+
export declare const createPreferencesSlice: StateCreator<PreferencesSlice, [], [], PreferencesSlice>;
|
|
32
|
+
/**
|
|
33
|
+
* `partialize` helper for `persist`: keep ONLY the persisted preference
|
|
34
|
+
* fields, dropping the action functions and any app-specific runtime fields
|
|
35
|
+
* (e.g. an auth session) that must never be written to disk.
|
|
36
|
+
*/
|
|
37
|
+
export declare function pickPersistedPreferences<S extends PreferencesSlice>(state: S): Pick<PreferencesSlice, 'theme' | 'hasCompletedOnboarding'>;
|
|
38
|
+
//# sourceMappingURL=preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;IACzC,sBAAsB,EAAE,OAAO,CAAA;IAC/B,yBAAyB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACpD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,EAAE,YAAY,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,gBAAgB,CAO1F,CAAA;AAEF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,gBAAgB,EACjE,KAAK,EAAE,CAAC,GACP,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,wBAAwB,CAAC,CAE5D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure SecureStore -> Zustand `StateStorage` bridge.
|
|
3
|
+
*
|
|
4
|
+
* Apps persist Zustand stores through a secure key-value store (e.g.
|
|
5
|
+
* `expo-secure-store`) so preferences (theme, onboarding flag, pinned ids)
|
|
6
|
+
* survive a reload AND a device reboot. The wrapping is a one-liner per
|
|
7
|
+
* method, but the contract has two load-bearing rules worth pinning with a
|
|
8
|
+
* test:
|
|
9
|
+
*
|
|
10
|
+
* 1. `getItem` MUST resolve to `null` when the key is missing. Zustand
|
|
11
|
+
* treats `null` as «no persisted state» and falls back to the store's
|
|
12
|
+
* initial state. SecureStore's `getItemAsync` already returns `null`
|
|
13
|
+
* for a missing key, so the adapter just passes it through — but we
|
|
14
|
+
* want a regression guard against accidentally translating that to
|
|
15
|
+
* `undefined`, an empty string, or a thrown error.
|
|
16
|
+
*
|
|
17
|
+
* 2. `removeItem` MUST be idempotent. Logging out clears the persisted
|
|
18
|
+
* slice, and a second logout (or a logout-on-cold-start cleanup pass)
|
|
19
|
+
* MUST NOT throw. SecureStore's `deleteItemAsync` is idempotent, so
|
|
20
|
+
* again the adapter just passes it through.
|
|
21
|
+
*
|
|
22
|
+
* The store API is INJECTED rather than imported, so this module never
|
|
23
|
+
* touches a native module: the production call site passes the real
|
|
24
|
+
* `expo-secure-store` functions in; tests pass an in-memory fake. That keeps
|
|
25
|
+
* the adapter loadable (and testable) in plain Node, outside a React Native
|
|
26
|
+
* runtime.
|
|
27
|
+
*/
|
|
28
|
+
import { type StateStorage } from 'zustand/middleware';
|
|
29
|
+
/**
|
|
30
|
+
* The subset of `expo-secure-store` (or any compatible secure key-value
|
|
31
|
+
* store) the adapter depends on. Only the three async functions Zustand's
|
|
32
|
+
* `StateStorage` needs — `setItemAsync`, `getItemAsync`, `deleteItemAsync`.
|
|
33
|
+
* Typed against the platform contract so a future SDK widening of the return
|
|
34
|
+
* type fails compilation here, not at runtime.
|
|
35
|
+
*/
|
|
36
|
+
export interface SecureStoreApi {
|
|
37
|
+
getItemAsync: (key: string) => Promise<string | null>;
|
|
38
|
+
setItemAsync: (key: string, value: string) => Promise<void>;
|
|
39
|
+
deleteItemAsync: (key: string) => Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build the `StateStorage` Zustand expects from a SecureStore-shaped API.
|
|
43
|
+
*
|
|
44
|
+
* Kept as a thin pass-through on purpose: any logic added here (caching,
|
|
45
|
+
* error swallowing, value transforms) would silently change the persisted
|
|
46
|
+
* shape across all stores. If you need such behaviour, add a SECOND wrapper
|
|
47
|
+
* around this one and document it next to the store that uses it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function makeSecureStoreAdapter(api: SecureStoreApi): StateStorage;
|
|
50
|
+
/**
|
|
51
|
+
* `createJSONStorage`-wrapped adapter — what `persist({ storage })` actually
|
|
52
|
+
* consumes. The factory function is invoked lazily by Zustand on first
|
|
53
|
+
* read/write, so importing this module does NOT touch the secure store at app
|
|
54
|
+
* boot. That matters because a native secure store is unavailable during SSR
|
|
55
|
+
* and during the test runner's module load.
|
|
56
|
+
*/
|
|
57
|
+
export declare function makeSecureJsonStorage(api: SecureStoreApi): import("zustand/middleware").PersistStorage<unknown, unknown> | undefined;
|
|
58
|
+
//# sourceMappingURL=secureStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secureStore.d.ts","sourceRoot":"","sources":["../../../src/secureStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEzE;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACrD,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY,CAMxE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,cAAc,6EAExD"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAe,CAAA;AAC7B,cAAc,kBAAe,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"module"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { StateCreator } from 'zustand';
|
|
2
|
+
/**
|
|
3
|
+
* User-chosen theme mode. `'system'` defers to the OS appearance. This type
|
|
4
|
+
* is owned here (it backs the persisted preference); the theme-rendering
|
|
5
|
+
* package re-exports it so callers have a single source of truth.
|
|
6
|
+
*/
|
|
7
|
+
export type ThemePreference = 'light' | 'dark' | 'system';
|
|
8
|
+
/**
|
|
9
|
+
* The slice of app state that is common to every app and persisted across a
|
|
10
|
+
* reload + reboot: the theme preference and the onboarding-completed flag.
|
|
11
|
+
* Apps compose this into their bound store alongside app-specific,
|
|
12
|
+
* runtime-only fields (auth session, bootstrap flags) which are NOT persisted.
|
|
13
|
+
*/
|
|
14
|
+
export interface PreferencesSlice {
|
|
15
|
+
theme: ThemePreference;
|
|
16
|
+
setTheme: (pref: ThemePreference) => void;
|
|
17
|
+
hasCompletedOnboarding: boolean;
|
|
18
|
+
setHasCompletedOnboarding: (value: boolean) => void;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Zustand slice creator for the shared preferences. Spread it into a bound
|
|
22
|
+
* store:
|
|
23
|
+
*
|
|
24
|
+
* create<AppState>()(persist((set, get, store) => ({
|
|
25
|
+
* ...createPreferencesSlice(set, get, store),
|
|
26
|
+
* // app-specific, runtime-only fields:
|
|
27
|
+
* session: null,
|
|
28
|
+
* setSession: (session) => set({ session }),
|
|
29
|
+
* }), { name: 'app-store', storage, partialize: pickPersistedPreferences }))
|
|
30
|
+
*/
|
|
31
|
+
export declare const createPreferencesSlice: StateCreator<PreferencesSlice, [], [], PreferencesSlice>;
|
|
32
|
+
/**
|
|
33
|
+
* `partialize` helper for `persist`: keep ONLY the persisted preference
|
|
34
|
+
* fields, dropping the action functions and any app-specific runtime fields
|
|
35
|
+
* (e.g. an auth session) that must never be written to disk.
|
|
36
|
+
*/
|
|
37
|
+
export declare function pickPersistedPreferences<S extends PreferencesSlice>(state: S): Pick<PreferencesSlice, 'theme' | 'hasCompletedOnboarding'>;
|
|
38
|
+
//# sourceMappingURL=preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../../src/preferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAA;AAEzD;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,eAAe,CAAA;IACtB,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAA;IACzC,sBAAsB,EAAE,OAAO,CAAA;IAC/B,yBAAyB,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;CACpD;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,EAAE,YAAY,CAAC,gBAAgB,EAAE,EAAE,EAAE,EAAE,EAAE,gBAAgB,CAO1F,CAAA;AAEF;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,SAAS,gBAAgB,EACjE,KAAK,EAAE,CAAC,GACP,IAAI,CAAC,gBAAgB,EAAE,OAAO,GAAG,wBAAwB,CAAC,CAE5D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure SecureStore -> Zustand `StateStorage` bridge.
|
|
3
|
+
*
|
|
4
|
+
* Apps persist Zustand stores through a secure key-value store (e.g.
|
|
5
|
+
* `expo-secure-store`) so preferences (theme, onboarding flag, pinned ids)
|
|
6
|
+
* survive a reload AND a device reboot. The wrapping is a one-liner per
|
|
7
|
+
* method, but the contract has two load-bearing rules worth pinning with a
|
|
8
|
+
* test:
|
|
9
|
+
*
|
|
10
|
+
* 1. `getItem` MUST resolve to `null` when the key is missing. Zustand
|
|
11
|
+
* treats `null` as «no persisted state» and falls back to the store's
|
|
12
|
+
* initial state. SecureStore's `getItemAsync` already returns `null`
|
|
13
|
+
* for a missing key, so the adapter just passes it through — but we
|
|
14
|
+
* want a regression guard against accidentally translating that to
|
|
15
|
+
* `undefined`, an empty string, or a thrown error.
|
|
16
|
+
*
|
|
17
|
+
* 2. `removeItem` MUST be idempotent. Logging out clears the persisted
|
|
18
|
+
* slice, and a second logout (or a logout-on-cold-start cleanup pass)
|
|
19
|
+
* MUST NOT throw. SecureStore's `deleteItemAsync` is idempotent, so
|
|
20
|
+
* again the adapter just passes it through.
|
|
21
|
+
*
|
|
22
|
+
* The store API is INJECTED rather than imported, so this module never
|
|
23
|
+
* touches a native module: the production call site passes the real
|
|
24
|
+
* `expo-secure-store` functions in; tests pass an in-memory fake. That keeps
|
|
25
|
+
* the adapter loadable (and testable) in plain Node, outside a React Native
|
|
26
|
+
* runtime.
|
|
27
|
+
*/
|
|
28
|
+
import { type StateStorage } from 'zustand/middleware';
|
|
29
|
+
/**
|
|
30
|
+
* The subset of `expo-secure-store` (or any compatible secure key-value
|
|
31
|
+
* store) the adapter depends on. Only the three async functions Zustand's
|
|
32
|
+
* `StateStorage` needs — `setItemAsync`, `getItemAsync`, `deleteItemAsync`.
|
|
33
|
+
* Typed against the platform contract so a future SDK widening of the return
|
|
34
|
+
* type fails compilation here, not at runtime.
|
|
35
|
+
*/
|
|
36
|
+
export interface SecureStoreApi {
|
|
37
|
+
getItemAsync: (key: string) => Promise<string | null>;
|
|
38
|
+
setItemAsync: (key: string, value: string) => Promise<void>;
|
|
39
|
+
deleteItemAsync: (key: string) => Promise<void>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Build the `StateStorage` Zustand expects from a SecureStore-shaped API.
|
|
43
|
+
*
|
|
44
|
+
* Kept as a thin pass-through on purpose: any logic added here (caching,
|
|
45
|
+
* error swallowing, value transforms) would silently change the persisted
|
|
46
|
+
* shape across all stores. If you need such behaviour, add a SECOND wrapper
|
|
47
|
+
* around this one and document it next to the store that uses it.
|
|
48
|
+
*/
|
|
49
|
+
export declare function makeSecureStoreAdapter(api: SecureStoreApi): StateStorage;
|
|
50
|
+
/**
|
|
51
|
+
* `createJSONStorage`-wrapped adapter — what `persist({ storage })` actually
|
|
52
|
+
* consumes. The factory function is invoked lazily by Zustand on first
|
|
53
|
+
* read/write, so importing this module does NOT touch the secure store at app
|
|
54
|
+
* boot. That matters because a native secure store is unavailable during SSR
|
|
55
|
+
* and during the test runner's module load.
|
|
56
|
+
*/
|
|
57
|
+
export declare function makeSecureJsonStorage(api: SecureStoreApi): import("zustand/middleware").PersistStorage<unknown, unknown> | undefined;
|
|
58
|
+
//# sourceMappingURL=secureStore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secureStore.d.ts","sourceRoot":"","sources":["../../../src/secureStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEzE;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAA;IACrD,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3D,eAAe,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAChD;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,cAAc,GAAG,YAAY,CAMxE;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,cAAc,6EAExD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "everkit-state",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Reusable client-state + persistence primitives for React Native / Expo apps: a SecureStore-to-Zustand StateStorage adapter and a composable preferences (theme + onboarding) slice. The storage backend is injected by the consumer, so the core stays pure and testable outside a React Native runtime.",
|
|
5
|
+
"private": false,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Vladyslav Petrykov",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"react-native",
|
|
10
|
+
"expo",
|
|
11
|
+
"zustand",
|
|
12
|
+
"secure-store",
|
|
13
|
+
"state",
|
|
14
|
+
"persistence"
|
|
15
|
+
],
|
|
16
|
+
"source": "./src/index.ts",
|
|
17
|
+
"main": "./dist/commonjs/index.js",
|
|
18
|
+
"module": "./dist/module/index.js",
|
|
19
|
+
"types": "./dist/typescript/commonjs/index.d.ts",
|
|
20
|
+
"react-native": "./dist/module/index.js",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"source": "./src/index.ts",
|
|
24
|
+
"import": {
|
|
25
|
+
"types": "./dist/typescript/module/index.d.ts",
|
|
26
|
+
"default": "./dist/module/index.js"
|
|
27
|
+
},
|
|
28
|
+
"require": {
|
|
29
|
+
"types": "./dist/typescript/commonjs/index.d.ts",
|
|
30
|
+
"default": "./dist/commonjs/index.js"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist",
|
|
37
|
+
"README.md",
|
|
38
|
+
"LICENSE",
|
|
39
|
+
"package.json",
|
|
40
|
+
"!**/__tests__",
|
|
41
|
+
"!**/*.test.ts"
|
|
42
|
+
],
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "bob build",
|
|
45
|
+
"prepare": "bob build",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"test": "node --require sucrase/register --test \"src/**/__tests__/**/*.test.ts\"",
|
|
48
|
+
"test:watch": "node --watch --require sucrase/register --test \"src/**/__tests__/**/*.test.ts\"",
|
|
49
|
+
"clean": "rm -rf dist"
|
|
50
|
+
},
|
|
51
|
+
"react-native-builder-bob": {
|
|
52
|
+
"source": "src",
|
|
53
|
+
"output": "dist",
|
|
54
|
+
"exclude": "{**/{__tests__,__fixtures__,__mocks__}/**,**/*.test.ts,**/*.d.ts}",
|
|
55
|
+
"targets": [
|
|
56
|
+
[
|
|
57
|
+
"module",
|
|
58
|
+
{
|
|
59
|
+
"esm": true,
|
|
60
|
+
"configFile": false,
|
|
61
|
+
"babelrc": false
|
|
62
|
+
}
|
|
63
|
+
],
|
|
64
|
+
[
|
|
65
|
+
"commonjs",
|
|
66
|
+
{
|
|
67
|
+
"esm": true,
|
|
68
|
+
"configFile": false,
|
|
69
|
+
"babelrc": false
|
|
70
|
+
}
|
|
71
|
+
],
|
|
72
|
+
[
|
|
73
|
+
"typescript",
|
|
74
|
+
{
|
|
75
|
+
"project": "tsconfig.build.json"
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
]
|
|
79
|
+
},
|
|
80
|
+
"peerDependencies": {
|
|
81
|
+
"zustand": ">=5.0.0"
|
|
82
|
+
},
|
|
83
|
+
"devDependencies": {
|
|
84
|
+
"@babel/core": "^7.29.0",
|
|
85
|
+
"@types/node": "^22.10.0",
|
|
86
|
+
"react-native-builder-bob": "^0.42.1",
|
|
87
|
+
"sucrase": "^3.35.1",
|
|
88
|
+
"typescript": "~5.9.2",
|
|
89
|
+
"zustand": "^5.0.11"
|
|
90
|
+
}
|
|
91
|
+
}
|