@firetable/project-xiaochun 0.1.14 → 0.1.16
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-CN.md +117 -19
- package/README.md +117 -19
- package/dist/avatar-element.d.ts +29 -6
- package/dist/chunks/{chunk-HLVD6HQM.js → chunk-HZ2ADKG7.js} +114 -11
- package/dist/chunks/chunk-HZ2ADKG7.js.map +7 -0
- package/dist/chunks/chunk-RHQW4QZH.js +222 -0
- package/dist/chunks/chunk-RHQW4QZH.js.map +7 -0
- package/dist/chunks/chunk-UWL65W7D.js +1083 -0
- package/dist/chunks/chunk-UWL65W7D.js.map +7 -0
- package/dist/client.d.ts +187 -7
- package/dist/element.cjs +738 -80
- package/dist/element.cjs.map +4 -4
- package/dist/element.js +4 -4
- package/dist/gesture-box.d.ts +72 -0
- package/dist/index.cjs +806 -81
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +38 -6
- package/dist/index.js.map +1 -1
- package/dist/loader.global.js +2 -2
- package/dist/loader.global.js.map +4 -4
- package/dist/protocol.cjs +133 -2
- package/dist/protocol.cjs.map +2 -2
- package/dist/protocol.d.ts +279 -9
- package/dist/protocol.js +36 -4
- package/dist/react.cjs +689 -86
- package/dist/react.cjs.map +4 -4
- package/dist/react.d.ts +23 -1
- package/dist/react.js +66 -18
- package/dist/react.js.map +2 -2
- package/package.json +5 -3
- package/dist/chunks/chunk-DUU5PTKT.js +0 -91
- package/dist/chunks/chunk-DUU5PTKT.js.map +0 -7
- package/dist/chunks/chunk-HLVD6HQM.js.map +0 -7
- package/dist/chunks/chunk-OLVSOJML.js +0 -579
- package/dist/chunks/chunk-OLVSOJML.js.map +0 -7
package/dist/protocol.d.ts
CHANGED
|
@@ -15,13 +15,13 @@ export declare const XC_PROTOCOL_VERSION: 1;
|
|
|
15
15
|
export declare const XC_DEFAULT_ORIGIN = "https://xiaochun.firetable.tech";
|
|
16
16
|
export declare const XC_DEFAULT_SRC = "https://xiaochun.firetable.tech/embed";
|
|
17
17
|
/** 宿主 → iframe 命令。 */
|
|
18
|
-
export declare const XC_HOST_TO_FRAME: readonly ["xc.init", "xc.say", "xc.audio", "xc.audio.chunk", "xc.audio.end", "xc.motion", "xc.expression", "xc.lookAt", "xc.pointer", "xc.setModel", "xc.setConfig", "xc.mic", "xc.pause", "xc.resume", "xc.destroy"];
|
|
18
|
+
export declare const XC_HOST_TO_FRAME: readonly ["xc.init", "xc.say", "xc.audio", "xc.audio.chunk", "xc.audio.end", "xc.motion", "xc.expression", "xc.lookAt", "xc.pointer", "xc.setModel", "xc.setOutfit", "xc.setScene", "xc.prefetch", "xc.setConfig", "xc.mic", "xc.pause", "xc.resume", "xc.destroy"];
|
|
19
19
|
/** iframe → 宿主 事件。 */
|
|
20
|
-
export declare const XC_FRAME_TO_HOST: readonly ["xc.ready", "xc.load.progress", "xc.loaded", "xc.state", "xc.stt", "xc.utterance", "xc.hit-region", "xc.error"];
|
|
20
|
+
export declare const XC_FRAME_TO_HOST: readonly ["xc.ready", "xc.load.progress", "xc.loaded", "xc.outfit-changed", "xc.scene-changed", "xc.lang-changed", "xc.prefetched", "xc.state", "xc.stt", "xc.utterance", "xc.hit-region", "xc.gesture-move", "xc.gesture-resize", "xc.error"];
|
|
21
21
|
export type XcHostMessageType = (typeof XC_HOST_TO_FRAME)[number];
|
|
22
22
|
export type XcFrameMessageType = (typeof XC_FRAME_TO_HOST)[number];
|
|
23
23
|
/** 当前 /embed 已实现的命令 (xc.init 是握手, 不计入)。 */
|
|
24
|
-
export declare const XC_IMPLEMENTED_COMMANDS: readonly ["xc.say", "xc.audio", "xc.audio.chunk", "xc.audio.end", "xc.motion", "xc.expression", "xc.pointer", "xc.setModel", "xc.setConfig", "xc.mic", "xc.pause", "xc.resume", "xc.destroy"];
|
|
24
|
+
export declare const XC_IMPLEMENTED_COMMANDS: readonly ["xc.say", "xc.audio", "xc.audio.chunk", "xc.audio.end", "xc.motion", "xc.expression", "xc.pointer", "xc.setModel", "xc.setOutfit", "xc.setScene", "xc.prefetch", "xc.setConfig", "xc.mic", "xc.pause", "xc.resume", "xc.destroy"];
|
|
25
25
|
/**
|
|
26
26
|
* 暂不支持 (底层无对应能力), /embed 回 `xc.error{code:'unsupported'}`。
|
|
27
27
|
* TODO(xc.lookAt): 视线目前由相机 + 随机扫视驱动 (GazeController), 没有"外部指定注视点"的入口;
|
|
@@ -59,8 +59,111 @@ export declare const XC_PROTOCOL_MAPPING: readonly [{
|
|
|
59
59
|
readonly action: "audio";
|
|
60
60
|
readonly url: null;
|
|
61
61
|
}];
|
|
62
|
-
export type XcErrorCode = 'unsupported' | 'bad_request' | 'not_ready' | 'origin_denied' | 'failed';
|
|
62
|
+
export type XcErrorCode = 'unsupported' | 'bad_request' | 'not_ready' | 'busy' | 'unknown_id' | 'origin_denied' | 'failed';
|
|
63
|
+
/**
|
|
64
|
+
* outfit / scene id 的统一格式: 小写字母开头, 小写字母/数字/下划线, 最长 64。
|
|
65
|
+
* 所有 id 入口 (xc.setOutfit / xc.setScene / ?outfit= / ?scene=) 都先过这条正则, 再用 hasOwnProperty 查表,
|
|
66
|
+
* 这样 `__proto__` / `constructor` / `toString` 这类原型键永远不会被当成合法 id。
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* iframe 内置界面部件名 (`?ui=chat,outfit,scene,lang,github` / SDK `ui: [...]`)。
|
|
70
|
+
* chat 底部聊天栏 (ChatBar, 对话走 WebLLM)
|
|
71
|
+
* bubble 头顶气泡 (说话文本 / 状态)
|
|
72
|
+
* outfit 换装按钮 (与主站 TopHeader 同款)
|
|
73
|
+
* scene 换场景(背景)按钮 (与主站 TopHeader 同款)
|
|
74
|
+
* lang 语言切换按钮 (中文 / English / 日本語; 与主站 TopHeader 同一个组件)
|
|
75
|
+
* github GitHub 链接按钮 (新标签页打开项目仓库; 与主站 TopHeader 同一个组件)
|
|
76
|
+
*/
|
|
77
|
+
/**
|
|
78
|
+
* 窗口圆角半径 (CSS px)。Tauri 桌宠的无框窗口圆角 (src/styles/main.css 的 --xc-window-radius) 与 /embed 非透明场景的默认外壳圆角共用这一个值,
|
|
79
|
+
* 有单测保证两处不漂移。角落弧线 (components/CornerHandle) 的几何就是按这个半径画的。
|
|
80
|
+
*/
|
|
81
|
+
export declare const XC_WINDOW_CORNER_RADIUS = 20;
|
|
82
|
+
export declare const XC_UI_PARTS: readonly ["chat", "bubble", "outfit", "scene", "lang", "github"];
|
|
83
|
+
export type XcUiPart = (typeof XC_UI_PARTS)[number];
|
|
84
|
+
/** 0.1.14 里 `ui=1` / `ui: true` 的含义 = 当时存在的全部部件。 */
|
|
85
|
+
export declare const XC_UI_LEGACY_PARTS: readonly XcUiPart[];
|
|
86
|
+
export interface XcUiParse {
|
|
87
|
+
/** 白名单内的部件 (去重, 保持 XC_UI_PARTS 顺序)。 */
|
|
88
|
+
parts: XcUiPart[];
|
|
89
|
+
/** 被忽略的未知项 (调用方负责 warn)。 */
|
|
90
|
+
unknown: string[];
|
|
91
|
+
/** 用了已弃用的 1 / true 写法 (调用方负责 warn)。 */
|
|
92
|
+
legacy: boolean;
|
|
93
|
+
}
|
|
94
|
+
/** 规整部件名列表: 非字符串 / 未知名字忽略并记入 unknown, 重复去重。 */
|
|
95
|
+
export declare function parseXcUiList(items: readonly unknown[]): XcUiParse;
|
|
96
|
+
/** `?ui=` 参数 / 元素属性: 逗号分隔的部件名; 缺省 / 空 / 0 / false = 全不显示; 1 / true = 旧写法 (弃用, 映射为 chat + bubble)。 */
|
|
97
|
+
export declare function parseXcUiParam(raw: string | null | undefined): XcUiParse;
|
|
98
|
+
/** SDK 选项 `ui` (数组, 或弃用的布尔) → 规整结果。 */
|
|
99
|
+
export declare function normalizeXcUiOption(v: unknown): XcUiParse;
|
|
100
|
+
/**
|
|
101
|
+
* 内置界面 (顶栏按钮 outfit/scene/lang/github + 聊天栏 chat) 的显示策略, 与 Tauri 桌宠的 "点击角色才出现" 同一套状态机 (src/hooks/usePetUiVisibility.ts):
|
|
102
|
+
* 'transparent' (默认) 与 Tauri 完全一致: 只有透明场景默认隐藏, 单击角色出现 (按住拖动 / 长按拖不算), 再单击角色收起, 单击空白收起, 10 秒无操作自动收起
|
|
103
|
+
* (悬停在按钮 / 聊天栏上、菜单或对话框打开、输入框聚焦 / 有输入 / 发送中 时不收); 亮 / 暗场景常显。
|
|
104
|
+
* true 所有场景都按上面的点击出现规则 (亮 / 暗场景也默认隐藏)。
|
|
105
|
+
* false 一直显示 (忽略点击规则)。
|
|
106
|
+
*/
|
|
107
|
+
export type XcUiAutoHide = boolean | 'transparent';
|
|
108
|
+
/** 默认值: 'transparent' (与 Tauri 一致: 只有透明场景点击出现)。 */
|
|
109
|
+
export declare const XC_UI_AUTOHIDE_DEFAULT: XcUiAutoHide;
|
|
110
|
+
/** `?uiAutoHide=` 参数 / 元素属性: 1|true → true; 0|false → false; transparent → 'transparent'; 缺省 / 非法 → undefined (调用方用默认值)。 */
|
|
111
|
+
export declare function parseXcUiAutoHide(raw: unknown): XcUiAutoHide | undefined;
|
|
112
|
+
/** 某个 uiAutoHide 取值在当前场景下是否生效 (隐藏 + 点击出现)。 */
|
|
113
|
+
export declare function xcUiAutoHideActive(mode: XcUiAutoHide, sceneTransparent: boolean): boolean;
|
|
114
|
+
/**
|
|
115
|
+
* 宿主可调的相机选项 (SDK `camera` 选项 / `?cameraFov=` 等 URL 参数 / `xc.setConfig{camera}`)。
|
|
116
|
+
* fov 视野角 (度, 默认 30): 越小越像长焦 (透视压缩、背景虚), 越大越广角。主体取景大小会随 fov 自动补偿 (距离 = 取景范围 / (2·tan(fov/2))), 所以只改 fov 时角色在画面里的大小基本不变
|
|
117
|
+
* distance 相机到角色的视距 (米, 默认约 2.5): 越小角色越大。显式设置后, 首次取景时忽略 iframe 里保存的视距 / 俯仰 (用户之后滚轮缩放仍可调, 且换装 / 换场景不会被拽回)
|
|
118
|
+
* height 取景高度偏移 (米, 默认 0): 正值 = 相机连同目标一起上抬 (角色在画面里下移), 负值相反。显式值不写入 iframe 的保存值
|
|
119
|
+
* intro 是否播放加载完成后的推镜头动画 (默认 true); false = 直接放到终点
|
|
120
|
+
* 缺省 / undefined = 不覆盖 (走 iframe 保存值 / 默认值); `xc.setConfig` 里 null = 清除该项覆盖。
|
|
121
|
+
*/
|
|
122
|
+
export interface XcCamera {
|
|
123
|
+
fov?: number | null;
|
|
124
|
+
distance?: number | null;
|
|
125
|
+
height?: number | null;
|
|
126
|
+
intro?: boolean | null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 各数值项允许的范围 (越界值会被夹到边界)。与主仓库 APP_CONFIG.camera (minFov/maxFov、defaultMin/MaxDistance、hostMaxYOffset)
|
|
130
|
+
* 一致, 主仓库有单测核对。capabilities.camera 也会上报这份范围。
|
|
131
|
+
*/
|
|
132
|
+
export declare const XC_CAMERA_RANGES: {
|
|
133
|
+
readonly fov: readonly [15, 60];
|
|
134
|
+
readonly distance: readonly [1, 15];
|
|
135
|
+
readonly height: readonly [-1, 1];
|
|
136
|
+
};
|
|
137
|
+
export type XcCameraNormalized = {
|
|
138
|
+
ok: true;
|
|
139
|
+
camera: XcCamera; /** 被夹到范围边界的项 (供告警) */
|
|
140
|
+
clamped: string[];
|
|
141
|
+
} | {
|
|
142
|
+
ok: false;
|
|
143
|
+
error: string;
|
|
144
|
+
};
|
|
145
|
+
/**
|
|
146
|
+
* 校验 + 规整一个 camera 对象 (xc.setConfig / SDK 选项共用)。
|
|
147
|
+
* 数字项必须是有限 number (越界夹到范围内); intro 必须是 boolean; null = 清除; 未知键 / 非对象 → 错误。
|
|
148
|
+
*/
|
|
149
|
+
export declare function normalizeXcCamera(raw: unknown): XcCameraNormalized;
|
|
150
|
+
/**
|
|
151
|
+
* 解析 URL 参数 cameraFov / cameraDistance / cameraHeight / cameraIntro (SDK 生成 / 手写 iframe 均可)。
|
|
152
|
+
* 数值非法 → 忽略并记 warning; 越界 → 夹到范围并记 warning; cameraIntro 认 0|1|true|false。
|
|
153
|
+
*/
|
|
154
|
+
export declare function parseXcCameraParams(get: (name: string) => string | null): {
|
|
155
|
+
camera: XcCamera;
|
|
156
|
+
warnings: string[];
|
|
157
|
+
};
|
|
158
|
+
export declare const XC_ID_RE: RegExp;
|
|
159
|
+
export declare const isXcId: (v: unknown) => v is string;
|
|
160
|
+
/** 只认对象自己的属性 (不走原型链); 等价于 Object.hasOwn, 但兼容 ES2020 目标。 */
|
|
161
|
+
export declare const xcHasOwn: (o: object, k: string) => boolean;
|
|
162
|
+
/** 内置场景 id (以 xc.ready.capabilities.scenes 为准; 目前就这三个主题, 不含真实场景资产)。 */
|
|
163
|
+
export type XcSceneId = 'light' | 'dark' | 'transparent';
|
|
63
164
|
export type XcLang = 'zh-CN' | 'en' | 'ja';
|
|
165
|
+
/** iframe 支持的界面语言 (与主站 SUPPORTED_LANGS 同一份; capabilities.ui.langs)。 */
|
|
166
|
+
export declare const XC_LANGS: readonly XcLang[];
|
|
64
167
|
export type XcPhase = 'idle' | 'loading' | 'thinking' | 'speaking' | 'listening' | 'paused';
|
|
65
168
|
/** lazy = 不预热 WebLLM / EMAGE, 首次互动再加载 (默认); eager = 立即预热。 */
|
|
66
169
|
export type XcHeavyMode = 'lazy' | 'eager';
|
|
@@ -75,10 +178,38 @@ export interface XcConfig {
|
|
|
75
178
|
lang?: XcLang;
|
|
76
179
|
/** 背景透明 (叠在宿主页面上)。 */
|
|
77
180
|
transparent?: boolean;
|
|
78
|
-
/**
|
|
79
|
-
|
|
181
|
+
/**
|
|
182
|
+
* 要显示的 iframe 内置界面部件 (见 XC_UI_PARTS), 例如 ['outfit','scene']; 省略 / 空数组 = 不显示。
|
|
183
|
+
* 传 true/false 是 0.1.14 的旧写法 (true = chat + bubble), 已弃用, 仅为兼容保留。
|
|
184
|
+
*/
|
|
185
|
+
ui?: XcUiPart[] | boolean;
|
|
186
|
+
/**
|
|
187
|
+
* 内置界面的显示策略 (见 XcUiAutoHide): 默认 'transparent' = 与 Tauri 一致 (只在透明场景隐藏、单击角色出现, 亮 / 暗场景常显); true = 所有场景都点击出现; false = 一直显示。
|
|
188
|
+
* 仅当 capabilities.ui 存在时才有意义 (旧版 /embed 忽略, 常显)。
|
|
189
|
+
*/
|
|
190
|
+
uiAutoHide?: XcUiAutoHide;
|
|
80
191
|
/** 重资源加载策略, 见 XcHeavyMode。 */
|
|
81
192
|
heavy?: XcHeavyMode;
|
|
193
|
+
/**
|
|
194
|
+
* 允许 xc.setModel 加载任意 https URL 的 .vrm/.vrmaddon/.vrmbase。默认 false (关闭): 只能用 capabilities.outfits 里的内置服装。
|
|
195
|
+
* 由宿主 SDK 的 `allowCustomModel` 选项发出 (放在 xc.init 的 config 里)。
|
|
196
|
+
*/
|
|
197
|
+
allowCustomModel?: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* 手势开关 (宿主 SDK 的 `draggable` / `resizable` 选项发出; 放在 xc.init 的 config 里, 也可用 xc.setConfig 运行时改)。
|
|
200
|
+
* 默认全 false: iframe 里**不识别**对应手势、也不拦截任何指针事件。仅当 capabilities.gestures 存在时才有意义 (旧版 /embed 忽略)。
|
|
201
|
+
* move = 左键在角色上拖动 → 发 xc.gesture-move, 由宿主移动 iframe
|
|
202
|
+
* resize = 在 iframe 四角热区按下拖动 → 发 xc.gesture-resize, 由宿主缩放 iframe
|
|
203
|
+
*/
|
|
204
|
+
gestures?: {
|
|
205
|
+
move?: boolean;
|
|
206
|
+
resize?: boolean;
|
|
207
|
+
};
|
|
208
|
+
/**
|
|
209
|
+
* 相机选项 (见 XcCamera); 放在 xc.init 的 config 里或用 xc.setConfig 运行时改 (缺省键 = 不变, null = 恢复默认, 非法值 → xc.error{bad_request})。
|
|
210
|
+
* 运行时改会立刻重新取景并取消进行中的推镜头。仅当 capabilities.camera 存在时才有意义 (旧版 /embed 忽略)。
|
|
211
|
+
*/
|
|
212
|
+
camera?: XcCamera;
|
|
82
213
|
}
|
|
83
214
|
export interface XcInitPayload {
|
|
84
215
|
/** 宿主声明的自身 origin (iframe 会与 event.origin 交叉校验)。 */
|
|
@@ -163,12 +294,37 @@ export interface XcPointerPayload {
|
|
|
163
294
|
y: number;
|
|
164
295
|
}
|
|
165
296
|
export interface XcSetModelPayload {
|
|
166
|
-
/** 完整 .vrm / .vrmaddon / .vrmbase URL (需 CORS)。 */
|
|
297
|
+
/** 完整 .vrm / .vrmaddon / .vrmbase URL (需 CORS)。**默认关闭**, 需要 xc.init config.allowCustomModel=true, 否则回 unsupported。 */
|
|
167
298
|
url?: string;
|
|
168
|
-
/** 内置服装
|
|
299
|
+
/** 内置服装 id (capabilities.outfits 里的 id, 如 'xiaochun_maid')。裸模 'base' 不对外开放 (回 unknown_id)。新代码请用 xc.setOutfit。 */
|
|
169
300
|
outfit?: string;
|
|
170
301
|
name?: string;
|
|
171
302
|
}
|
|
303
|
+
/** xc.setOutfit — 换内置服装 (id 来自 xc.ready.capabilities.outfits)。串行 + last-wins, 见 docs/EMBED.md。 */
|
|
304
|
+
export interface XcSetOutfitPayload {
|
|
305
|
+
id: string;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* xc.prefetch — 预取服装资源到 iframe 的 IndexedDB (之后 xc.setOutfit 直接命中缓存, 不走网络)。默认不会自动发生。
|
|
309
|
+
* 全局串行 (并发 1); 开了 heavy:'eager' 时排在 EMAGE 加载之后, 也不会和进行中的换装抢带宽。
|
|
310
|
+
* ids 省略 = 全部内置服装, **除了**体积大的婚纱 (xiaochun_wedding, 13.9MB); 显式点名则照做。
|
|
311
|
+
* 应答 xc.prefetched (带同一个信封 id)。
|
|
312
|
+
*/
|
|
313
|
+
export interface XcPrefetchPayload {
|
|
314
|
+
ids?: string[];
|
|
315
|
+
}
|
|
316
|
+
/** xc.prefetched — 预取完成 (逐项成败不影响整体; failed 里的 id 可稍后重试)。 */
|
|
317
|
+
export interface XcPrefetchedPayload {
|
|
318
|
+
downloaded: string[];
|
|
319
|
+
cached: string[];
|
|
320
|
+
failed: string[];
|
|
321
|
+
/** 'save-data' = 用户开了省流量模式, 整个请求被跳过。 */
|
|
322
|
+
skipped?: 'save-data';
|
|
323
|
+
}
|
|
324
|
+
/** xc.setScene — 运行时切场景 (id 来自 xc.ready.capabilities.scenes: light / dark / transparent)。 */
|
|
325
|
+
export interface XcSetScenePayload {
|
|
326
|
+
id: string;
|
|
327
|
+
}
|
|
172
328
|
export interface XcMicPayload {
|
|
173
329
|
enabled: boolean;
|
|
174
330
|
}
|
|
@@ -188,16 +344,96 @@ export interface XcReadyPayload {
|
|
|
188
344
|
};
|
|
189
345
|
/** iframe 内 `self.crossOriginIsolated` (true = 可用 SharedArrayBuffer / 多线程 wasm)。旧版 /embed 没有这个字段。仅诊断用。 */
|
|
190
346
|
crossOriginIsolated?: boolean;
|
|
347
|
+
/** 可换的内置服装 (不含裸模)。旧版 /embed 没有这个字段 → 宿主应视为"不支持 xc.setOutfit"。 */
|
|
348
|
+
outfits?: XcOutfitInfo[];
|
|
349
|
+
/** 可切的场景。旧版 /embed 没有这个字段 → 视为"不支持 xc.setScene"。 */
|
|
350
|
+
scenes?: XcSceneInfo[];
|
|
351
|
+
/** 支持 xc.prefetch。旧版 /embed 没有这个字段。 */
|
|
352
|
+
prefetch?: boolean;
|
|
353
|
+
/**
|
|
354
|
+
* iframe 内手势 (拖动 / 角落缩放) 支持情况; 旧版 /embed 没有这个字段 → 宿主视为"不支持", draggable / resizable 无效。
|
|
355
|
+
* cornerSize = 四角热区边长 (CSS px, iframe 视口左上/右上/左下/右下各一个正方形), 宿主 UI 可据此提示。
|
|
356
|
+
*/
|
|
357
|
+
gestures?: {
|
|
358
|
+
move: boolean;
|
|
359
|
+
resize: boolean;
|
|
360
|
+
cornerSize: number;
|
|
361
|
+
};
|
|
362
|
+
/**
|
|
363
|
+
* 内置界面能力; 旧版 /embed 没有这个字段 → 宿主视为"没有 lang / github 部件、不支持 uiAutoHide (界面常显)"。
|
|
364
|
+
* parts = 可用的部件名; autoHide = 支持 uiAutoHide (点击出现); langs = 语言按钮 / `lang` 选项可用的取值。
|
|
365
|
+
*/
|
|
366
|
+
ui?: {
|
|
367
|
+
parts: XcUiPart[];
|
|
368
|
+
autoHide: boolean;
|
|
369
|
+
langs: XcLang[];
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* 相机选项能力 (见 XcCamera); 旧版 /embed 没有这个字段 → 宿主视为"不支持 camera 选项"。
|
|
373
|
+
* fov / distance / height = 各项允许范围 [min, max] (越界会被夹到边界); intro = 支持关闭推镜头。
|
|
374
|
+
*/
|
|
375
|
+
camera?: {
|
|
376
|
+
fov: [number, number];
|
|
377
|
+
distance: [number, number];
|
|
378
|
+
height: [number, number];
|
|
379
|
+
intro: boolean;
|
|
380
|
+
};
|
|
191
381
|
};
|
|
192
382
|
}
|
|
383
|
+
export interface XcOutfitInfo {
|
|
384
|
+
id: string;
|
|
385
|
+
/** 展示名 (英文, 来自主仓库配置)。 */
|
|
386
|
+
name: string;
|
|
387
|
+
/** 服装文件大小提示 (MB, 十进制, 约值; 公共的裸模 ~5.7MB 不计)。仅供宿主自己的 UI 参考 (内置换装菜单不显示体积); 旧版 /embed 没有这个字段。 */
|
|
388
|
+
sizeMB?: number;
|
|
389
|
+
}
|
|
390
|
+
export interface XcSceneInfo {
|
|
391
|
+
id: string;
|
|
392
|
+
/** true = 背景透明 (叠在宿主页上, 可开穿透)。 */
|
|
393
|
+
transparent: boolean;
|
|
394
|
+
}
|
|
193
395
|
export interface XcLoadProgressPayload {
|
|
194
|
-
|
|
396
|
+
/**
|
|
397
|
+
* 'model' = 首次加载; 'outfit' = 运行中换装 (id = 目标服装 id, 自定义 URL 时省略);
|
|
398
|
+
* 'prefetch' = 宿主发了 xc.prefetch 后的后台下载 (id = 正在预取的服装)。已有的"model 进度条"逻辑请先判断 phase。
|
|
399
|
+
*/
|
|
400
|
+
phase: 'model' | 'outfit' | 'prefetch';
|
|
195
401
|
/** 0~100 */
|
|
196
402
|
progress: number;
|
|
403
|
+
id?: string;
|
|
197
404
|
}
|
|
198
405
|
export interface XcLoadedPayload {
|
|
199
406
|
model: string;
|
|
200
407
|
}
|
|
408
|
+
/**
|
|
409
|
+
* xc.outfit-changed — 服装已生效。三种来源: 首次加载 (initial:true)、xc.setOutfit / xc.setModel 的应答 (带同一个信封 id)。
|
|
410
|
+
* noop:true = 目标已经是当前服装 (或与另一个同目标请求合并), 没有重新加载; SDK 只用它 resolve 对应的 Promise, 不再触发事件。
|
|
411
|
+
*/
|
|
412
|
+
export interface XcOutfitChangedPayload {
|
|
413
|
+
/** 内置服装 id; 自定义 URL 模型为 null。 */
|
|
414
|
+
id: string | null;
|
|
415
|
+
name: string;
|
|
416
|
+
previous?: string | null;
|
|
417
|
+
initial?: boolean;
|
|
418
|
+
noop?: boolean;
|
|
419
|
+
}
|
|
420
|
+
/** xc.scene-changed — 场景已生效 (首次握手后的当前场景 / xc.setScene 应答 / xc.setConfig{transparent} 引起的切换)。 */
|
|
421
|
+
export interface XcSceneChangedPayload {
|
|
422
|
+
id: string;
|
|
423
|
+
transparent: boolean;
|
|
424
|
+
previous?: string | null;
|
|
425
|
+
initial?: boolean;
|
|
426
|
+
noop?: boolean;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* xc.lang-changed — iframe 当前界面语言 (握手后上报一次 initial:true; 之后用户点语言按钮 / xc.setConfig{lang} 引起的变化)。
|
|
430
|
+
* 初始语言优先级: `?lang=` (SDK `lang` 选项) > iframe 自己 localStorage 里记住的用户选择 > 浏览器语言 > zh-CN。
|
|
431
|
+
*/
|
|
432
|
+
export interface XcLangChangedPayload {
|
|
433
|
+
lang: XcLang;
|
|
434
|
+
previous?: XcLang | null;
|
|
435
|
+
initial?: boolean;
|
|
436
|
+
}
|
|
201
437
|
export interface XcStatePayload {
|
|
202
438
|
phase: XcPhase;
|
|
203
439
|
paused: boolean;
|
|
@@ -224,6 +460,31 @@ export interface XcHitRegionPayload {
|
|
|
224
460
|
x: number;
|
|
225
461
|
y: number;
|
|
226
462
|
}
|
|
463
|
+
/** 手势阶段: start = 按下后确认成手势; move = 增量; end = 结束 (松手 / 取消 / 失焦)。 */
|
|
464
|
+
export type XcGesturePhase = 'start' | 'move' | 'end';
|
|
465
|
+
/**
|
|
466
|
+
* xc.gesture-move / xc.gesture-resize 的公共字段。单位 CSS px (屏幕坐标差, iframe 被移动时仍稳定)。
|
|
467
|
+
* - gesture: 手势序号, 每次新手势 +1 (从 1 起); 宿主据此区分手势, 丢弃过期手势的迟到消息。
|
|
468
|
+
* - seq: 该手势内的消息序号, start = 0, 之后严格递增; 宿主丢弃 seq 不递增的消息。
|
|
469
|
+
* - dx / dy: 相对上一条消息的增量; totalDx / totalDy: 相对 start 的累计 (宿主以它为准计算, 增量只是参考, 丢包也不漂移)。
|
|
470
|
+
* - reason: 仅 phase='end' 带: up = 松手, cancel = 指针被系统取消, blur = 窗口失焦。
|
|
471
|
+
*/
|
|
472
|
+
export interface XcGestureBase {
|
|
473
|
+
gesture: number;
|
|
474
|
+
seq: number;
|
|
475
|
+
phase: XcGesturePhase;
|
|
476
|
+
dx: number;
|
|
477
|
+
dy: number;
|
|
478
|
+
totalDx: number;
|
|
479
|
+
totalDy: number;
|
|
480
|
+
reason?: 'up' | 'cancel' | 'blur';
|
|
481
|
+
}
|
|
482
|
+
export type XcGestureMovePayload = XcGestureBase;
|
|
483
|
+
export type XcGestureCorner = 'NW' | 'NE' | 'SW' | 'SE';
|
|
484
|
+
export interface XcGestureResizePayload extends XcGestureBase {
|
|
485
|
+
/** 被拖的角; 对角固定不动。 */
|
|
486
|
+
corner: XcGestureCorner;
|
|
487
|
+
}
|
|
227
488
|
export interface XcErrorPayload {
|
|
228
489
|
code: XcErrorCode;
|
|
229
490
|
message: string;
|
|
@@ -241,6 +502,9 @@ export interface XcHostPayloadMap {
|
|
|
241
502
|
'xc.lookAt': XcLookAtPayload;
|
|
242
503
|
'xc.pointer': XcPointerPayload;
|
|
243
504
|
'xc.setModel': XcSetModelPayload;
|
|
505
|
+
'xc.setOutfit': XcSetOutfitPayload;
|
|
506
|
+
'xc.setScene': XcSetScenePayload;
|
|
507
|
+
'xc.prefetch': XcPrefetchPayload;
|
|
244
508
|
'xc.setConfig': XcConfig;
|
|
245
509
|
'xc.mic': XcMicPayload;
|
|
246
510
|
'xc.pause': undefined;
|
|
@@ -251,10 +515,16 @@ export interface XcFramePayloadMap {
|
|
|
251
515
|
'xc.ready': XcReadyPayload;
|
|
252
516
|
'xc.load.progress': XcLoadProgressPayload;
|
|
253
517
|
'xc.loaded': XcLoadedPayload;
|
|
518
|
+
'xc.outfit-changed': XcOutfitChangedPayload;
|
|
519
|
+
'xc.scene-changed': XcSceneChangedPayload;
|
|
520
|
+
'xc.lang-changed': XcLangChangedPayload;
|
|
521
|
+
'xc.prefetched': XcPrefetchedPayload;
|
|
254
522
|
'xc.state': XcStatePayload;
|
|
255
523
|
'xc.stt': XcSttPayload;
|
|
256
524
|
'xc.utterance': XcUtterancePayload;
|
|
257
525
|
'xc.hit-region': XcHitRegionPayload;
|
|
526
|
+
'xc.gesture-move': XcGestureMovePayload;
|
|
527
|
+
'xc.gesture-resize': XcGestureResizePayload;
|
|
258
528
|
'xc.error': XcErrorPayload;
|
|
259
529
|
}
|
|
260
530
|
export type XcHostMessage = {
|
package/dist/protocol.js
CHANGED
|
@@ -1,28 +1,60 @@
|
|
|
1
|
-
/*! @firetable/project-xiaochun v0.1.
|
|
1
|
+
/*! @firetable/project-xiaochun v0.1.16 | MIT | https://github.com/FireTable/project-xiaochun */
|
|
2
2
|
import {
|
|
3
|
+
XC_CAMERA_RANGES,
|
|
3
4
|
XC_DEFAULT_ORIGIN,
|
|
4
5
|
XC_DEFAULT_SRC,
|
|
5
6
|
XC_FRAME_TO_HOST,
|
|
6
7
|
XC_HOST_TO_FRAME,
|
|
8
|
+
XC_ID_RE,
|
|
7
9
|
XC_IMPLEMENTED_COMMANDS,
|
|
10
|
+
XC_LANGS,
|
|
8
11
|
XC_PROTOCOL_MAPPING,
|
|
9
12
|
XC_PROTOCOL_VERSION,
|
|
13
|
+
XC_UI_AUTOHIDE_DEFAULT,
|
|
14
|
+
XC_UI_LEGACY_PARTS,
|
|
15
|
+
XC_UI_PARTS,
|
|
10
16
|
XC_UNSUPPORTED_COMMANDS,
|
|
17
|
+
XC_WINDOW_CORNER_RADIUS,
|
|
11
18
|
isXcEnvelope,
|
|
19
|
+
isXcId,
|
|
12
20
|
normalizeOrigin,
|
|
13
|
-
|
|
14
|
-
|
|
21
|
+
normalizeXcCamera,
|
|
22
|
+
normalizeXcUiOption,
|
|
23
|
+
parseXcCameraParams,
|
|
24
|
+
parseXcUiAutoHide,
|
|
25
|
+
parseXcUiList,
|
|
26
|
+
parseXcUiParam,
|
|
27
|
+
xcHasOwn,
|
|
28
|
+
xcMessage,
|
|
29
|
+
xcUiAutoHideActive
|
|
30
|
+
} from "./chunks/chunk-RHQW4QZH.js";
|
|
15
31
|
export {
|
|
32
|
+
XC_CAMERA_RANGES,
|
|
16
33
|
XC_DEFAULT_ORIGIN,
|
|
17
34
|
XC_DEFAULT_SRC,
|
|
18
35
|
XC_FRAME_TO_HOST,
|
|
19
36
|
XC_HOST_TO_FRAME,
|
|
37
|
+
XC_ID_RE,
|
|
20
38
|
XC_IMPLEMENTED_COMMANDS,
|
|
39
|
+
XC_LANGS,
|
|
21
40
|
XC_PROTOCOL_MAPPING,
|
|
22
41
|
XC_PROTOCOL_VERSION,
|
|
42
|
+
XC_UI_AUTOHIDE_DEFAULT,
|
|
43
|
+
XC_UI_LEGACY_PARTS,
|
|
44
|
+
XC_UI_PARTS,
|
|
23
45
|
XC_UNSUPPORTED_COMMANDS,
|
|
46
|
+
XC_WINDOW_CORNER_RADIUS,
|
|
24
47
|
isXcEnvelope,
|
|
48
|
+
isXcId,
|
|
25
49
|
normalizeOrigin,
|
|
26
|
-
|
|
50
|
+
normalizeXcCamera,
|
|
51
|
+
normalizeXcUiOption,
|
|
52
|
+
parseXcCameraParams,
|
|
53
|
+
parseXcUiAutoHide,
|
|
54
|
+
parseXcUiList,
|
|
55
|
+
parseXcUiParam,
|
|
56
|
+
xcHasOwn,
|
|
57
|
+
xcMessage,
|
|
58
|
+
xcUiAutoHideActive
|
|
27
59
|
};
|
|
28
60
|
//# sourceMappingURL=protocol.js.map
|