pinia-plugin-uni-persist-next 1.0.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 ADDED
@@ -0,0 +1,117 @@
1
+ # pinia-plugin-uni-persist
2
+
3
+ 专为 **UniApp** 打造的 Pinia 持久化插件。
4
+
5
+ > A Pinia persistence plugin specifically designed for UniApp.
6
+
7
+ ## ✨ 特性
8
+
9
+ - ⚡ **UniApp 专用**:基于 `uni.setStorage` 和 `uni.getStorageSync` 开发。
10
+ - 🚀 **性能优化**:
11
+ - **写入**:默认异步 (`async`),避免大数据量写入阻塞主线程导致页面卡顿。
12
+ - **读取**:初始化时同步 (`sync`),确保页面渲染前数据已就绪。
13
+ - 🛡️ **安全可靠**:自动处理 `BigInt`、`Date` 和循环引用 (`Circular References`)。
14
+ - 📦 **TypeScript**:提供完整的类型定义。
15
+
16
+ ## 📦 安装
17
+
18
+ 使用 pnpm (推荐):
19
+
20
+ ```bash
21
+ pnpm add pinia-plugin-uni-persist
22
+ ```
23
+
24
+ 或者 npm/yarn:
25
+
26
+ ```bash
27
+ npm install pinia-plugin-uni-persist
28
+ # yarn add pinia-plugin-uni-persist
29
+ ```
30
+
31
+ ## 🚀 快速上手
32
+
33
+ ### 1. 注册插件 (main.ts)
34
+
35
+ ```typescript
36
+ import { createSSRApp } from "vue";
37
+ import { createPinia } from "pinia";
38
+ import { createUniPersistPlugin } from "pinia-plugin-uni-persist"; // 引入插件
39
+ import App from "./App.vue";
40
+
41
+ export function createApp() {
42
+ const app = createSSRApp(App);
43
+ const pinia = createPinia();
44
+
45
+ // 注册插件
46
+ pinia.use(
47
+ createUniPersistPlugin({
48
+ keyPrefix: "app_storage_", // 可选:配置统一的 key 前缀
49
+ })
50
+ );
51
+
52
+ app.use(pinia);
53
+ return { app };
54
+ }
55
+ ```
56
+
57
+ ### 2. 在 Store 中使用
58
+
59
+ 在定义 store 时,添加 `persist` 配置即可。
60
+
61
+ #### 组合式 (Setup Store) - 推荐
62
+
63
+ ```typescript
64
+ import { defineStore } from "pinia";
65
+ import { ref } from "vue";
66
+
67
+ export const useUserStore = defineStore(
68
+ "user",
69
+ () => {
70
+ const token = ref("");
71
+ const userInfo = ref({ name: "UniApp", age: 18 });
72
+
73
+ return { token, userInfo };
74
+ },
75
+ {
76
+ persist: {
77
+ enabled: true, // 开启持久化
78
+ strategies: [
79
+ {
80
+ key: "user_key", // 自定义存储 key
81
+ paths: ["token"], // 指定只持久化 token
82
+ },
83
+ ],
84
+ },
85
+ }
86
+ );
87
+ ```
88
+
89
+ ## ⚙️ 配置说明
90
+
91
+ | 选项 | 类型 | 默认值 | 说明 |
92
+ | ------------ | --------- | ---------------------- | ---------------------------- |
93
+ | `enabled` | `boolean` | `false` | 是否开启当前 store 的持久化 |
94
+ | `async` | `boolean` | `true` | 是否异步存储 (推荐保持 true) |
95
+ | `strategies` | `Array` | `[{ key: store.$id }]` | 存储策略数组 |
96
+
97
+ ### Strategy 详情
98
+
99
+ - **key**: 存储到本地缓存的键名。
100
+ - **paths**: 需要持久化的 state 属性名数组(如 `['count', 'token']`)。如果不传,则持久化整个 store。
101
+ - **async**: 覆盖全局的异步设置。
102
+
103
+ ## 🛠 工具函数
104
+
105
+ ```typescript
106
+ import { clearStore, clearAll } from "pinia-plugin-uni-persist";
107
+
108
+ // 清除特定 key
109
+ clearStore("app_storage_user_key");
110
+
111
+ // 清除全部缓存
112
+ clearAll();
113
+ ```
114
+
115
+ ## License
116
+
117
+ MIT
@@ -0,0 +1,35 @@
1
+ import { PiniaPluginContext } from 'pinia';
2
+
3
+ interface PersistStrategy {
4
+ /** 存储 key,默认为 store.$id */
5
+ key?: string;
6
+ /** 只持久化指定的 state 路径 */
7
+ paths?: string[];
8
+ /** 强制异步存储(优先级高于全局 async) */
9
+ async?: boolean;
10
+ }
11
+ interface PersistOptions {
12
+ enabled?: boolean;
13
+ /** 多个存储策略 */
14
+ strategies?: PersistStrategy[];
15
+ /** 全局默认异步(推荐 true,避免主线程卡顿) */
16
+ async?: boolean;
17
+ /** 恢复前钩子(可用于数据迁移) */
18
+ beforeRestore?: (ctx: PiniaPluginContext) => void;
19
+ /** 恢复后钩子 */
20
+ afterRestore?: (ctx: PiniaPluginContext) => void;
21
+ }
22
+ interface PluginOptions {
23
+ /** 存储 key 统一前缀,如 'hsbc_' */
24
+ keyPrefix?: string;
25
+ }
26
+ declare module 'pinia' {
27
+ interface DefineStoreOptionsBase<S extends StateTree, Store> {
28
+ persist?: PersistOptions;
29
+ }
30
+ }
31
+ declare const createUniPersistPlugin: (pluginOptions?: PluginOptions) => (ctx: PiniaPluginContext) => void;
32
+ declare const clearStore: (key: string) => void;
33
+ declare const clearAll: () => void;
34
+
35
+ export { type PersistOptions, type PersistStrategy, type PluginOptions, clearAll, clearStore, createUniPersistPlugin };
@@ -0,0 +1,35 @@
1
+ import { PiniaPluginContext } from 'pinia';
2
+
3
+ interface PersistStrategy {
4
+ /** 存储 key,默认为 store.$id */
5
+ key?: string;
6
+ /** 只持久化指定的 state 路径 */
7
+ paths?: string[];
8
+ /** 强制异步存储(优先级高于全局 async) */
9
+ async?: boolean;
10
+ }
11
+ interface PersistOptions {
12
+ enabled?: boolean;
13
+ /** 多个存储策略 */
14
+ strategies?: PersistStrategy[];
15
+ /** 全局默认异步(推荐 true,避免主线程卡顿) */
16
+ async?: boolean;
17
+ /** 恢复前钩子(可用于数据迁移) */
18
+ beforeRestore?: (ctx: PiniaPluginContext) => void;
19
+ /** 恢复后钩子 */
20
+ afterRestore?: (ctx: PiniaPluginContext) => void;
21
+ }
22
+ interface PluginOptions {
23
+ /** 存储 key 统一前缀,如 'hsbc_' */
24
+ keyPrefix?: string;
25
+ }
26
+ declare module 'pinia' {
27
+ interface DefineStoreOptionsBase<S extends StateTree, Store> {
28
+ persist?: PersistOptions;
29
+ }
30
+ }
31
+ declare const createUniPersistPlugin: (pluginOptions?: PluginOptions) => (ctx: PiniaPluginContext) => void;
32
+ declare const clearStore: (key: string) => void;
33
+ declare const clearAll: () => void;
34
+
35
+ export { type PersistOptions, type PersistStrategy, type PluginOptions, clearAll, clearStore, createUniPersistPlugin };
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";var P=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var m=(n,t)=>{for(var r in t)P(n,r,{get:t[r],enumerable:!0})},E=(n,t,r,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of _(t))!k.call(n,a)&&a!==r&&P(n,a,{get:()=>t[a],enumerable:!(e=b(t,a))||e.enumerable});return n};var w=n=>E(P({},"__esModule",{value:!0}),n);var B={};m(B,{clearAll:()=>D,clearStore:()=>R,createUniPersistPlugin:()=>j});module.exports=w(B);var A=n=>{if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;let t=0;for(let r=0;r<n.length;r++){let e=n.charCodeAt(r);t+=e<=127?1:e<=2047?2:e<=65535?3:4}return t},C=n=>{let t=new WeakSet;return JSON.stringify(n,(r,e)=>{if(e===void 0)return null;if(typeof e=="bigint")return e.toString();if(e instanceof Date)return{__date__:e.toISOString()};if(typeof e=="object"&&e!==null){if(t.has(e))return"[Circular]";t.add(e)}return e})},O=n=>{if(!n)return null;try{let t=typeof n=="string"?JSON.parse(n):n;return t&&typeof t=="object"&&Object.keys(t).forEach(r=>{let e=t[r];e&&e.__date__&&typeof e.__date__=="string"&&(t[r]=new Date(e.__date__))}),t}catch(t){return console.error("[Pinia Persist] Parse failed:",t),null}},T=(n,t)=>{if(!t||t.length===0)return{...n};let r={};return t.forEach(e=>{e in n&&(r[e]=n[e])}),r},j=n=>{let t=(n==null?void 0:n.keyPrefix)||"";return r=>{var S,h,p,x;let{store:e,options:a}=r,o=a.persist;if(!(o!=null&&o.enabled))return;let l=(S=o.strategies)!=null&&S.length?o.strategies:[{key:e.$id}],y=(h=o.async)!=null?h:!0,u=f=>`${t}${f}`;if((p=o.beforeRestore)==null||p.call(o,r),l.forEach(f=>{let c=u(f.key||e.$id);try{let i=uni.getStorageSync(c),s=O(i);s!==null&&e.$patch(s)}catch(i){console.error(`[Pinia Persist] Load failed: ${c}`,i),uni.removeStorageSync(c)}}),(x=o.afterRestore)==null||x.call(o,r),e.$subscribe((f,c)=>{l.forEach(i=>{let s=u(i.key||e.$id),$=T(c,i.paths),d=C($);if(A(d)>3670016&&console.warn(`[Pinia Persist] Data too large (${s}): > 3.5MB`),y&&i.async!==!1||i.async===!0)uni.setStorage({key:s,data:d,fail:g=>{console.error(`[Pinia Persist] Async save failed (${s}):`,g)}});else try{uni.setStorageSync(s,d)}catch(g){console.error(`[Pinia Persist] Sync save failed (${s}):`,g)}})},{detached:!0,deep:!0,flush:y?"post":"sync"}),typeof e.$reset=="function"){let f=e.$reset;Object.defineProperty(e,"$reset",{value:function(){f.call(this),l.forEach(c=>{try{uni.removeStorageSync(u(c.key||e.$id))}catch{}})},writable:!0,configurable:!0})}console.log(`[Pinia Persist] ${e.$id} \u5DF2\u542F\u7528\u6301\u4E45\u5316 (${y?"\u5F02\u6B65":"\u540C\u6B65"}, \u524D\u7F00: "${t}")`)}},R=n=>uni.removeStorageSync(n),D=()=>uni.clearStorageSync();0&&(module.exports={clearAll,clearStore,createUniPersistPlugin});
package/dist/index.mjs ADDED
@@ -0,0 +1 @@
1
+ var $=n=>{if(typeof TextEncoder!="undefined")return new TextEncoder().encode(n).length;let t=0;for(let r=0;r<n.length;r++){let e=n.charCodeAt(r);t+=e<=127?1:e<=2047?2:e<=65535?3:4}return t},b=n=>{let t=new WeakSet;return JSON.stringify(n,(r,e)=>{if(e===void 0)return null;if(typeof e=="bigint")return e.toString();if(e instanceof Date)return{__date__:e.toISOString()};if(typeof e=="object"&&e!==null){if(t.has(e))return"[Circular]";t.add(e)}return e})},_=n=>{if(!n)return null;try{let t=typeof n=="string"?JSON.parse(n):n;return t&&typeof t=="object"&&Object.keys(t).forEach(r=>{let e=t[r];e&&e.__date__&&typeof e.__date__=="string"&&(t[r]=new Date(e.__date__))}),t}catch(t){return console.error("[Pinia Persist] Parse failed:",t),null}},k=(n,t)=>{if(!t||t.length===0)return{...n};let r={};return t.forEach(e=>{e in n&&(r[e]=n[e])}),r},E=n=>{let t=(n==null?void 0:n.keyPrefix)||"";return r=>{var g,P,S,h;let{store:e,options:p}=r,o=p.persist;if(!(o!=null&&o.enabled))return;let f=(g=o.strategies)!=null&&g.length?o.strategies:[{key:e.$id}],l=(P=o.async)!=null?P:!0,y=c=>`${t}${c}`;if((S=o.beforeRestore)==null||S.call(o,r),f.forEach(c=>{let a=y(c.key||e.$id);try{let i=uni.getStorageSync(a),s=_(i);s!==null&&e.$patch(s)}catch(i){console.error(`[Pinia Persist] Load failed: ${a}`,i),uni.removeStorageSync(a)}}),(h=o.afterRestore)==null||h.call(o,r),e.$subscribe((c,a)=>{f.forEach(i=>{let s=y(i.key||e.$id),x=k(a,i.paths),u=b(x);if($(u)>3670016&&console.warn(`[Pinia Persist] Data too large (${s}): > 3.5MB`),l&&i.async!==!1||i.async===!0)uni.setStorage({key:s,data:u,fail:d=>{console.error(`[Pinia Persist] Async save failed (${s}):`,d)}});else try{uni.setStorageSync(s,u)}catch(d){console.error(`[Pinia Persist] Sync save failed (${s}):`,d)}})},{detached:!0,deep:!0,flush:l?"post":"sync"}),typeof e.$reset=="function"){let c=e.$reset;Object.defineProperty(e,"$reset",{value:function(){c.call(this),f.forEach(a=>{try{uni.removeStorageSync(y(a.key||e.$id))}catch{}})},writable:!0,configurable:!0})}console.log(`[Pinia Persist] ${e.$id} \u5DF2\u542F\u7528\u6301\u4E45\u5316 (${l?"\u5F02\u6B65":"\u540C\u6B65"}, \u524D\u7F00: "${t}")`)}},w=n=>uni.removeStorageSync(n),A=()=>uni.clearStorageSync();export{A as clearAll,w as clearStore,E as createUniPersistPlugin};
package/package.json ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "name": "pinia-plugin-uni-persist-next",
3
+ "version": "1.0.1",
4
+ "description": "专为 UniApp 设计的 Pinia 持久化插件,支持异步/同步策略。",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.mjs",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "keywords": [
19
+ "uniapp",
20
+ "pinia",
21
+ "storage",
22
+ "persist",
23
+ "plugin"
24
+ ],
25
+ "author": "1401009231@qq.com",
26
+ "license": "ISC",
27
+ "peerDependencies": {
28
+ "pinia": ">=3.0.4",
29
+ "typescript": ">=5.9.3"
30
+ },
31
+ "devDependencies": {
32
+ "@dcloudio/types": "^3.4.28",
33
+ "@types/node": "^25.0.1",
34
+ "pinia": "^3.0.4",
35
+ "tsup": "^8.5.1",
36
+ "typescript": "^5.9.3"
37
+ },
38
+ "scripts": {
39
+ "dev": "tsup --watch",
40
+ "build": "tsup"
41
+ }
42
+ }