@lmzhen/dsh-evolution-settings-ui 0.21.0 → 0.23.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/lib/client.js +360 -151
- package/lib/types/client/ParamCard.d.ts +19 -7
- package/lib/types/client/PendingCard.d.ts +14 -1
- package/lib/types/client/RowConfigCard.d.ts +1 -1
- package/lib/types/client/generated-about.d.ts +11 -0
- package/lib/types/client/generated-params.d.ts +2 -0
- package/lib/types/client/guards.d.ts +13 -0
- package/lib/types/client/messages.d.ts +31 -4
- package/lib/types/client/seam.d.ts +4 -0
- package/lib/types/client/source.d.ts +4 -8
- package/package.json +1 -1
- package/lib/types/client/settle.d.ts +0 -35
|
@@ -28,10 +28,11 @@ import type { ParamSectionSnapshot, ParamSectionSource, SettingsPathOpLike } fro
|
|
|
28
28
|
export interface ParamCardFace {
|
|
29
29
|
namespace: string;
|
|
30
30
|
fields: readonly ClientParamField[];
|
|
31
|
-
t: (key: MessageKey) => string;
|
|
32
|
-
/** ONE call per save, carrying every dirty field as one op list (T5-01/A56).
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
|
|
32
|
+
/** ONE call per save, carrying every dirty field as one op list (T5-01/A56). The returned boolean IS
|
|
33
|
+
* the Host's verdict (contract C2/G5): `true` = accepted, `false` = refused after its recovery read. */
|
|
34
|
+
mutateOnce: (ops: readonly SettingsParamOp[]) => Promise<boolean>;
|
|
35
|
+
clear: (field: string) => Promise<boolean>;
|
|
35
36
|
hooks: {
|
|
36
37
|
paramSection: ParamSectionSource;
|
|
37
38
|
};
|
|
@@ -47,6 +48,17 @@ export type ParamCardProps = Omit<ParamCardFace, 'hooks'> & {
|
|
|
47
48
|
};
|
|
48
49
|
/** The op list a save hands to the seat — the seam's own shape, never a second vocabulary. */
|
|
49
50
|
export type SettingsParamOp = SettingsPathOpLike;
|
|
51
|
+
/**
|
|
52
|
+
* U-4: whether one field's CURRENT text is a value the Host can take. The controls constrain their own
|
|
53
|
+
* domains (a number input sanitizes, a select only offers listed values), so the reachable case is a
|
|
54
|
+
* value the registry no longer lists — carried in the user layer and re-staged by any other edit.
|
|
55
|
+
* @param field - the generated field.
|
|
56
|
+
* @param text - the text the control holds right now.
|
|
57
|
+
* @param peer - U-4: the text the row this field declares `atLeast` against currently holds (absent
|
|
58
|
+
* when the field declares no relation, or when that row is not on this card).
|
|
59
|
+
* @returns the message key explaining the refusal, or null when the value is acceptable.
|
|
60
|
+
*/
|
|
61
|
+
export declare function invalidReason(field: ClientParamField, text: string, peer?: string): MessageKey | null;
|
|
50
62
|
/**
|
|
51
63
|
* Render one namespace's card.
|
|
52
64
|
* @param props - the card data, its callbacks, and the bound section hook.
|
|
@@ -56,11 +68,11 @@ export type SettingsParamOp = SettingsPathOpLike;
|
|
|
56
68
|
export interface ParamCardViewProps {
|
|
57
69
|
namespace: string;
|
|
58
70
|
fields: readonly ClientParamField[];
|
|
59
|
-
t: (key: MessageKey) => string;
|
|
71
|
+
t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
|
|
60
72
|
/** ONE call per save, carrying every dirty field as one op list (T5-01/A56). */
|
|
61
|
-
mutateOnce: (ops: readonly SettingsParamOp[]) => Promise<
|
|
73
|
+
mutateOnce: (ops: readonly SettingsParamOp[]) => Promise<boolean>;
|
|
62
74
|
/** Ask the scope to drop one override; resolves when the scope answered, not when it landed. */
|
|
63
|
-
clear: (field: string) => Promise<
|
|
75
|
+
clear: (field: string) => Promise<boolean>;
|
|
64
76
|
/** The current row state, from whichever source owns it (the bound hook or the page). */
|
|
65
77
|
snapshot: ParamSectionSnapshot;
|
|
66
78
|
}
|
|
@@ -17,9 +17,22 @@ import type { ApprovalApi } from './api.ts';
|
|
|
17
17
|
import type { MessageKey } from './messages.ts';
|
|
18
18
|
/** Injected face: the copy seat and the host calls. No hook compartment — this card keeps its own state. */
|
|
19
19
|
export interface PendingCardFace {
|
|
20
|
-
t: (key: MessageKey) => string;
|
|
20
|
+
t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
|
|
21
21
|
api: ApprovalApi;
|
|
22
|
+
/**
|
|
23
|
+
* U-6 (registry `approvalConfirm`): read PER RENDER, like the entry's own seat probe — a value
|
|
24
|
+
* captured once would pin the gate for the life of the fiber. Absent ⇒ the shipped default `auto`.
|
|
25
|
+
*/
|
|
26
|
+
confirmMode?: () => 'auto' | 'ask' | 'timeout';
|
|
22
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* U-6: the registry's gate word, read out of a section's user layer. ONE definition, exported so the
|
|
30
|
+
* mapping itself is judgeable: the entry does the wiring, this does the reading. Anything that is not
|
|
31
|
+
* one of the two explicit words falls back to the shipped default (`auto`) — a document written by a
|
|
32
|
+
* future version must not silently turn the confirmation ON, and a typo must not turn it off. The
|
|
33
|
+
* independent review flagged that this reader had no case at all (P2-11).
|
|
34
|
+
*/
|
|
35
|
+
export declare function confirmModeFrom(user: unknown): 'auto' | 'ask' | 'timeout';
|
|
23
36
|
/**
|
|
24
37
|
* Render the pending window.
|
|
25
38
|
* @param props - the copy seat and the host calls.
|
|
@@ -17,7 +17,7 @@ export interface RowConfigFace {
|
|
|
17
17
|
/** The row's entry id, for the card title. */
|
|
18
18
|
namespace: string;
|
|
19
19
|
fields: readonly ClientParamField[];
|
|
20
|
-
t: (key: MessageKey) => string;
|
|
20
|
+
t: (key: MessageKey, values?: Readonly<Record<string, string | number>>) => string;
|
|
21
21
|
}
|
|
22
22
|
/** Props one row entry is rendered with: the page's seat plus this row's own face. */
|
|
23
23
|
export type RowConfigCardProps = RowConfigViewProps & RowConfigFace;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GENERATED by packages/scripts/gen-about.mjs — do not edit.
|
|
3
|
+
*
|
|
4
|
+
* The version comes from the repository package.json and the purpose from this package own
|
|
5
|
+
* description, so the settings surface can state both without a hand-written copy.
|
|
6
|
+
*/
|
|
7
|
+
/** The family version this surface belongs to. */
|
|
8
|
+
export declare const FAMILY_VERSION = "0.23.0";
|
|
9
|
+
/** What this surface is for, in one line. */
|
|
10
|
+
export declare const PACKAGE_PURPOSE = "Web settings cards for the evolution family's parameter namespaces";
|
|
11
|
+
//# sourceMappingURL=generated-about.d.ts.map
|
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
export interface ClientParamField {
|
|
9
9
|
id: string;
|
|
10
10
|
group: string;
|
|
11
|
+
/** U-4: the sibling id this field may not go below (an empty string when the row declares no relation). */
|
|
12
|
+
atLeast: string;
|
|
11
13
|
/** The registry summary (English), kept for parity with PARAMETERS.md. */
|
|
12
14
|
doc: string;
|
|
13
15
|
/** Card label, from the registry UI tail (Chinese). */
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is this a non-null, non-array object (what JSON calls an object)?
|
|
3
|
+
* @param value - the value to test.
|
|
4
|
+
* @returns whether it is a plain object.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isRecord(value: unknown): value is Record<string, unknown>;
|
|
7
|
+
/**
|
|
8
|
+
* Read a value as a record, or undefined when it is not one.
|
|
9
|
+
* @param value - the value to read.
|
|
10
|
+
* @returns the value typed as a record, or undefined.
|
|
11
|
+
*/
|
|
12
|
+
export declare function asRecord(value: unknown): Record<string, unknown> | undefined;
|
|
13
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -14,7 +14,7 @@ export declare const NS = "evolution-settings";
|
|
|
14
14
|
export declare const zh: {
|
|
15
15
|
readonly title: "自进化";
|
|
16
16
|
readonly subtitle: "待你决定的写入在最上面;下面按功能列出你能改的参数,没有列出的由安装时的配置决定。";
|
|
17
|
-
readonly overridden: "
|
|
17
|
+
readonly overridden: "已覆盖";
|
|
18
18
|
readonly deployment: "默认";
|
|
19
19
|
readonly loading: "正在读取设置…";
|
|
20
20
|
readonly unavailable: "这个功能没有启动(对应的插件没有安装)";
|
|
@@ -24,12 +24,21 @@ export declare const zh: {
|
|
|
24
24
|
readonly apply: "保存";
|
|
25
25
|
readonly reset: "恢复默认值";
|
|
26
26
|
readonly empty: "这里没有可改项";
|
|
27
|
-
readonly changed: "{n}
|
|
27
|
+
readonly changed: "{n} 项已覆盖";
|
|
28
28
|
readonly discard: "放弃修改";
|
|
29
29
|
readonly saving: "保存中…";
|
|
30
30
|
readonly resetting: "恢复中…";
|
|
31
|
-
readonly
|
|
32
|
-
readonly
|
|
31
|
+
readonly destHost: "保存去向:本机配置";
|
|
32
|
+
readonly invalidNumber: "需要一个数字";
|
|
33
|
+
readonly invalidSelect: "不在允许的取值里";
|
|
34
|
+
readonly invalidAtLeast: "不能小于同组的 {n}";
|
|
35
|
+
readonly approvalConfirmNamed: "即将批准:{n}";
|
|
36
|
+
readonly approvalConfirmYes: "确认批准";
|
|
37
|
+
readonly approvalConfirmNo: "取消";
|
|
38
|
+
readonly destMemory: "保存去向:仅本次会话";
|
|
39
|
+
readonly resetTo: "复位为 {value}";
|
|
40
|
+
readonly refused: "这个值没有被接受(界面上保持原样)。想看原因:在对话里让它说明。";
|
|
41
|
+
readonly resetRefused: "恢复默认值没有生效(这一行还是你的值)。想看原因:在对话里让它说明。";
|
|
33
42
|
readonly cardReview: "会话回顾";
|
|
34
43
|
readonly cardMemory: "长期记忆";
|
|
35
44
|
readonly cardToolMemory: "记忆写入";
|
|
@@ -81,4 +90,22 @@ export type MessageKey = keyof typeof zh;
|
|
|
81
90
|
* @returns the copy this bundle carries.
|
|
82
91
|
*/
|
|
83
92
|
export declare function message(key: MessageKey, language?: 'zh' | 'en'): string;
|
|
93
|
+
/**
|
|
94
|
+
* Fill one TEMPLATE's `{slot}` placeholders (G5 C4). The seat's translator takes the values, so the
|
|
95
|
+
* rule lives here instead of at every call site — `t('changed').replace('{n}', …)` used to be
|
|
96
|
+
* written seven times across three components. An UNKNOWN slot is left standing: a missing value
|
|
97
|
+
* must not print "undefined" into the operator's UI.
|
|
98
|
+
* @param template - the resolved copy, with `{slot}` placeholders.
|
|
99
|
+
* @param values - substitutions keyed by the slot name inside the braces.
|
|
100
|
+
* @returns the filled copy.
|
|
101
|
+
*/
|
|
102
|
+
export declare function fill(template: string, values: Readonly<Record<string, string | number>>): string;
|
|
103
|
+
/**
|
|
104
|
+
* Resolve one message and fill its slots in one step: exactly what the seat's `t` does (G5 C4),
|
|
105
|
+
* for specs and stand-alone callers that hold no seat.
|
|
106
|
+
* @param key - the copy key.
|
|
107
|
+
* @param values - substitutions, or undefined for the plain copy.
|
|
108
|
+
* @returns the copy a reader sees.
|
|
109
|
+
*/
|
|
110
|
+
export declare function formatText(key: MessageKey, values?: Readonly<Record<string, string | number>>): string;
|
|
84
111
|
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -42,6 +42,10 @@ export interface ParamSectionSnapshot {
|
|
|
42
42
|
/** Raw user section: a key's PRESENCE marks the override, not its value. */
|
|
43
43
|
user: unknown;
|
|
44
44
|
writable: boolean;
|
|
45
|
+
/** U-5: the composition layer a cleared field reverts to (platform `base`, previously dropped). */
|
|
46
|
+
base: Record<string, unknown> | undefined;
|
|
47
|
+
/** U-5: where a save lands — `memory` means this session only (platform `mode`, previously dropped). */
|
|
48
|
+
mode: 'host' | 'memory';
|
|
45
49
|
/**
|
|
46
50
|
* Why an `unavailable` snapshot is unavailable: this bundle found no settings seat at
|
|
47
51
|
* all, or the seat is there and serves no such row. The two read differently to the
|
|
@@ -29,12 +29,8 @@ export declare const SEAT_MISSING: ParamSectionSnapshot;
|
|
|
29
29
|
* so a failing row keeps ONE reference: a fresh object per call would reintroduce the
|
|
30
30
|
* render loop this module exists to prevent. */
|
|
31
31
|
export declare const PROJECTION_FAILED: ParamSectionSnapshot;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
* @param value - the value to test.
|
|
35
|
-
* @returns true for a non-null, non-array object.
|
|
36
|
-
*/
|
|
37
|
-
export declare function isSection(value: unknown): value is Record<string, unknown>;
|
|
32
|
+
import { isRecord as isSection } from './guards.ts';
|
|
33
|
+
export { isSection };
|
|
38
34
|
/**
|
|
39
35
|
* Project one platform snapshot into the card's own shape.
|
|
40
36
|
* @param snapshot - the seat's snapshot.
|
|
@@ -70,8 +66,8 @@ export declare function sourceFor(probe: SeatProbe, namespace: string): ParamSec
|
|
|
70
66
|
* @returns the two calls a card's save/reset path uses; without a seat they resolve without writing.
|
|
71
67
|
*/
|
|
72
68
|
export declare function writeFaceFor(probe: SeatProbe, namespace: string): {
|
|
73
|
-
mutateOnce: (ops: readonly SettingsPathOpLike[]) => Promise<
|
|
74
|
-
clear: (field: string) => Promise<
|
|
69
|
+
mutateOnce: (ops: readonly SettingsPathOpLike[]) => Promise<boolean>;
|
|
70
|
+
clear: (field: string) => Promise<boolean>;
|
|
75
71
|
};
|
|
76
72
|
/**
|
|
77
73
|
* One source object per namespace, for the life of the plugin fiber.
|
package/package.json
CHANGED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The save verdict: did the Host take the values this card asked for?
|
|
3
|
-
*
|
|
4
|
-
* A write promise that resolves is not a verdict. Both settings scopes this bundle runs
|
|
5
|
-
* on finish a recovery read before it resolves, so a value the Host refused is simply
|
|
6
|
-
* still the previous one. Presence in the user layer cannot tell refusal from acceptance
|
|
7
|
-
* on a field the operator had already overridden — the refused value's key is present
|
|
8
|
-
* too — so the verdict compares what each staged id holds now against what was requested.
|
|
9
|
-
* @module @lmzhen/dsh-evolution-settings-ui
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* One staged operation awaiting its verdict, in the platform's own two op kinds.
|
|
13
|
-
*
|
|
14
|
-
* `unset` is here because "restore the default" had NO verdict at all (T5-05/A60): the reset path
|
|
15
|
-
* called the scope and dropped its answer, so a host refusal changed nothing on screen — the row kept
|
|
16
|
-
* its "edited by you" chip and the reader concluded the button was broken. The two ops need different
|
|
17
|
-
* evidence (a set landed when the id holds the value; an unset landed when the id is GONE), which is
|
|
18
|
-
* exactly why they are one union judged by one function instead of two look-alike helpers.
|
|
19
|
-
*/
|
|
20
|
-
export type Settlement = {
|
|
21
|
-
readonly op: 'set';
|
|
22
|
-
readonly id: string;
|
|
23
|
-
readonly want: unknown;
|
|
24
|
-
} | {
|
|
25
|
-
readonly op: 'unset';
|
|
26
|
-
readonly id: string;
|
|
27
|
-
};
|
|
28
|
-
/**
|
|
29
|
-
* Whether every staged operation is visible in the user layer.
|
|
30
|
-
* @param pending - the operations awaiting a verdict.
|
|
31
|
-
* @param user - the user layer of the post-write snapshot; a non-section reads as empty.
|
|
32
|
-
* @returns true when each staged id now holds the requested value, or is gone after an `unset`.
|
|
33
|
-
*/
|
|
34
|
-
export declare function landedSettlements(pending: readonly Settlement[], user: unknown): boolean;
|
|
35
|
-
//# sourceMappingURL=settle.d.ts.map
|