@longzai-intelligence-layout/preferences 0.0.0-stage → 0.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/dist/index.d.ts +238 -0
- package/dist/index.js +1 -0
- package/package.json +54 -4
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户偏好编解码器
|
|
3
|
+
*
|
|
4
|
+
* 偏好值与存储字符串之间的双向编解码契约与常用构造器,
|
|
5
|
+
* 解析对键缺失与非法取值一律回落默认形态,对齐既有容错解析惯例
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* 偏好编解码器契约
|
|
9
|
+
*
|
|
10
|
+
* @typeParam T - 偏好值类型
|
|
11
|
+
*/
|
|
12
|
+
type PreferenceCodec<T> = {
|
|
13
|
+
/**
|
|
14
|
+
* 解析存储原始值为偏好值,键缺失与非法取值回落默认形态
|
|
15
|
+
*/
|
|
16
|
+
decode: (raw: string | null) => T;
|
|
17
|
+
/**
|
|
18
|
+
* 编码偏好值为存储字符串
|
|
19
|
+
*/
|
|
20
|
+
encode: (value: T) => string;
|
|
21
|
+
/**
|
|
22
|
+
* 归敛候选偏好值,越界与非法形态收敛到可用区间,缺省恒等
|
|
23
|
+
*/
|
|
24
|
+
normalize?: (value: T) => T;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* 归敛候选偏好值
|
|
28
|
+
*
|
|
29
|
+
* @typeParam T - 偏好值类型
|
|
30
|
+
* @param codec - 目标编解码器
|
|
31
|
+
* @param value - 候选偏好值
|
|
32
|
+
* @returns 归敛后的偏好值,编解码器未声明归敛时原样返回
|
|
33
|
+
*/
|
|
34
|
+
declare function normalizePreferenceValue<T>(codec: PreferenceCodec<T>, value: T): T;
|
|
35
|
+
/**
|
|
36
|
+
* 布尔开关编解码器
|
|
37
|
+
*
|
|
38
|
+
* @remarks
|
|
39
|
+
* 存储编码为 `'1'` 与 `'0'`,默认取真时除 `'0'` 外一律解析为真,
|
|
40
|
+
* 默认取假时仅 `'1'` 解析为真,对齐软换行与折叠类偏好的既有语义
|
|
41
|
+
* @param defaultValue - 键缺失与非法取值的回落值
|
|
42
|
+
* @returns 布尔开关编解码器
|
|
43
|
+
*/
|
|
44
|
+
declare function booleanFlagCodec(defaultValue: boolean): PreferenceCodec<boolean>;
|
|
45
|
+
/**
|
|
46
|
+
* 枚举编解码器
|
|
47
|
+
*
|
|
48
|
+
* @remarks
|
|
49
|
+
* 仅接受值清单内的取值,键缺失与其余取值一律回落默认值
|
|
50
|
+
* @typeParam V - 枚举取值字面量类型
|
|
51
|
+
* @param values - 合法取值清单
|
|
52
|
+
* @param fallback - 键缺失与非法取值的回落值
|
|
53
|
+
* @returns 枚举编解码器
|
|
54
|
+
*/
|
|
55
|
+
declare function enumCodec<V extends string>(values: readonly V[], fallback: V): PreferenceCodec<V>;
|
|
56
|
+
/**
|
|
57
|
+
* 钳制数值界
|
|
58
|
+
*/
|
|
59
|
+
type ClampedNumberBounds = {
|
|
60
|
+
/**
|
|
61
|
+
* 键缺失与非法取值的回落值
|
|
62
|
+
*/
|
|
63
|
+
fallback: number;
|
|
64
|
+
/**
|
|
65
|
+
* 下界,收敛结果不得低于此值
|
|
66
|
+
*/
|
|
67
|
+
min: number;
|
|
68
|
+
/**
|
|
69
|
+
* 上界,收敛结果不得高于此值
|
|
70
|
+
*/
|
|
71
|
+
max: number;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* 钳制数值编解码器
|
|
75
|
+
*
|
|
76
|
+
* @remarks
|
|
77
|
+
* 键缺失与非法取值回落默认值,可解析取值钳制到界内并取整
|
|
78
|
+
* @param bounds - 钳制数值界
|
|
79
|
+
* @returns 钳制数值编解码器
|
|
80
|
+
*/
|
|
81
|
+
declare function clampedNumberCodec(bounds: ClampedNumberBounds): PreferenceCodec<number>;
|
|
82
|
+
/**
|
|
83
|
+
* 去空白字符串编解码器
|
|
84
|
+
*
|
|
85
|
+
* @remarks
|
|
86
|
+
* 键缺失与空白取值回落默认值,其余取值去首尾空白后采纳
|
|
87
|
+
* @param fallback - 键缺失与空白取值的回落值
|
|
88
|
+
* @returns 去空白字符串编解码器
|
|
89
|
+
*/
|
|
90
|
+
declare function trimmedStringCodec(fallback: string): PreferenceCodec<string>;
|
|
91
|
+
/**
|
|
92
|
+
* 原样字符串编解码器
|
|
93
|
+
*
|
|
94
|
+
* @remarks
|
|
95
|
+
* 键缺失回落默认值,其余取值原样采纳,适配输入框草稿一类允许任意中间形态的记忆
|
|
96
|
+
* @param fallback - 键缺失时的回落值
|
|
97
|
+
* @returns 原样字符串编解码器
|
|
98
|
+
*/
|
|
99
|
+
declare function rawStringCodec(fallback: string): PreferenceCodec<string>;
|
|
100
|
+
/**
|
|
101
|
+
* 可空字符串编解码器
|
|
102
|
+
*
|
|
103
|
+
* @remarks
|
|
104
|
+
* null 编码为空串存储,空串与键缺失解析回 null,
|
|
105
|
+
* 适配仓库标识一类契约上非空字符串的可空记忆
|
|
106
|
+
* @returns 可空字符串编解码器
|
|
107
|
+
*/
|
|
108
|
+
declare function nullableStringCodec(): PreferenceCodec<string | null>;
|
|
109
|
+
/**
|
|
110
|
+
* 字符串列表编解码器
|
|
111
|
+
*
|
|
112
|
+
* @remarks
|
|
113
|
+
* 列表以逗号拼接存储,条目自身约定不含逗号,
|
|
114
|
+
* 解析侧去空串与重复项,键缺失与空白取值回落默认列表
|
|
115
|
+
* @param fallback - 键缺失与空白取值的回落列表
|
|
116
|
+
* @returns 字符串列表编解码器
|
|
117
|
+
*/
|
|
118
|
+
declare function stringListCodec(fallback: string[]): PreferenceCodec<string[]>;
|
|
119
|
+
/**
|
|
120
|
+
* 用户偏好键类型
|
|
121
|
+
*
|
|
122
|
+
* 偏好存储键条目与两级存储层级的类型契约,
|
|
123
|
+
* 键清单由消费方仓自建,键名约定挂消费方命名空间前缀并可枚举供偏好面审计
|
|
124
|
+
*/
|
|
125
|
+
/**
|
|
126
|
+
* 偏好存储层级
|
|
127
|
+
*/
|
|
128
|
+
type PreferenceTier = 'persistent' | 'session';
|
|
129
|
+
/**
|
|
130
|
+
* 偏好存储键条目
|
|
131
|
+
*/
|
|
132
|
+
type PreferenceKeyEntry = {
|
|
133
|
+
/**
|
|
134
|
+
* 完整存储键名
|
|
135
|
+
*/
|
|
136
|
+
key: string;
|
|
137
|
+
/**
|
|
138
|
+
* 存储层级,`persistent` 跨会话留存在 localStorage,`session` 仅当前标签页留存在 sessionStorage
|
|
139
|
+
*/
|
|
140
|
+
tier: PreferenceTier;
|
|
141
|
+
};
|
|
142
|
+
/**
|
|
143
|
+
* 构造带命名空间前缀的偏好存储键名
|
|
144
|
+
*
|
|
145
|
+
* @remarks
|
|
146
|
+
* 消费方键清单内禁止手写拼接字符串,统一经本函数装配保证前缀一致
|
|
147
|
+
* @param namespace - 消费方命名空间,约定为消费方产品短名
|
|
148
|
+
* @param name - 偏好短名,使用 kebab-case
|
|
149
|
+
* @returns 完整存储键名
|
|
150
|
+
*/
|
|
151
|
+
declare function buildPreferenceKey(namespace: string, name: string): string;
|
|
152
|
+
/**
|
|
153
|
+
* 用户偏好定义
|
|
154
|
+
*
|
|
155
|
+
* @typeParam T - 偏好值类型
|
|
156
|
+
*/
|
|
157
|
+
type PreferenceDefinition<T> = {
|
|
158
|
+
/**
|
|
159
|
+
* 存储键条目,取自键清单
|
|
160
|
+
*/
|
|
161
|
+
entry: PreferenceKeyEntry;
|
|
162
|
+
/**
|
|
163
|
+
* 编解码器
|
|
164
|
+
*/
|
|
165
|
+
codec: PreferenceCodec<T>;
|
|
166
|
+
};
|
|
167
|
+
/**
|
|
168
|
+
* 定义用户偏好
|
|
169
|
+
*
|
|
170
|
+
* @typeParam T - 偏好值类型
|
|
171
|
+
* @param entry - 存储键条目,取自键清单单一真源
|
|
172
|
+
* @param codec - 编解码器
|
|
173
|
+
* @returns 用户偏好定义
|
|
174
|
+
*/
|
|
175
|
+
declare function definePreference<T>(entry: PreferenceKeyEntry, codec: PreferenceCodec<T>): PreferenceDefinition<T>;
|
|
176
|
+
/**
|
|
177
|
+
* 读取偏好值
|
|
178
|
+
*
|
|
179
|
+
* @typeParam T - 偏好值类型
|
|
180
|
+
* @param preference - 用户偏好定义
|
|
181
|
+
* @returns 解析后的偏好值,键缺失与存储异常回落默认形态
|
|
182
|
+
*/
|
|
183
|
+
declare function readPreference<T>(preference: PreferenceDefinition<T>): T;
|
|
184
|
+
/**
|
|
185
|
+
* 写入偏好值
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* 写入前先归敛候选值,存储层异常静默收敛不抛出
|
|
189
|
+
* @typeParam T - 偏好值类型
|
|
190
|
+
* @param preference - 用户偏好定义
|
|
191
|
+
* @param value - 候选偏好值
|
|
192
|
+
*/
|
|
193
|
+
declare function writePreference<T>(preference: PreferenceDefinition<T>, value: T): void;
|
|
194
|
+
/**
|
|
195
|
+
* 读取偏好存储原始值
|
|
196
|
+
*
|
|
197
|
+
* @param tier - 偏好存储层级
|
|
198
|
+
* @param key - 完整存储键名
|
|
199
|
+
* @returns 存储原始值,键不存在或存储不可用时为 null
|
|
200
|
+
*/
|
|
201
|
+
declare function readStoredPreference(tier: PreferenceTier, key: string): string | null;
|
|
202
|
+
/**
|
|
203
|
+
* 写入偏好存储原始值
|
|
204
|
+
*
|
|
205
|
+
* @remarks
|
|
206
|
+
* 存储禁用与配额超限等写入异常不向调用方抛出,写入失败经日志实例告警留痕,
|
|
207
|
+
* 供偏好未持久化现象的现场定位
|
|
208
|
+
* @param tier - 偏好存储层级
|
|
209
|
+
* @param key - 完整存储键名
|
|
210
|
+
* @param value - 写入的字符串值
|
|
211
|
+
*/
|
|
212
|
+
declare function writeStoredPreference(tier: PreferenceTier, key: string, value: string): void;
|
|
213
|
+
/**
|
|
214
|
+
* 用户偏好状态集合
|
|
215
|
+
*
|
|
216
|
+
* @typeParam T - 偏好值类型
|
|
217
|
+
*/
|
|
218
|
+
type PreferenceControl<T> = {
|
|
219
|
+
/**
|
|
220
|
+
* 当前偏好值
|
|
221
|
+
*/
|
|
222
|
+
value: T;
|
|
223
|
+
/**
|
|
224
|
+
* 切换偏好值并记忆到存储
|
|
225
|
+
*
|
|
226
|
+
* @param next - 候选偏好值
|
|
227
|
+
*/
|
|
228
|
+
change: (next: T) => void;
|
|
229
|
+
};
|
|
230
|
+
/**
|
|
231
|
+
* 用户偏好通用钩子
|
|
232
|
+
*
|
|
233
|
+
* @typeParam T - 偏好值类型
|
|
234
|
+
* @param preference - 用户偏好定义
|
|
235
|
+
* @returns 偏好值与切换动作
|
|
236
|
+
*/
|
|
237
|
+
declare function usePreference<T>(preference: PreferenceDefinition<T>): PreferenceControl<T>;
|
|
238
|
+
export { type ClampedNumberBounds, type PreferenceCodec, type PreferenceControl, type PreferenceDefinition, type PreferenceKeyEntry, type PreferenceTier, booleanFlagCodec, buildPreferenceKey, clampedNumberCodec, definePreference, enumCodec, normalizePreferenceValue, nullableStringCodec, rawStringCodec, readPreference, readStoredPreference, stringListCodec, trimmedStringCodec, usePreference, writePreference, writeStoredPreference };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createBrowserLogger as e}from"@longzai-intelligence-logger/browser";import{useCallback as t,useState as n}from"react";function r(e,t){return e.normalize?e.normalize(t):t}function i(e){return{decode:t=>e?t!==`0`:t===`1`,encode:e=>e?`1`:`0`}}function a(e,t){function n(t){return e.includes(t)}return{decode:e=>e!==null&&n(e)?e:t,encode:e=>e}}function o(e){let t=t=>Math.round(Math.min(Math.max(t,e.min),e.max));return{decode:n=>{if(n===null||n.trim()===``)return e.fallback;let r=Number(n);return Number.isFinite(r)?t(r):e.fallback},encode:e=>String(e),normalize:t}}function s(e){return{decode:t=>t===null||t.trim()===``?e:t.trim(),encode:e=>e}}function c(e){return{decode:t=>t??e,encode:e=>e}}function l(){return{decode:e=>e===null||e===``?null:e,encode:e=>e??``}}function u(e){let t=e=>{let t=e.split(`,`).map(e=>e.trim()).filter(e=>e!==``);return[...new Set(t)]};return{decode:n=>n===null||n.trim()===``?e:t(n),encode:e=>e.join(`,`),normalize:e=>[...new Set(e)]}}const d=e(`lib/preferences/preference-storage.utils`);function f(e){try{return e===`persistent`?window.localStorage:window.sessionStorage}catch{return null}}function p(e,t){try{return f(e)?.getItem(t)??null}catch{return null}}function m(e,t,n){try{f(e)?.setItem(t,n)}catch(e){d.warn(`偏好写入存储失败 ${t}`,{error:e instanceof Error?e.message:String(e)})}}function h(e,t){return{entry:e,codec:t}}function g(e){return e.codec.decode(p(e.entry.tier,e.entry.key))}function _(e,t){let n=r(e.codec,t);m(e.entry.tier,e.entry.key,e.codec.encode(n))}function v(e,t){return`${e}.${t}`}function y(e){let[i,a]=n(()=>g(e));return{value:i,change:t(t=>{let n=r(e.codec,t);a(n),m(e.entry.tier,e.entry.key,e.codec.encode(n))},[e])}}export{i as booleanFlagCodec,v as buildPreferenceKey,o as clampedNumberCodec,h as definePreference,a as enumCodec,r as normalizePreferenceValue,l as nullableStringCodec,c as rawStringCodec,g as readPreference,p as readStoredPreference,u as stringListCodec,s as trimmedStringCodec,y as usePreference,_ as writePreference,m as writeStoredPreference};
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-layout/preferences",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "Longzai Intelligence 界面偏好键声明与持久化框架包",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"layout",
|
|
7
|
+
"longzai-intelligence",
|
|
8
|
+
"persistence",
|
|
9
|
+
"preferences"
|
|
10
|
+
],
|
|
11
|
+
"license": "UNLICENSED",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist"
|
|
14
|
+
],
|
|
15
|
+
"type": "module",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"main": "./dist/index.js",
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"types": "./dist/index.d.ts",
|
|
22
|
+
"import": "./dist/index.js"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "lzi-builder",
|
|
27
|
+
"build:prod": "NODE_ENV=production bun run build",
|
|
28
|
+
"prepublishOnly": "bun run build:prod",
|
|
29
|
+
"typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
|
|
30
|
+
"typecheck:app": "lzi-tsgo typecheck tsconfig/app.json",
|
|
31
|
+
"typecheck:node": "lzi-tsgo typecheck tsconfig/node.json",
|
|
32
|
+
"typecheck:test": "lzi-tsgo typecheck tsconfig/test.json",
|
|
33
|
+
"lint": "oxlint && oxfmt --check",
|
|
34
|
+
"lint:fix": "oxlint --fix && oxfmt",
|
|
35
|
+
"test": "bun test",
|
|
36
|
+
"test:watch": "bun test --watch",
|
|
37
|
+
"test:coverage": "bun test --coverage",
|
|
38
|
+
"test:unit": "bun test src/__tests__/unit/",
|
|
39
|
+
"clean": "lzi-dev-cli clean"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@longzai-intelligence-logger/browser": "^0.1.8"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@happy-dom/global-registrator": "^20.11.2",
|
|
46
|
+
"@testing-library/react": "^16.3.2",
|
|
47
|
+
"@types/react": "^19.2.17",
|
|
48
|
+
"@types/react-dom": "^19.3.0",
|
|
49
|
+
"happy-dom": "^20.11.2",
|
|
50
|
+
"react": "19.2.6",
|
|
51
|
+
"react-dom": "19.2.6"
|
|
52
|
+
},
|
|
53
|
+
"peerDependencies": {
|
|
54
|
+
"react": "^19.2.6"
|
|
55
|
+
}
|
|
56
|
+
}
|
package/README.md
DELETED