@lingfan-engine/shell 0.1.5 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lingfan-engine/shell",
3
- "version": "0.1.5",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "灵泛叙事引擎宿主编排层:平台无关的宿主装配逻辑(提示条、事件落点、面板数据、叙事状态投影),消费方用自己的响应式系统落地",
6
6
  "license": "Apache-2.0",
@@ -13,8 +13,8 @@
13
13
  ],
14
14
  "sideEffects": false,
15
15
  "dependencies": {
16
- "@lingfan-engine/core": "^0.1.5",
17
- "@lingfan-engine/ui": "^0.1.5"
16
+ "@lingfan-engine/core": "^0.3.0",
17
+ "@lingfan-engine/ui": "^0.3.0"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
package/src/index.ts CHANGED
@@ -41,6 +41,7 @@ export {
41
41
  /** 叙事视图状态投影 */
42
42
  export {
43
43
  createNarrativeState,
44
+ type InputCandidate,
44
45
  type MenuChoice,
45
46
  type NarrativeState,
46
47
  type NarrativeStateOptions,
@@ -3,6 +3,7 @@
3
3
  */
4
4
  export { createNarrativeState } from "./narrativeState";
5
5
  export type {
6
+ InputCandidate,
6
7
  MenuChoice,
7
8
  NarrativeState,
8
9
  NarrativeStateOptions,
@@ -17,6 +17,7 @@ import {
17
17
  INSTANCE_Z_KEYS,
18
18
  SYS,
19
19
  type ElementInstance,
20
+ type InputCandidate,
20
21
  } from "@lingfan-engine/core";
21
22
  import {
22
23
  createStateView,
@@ -38,6 +39,7 @@ const STATE_KEYS: StateKeyTable = {
38
39
  nvlBuffer: SYS.nvlBuffer,
39
40
  menuOptions: SYS.menuOptions,
40
41
  menuTargets: SYS.menuTargets,
42
+ inputOptions: SYS.inputOptions,
41
43
  dialogVisible: SYS.dialogVisible,
42
44
  elements: SYS.elements,
43
45
  };
@@ -65,6 +67,7 @@ export function createNarrativeState(
65
67
  const dialogHidden = cell(false);
66
68
  const menuPrompt = cell("");
67
69
  const inputPrompt = cell("");
70
+ const inputCandidates = cell<InputCandidate[]>([]);
68
71
  const inputValue = cell("");
69
72
  const rawTexts = cell<string[]>([]);
70
73
  const rawTargets = cell<string[]>([]);
@@ -88,6 +91,19 @@ export function createNarrativeState(
88
91
  }));
89
92
  }
90
93
 
94
+ /** 输入候选的读形:只收 `{ text, value }` 双字符串项,畸形项整项丢弃 */
95
+ function candidatesOf(value: unknown): InputCandidate[] {
96
+ if (!Array.isArray(value)) return [];
97
+ const out: InputCandidate[] = [];
98
+ for (const item of value) {
99
+ if (item === null || typeof item !== "object") continue;
100
+ const { text, value: fill } = item as { text?: unknown; value?: unknown };
101
+ if (typeof text !== "string" || typeof fill !== "string") continue;
102
+ out.push({ text, value: fill });
103
+ }
104
+ return out;
105
+ }
106
+
91
107
  const toIntent = createStateView({
92
108
  keys: STATE_KEYS,
93
109
  resolveLayer: (key) => options.resolveLayer(key),
@@ -151,6 +167,9 @@ export function createNarrativeState(
151
167
  rawTargets.value = value as string[];
152
168
  refreshMenuOptions();
153
169
  }
170
+ } else if (key === STATE_KEYS.inputOptions) {
171
+ // 候选是「显示文本 + 填入值」的对象数组:畸形项整项丢弃,全丢即等于无候选
172
+ inputCandidates.value = candidatesOf(value);
154
173
  }
155
174
  return;
156
175
  case "nvl-mode":
@@ -198,6 +217,7 @@ export function createNarrativeState(
198
217
  dialogHidden,
199
218
  menuPrompt,
200
219
  inputPrompt,
220
+ inputCandidates,
201
221
  inputValue,
202
222
  rawTexts,
203
223
  rawTargets,
@@ -229,6 +249,7 @@ export function createNarrativeState(
229
249
  menuPrompt.value = typeof mp === "string" ? mp : "";
230
250
  const ip = read(SYS.inputPrompt);
231
251
  inputPrompt.value = typeof ip === "string" ? ip : "";
252
+ inputCandidates.value = candidatesOf(read(SYS.inputOptions));
232
253
  const opts = read(SYS.menuOptions);
233
254
  rawTexts.value = Array.isArray(opts) ? (opts as string[]) : [];
234
255
  const tgts = read(SYS.menuTargets);
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type {
9
9
  ElementInstance,
10
+ InputCandidate,
10
11
  LayerId,
11
12
  MenuChoice,
12
13
  } from "@lingfan-engine/core";
@@ -14,7 +15,7 @@ import type { TypingSetting } from "@lingfan-engine/ui";
14
15
  import type { Cell, ReadonlyCell } from "../cell";
15
16
 
16
17
  // 选项形状属于引擎读口,本域只转出:消费方不必为此再引一个包
17
- export type { MenuChoice };
18
+ export type { InputCandidate, MenuChoice };
18
19
 
19
20
  /** 本域的状态单元集:每个视图字段一个单元(框架宿主传响应式单元) */
20
21
  export interface StateCells {
@@ -74,6 +75,8 @@ export interface NarrativeState {
74
75
  readonly menuPrompt: Cell<string>;
75
76
  /** 输入提示行 */
76
77
  readonly inputPrompt: Cell<string>;
78
+ /** 输入候选(显示文本 + 填入值;空数组 = 只有输入框) */
79
+ readonly inputCandidates: ReadonlyCell<InputCandidate[]>;
77
80
  /** 输入框内容 */
78
81
  readonly inputValue: Cell<string>;
79
82
  /** 选项文本(引擎原样) */