weifuwu 0.82.12 → 0.83.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/README.md +1 -0
- package/dist/ui-dom/index.d.ts +4 -0
- package/dist/ui-dom/index.js +12 -12
- package/dist/ui-dom/router.d.ts +7 -0
- package/dist/ui-dom/testing.js +1 -1
- package/dist/ui-dom/vdom2/audit.d.ts +4 -1
- package/dist/ui-dom/vdom2/dom-trace.d.ts +4 -0
- package/dist/ui-dom/vdom2/events.d.ts +5 -1
- package/dist/ui-dom/vdom2/lifecycle.d.ts +4 -0
- package/dist/ui-dom/vdom2/mount.d.ts +14 -1
- package/dist/ui-dom/vdom2/patch.d.ts +2 -0
- package/dist/ui-dom/vdom3/README.d.ts +29 -0
- package/dist/ui-dom/vdom3/audit.d.ts +16 -0
- package/dist/ui-dom/vdom3/build.d.ts +16 -0
- package/dist/ui-dom/vdom3/commands.d.ts +11 -0
- package/dist/ui-dom/vdom3/compat.d.ts +20 -0
- package/dist/ui-dom/vdom3/events.d.ts +11 -0
- package/dist/ui-dom/vdom3/index.d.ts +40 -0
- package/dist/ui-dom/vdom3/jsx.d.ts +10 -0
- package/dist/ui-dom/vdom3/record.d.ts +13 -0
- package/dist/ui-dom/vdom3/registry.d.ts +30 -0
- package/dist/ui-dom/vdom3/render.d.ts +26 -0
- package/dist/ui-dom/vdom3/replay.d.ts +25 -0
- package/dist/ui-dom/vdom3/root.d.ts +28 -0
- package/dist/ui-dom/vdom3/router.d.ts +31 -0
- package/dist/ui-dom/vdom3/scheduler.d.ts +23 -0
- package/dist/ui-dom/vdom3/ssr.d.ts +27 -0
- package/dist/ui-dom/vdom3/sync.d.ts +22 -0
- package/dist/ui-dom/vdom3/types.d.ts +115 -0
- package/dist/ui-dom/vdom3/ui.d.ts +43 -0
- package/dist/ui-dom/vdom3.js +39 -0
- package/docs/frontend.md +5 -0
- package/package.json +6 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 replay — 事件流回放 / 取消 / 断言(DOM = fold(事件流))
|
|
3
|
+
*
|
|
4
|
+
* 回放(replay):从目标容器重放事件流——NODE_CREATE 建节点(id→节点映射)、
|
|
5
|
+
* INSERT 挂载、PROP/TEXT_UPDATE 应用——结果 = 原渲染的 DOM(fold 不变量)。
|
|
6
|
+
*
|
|
7
|
+
* 取消(undo):从事件流末尾取 N 个事件 → 应用逆操作——INSERT→REMOVE、
|
|
8
|
+
* REMOVE→恢复(registry 保存的节点)、PROP/TEXT_UPDATE→恢复 prev。
|
|
9
|
+
*
|
|
10
|
+
* 断言(eventsOf/hasEvent):渲染 = 事件序列断言(测试/调试)。
|
|
11
|
+
*/
|
|
12
|
+
import type { V3Event } from './types.ts';
|
|
13
|
+
import { NodeRegistry } from './registry.ts';
|
|
14
|
+
/** 应用单个事件(流式客户端逐事件消费——replay 循环的拆解) */
|
|
15
|
+
export declare function applyEvent(ev: V3Event, target: HTMLElement, reg: NodeRegistry): void;
|
|
16
|
+
/** 回放事件流到目标容器(DOM = fold(events)——结果与原始渲染同构) */
|
|
17
|
+
export declare function replay(events: V3Event[], target: HTMLElement, reg?: NodeRegistry): void;
|
|
18
|
+
/** 取消:从事件流末尾取 n 个 DOM 指令 → 应用逆操作(撤销渲染变化) */
|
|
19
|
+
export declare function undo(events: V3Event[], n: number, reg?: NodeRegistry): void;
|
|
20
|
+
/** 断言工具:过滤事件(按类型/谓词) */
|
|
21
|
+
export declare function eventsOf(events: V3Event[], type: V3Event['type']): V3Event[];
|
|
22
|
+
/** 断言工具:是否存在匹配事件 */
|
|
23
|
+
export declare function hasEvent(events: V3Event[], predicate: (e: V3Event) => boolean): boolean;
|
|
24
|
+
/** 断言:渲染 = 事件序列(测试——精确描述渲染做了什么) */
|
|
25
|
+
export declare function expectEventSequence(events: V3Event[], expected: V3Event['type'][]): void;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 root — 应用入口:createRoot(挂载 + 组件渲染上下文)
|
|
3
|
+
*
|
|
4
|
+
* 组件 ctx.render():调度自身重渲染(同 tick 合并——一次 patch)。
|
|
5
|
+
* 渲染流程:renderFn 重跑 → buildVNode(oldV 对照复用)→ patch(事件流 → DOM)。
|
|
6
|
+
*/
|
|
7
|
+
import type { VNode } from './types.ts';
|
|
8
|
+
export interface V3Ctx {
|
|
9
|
+
render: () => void;
|
|
10
|
+
/** 组件自身输出(渲染定位) */
|
|
11
|
+
_vnode: VNode;
|
|
12
|
+
_parent: Node | null;
|
|
13
|
+
}
|
|
14
|
+
export interface RootHandle {
|
|
15
|
+
ctx: V3Ctx;
|
|
16
|
+
/** 组件重渲染(ctx.render 内部路径——同 tick 合并) */
|
|
17
|
+
rerender(): void;
|
|
18
|
+
/** 立即刷新(测试) */
|
|
19
|
+
flush(): void;
|
|
20
|
+
unmount(): void;
|
|
21
|
+
/** 首帧完成 Promise(初始挂载——工厂 await + 渲染落地) */
|
|
22
|
+
ready: Promise<void>;
|
|
23
|
+
}
|
|
24
|
+
/** 创建应用根(挂载组件树——组件获得 ctx.render 调度能力;options.ctx 注入扩展字段
|
|
25
|
+
* ——中间件面(app/i18n/auth/data 等——组件 ctx 可选链消费)) */
|
|
26
|
+
export declare function createRoot(vnode: VNode, root: HTMLElement, options?: {
|
|
27
|
+
ctx?: Record<string, unknown>;
|
|
28
|
+
}): RootHandle;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 router — 路由(location → ROUTE_CHANGE 事件 → 组件挂载 → DOM 全链路)
|
|
3
|
+
*
|
|
4
|
+
* 事件流覆盖:ROUTE_CHANGE(path, params) → COMP_MOUNT → NODE_CREATE/INSERT → ...
|
|
5
|
+
* 页面切换 = 异类型 patch(旧页面 COMP_UNMOUNT + REMOVE;新页面 MOUNT + CREATE/INSERT)——
|
|
6
|
+
* 全链路事件化(location→DOM 的完整因果链可回放)。
|
|
7
|
+
*/
|
|
8
|
+
import type { VNode } from './types.ts';
|
|
9
|
+
/** 布局包裹(跨路由复用——layout 函数引用稳定 → patch 同位置同类型复用——
|
|
10
|
+
* 工厂不重跑——内部状态(折叠/高亮)保持——vdom2 布局层语义) */
|
|
11
|
+
export type RouteLayout = (page: VNode) => VNode;
|
|
12
|
+
export interface RouteDef {
|
|
13
|
+
path: string;
|
|
14
|
+
/** 页面渲染(params 注入——:id 等) */
|
|
15
|
+
render: (params: Record<string, string>) => VNode;
|
|
16
|
+
/** 布局包裹(可选——页面在布局插槽内) */
|
|
17
|
+
layout?: RouteLayout;
|
|
18
|
+
}
|
|
19
|
+
export interface RouterHandle {
|
|
20
|
+
navigate(path: string): void;
|
|
21
|
+
/** 当前路径 */
|
|
22
|
+
path(): string;
|
|
23
|
+
/** 立即处理当前 URL(测试/恢复) */
|
|
24
|
+
refresh(): void;
|
|
25
|
+
close(): void;
|
|
26
|
+
}
|
|
27
|
+
/** 创建路由应用(初始挂载 + popstate 导航;options.ctx 注入中间件面——页面组件消费) */
|
|
28
|
+
export declare function createRouter(routes: RouteDef[], root: HTMLElement, options?: {
|
|
29
|
+
initialPath?: string;
|
|
30
|
+
ctx?: Record<string, unknown>;
|
|
31
|
+
}): RouterHandle;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 scheduler — 渲染调度(同 tick 合并 + 批处理 + 防死循环)
|
|
3
|
+
*
|
|
4
|
+
* 语义:
|
|
5
|
+
* - schedule(fn):收集渲染请求——同 tick 多次 schedule 合并为一次 flush(微任务)
|
|
6
|
+
* - flush:批量执行(一次事件循环内所有待渲染请求)
|
|
7
|
+
* - 渲染中再次 schedule(组件 renderFn 内触发)→ 排队到下一轮(合并补跑)
|
|
8
|
+
* - 防死循环:单次 flush 内重渲染次数上限(吸取 vdom2 pending 死循环教训)
|
|
9
|
+
*/
|
|
10
|
+
export declare class Scheduler {
|
|
11
|
+
private queue;
|
|
12
|
+
private running;
|
|
13
|
+
private iterations;
|
|
14
|
+
/** 调度渲染(同 tick 合并——微任务批量执行) */
|
|
15
|
+
schedule(fn: () => void): void;
|
|
16
|
+
/** 立即执行队列(测试/显式刷新用) */
|
|
17
|
+
flush(): void;
|
|
18
|
+
/** 待处理数量(测试断言——合并语义) */
|
|
19
|
+
pending(): number;
|
|
20
|
+
get isRunning(): boolean;
|
|
21
|
+
}
|
|
22
|
+
/** 全局调度器(默认实例——后续 per-app 实例化) */
|
|
23
|
+
export declare const scheduler: Scheduler;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 ssr — 服务端事件流生成(dry-run——不创建 DOM)
|
|
3
|
+
*
|
|
4
|
+
* 差异化能力(可移植执行记录):服务端执行组件(buildVNode)→ 生成渲染事件流
|
|
5
|
+
* (NODE_CREATE/PROP_UPDATE/INSERT/TEXT_CREATE——自包含指令)→ 序列化传输 →
|
|
6
|
+
* 客户端 replay(events, root) 重建 DOM——**零 DOM 猜测**(事件流自带全部指令)。
|
|
7
|
+
*
|
|
8
|
+
* 与 vdom2 SSR(HTML 字符串 + hydrate 游标收养)的本质区别:
|
|
9
|
+
* - vdom2:服务端序列化 HTML → 客户端解析 + 游标匹配(DOM 结构猜测)
|
|
10
|
+
* - vdom3:服务端生成事件流 → 客户端重放(精确增量——无猜测)
|
|
11
|
+
*/
|
|
12
|
+
import type { VNode, V3Event } from './types.ts';
|
|
13
|
+
import { stream } from './events.ts';
|
|
14
|
+
/** 服务端渲染 → 事件流(dry-run:只生成指令,不创建 DOM——可传输/回放) */
|
|
15
|
+
export declare function renderToEvents(vnode: VNode): Promise<V3Event[]>;
|
|
16
|
+
/**
|
|
17
|
+
* 流式渲染:服务端逐事件推送(AsyncGenerator)→ 客户端逐事件应用
|
|
18
|
+
* ——TTFB 后首帧渐进(根节点先到 → 内容逐块)——vdom2 无法做到(HTML 需完整)
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderToEventStream(vnode: VNode): AsyncGenerator<V3Event>;
|
|
21
|
+
/** 事件流 → HTML 字符串(首帧序列化——SEO/爬虫/首帧;客户端用事件流重建——零 DOM 猜测) */
|
|
22
|
+
export declare function eventsToHtml(events: V3Event[]): string;
|
|
23
|
+
/** 序列化(传输——事件流 JSON 化) */
|
|
24
|
+
export declare function serializeEvents(events: V3Event[]): string;
|
|
25
|
+
/** 反序列化 */
|
|
26
|
+
export declare function deserializeEvents(json: string): V3Event[];
|
|
27
|
+
export { stream };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 sync — 多端同步(事件流 = 操作日志 → 镜像容器)
|
|
3
|
+
*
|
|
4
|
+
* 协作基础:一端渲染/交互 → 事件流(操作日志)→ 另一端增量应用(applyEvent)→
|
|
5
|
+
* DOM 同构——**无需重放全量**(增量同步——日志位置游标)。
|
|
6
|
+
*
|
|
7
|
+
* 裁剪(诚实):单向往复(一端事件 → 多端镜像);双向 OT/冲突解决不在本层
|
|
8
|
+
* (事件流是不可变日志——双向 = 双方各自日志 + 合并策略——后续工作)。
|
|
9
|
+
*/
|
|
10
|
+
import type { V3Event } from './types.ts';
|
|
11
|
+
export interface SyncHandle {
|
|
12
|
+
/** 增量应用新事件(返回本批应用数)——新事件到达时调用 */
|
|
13
|
+
sync(): number;
|
|
14
|
+
/** 已应用事件数(日志游标) */
|
|
15
|
+
applied(): number;
|
|
16
|
+
/** 最近一次同步的截断事件流(诊断) */
|
|
17
|
+
lastBatch(): V3Event[];
|
|
18
|
+
}
|
|
19
|
+
/** 创建多端镜像:目标容器 + 事件日志源(getEvents)→ 增量同步 */
|
|
20
|
+
export declare function createSync(target: HTMLElement, getEvents: () => V3Event[]): SyncHandle;
|
|
21
|
+
/** 自动同步(监听回调驱动的镜像——如 store 变化/WS 消息 → 自动 sync) */
|
|
22
|
+
export declare function autoSync(target: HTMLElement, getEvents: () => V3Event[], subscribe: (cb: () => void) => () => void): () => void;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 核心类型——vnode 树(声明式)+ 渲染事件流(执行层)
|
|
3
|
+
*
|
|
4
|
+
* 架构:vnode + stream
|
|
5
|
+
* 状态 → renderFn → vnode 树(声明式——组件输出完整树,与 vdom2 同模型)
|
|
6
|
+
* → 渲染器:树 → **事件流**(CREATE/INSERT/PROP_UPDATE/TEXT_UPDATE/REMOVE...)
|
|
7
|
+
* → 执行器:消费事件 → DOM
|
|
8
|
+
*
|
|
9
|
+
* 事件流是引擎本体:从 location 到 DOM 的每一步都是事件——可记录/回放/取消/断言。
|
|
10
|
+
* 不变量:DOM = fold(事件流)——给定初始 DOM + 事件流 = 任意时刻 DOM。
|
|
11
|
+
*/
|
|
12
|
+
/** 两阶段组件契约(与 vdom2 同模型:mount 工厂一次 + renderFn 每次渲染)
|
|
13
|
+
* 返回 Promise<any>(兼容 vdom2 组件——renderFn 产出 JSX.Element(名义类型
|
|
14
|
+
* 不同于 VNode——结构兼容)——vdom2 资产零改动迁移的前提) */
|
|
15
|
+
export type Component<P = Record<string, unknown>, C = Record<string, unknown>> = (initProps: P, ctx: C) => Promise<(props: P) => Promise<any>>;
|
|
16
|
+
export interface VNode {
|
|
17
|
+
/** native 标签名 / 组件函数 / Fragment 符号 */
|
|
18
|
+
type: string | symbol | Component;
|
|
19
|
+
props: Record<string, unknown>;
|
|
20
|
+
key?: string | null;
|
|
21
|
+
/** 渲染后回填:DOM 元素(native)/ 组件实例输出(comp) */
|
|
22
|
+
el?: Node | null;
|
|
23
|
+
children?: VNodeChild[];
|
|
24
|
+
/** 组件实例状态(comp:工厂返回的 renderFn + 实例 id) */
|
|
25
|
+
_render?: (props: any) => Promise<VNode | null>;
|
|
26
|
+
_id?: string;
|
|
27
|
+
/** 组件输出(build 写——独立于 children(props.children 是入参);避免覆盖污染对照树) */
|
|
28
|
+
_child?: VNode | null;
|
|
29
|
+
}
|
|
30
|
+
export type VNodeChild = VNode | string | number | null | undefined | boolean;
|
|
31
|
+
export declare function childrenOf(v: VNode): VNodeChild[];
|
|
32
|
+
export declare const Fragment: unique symbol;
|
|
33
|
+
/** Portal(浮层渲染到远程容器——#__wf_portal 下按 key 的容器——脱离父节点位置) */
|
|
34
|
+
export declare const Portal: unique symbol;
|
|
35
|
+
export type PortalVNode = VNode & {
|
|
36
|
+
type: typeof Portal;
|
|
37
|
+
portalKey?: string | null;
|
|
38
|
+
};
|
|
39
|
+
export type V3Event =
|
|
40
|
+
/** 路由 */
|
|
41
|
+
{
|
|
42
|
+
type: 'ROUTE_CHANGE';
|
|
43
|
+
path: string;
|
|
44
|
+
params: Record<string, string>;
|
|
45
|
+
ts: number;
|
|
46
|
+
}
|
|
47
|
+
/** 组件 */
|
|
48
|
+
| {
|
|
49
|
+
type: 'COMP_MOUNT';
|
|
50
|
+
id: string;
|
|
51
|
+
name: string;
|
|
52
|
+
ts: number;
|
|
53
|
+
} | {
|
|
54
|
+
type: 'COMP_UNMOUNT';
|
|
55
|
+
id: string;
|
|
56
|
+
name: string;
|
|
57
|
+
ts: number;
|
|
58
|
+
}
|
|
59
|
+
/** 渲染指令(DOM 变更——执行器消费;可逆) */
|
|
60
|
+
| {
|
|
61
|
+
type: 'NODE_CREATE';
|
|
62
|
+
id: string;
|
|
63
|
+
tag: string;
|
|
64
|
+
ts: number;
|
|
65
|
+
} | {
|
|
66
|
+
type: 'TEXT_CREATE';
|
|
67
|
+
id: string;
|
|
68
|
+
value: string;
|
|
69
|
+
ts: number;
|
|
70
|
+
} | {
|
|
71
|
+
type: 'INSERT';
|
|
72
|
+
parent: string;
|
|
73
|
+
child: string;
|
|
74
|
+
ref?: string | null;
|
|
75
|
+
ts: number;
|
|
76
|
+
} | {
|
|
77
|
+
type: 'REMOVE';
|
|
78
|
+
parent: string;
|
|
79
|
+
child: string;
|
|
80
|
+
ts: number;
|
|
81
|
+
} | {
|
|
82
|
+
type: 'PROP_UPDATE';
|
|
83
|
+
target: string;
|
|
84
|
+
key: string;
|
|
85
|
+
value: unknown;
|
|
86
|
+
prev: unknown;
|
|
87
|
+
ts: number;
|
|
88
|
+
} | {
|
|
89
|
+
type: 'TEXT_UPDATE';
|
|
90
|
+
target: string;
|
|
91
|
+
value: string;
|
|
92
|
+
prev: string;
|
|
93
|
+
ts: number;
|
|
94
|
+
} | {
|
|
95
|
+
type: 'MOVE';
|
|
96
|
+
node: string;
|
|
97
|
+
parent: string;
|
|
98
|
+
ref: string | null;
|
|
99
|
+
prev?: string | null;
|
|
100
|
+
ts: number;
|
|
101
|
+
};
|
|
102
|
+
/** 事件流(记录/回放/断言——DOM = fold(events)) */
|
|
103
|
+
export interface EventStream {
|
|
104
|
+
emit(ev: V3Event): void;
|
|
105
|
+
events(): V3Event[];
|
|
106
|
+
/** 逆操作(取消——INSERT↔REMOVE / UPDATE 恢复旧值) */
|
|
107
|
+
inverse(ev: V3Event): V3Event | null;
|
|
108
|
+
reset(): void;
|
|
109
|
+
}
|
|
110
|
+
export interface Renderer {
|
|
111
|
+
/** 挂载(vnode → 事件流 → DOM) */
|
|
112
|
+
mount(vnode: VNode, root: HTMLElement): void;
|
|
113
|
+
/** 更新(旧树 vs 新树 → 事件流 → DOM——同位置同类型复用,仅变更发事件) */
|
|
114
|
+
patch(oldV: VNode | null, newV: VNodeChild, parent: Node, anchor?: Node | null): void;
|
|
115
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom3 ui — ctx.ui 兼容面(hooks shim——阶段 2)
|
|
3
|
+
*
|
|
4
|
+
* 迁移策略 D1:vdom2 hooks 源码复用(与引擎解耦)——vdom3 实现 HookEnv
|
|
5
|
+
* (12 字段)+ 薄转发 ctx.ui.useXXX——组件库零改动。
|
|
6
|
+
*
|
|
7
|
+
* 当前实现(最小闭环):useExternal/useControlled/useOpen——按组件库依赖
|
|
8
|
+
* 排序逐步扩展(usePopup 等引擎耦合 hooks 单独攻坚)。
|
|
9
|
+
* render(ids) 语义:含自身 id → vdom3 ctx.render()(组件自身重渲染);
|
|
10
|
+
* 其他 id → vdom3 无跨组件 render(诚实 warn——后续补 registry 级 render)。
|
|
11
|
+
*/
|
|
12
|
+
/** 组件 ctx.ui(vdom2 兼容面)——组件库零改动运行 */
|
|
13
|
+
export interface V3Ui {
|
|
14
|
+
render(ids?: string[]): void;
|
|
15
|
+
onUnmount(fn: () => void): (() => void) | undefined;
|
|
16
|
+
selfId(name: string): void;
|
|
17
|
+
useExternal(store: any): any;
|
|
18
|
+
useControlled(options: any): any;
|
|
19
|
+
useControlledInput(options: any): any;
|
|
20
|
+
useOpen(options: any): any;
|
|
21
|
+
usePopup(options: any): any;
|
|
22
|
+
usePopupPosition(options: any): any;
|
|
23
|
+
useTween(target: number, opts?: any): any;
|
|
24
|
+
useInView(options?: any): any;
|
|
25
|
+
useScrollPosition(options?: any): any;
|
|
26
|
+
useGlobalKey(handler: (e: KeyboardEvent) => void): () => void;
|
|
27
|
+
useDrag(options?: any): any;
|
|
28
|
+
useDragDrop(options?: any): any;
|
|
29
|
+
useMedia(query: string, callback: (matches: boolean) => void): void;
|
|
30
|
+
useBreakpoint(bps: any, callback?: any): void;
|
|
31
|
+
useReducedMotion(): boolean;
|
|
32
|
+
useStableRef(init: any, cleanup?: any): any;
|
|
33
|
+
useAnimationEnd(cb: any, opts?: any): any;
|
|
34
|
+
usePresence(options?: any): any;
|
|
35
|
+
useLongPress(options?: any): any;
|
|
36
|
+
useHoverCapable(): boolean;
|
|
37
|
+
useVisualViewport(): any;
|
|
38
|
+
useAsync(fetcher: any): any;
|
|
39
|
+
useChat(options: any): any;
|
|
40
|
+
[key: string]: any;
|
|
41
|
+
}
|
|
42
|
+
/** 组装 HookEnv + ctx.ui(组件实例级——id 绑定;共享态模块级) */
|
|
43
|
+
export declare function createV3Ui(compId: string, render: () => void, onUnmountCb: (fn: () => void) => void): V3Ui;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function ue(e){return e==null||typeof e=="boolean"?[]:Array.isArray(e)?e.flatMap(t=>ue(t)):[e]}function T(e){if(e.children!=null)return ue(e.children);let t=e.props?.children??[];return ue(t)}var A=Symbol("v3-fragment"),F=Symbol("v3-portal");function mt(e,t,...n){let o=n.length===1&&Array.isArray(n[0])?n[0]:n,l=t?{...t}:{};return n.length>0&&(l.children=o),{type:e,props:l,key:t?.key??null}}function yt(e,t){return{type:F,props:{children:Array.isArray(e)?e:[e],portalKey:t??"default"},key:t??null}}function Ne(e=2e4){let t=[],n=0,o=0,l=i=>t[(n+i)%e],s=(i,r)=>{t[(n+i)%e]=r};return{emit(i){o<e?(s(o,i),o++):(s(0,i),n=(n+1)%e)},events(){let i=new Array(o);for(let r=0;r<o;r++)i[r]=l(r);return i},inverse(i){switch(i.type){case"INSERT":return{type:"REMOVE",parent:i.parent,child:i.child,ts:Date.now()};case"REMOVE":return null;case"PROP_UPDATE":return{type:"PROP_UPDATE",target:i.target,key:i.key,value:i.prev,prev:i.value,ts:Date.now()};case"TEXT_UPDATE":return{type:"TEXT_UPDATE",target:i.target,value:i.prev,prev:i.value,ts:Date.now()};case"MOVE":return null;default:return null}},reset(){n=0,o=0}}}var E=Ne(),gt=0;function H(){return`n${++gt}`}function U(e){let t=document.getElementById("__wf_portal");t||(t=document.createElement("div"),t.id="__wf_portal",document.body.appendChild(t));let n=t.querySelector(`[data-wf-portal-key="${e}"]`);return n||(n=document.createElement("div"),n.setAttribute("data-wf-portal-key",e),t.appendChild(n)),n}var V=class{byId=new Map;idByNode=new WeakMap;removed=new Map;static PORTAL=t=>`portal:${t}`;resolveParent(t){return t.startsWith("portal:")?U(t.slice(7)):this.get(t)}get(t){return t.startsWith("portal:")?U(t.slice(7)):this.byId.get(t)??null}register(t,n){this.byId.set(t,n),this.idByNode.set(n,t)}idOf(t){return t?t.nodeType===1?t.getAttribute("data-v3-id")??this.idByNode.get(t)??"el":this.idByNode.get(t)??"node":"null"}unregister(t,n){this.byId.delete(t),this.removed.set(t,n)}takeRemoved(t){let n=this.removed.get(t);return n&&this.removed.delete(t),n??null}static ROOT="root"};function Te(e,t){let n=e.selfId(),o;return n&&(o=t.subscribe(()=>e.render([n])),e.onUnmount(()=>o?.())),t}function de(e,t){let n=e.selfId(),o=t.value!==void 0;if(o&&!t.onChange&&t.name&&(e.warned.has(t.name)||(e.warned.add(t.name),console.warn(`[weifuwu/${t.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08value \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
|
|
2
|
+
\u975E\u53D7\u63A7\uFF1A\u53BB\u6389 value\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onChange={(v) => setValue(v)}`))),!o&&n&&!e.uncontrolledValues.has(n)){e.uncontrolledValues.set(n,t.value);let s=e.onUnmount(i=>{i===n&&(e.uncontrolledValues.delete(n),s())})}let l=s=>{if(o){t.onChange?.(s);return}n&&e.uncontrolledValues.set(n,s),n?e.render([n]):e.render()};return{value:o?t.value:n?e.uncontrolledValues.get(n):t.value,setValue:l,controlled:o}}function Ve(e,t){let n=e.selfId(),o=de(e,{value:t.value,onChange:t.onChange,name:t.name});if(n&&!e.inputStates.has(n)){e.inputStates.set(n,{keyword:"",selectedLabel:""});let i=e.onUnmount(r=>{r===n&&(e.inputStates.delete(n),i())})}let l=n?e.inputStates.get(n):{keyword:"",selectedLabel:""},s=()=>{n?e.render([n]):e.render()};return{...o,get keyword(){return l.keyword},setKeyword(i){l.keyword=i,s()},get selectedLabel(){return l.selectedLabel},setSelectedLabel(i){l.selectedLabel=i,s()}}}function xe(e,t){let n=e.selfId(),o=!1;if(n){let u=e.onUnmount(d=>{d===n&&(o=!0,u())})}let l=()=>{o||(n?e.render([n]):e.render())},s={data:void 0,loading:!1,error:void 0},i=0,r=()=>{let u=++i;s.loading=!0,s.error=null,l(),Promise.resolve().then(()=>t()).then(d=>{i===u&&(s.data=d,s.loading=!1,l())}).catch(d=>{i===u&&(s.error=d,s.loading=!1,l())})};return r(),s.reload=r,s}function ke(e,t,n){return l=>{l?t(l):n?.()}}function J(e){return typeof window<"u"&&!!window.matchMedia?.("(hover: hover)").matches}function ce(e){return typeof window<"u"&&!!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches}function Ce(e,t,n){let o=null,l=()=>{t(),n?.once&&o&&o.removeEventListener("animationend",l)};return i=>{i?(o=i,i.addEventListener("animationend",l)):o&&(o.removeEventListener("animationend",l),o=null)}}function Pe(e,t){let{onLongPress:n,duration:o=500}=t,l,s=0,i=0,r=null,u=()=>{clearTimeout(l),l=void 0},d=e.selfId();if(d){let a=e.onUnmount(c=>{c===d&&(u(),a())})}return{onPointerDown:a=>{s=a.clientX??0,i=a.clientY??0,r=a,u(),l=setTimeout(()=>{l=void 0,r&&n(r)},o)},onPointerUp:u,onPointerLeave:u,onPointerMove:a=>{let c=Math.abs((a.clientX??0)-s),f=Math.abs((a.clientY??0)-i);(c>10||f>10)&&u()},onContextMenu:a=>{a.preventDefault(),n(a)}}}function Q(e,t){let n=e.selfId(),o="closed",l,s=()=>{o="closed",n?e.render([n]):e.render()};return{get phase(){return o},ref:r=>{r?l||(l=()=>{o==="exit"&&s()},r.addEventListener("animationend",l)):l=void 0},sync:r=>(r?o="open":o==="open"&&(o="exit"),o)}}function Re(e,t,n){let o=e.selfId(),l=ce(e),s=n?.duration??400,i=n?.ease==="linear"?f=>f:f=>1-Math.pow(1-f,3),r,u=t,d={value:l?t:0,reset:()=>{}},a=()=>{o?e.render([o]):e.render()},c=f=>{if(u=f,l){d.value=f,a();return}if(f===d.value)return;r&&cancelAnimationFrame(r);let g=d.value,m=performance.now(),y=h=>{let v=Math.min(1,(h-m)/s);d.value=Math.round(g+(f-g)*i(v)),v<1?(r=requestAnimationFrame(y),a()):(r=void 0,a())};r=requestAnimationFrame(y)};if(d.reset=f=>{f===u&&r||c(f)},o){let f=e.onUnmount(g=>{g===o&&(r&&(cancelAnimationFrame(r),r=void 0),f())})}return queueMicrotask(()=>c(t)),d}function I(){return{activeElement:()=>typeof document<"u"?document.activeElement:null,byId:e=>typeof document<"u"?document.getElementById(e):null,query:e=>typeof document<"u"?document.querySelector(e):null,queryAll:e=>typeof document<"u"?document.querySelectorAll(e):null,createElement:e=>typeof document<"u"?document.createElement(e):null,createElementNS:(e,t)=>typeof document<"u"?document.createElementNS(e,t):null,createDocumentFragment:()=>typeof document<"u"?document.createDocumentFragment():null,createComment:e=>typeof document<"u"?document.createComment(e):null,createTextNode:e=>typeof document<"u"?document.createTextNode(e):null,addEventListener:(e,t,n)=>{typeof window<"u"&&window.addEventListener(e,t,n)},removeEventListener:(e,t,n)=>{typeof window<"u"&&window.removeEventListener(e,t,n)},scrollTo:e=>{typeof window<"u"&&window.scrollTo(0,e)},matchMedia:e=>typeof window<"u"&&typeof window.matchMedia=="function"?window.matchMedia(e):null,visualViewport:()=>(typeof window<"u"?window:null)?.visualViewport??null,scrollingElement:()=>typeof document<"u"?document.scrollingElement:null,bodyElement:()=>typeof document<"u"?document.body:null,bodyAppend:e=>{typeof document<"u"&&document.body.appendChild(e)},bodyRemove:e=>{typeof document<"u"&&e.parentNode&&document.body.removeChild(e)},clearBody:()=>{typeof document<"u"&&(document.body.innerHTML="")},event:(e,t)=>{let n=typeof window<"u"?window:null,o=t&&(t.key||t.code)?"KeyboardEvent":t&&(t.clientX!==void 0||t.clientY!==void 0||t.pointerId!==void 0)?"PointerEvent":"Event";try{return new n[o](e,t)}catch{return new n.Event(e,t)}},dispatchEvent:(e,t)=>typeof e<"u"?e.dispatchEvent(t):!1,reload:()=>{typeof window<"u"&&window.location.reload()},navigate:e=>{typeof window>"u"||(window.history.pushState(null,"",e),window.dispatchEvent(new PopStateEvent("popstate",{state:null})))},downloadFile:(e,t,n="text/plain")=>{try{if(typeof document>"u"||typeof URL>"u"||!URL.createObjectURL)return!1;let o=new Blob([t],{type:n}),l=URL.createObjectURL(o),s=document.createElement("a");return s.href=l,s.download=e,document.body.appendChild(s),s.click(),document.body.removeChild(s),setTimeout(()=>URL.revokeObjectURL(l),1e3),!0}catch{return!1}},copyText:async e=>{let t=typeof window<"u"?window:null;if(t?.navigator?.clipboard?.writeText)try{return await t.navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return!1;let n=document.createElement("textarea");n.value=e,n.style.position="fixed",n.style.opacity="0",document.body.appendChild(n),n.select();let o=document.execCommand("copy");return document.body.removeChild(n),o}catch{return!1}},execCommand:(e,t)=>typeof document<"u"?document.execCommand(e,!1,t):!1,queryCommandState:e=>typeof document<"u"?document.queryCommandState(e):!1,queryCommandValue:e=>typeof document<"u"?document.queryCommandValue(e):"",selectionText:()=>typeof window<"u"?window.getSelection?.()?.toString()??null:null,getSelection:()=>typeof window<"u"?window.getSelection():null,viewportHeight:()=>typeof window<"u"?window.innerHeight:0,viewportWidth:()=>typeof window<"u"?window.innerWidth:0,pathname:()=>typeof window<"u"?window.location.pathname:"",createTreeWalker:(e,t)=>typeof document<"u"?document.createTreeWalker(e,t??NodeFilter.SHOW_ALL):null,scrollTop:()=>{let e=typeof document<"u"?document:null,t=typeof window<"u"?window:null;return e?.scrollingElement?.scrollTop??t?.scrollY??0},hash:()=>typeof window<"u"?window.location?.hash??"":"",setHash:e=>{typeof window<"u"&&(window.location.hash=e)},timeout:(e,t)=>typeof window<"u"?window.setTimeout(e,t):0,rootElement:()=>typeof document<"u"?document.documentElement:null,storageGet:e=>{try{return typeof window<"u"?window.localStorage?.getItem(e)??null:null}catch{return null}},storageSet:(e,t)=>{try{typeof window<"u"&&window.localStorage?.setItem(e,t)}catch{}}}}var Oe=I();function Se(e,t="bottom",n=6,o=!0){switch(t){case"bottom":return{top:e.bottom+n,left:o?e.left+e.width/2:e.left};case"top":return{top:e.top-n,left:o?e.left+e.width/2:e.left};case"left":return{top:o?e.top+e.height/2:e.top,left:e.left-n};case"right":return{top:o?e.top+e.height/2:e.top,left:e.right+n}}}function Me(e,t,n=8){if(!t)return e;let o=t.getBoundingClientRect();if(o.width===0&&o.height===0)return e;let l=Number.parseFloat(t.style.top)||o.top,s=Number.parseFloat(t.style.left)||o.left,i=e.top-l,r=e.left-s,u={top:o.top+i,bottom:o.bottom+i,left:o.left+r,right:o.right+r},d=Oe.viewportWidth(),a=Oe.viewportHeight(),c=e.top,f=e.left;return u.bottom>a-n&&(c=Math.max(n,c-(u.bottom-(a-n)))),u.top<n&&(c=Math.max(n,c+(n-u.top))),u.right>d-n&&(f=Math.max(n,f-(u.right-(d-n)))),u.left<n&&(f=Math.max(n,f+(n-u.left))),{top:c,left:f,width:e.width}}var vt=Symbol("Fragment"),De=Symbol("Portal");function Z(e,t,n=null){return{type:e,props:t,key:n,_child:null,_parentNode:null,_refNode:null,_id:null,_customId:null,_parentVNode:null,_ctxVersion:null,_lifecycle:"fresh"}}function Le(e,t,n=null){return e===vt?{...Z(e,t,n),type:e}:e===De?{...Z(e,t,n),type:e,_remoteEl:null,_placement:"remote"}:typeof e=="function"?{...Z(e,t,n),type:e,_render:null,_outputChild:null}:{...Z(e,t,n),type:e,el:null}}function fe(e,t,...n){let o=ht(t??{});return n.length>0&&(o.children=n.length===1?n[0]:n),Le(e,o,t?.key??null)}function ht(e){if(!e)return{};let t={};for(let n of Object.keys(e))n!=="key"&&(t[n]=e[n]);return t}function pe(e,t){let n=Le(De,{children:e,portalKey:t});return n.key=t??null,n}function me(e,t){let n=e.selfId(),o={top:0,left:0,refresh:()=>{}};if(!n)return o;let l={pos:o,getEl:t.el,isOpen:t.isOpen,compute:t.compute,panel:t.panel,margin:t.margin??8};e.popupTrackers.set(n,l),e.ensurePopupListeners();let s=e.onUnmount(i=>{i===n&&(e.popupTrackers.delete(n),s())});return o.refresh=()=>{let i=l.getEl();if(!i)return;let r=i.getBoundingClientRect();if(r.width===0&&r.height===0)return;let u=l.compute(r);Object.assign(o,Me(u,l.panel?.(),l.margin))},o}function _e(e,t){let n=e.selfId(),o=e.browser,l=J(e),s=()=>typeof t.trigger=="function"?t.trigger():t.trigger??"manual",i=t.open!==void 0,r=()=>!!t.disabled?.(),u=()=>i?typeof t.open=="function"?!!t.open():!!t.open:t.isOpen(),d=t.presence?Q(e,{name:t.name}):null,a,c=!1,f=p=>{if(!d)return p?"open":"closed";let w=d.sync(p);return p&&t.lockScroll&&!c&&(Et(),c=!0),w},g=p=>{r()||(i?t.onOpenChange?.(p):d?p?f(!0):u()&&f(!1):t.setOpen(p))},m=()=>{let p=t.placement;return typeof p=="function"?p():p??"bottom"},y=null,h=!1,v=me(e,{el:t.el??(()=>null),isOpen:()=>u(),compute:p=>{if(t.position){let w=t.position();return{top:w.y,left:w.x,width:w.width}}return Se(p,m(),t.gap??6,t.center!==!1)},panel:()=>y,margin:t.margin??8}),N=p=>{if(t.closeOnOutside===!1||t.mask||!u())return;let w=p.target;if(!(w instanceof Node))return;let S=t.el?.()??null;S&&S.contains(w)||y&&y.contains(w)||g(!1)},P=p=>{t.closeOnEscape!==!1&&(p.key!=="Escape"||!u()||g(!1))};if(o.addEventListener("mousedown",N),o.addEventListener("keydown",P),n){let p=e.onUnmount(w=>{w===n&&(o.removeEventListener("mousedown",N),o.removeEventListener("keydown",P),p())})}let k={},Ee=p=>typeof p=="function"?p():p??0,we=()=>Ee(t.openDelay),re=()=>Ee(t.closeDelay),R,C,st=()=>{clearTimeout(R),clearTimeout(C),R=void 0,C=void 0},it=p=>{if(r())return;let w=p.currentTarget,S=p.relatedTarget;w.contains(S)||(clearTimeout(C),C=void 0,R=setTimeout(()=>{R=void 0,g(!0)},we()))},lt=p=>{if(r())return;let w=p.currentTarget,S=p.relatedTarget;w.contains(S)||(clearTimeout(R),R=void 0,C=setTimeout(()=>{C=void 0,g(!1)},re()))},at=()=>{r()||(clearTimeout(C),C=void 0,R=setTimeout(()=>{R=void 0,g(!0)},we()))},ut=()=>{r()||(clearTimeout(R),R=void 0,C=setTimeout(()=>{C=void 0,g(!1)},re()))},B=()=>s()==="hover";if(k.onMouseOver=p=>{B()&&it(p)},k.onMouseOut=p=>{B()&<(p)},k.onClick=()=>{B()?l||g(!u()):s()==="click"&&g(!0)},k.onFocus=()=>{B()?at():s()==="focus"&&(clearTimeout(C),C=void 0,g(!0))},k.onBlur=()=>{B()?ut():s()==="focus"&&(clearTimeout(R),R=void 0,C=setTimeout(()=>{C=void 0,g(!1)},re()))},s()==="longpress"){let p,w=0,S=0,_=()=>{clearTimeout(p),p=void 0};k.onPointerDown=x=>{r()||(w=x.clientX??0,S=x.clientY??0,_(),p=setTimeout(()=>{p=void 0,t.onTrigger?.({clientX:w,clientY:S}),g(!0)},t.longPressDuration??500))},k.onPointerUp=_,k.onPointerLeave=_,k.onPointerMove=x=>{let le=Math.abs((x.clientX??0)-w),ae=Math.abs((x.clientY??0)-S);(le>10||ae>10)&&_()},k.onContextMenu=x=>{x.preventDefault(),t.onTrigger?.({clientX:x.clientX??0,clientY:x.clientY??0}),g(!0)}}if(k.onKeyDown=p=>{p.key==="Escape"&&t.closeOnEscape!==!1&&g(!1)},n){let p=e.onUnmount(w=>{w===n&&(st(),p())})}let dt=p=>{if(p){y=p;let w=()=>v.refresh();p.addEventListener("animationend",w,{once:!0})}else y=null},se=null,ie=null,be=p=>{dt(p),ie&&ie(p),d?.ref(p),t.trapFocus&&(p?a=Nt(p):(a?.(),a=void 0)),t.lockScroll&&!p&&c&&(wt(),c=!1)};return{get open(){return u()},setOpen:g,get phase(){return d?d.phase:u()?"open":"closed"},sync:f,wrapProps:k,portal:(p,w="popover")=>{if(r())return null;if(!(d?d.phase!=="closed":u()))return h=!1,se=null,null;let _=t.el?.()??null;(!h||_!==se)&&(_?v.refresh():queueMicrotask(()=>{u()&&v.refresh()}),h=!0,se=_);let x=p.props??{};ie=x.ref??null;let le=t.positioning==="none"?x.class??"":["wf-popup",x.class].filter(Boolean).join(" "),ae=t.positioning==="none"?{...x.style??{},position:"fixed"}:{...x.style??{},position:"fixed",top:`${v.top}px`,left:`${v.left}px`,...v.width!==void 0?{width:`${v.width}px`}:{},maxWidth:(()=>{let G=typeof t.width=="function"?t.width():t.width;return G!==void 0?`min(${G}px, calc(100vw - 32px))`:"calc(100vw - 32px)"})()},q={...p,props:{...x,class:le,style:ae,ref:be}};if(t.mask){let G=typeof t.mask=="object"?t.mask:fe("div",{class:"wf-popup-mask","data-portal-mask":w,onClick:t.maskClosable===!1?void 0:()=>g(!1)}),ct=t.maskCentered?fe("div",{class:"wf-cover",style:{"--wf-z":"var(--wf-z-popover)",pointerEvents:"none"}},{...q,props:{...q.props,style:{...x.style??{},pointerEvents:"auto"},ref:be}}):null,ft=t.maskCentered?void 0:{...q.props?.style??{},zIndex:"var(--wf-z-popover)"},pt=t.maskCentered?ct:{...q,props:{...q.props,style:ft}};return pe([G,pt],w)}return pe(q,w)},refresh:()=>v.refresh()}}function Ae(e,t){let n=e.selfId();if(n&&!e.openStates.has(n)){e.openStates.set(n,!1);let r=e.onUnmount(u=>{u===n&&(e.openStates.delete(n),r())})}let o=t.open!==void 0;o&&!t.onOpenChange&&t.name&&!e.warned.has(t.name)&&(e.warned.add(t.name),console.warn(`[weifuwu/${t.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08open \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onOpenChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
|
|
3
|
+
\u975E\u53D7\u63A7\uFF1A\u53BB\u6389 open\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onOpenChange={(o) => setOpen(o)}`));let l=()=>o?!!t.open:n?e.openStates.get(n)??!1:!1,s=()=>{n?e.render([n]):e.render()},i=r=>{if(o){t.onOpenChange?.(r);return}n&&e.openStates.set(n,r),s()};return{get open(){return l()},setOpen:i,triggerProps:{onClick:()=>i(!0),onFocus:()=>{t.openOnFocus&&i(!0)}}}}var W=I(),X=0,He="",Ue="",Ie="",We="",ee=0;function je(){return typeof window<"u"&&typeof document<"u"}function Et(){if(X++,X>1||!je())return;ee=W.scrollTop();let e=W.bodyElement();He=e.style.overflow,Ue=e.style.position,Ie=e.style.top,We=e.style.width,e.style.overflow="hidden",(/iPhone|iPad|iPod/.test(navigator.platform)||/Mac/.test(navigator.platform)&&"ontouchend"in document)&&(e.style.position="fixed",e.style.top=`-${ee}px`,e.style.width="100%")}function wt(){if(X===0||(X--,X>0)||!je())return;let e=W.bodyElement();e.style.overflow=He,e.style.position=Ue,e.style.top=Ie,e.style.width=We,ee>0&&W.scrollTo(ee)}var bt='a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';function Nt(e){let t;return queueMicrotask(()=>{let n=e.querySelectorAll(bt);if(n.length===0)return;let o=n[0],l=n[n.length-1],s=r=>{r.key==="Tab"&&(r.shiftKey&&W.activeElement()===o?(r.preventDefault(),l.focus()):!r.shiftKey&&W.activeElement()===l&&(r.preventDefault(),o.focus()))},i=W.activeElement();o.focus(),e.addEventListener("keydown",s),t=()=>{e.removeEventListener("keydown",s),i?.focus()}}),()=>t?.()}function qe(e,t,n){let o=e.selfId(),l=e.browser,s=`media:${o}:${t}`;if(!e.mediaRegistry.has(s)){let i=l.matchMedia(t);n(i.matches);let r=d=>n(d.matches);i.addEventListener("change",r),e.mediaRegistry.set(s,{mql:i,handler:r});let u=e.onUnmount(d=>{if(d!==o)return;let a=e.mediaRegistry.get(s);if(a?.mql&&a.handler)try{a.mql.removeEventListener("change",a.handler)}catch{}e.mediaRegistry.delete(s),u()})}}function Fe(e,t,n){let o=e.browser,l=typeof t=="function"?{mobile:"(max-width: 639px)",tablet:"(min-width: 640px) and (max-width: 1023px)",desktop:"(min-width: 1024px)"}:t,s=typeof t=="function"?t:n,i=e.selfId(),r=`bp:${i}`;function u(){for(let[d,a]of Object.entries(l))if(o.matchMedia(a).matches)return d;return Object.keys(l)[0]??""}if(!e.mediaRegistry.has(r)){s(u());let d=[];for(let c of Object.values(l)){let f=o.matchMedia(c),g=()=>s(u());f.addEventListener("change",g),d.push({mql:f,handler:g})}e.mediaRegistry.set(r,{mqls:d});let a=e.onUnmount(c=>{if(c!==i)return;let f=e.mediaRegistry.get(r);if(f?.mqls)for(let g of f.mqls)try{g.mql.removeEventListener("change",g.handler)}catch{}e.mediaRegistry.delete(r),a()})}}function $e(e){let t=e.selfId(),n=e.browser,o={height:n.viewportHeight(),offsetTop:0,keyboardOpen:!1},l=()=>{t?e.render([t]):e.render()},s=()=>{let r=n.visualViewport();o.height=r?.height??n.viewportHeight(),o.offsetTop=r?.offsetTop??0,o.keyboardOpen=o.height<n.viewportHeight()*.9,l()},i=n.visualViewport();if(i?.addEventListener?(i.addEventListener("resize",s),i.addEventListener("scroll",s)):n.addEventListener("resize",s),t){let r=e.onUnmount(u=>{u===t&&(i?.removeEventListener?(i.removeEventListener("resize",s),i.removeEventListener("scroll",s)):n.removeEventListener("resize",s),r())})}return o}function Be(e,t){let n=e.selfId(),o={isIn:!1,ready:!1,observe:u,refresh:d,disconnect:a},l=null,s=null,i=()=>{n?e.render([n]):e.render()};function r(){if(s?.disconnect(),s=null,!l)return;let c=typeof t.rootMargin=="function"?t.rootMargin():t.rootMargin,f=typeof t.threshold=="function"?t.threshold():t.threshold;s=new IntersectionObserver(g=>{let m=g[g.length-1];if(!m)return;let y=m.isIntersecting,h=y!==o.isIn,v=!o.ready;o.isIn=y,o.ready=!0,t.onChange?.(m,y),(h||v)&&i()},{root:t.root?t.root():null,rootMargin:c??"0px",threshold:f??0}),s.observe(l)}function u(c){l=c,c?r():(s?.disconnect(),s=null,o.isIn=!1)}function d(){r()}function a(){s?.disconnect(),s=null}if(n){let c=e.onUnmount(f=>{f===n&&(a(),c())})}return o}function Xe(e,t){let n=e.selfId(),o=e.browser,l={y:0,refresh(){let r=s.getScroller();l.y=r instanceof Window?o.scrollingElement()?.scrollTop??o.scrollTop():r.scrollTop??0}},s={handle:l,getScroller:t.getScroller??(()=>window)};if(!n)return l.refresh(),l;e.scrollTrackers.set(n,s),e.ensurePopupListeners(),l.refresh();let i=e.onUnmount(r=>{r===n&&(e.scrollTrackers.delete(n),i())});return l}function Ke(e,t){let n=e.selfId(),o=e.browser;if(typeof window>"u")return()=>{};if(o.addEventListener("keydown",t),n){let l=e.onUnmount(s=>{s===n&&(o.removeEventListener("keydown",t),l())})}return()=>o.removeEventListener("keydown",t)}function ze(e,t){let n=e.browser,o=0,l=0,s=!1,i=a=>{s&&t.onMove(a,{x:a.clientX-o,y:a.clientY-l})},r=a=>{s&&(s=!1,n.removeEventListener("pointermove",i),n.removeEventListener("pointerup",r),t.onEnd?.(a))},u=a=>{s||(a.preventDefault(),s=!0,o=a.clientX,l=a.clientY,n.addEventListener("pointermove",i),n.addEventListener("pointerup",r),t.onStart?.(a))},d=e.selfId();if(d){let a=e.onUnmount(c=>{c===d&&(s&&(n.removeEventListener("pointermove",i),n.removeEventListener("pointerup",r),s=!1),a())})}return{onPointerDown:u}}function Ye(e,t){let n={};t.onDrop&&(n.onDrop=l=>{l.preventDefault(),t.onDrop(l)}),t.onDragOver&&(n.onDragOver=l=>{l.preventDefault(),t.onDragOver(l)}),t.onDragLeave&&(n.onDragLeave=l=>t.onDragLeave(l));let o={draggable:!0};if(t.onDragStart){let l=t.onDragStart;o.onDragStart=s=>{typeof document<"u"&&document.body.classList.add("wf-dragging"),l(s)}}if(t.onDragEnd){let l=t.onDragEnd;o.onDragEnd=s=>{typeof document<"u"&&document.body.classList.remove("wf-dragging"),l(s)}}return{dropProps:n,dragProps:o}}function Tt(e){return e.map(t=>{let n={role:t.role,content:t.content};return t.reasoning&&(n.reasoning_content=t.reasoning),n})}function ye(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Ge(e,t,n,o){n.initialMessages?e.messages=structuredClone(n.initialMessages):e.messages===void 0&&(e.messages=[]),e.input===void 0&&(e.input=""),e.streaming===void 0&&(e.streaming=!1),e.error===void 0&&(e.error=null),e.usage===void 0&&(e.usage=null),e.step===void 0&&(e.step=null);let l=null;function s(){if(!e.streaming)return;let m=e.messages[e.messages.length-1];return m&&m.role==="assistant"&&m.status==="streaming"?m:void 0}function i(m,y,h){let v=s();switch(m){case"wf:token":v&&(v.content+=y.text);break;case"wf:tool_call":{v&&(v.toolCalls||(v.toolCalls=[]),v.toolCalls.push({call:y,status:"running"}));break}case"wf:tool_progress":{let N=y,P=v?.toolCalls?.find(k=>k.call.id===N.toolCallId);P&&(P.progress=N);break}case"wf:tool_result":{let N=y,P=v?.toolCalls?.find(k=>k.call.id===N.id);P&&(P.result=N,P.status=N.ok?"ok":"error");break}case"wf:approval_request":v&&(v.approval=y);break;case"wf:usage":v&&(v.usage=y);break;case"wf:step":e.step=y;break;case"wf:done":if(v){v.status="done",v.approval=void 0;let N=y;N.reasoning&&(v.reasoning=N.reasoning)}e.streaming=!1,e.step=null;break;case"wf:error":v&&(v.status="error",v.error=y,v.approval=void 0),e.error=y,e.streaming=!1,e.step=null;break;default:h?.(m,y);break}o?.()}function r(){let m=n.body?n.body(e.messages):{messages:Tt(e.messages)};l=t(n.url,m,{onToken:h=>i("wf:token",{text:h}),onToolCall:h=>i("wf:tool_call",h),onToolProgress:h=>i("wf:tool_progress",h),onToolResult:h=>i("wf:tool_result",h),onApproval:h=>i("wf:approval_request",h),onUsage:h=>i("wf:usage",h),onStep:h=>i("wf:step",h),onDone:h=>i("wf:done",h),onError:h=>i("wf:error",h),onEvent:(h,v)=>i(h,v,n.onEvent)},{signal:n.signal,headers:n.headers}),e.streaming=!0;let y=s();y&&l?.traceId&&(y.id=l.traceId)}function u(){if(e.streaming)return;let m=String(e.input??"").trim();m&&(e.input="",e.error=null,e.usage=null,e.step=null,e.messages.push({id:ye(),role:"user",content:m,status:"done"},{id:ye(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r(),o?.())}function d(){l?.abort(),e.streaming=!1,e.step=null;let m=e.messages[e.messages.length-1];m&&m.role==="assistant"&&m.status==="streaming"&&(!m.content&&(!m.toolCalls||m.toolCalls.length===0)?e.messages.pop():m.status="done"),o?.()}function a(){if(e.streaming)return;let m=-1;for(let y=e.messages.length-1;y>=0;y--)if(e.messages[y].role==="user"){m=y;break}m!==-1&&(e.messages.splice(m+1),e.error=null,e.usage=null,e.step=null,e.messages.push({id:ye(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r(),o?.())}function c(){l?.abort(),e.messages=[],e.input="",e.streaming=!1,e.error=null,e.usage=null,e.step=null,o?.()}async function f(m,y,h){let v=e.messages[e.messages.length-1],N=v?.role==="assistant"?v.approval:void 0;if(N&&(v.approval=void 0,o?.(),!!n.approveUrl))try{await fetch(n.approveUrl,{method:"POST",headers:{"Content-Type":"application/json",...n.headers},body:JSON.stringify(h?{id:N.id,decision:m,note:y,modifiedArgs:h}:{id:N.id,decision:m,note:y}),signal:n.signal})}catch(P){if(n.signal?.aborted)return;e.error={code:"provider_error",message:P instanceof Error?P.message:String(P)},o?.()}}function g(){l?.abort(),l=null}return{send:u,stop:d,retry:a,clear:c,approve:f,dispose:g}}function Je(e,t,n){let o=new AbortController,l=n?.signal;l&&(l.aborted?o.abort():l.addEventListener("abort",()=>o.abort(),{once:!0}));let s=n?.traceId??Pt(),i=n?.record!==!1,r=[],u=(async()=>{let d;try{d=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Trace-Id":s,Accept:"text/event-stream",...n?.headers},body:JSON.stringify(t),signal:o.signal})}catch(a){if(o.signal.aborted)return;n?.onError?.({code:"provider_error",message:a instanceof Error?a.message:String(a)});return}if(!d.ok){n?.onError?.({code:Ct(d.status),message:`HTTP ${d.status} ${d.statusText}`});return}try{for await(let{name:a,data:c}of xt(d.body)){if(o.signal.aborted)return;kt(r,{name:a,data:c},i),Vt(a,c,n??{})}}catch(a){if(o.signal.aborted)return;n?.onError?.({code:"provider_error",message:a instanceof Error?a.message:String(a)})}})();return{abort:()=>o.abort(),done:u,traceId:s,events:r}}function Vt(e,t,n){switch(e){case"wf:token":return n.onToken?.(t.text);case"wf:tool_call":return n.onToolCall?.(t);case"wf:tool_result":return n.onToolResult?.(t);case"wf:tool_progress":return n.onToolProgress?.(t);case"wf:step":return n.onStep?.(t);case"wf:approval_request":return n.onApproval?.(t);case"wf:usage":return n.onUsage?.(t);case"wf:done":return n.onDone?.(t);case"wf:error":return n.onError?.(t);default:return n.onEvent?.(e,t)}}async function*xt(e){let t=e.getReader(),n=new TextDecoder,o="";try{for(;;){let{done:l,value:s}=await t.read();if(l)break;o+=n.decode(s,{stream:!0});let i=o.split(`
|
|
4
|
+
|
|
5
|
+
`);o=i.pop()??"";for(let r of i){let u="message",d="";for(let a of r.split(`
|
|
6
|
+
`))a.startsWith("event: ")?u=a.slice(7):a.startsWith("data: ")&&(d+=a.slice(6));if(d)try{yield{name:u,data:JSON.parse(d)}}catch{}}}}finally{t.releaseLock()}}function kt(e,t,n){n&&(e.length>=1e3&&e.shift(),e.push(t))}function Ct(e){return e===401||e===403?"auth_failed":e===429?"rate_limited":e>=500?"provider_error":"invalid_request"}function Pt(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`trace-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Qe(e,t){let n={messages:[],input:"",streaming:!1,error:null,usage:null,step:null},o=new Set,s=Ge(n,Je,t,()=>{for(let r of[...o])r()});Object.assign(n,s),n.subscribe=r=>(o.add(r),()=>{o.delete(r)});let i=e.selfId();if(i){let r=e.onUnmount(u=>{u===i&&(s.dispose(),r())})}return n}var Rt=new Map,et=new Map,Ot=new Map,St=new Set,Mt=new Map,Dt=new Map,Lt=new Map,Ze=!1;function _t(){if(Ze)return;Ze=!0;let e=I(),t=()=>{for(let n of et.values())try{if(n.isOpen()){let l=n.getEl()?.getBoundingClientRect();l&&l.width>0&&n.compute(l)}}catch{}};e.addEventListener?.("scroll",t,{capture:!0,passive:!0}),e.addEventListener?.("resize",t)}function ge(e,t,n){let o={selfId:()=>e,render:s=>{!s||s.length===0||s.includes(e)?t():console.warn(`[vdom3/ui] render([${s.join(",")}]) \u8DE8\u7EC4\u4EF6\u6E32\u67D3\u6682\u672A\u5B9E\u73B0\uFF08vdom3 \u5F53\u524D\u4EC5\u7EC4\u4EF6\u81EA\u8EAB render\uFF09`)},browser:I(),onUnmount:s=>(n(()=>s(e)),()=>{}),registry:{idRegistry:new Map},mediaRegistry:Rt,popupTrackers:et,scrollTrackers:Ot,isMounting:()=>!1,warned:St,uncontrolledValues:Mt,inputStates:Dt,openStates:Lt,ensurePopupListeners:_t};return{render:s=>o.render(s),onUnmount:s=>{n(s)},selfId:s=>{o.registry.idRegistry.set(s,e)},useExternal:s=>Te(o,s),useControlled:s=>de(o,s),useControlledInput:s=>Ve(o,s),useOpen:s=>Ae(o,s),usePopup:s=>_e(o,s),usePopupPosition:s=>me(o,s),useTween:(s,i)=>Re(o,s,i),useInView:s=>Be(o,s),useScrollPosition:s=>Xe(o,s),useGlobalKey:s=>Ke(o,s),useDrag:s=>ze(o,s),useDragDrop:s=>Ye(o,s),useMedia:(s,i)=>{qe(o,s,i)},useBreakpoint:(s,i)=>{Fe(o,s,i)},useReducedMotion:()=>ce(o),useStableRef:(s,i)=>ke(o,s,i),useAnimationEnd:(s,i)=>Ce(o,s,i),usePresence:s=>Q(o,s),useLongPress:s=>Pe(o,s),useHoverCapable:()=>J(o),useVisualViewport:()=>$e(o),useAsync:s=>xe(o,s),useChat:s=>Qe(o,s)}}var te=new Map;function tt(e){let t=te.get(e);if(t){try{t()}catch{}te.delete(e)}}function D(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)&&"type"in e}async function O(e,t,n){if(typeof e.type=="function"){let r={...e},u=n!=null&&typeof n=="object"&&n.type===e.type&&n.key===e.key&&n._render?n:null;if(u)r._render=u._render,r._id=u._id;else{r._id=H(),E.emit({type:"COMP_MOUNT",id:r._id,name:At(r.type),ts:Date.now()});let c=r._id,f=Object.assign(Object.create(t),{onUnmount:g=>{te.set(c,g)},ui:ge(c,()=>{t.render?.()},g=>{te.set(c,g)})});r._render=await r.type(r.props,f)}let d=await r._render(r.props);r._child=null;let a=u?._child??null;if(d){let c=await O(d,t,a!=null&&typeof a=="object"?a:null);r._child=c}return r}let o={...e},l=T(n??{}),s=0,i=null;for(let r of T(e)){if(D(r)){let u=l[s],d=await O(r,t,u!=null&&typeof u=="object"?u:null);d!==r&&(i??=[...T(e)],i[s]=d)}s++}return i&&(o.children=i),o}function At(e){return typeof e=="function"?e.name||"anonymous":String(e)}var Ht=globalThis.__WF_V3_AUDIT!=="0";function nt(e,t){if(!Ht)return;let n=T(t).filter(s=>s!=null&&typeof s=="object"&&s.el!=null);if(n.length<2)return;let o=n[0].el?.parentNode;if(!o)return;let l=-1;for(let s of n){let i=s.el;if(i.parentNode!==o)return;let r=[...o.childNodes].indexOf(i);if(r<0)return;if(r<l){console.warn(`[vdom3/audit] children \u987A\u5E8F\u9519\u4F4D\uFF08vnode \u987A\u5E8F \u2260 DOM \u987A\u5E8F\u2014\u2014\u7D22\u5F15 ${r} < ${l}\uFF09`);return}l=r}}function z(e){if(e==null||typeof e!="object")return!1;let t=e.type;return t===F||typeof t=="symbol"&&e.props?.portalKey!=null}function Ut(e){if(e==null||typeof e!="object")return!1;let t=e.type;return(t===A||typeof t=="symbol")&&e.props?.portalKey==null}var b=new V;function $(e,t){b.register(V.ROOT,t),j(e,t)}function j(e,t,n){if(typeof e.type=="function"){let i=e._child??T(e)[0]??null;if(i==null)return null;if(e.el==null||!e.el.isConnected){let r=j(i,t,n);return e.el=r,r}return e.el}if(Ut(e)){let i=null;for(let r of T(e)){let u=ve(r,t,n);u&&!i&&(i=u)}return i}if(z(e)){let r=String(e.props?.portalKey??"default"),u=U(r);b.register(V.PORTAL(r),u);let d=null;for(let a of T(e)){let c=ve(a,u);c&&!d&&(d=c)}return e.el=u,d??u}let o=document.createElement(e.type),l=H();o.setAttribute("data-v3-id",l),b.register(l,o),e.el=o,E.emit({type:"NODE_CREATE",id:l,tag:e.type,ts:Date.now()});for(let[i,r]of Object.entries(e.props??{}))if(!(i==="key"||i==="children"||i==="ref")){if(typeof r=="function"&&/^on[A-Z]/.test(i)){let u=o.__v3evtKeys??=new Set;u.has(i)||(o.addEventListener(i.slice(2).toLowerCase(),d=>r(d)),u.add(i));continue}r!=null&&r!==!1&&(i==="value"&&o instanceof HTMLInputElement?o.value=String(r):o.setAttribute(i,String(r)),E.emit({type:"PROP_UPDATE",target:l,key:i,value:r,prev:"",ts:Date.now()}))}n&&n.parentNode===t?t.insertBefore(o,n):t.appendChild(o),E.emit({type:"INSERT",parent:K(t),child:l,ref:n?M(n):null,ts:Date.now()});let s=e.props?.ref;typeof s=="function"&&s(o);for(let i of T(e))ve(i,o);return o}function ve(e,t,n){if(e==null||e===!1||e===!0)return null;if(typeof e=="string"||typeof e=="number"){let o=document.createTextNode(String(e)),l=H();return b.register(l,o),E.emit({type:"TEXT_CREATE",id:l,value:String(e),ts:Date.now()}),n&&n.parentNode===t?t.insertBefore(o,n):t.appendChild(o),E.emit({type:"INSERT",parent:K(t),child:l,ref:n?M(n):null,ts:Date.now()}),o}return j(e,t,n)}function L(e,t,n,o){if(typeof t=="string"||typeof t=="number"){let r=String(t),u=e&&typeof e=="object"?e.el:n.childNodes[0]??null;if(u&&u.nodeType===3)return u.nodeValue!==r&&(E.emit({type:"TEXT_UPDATE",target:M(u),value:r,prev:u.nodeValue??"",ts:Date.now()}),u.nodeValue=r),u;let d=document.createTextNode(r),a=H();return b.register(a,d),E.emit({type:"TEXT_CREATE",id:a,value:r,ts:Date.now()}),o&&o.parentNode===n?n.insertBefore(d,o):n.appendChild(d),E.emit({type:"INSERT",parent:K(n),child:a,ref:o?M(o):null,ts:Date.now()}),d}if(t==null||t===!1||t===!0){if(e!=null&&e.el&&e.el.parentNode===n){let r=b.idOf(e.el);E.emit({type:"REMOVE",parent:K(n),child:r,ts:Date.now()}),e.el.parentNode?.removeChild(e.el),b.unregister(r,e.el)}return null}let l=t,s=e!=null&&typeof e=="object"&&"type"in e;if(s&&e.type===l.type&&e.key===l.key){let r=e;if(z(l)){let d=String(l.props?.portalKey??"default"),a=U(d);return b.register(V.PORTAL(d),a),ot(r,l,a),l.el=a,a}if(typeof l.type=="function"){l._render=r._render,l._id=r._id;let d=l._child??T(l)[0]??null,a=r._child??T(r)[0]??null;return d==null?(r.el&&(r.el.parentNode?.removeChild(r.el),r.el=null),l.el=null,null):(r.el==null||!r.el.isConnected?l.el=j(l,n,o):(L(a,d,n,o),l.el=r.el),l.el)}let u=r.el;return l.el=u,It(u,r.props,l.props),ot(r,l,u),u}if(s&&typeof e.type=="function"&&e._id&&(tt(e._id),E.emit({type:"COMP_UNMOUNT",id:e._id,name:qt(e.type),ts:Date.now()})),s){let r=e.el;if(r&&r.parentNode===n){let u=e.props?.ref;typeof u=="function"&&u(null);let d=b.idOf(r);E.emit({type:"REMOVE",parent:K(n),child:d,ts:Date.now()}),r.parentNode?.removeChild(r),b.unregister(d,r)}else e&&z(e)&&he(e)}return j(l,n,o)}function It(e,t,n){let o=M(e),l=new Set([...Object.keys(t??{}),...Object.keys(n??{})]),s=t?.ref,i=n?.ref;s!==i&&(typeof s=="function"&&s(null),typeof i=="function"&&i(e));for(let r of l){if(r==="key"||r==="children"||r==="ref")continue;let u=t?.[r],d=n?.[r];if(u!==d){if(typeof d=="function"&&/^on[A-Z]/.test(r)){let a=e.__v3evtKeys??=new Set;a.has(r)||(e.addEventListener(r.slice(2).toLowerCase(),c=>d(c)),a.add(r));continue}d==null||d===!1?r==="value"&&e instanceof HTMLInputElement?e.value="":e.removeAttribute(r):r==="value"&&e instanceof HTMLInputElement?e.value=String(d):e.setAttribute(r,String(d)),E.emit({type:"PROP_UPDATE",target:o,key:r,value:d,prev:u??"",ts:Date.now()})}}}function Wt(e,t,n){let o=new Map;e.forEach((s,i)=>{D(s)&&s.key!=null&&o.set(s.key,i)});let l=null;for(let s=0;s<t.length;s++){let i=t[s];if(!D(i)||i.key==null){l=null;continue}let r=o.get(i.key),u=null;if(r!=null&&D(e[r])&&(u=e[r].el??null),u&&u.parentNode===n){let d=l?l.nextSibling:n.firstChild;if(d!==u){let a=u.previousSibling?b.idOf(u.previousSibling):null;n.insertBefore(u,d),E.emit({type:"MOVE",node:b.idOf(u),parent:M(n),ref:d?b.idOf(d):null,prev:a,ts:Date.now()})}l=u}}}function jt(e,t,n){let o=new Map;for(let i of e)D(i)&&i.key!=null&&o.set(i.key,i);Wt(e,t,n);let l=null;for(let i of t){let r=i,u=o.get(r.key??"")??null;u&&u!==r?(L(u,r,n),l=r.el??l):u||(j(r,n,l?l.nextSibling:n.firstChild),l=r.el??l)}let s=new Set(t.filter(i=>D(i)).map(i=>i.key));for(let i of e)if(D(i)&&i.key!=null&&!s.has(i.key)&&i.el?.parentNode===n){let r=b.idOf(i.el);E.emit({type:"REMOVE",parent:M(n),child:r,ts:Date.now()}),i.el.parentNode?.removeChild(i.el),b.unregister(r,i.el)}}function he(e){let t=String(e.props?.portalKey??"default"),n=U(t);for(let o of[...n.childNodes]){let l=b.idOf(o);E.emit({type:"REMOVE",parent:V.PORTAL(t),child:l,ts:Date.now()}),n.removeChild(o),b.unregister(l,o)}}function ot(e,t,n){let o=T(e),l=T(t);if(l.length>1&&l.every(r=>D(r)&&r.key!=null)){jt(o,l,n);return}let s=null,i=Math.max(o.length,l.length);for(let r=0;r<i;r++){let u=r<o.length?o[r]:null,d=r<l.length?l[r]:null;if(r>=l.length){if(u!=null&&typeof u=="object"&&z(u)){he(u);continue}if(u!=null&&typeof u=="object"&&u.el){let a=u.props?.ref;typeof a=="function"&&a(null);let c=u.el,f=b.idOf(c);E.emit({type:"REMOVE",parent:M(n),child:f,ts:Date.now()}),c.parentNode?.removeChild(c),b.unregister(f,c)}else{let a=n.childNodes[r];a&&a.parentNode?.removeChild(a)}continue}if(typeof d=="string"||typeof d=="number"){let a=String(d),c=n.childNodes[r];if(c&&c.nodeType===3)c.nodeValue!==a&&(E.emit({type:"TEXT_UPDATE",target:M(c),value:a,prev:c.nodeValue??"",ts:Date.now()}),c.nodeValue=a);else{let f=document.createTextNode(a),g=H();b.register(g,f),E.emit({type:"TEXT_CREATE",id:g,value:a,ts:Date.now()}),n.insertBefore(f,n.childNodes[r]??null),E.emit({type:"INSERT",parent:M(n),child:g,ref:null,ts:Date.now()})}continue}if(d==null||d===!1||d===!0){if(u!=null&&typeof u=="object"&&z(u)){he(u);continue}if(u!=null&&typeof u=="object"&&u.el){let a=u.props?.ref;typeof a=="function"&&a(null);let c=u.el,f=b.idOf(c);E.emit({type:"REMOVE",parent:M(n),child:f,ts:Date.now()}),c.parentNode?.removeChild(c),b.unregister(f,c)}continue}if(u!=null&&typeof u=="object"){L(u,d,n);let a=d.el;a&&a.parentNode===n&&(s=a)}else{let a=s?s.nextSibling:n.firstChild,c=j(d,n,a);c&&c.parentNode===n&&(s=c)}}nt(n,t)}function qt(e){return typeof e=="function"?e.name||"anonymous":String(e)}function M(e){return b.idOf(e)}function K(e){return b.idOf(e)}var ne=class{queue=[];running=!1;iterations=0;schedule(t){this.queue.push(t),this.running||(this.running=!0,this.iterations=0,queueMicrotask(()=>this.flush()))}flush(){if(!(!this.running&&this.queue.length===0)){this.running=!0;do{if(++this.iterations>10){console.error("[vdom3/scheduler] \u6E32\u67D3\u5FAA\u73AF\u8D85\u9650\uFF08\u7591\u4F3C\u6B7B\u5FAA\u73AF\uFF09\u2014\u2014\u4E2D\u6B62\u672C\u8F6E flush"),this.queue=[];break}let t=this.queue;this.queue=[];for(let n of t)try{n()}catch(o){console.error("[vdom3/scheduler] render error:",o)}}while(this.queue.length>0);this.running=!1,this.iterations=0}}pending(){return this.queue.length}get isRunning(){return this.running}},Y=new ne;function Ft(e,t,n){let o=e,l=!1,s=!1;async function i(){if(l){s=!0;return}l=!0;try{do{s=!1;let c=await O(e,r,o);o==null?$(c,t):L(o,c,t),o=c}while(s)}finally{l=!1}}let r={_vnode:e,_parent:t,...n?.ctx??{},render(){Y.schedule(()=>{i()})}},u,d=new Promise(c=>{u=c}),a={ctx:r,ready:d,rerender:()=>Y.schedule(()=>{i()}),flush:()=>Y.flush(),unmount(){o._id&&E.emit({type:"COMP_UNMOUNT",id:o._id,name:"root",ts:Date.now()}),t.innerHTML=""}};return(async()=>{try{let c=await O(e,r);$(c,t),o=c}finally{u()}})(),a}function oe(e,t,n){switch(e.type){case"NODE_CREATE":{let o=document.createElement(e.tag);o.setAttribute("data-v3-id",e.id),n.register(e.id,o);break}case"TEXT_CREATE":{let o=document.createTextNode(e.value);n.register(e.id,o);break}case"INSERT":{let o=e.parent===V.ROOT?t:n.resolveParent(e.parent),l=n.get(e.child),s=e.ref?n.get(e.ref):null;o&&l&&(s&&s.parentNode===o?o.insertBefore(l,s):o.appendChild(l));break}case"REMOVE":{let o=n.get(e.child);o?.parentNode&&o.parentNode.removeChild(o);break}case"MOVE":{let o=n.get(e.node),l=e.parent===V.ROOT?t:n.resolveParent(e.parent),s=e.ref?n.get(e.ref):null;o&&l&&o.parentNode===l&&(s&&s.parentNode===l?l.insertBefore(o,s):l.appendChild(o));break}case"PROP_UPDATE":{let o=n.get(e.target);o?.nodeType===1&&(e.value==null||e.value===!1?o.removeAttribute(e.key):o.setAttribute(e.key,String(e.value)));break}case"TEXT_UPDATE":{let o=n.get(e.target);o?.nodeType===3&&(o.nodeValue=e.value);break}default:break}}function $t(e,t,n=new V){n.register(V.ROOT,t),t.innerHTML="";for(let o of e)oe(o,t,n)}function Bt(e,t,n=new V){let l=e.filter(s=>s.type==="INSERT"||s.type==="REMOVE"||s.type==="PROP_UPDATE"||s.type==="TEXT_UPDATE"||s.type==="MOVE").slice(-t);for(let s of[...l].reverse())switch(s.type){case"INSERT":{let i=n.get(s.child);i?.parentNode&&i.parentNode.removeChild(i);break}case"REMOVE":{let i=n.takeRemoved(s.child),r=s.parent===V.ROOT?null:n.get(s.parent);i&&r&&r.appendChild(i);break}case"PROP_UPDATE":{let i=n.get(s.target);i?.nodeType===1&&(s.prev==null||s.prev===""?i.removeAttribute(s.key):i.setAttribute(s.key,String(s.prev)));break}case"TEXT_UPDATE":{let i=n.get(s.target);i?.nodeType===3&&(i.nodeValue=s.prev);break}case"MOVE":{let i=n.get(s.node),r=s.parent===V.ROOT?null:n.get(s.parent);if(i&&r&&i.parentNode===r)if(s.prev){let u=n.get(s.prev);u&&u.parentNode===r&&r.insertBefore(i,u.nextSibling)}else r.insertBefore(i,r.firstChild);break}default:break}}function Xt(e,t){return e.filter(n=>n.type===t)}function Kt(e,t){return e.some(t)}function zt(e,t){let n=e.map(l=>l.type);if(!t.map((l,s)=>n[s]===l).every(Boolean))throw new Error(`\u4E8B\u4EF6\u5E8F\u5217\u4E0D\u7B26\uFF1A\u671F\u671B [${t.join(",")}] \u5B9E\u9645 [${n.slice(0,t.length).join(",")}]`)}function Yt(e){let t=[],n=String(e).replace(/:(\w+)/g,(o,l)=>(t.push(l),"([^/]+)")).replace(/\*/g,".*");return{re:new RegExp(`^${n}$`),keys:t}}function Gt(e,t){for(let n of e){let{re:o,keys:l}=Yt(n.path),s=t.match(o);if(!s)continue;let i={};for(let r=0;r<l.length;r++)i[l[r]]=decodeURIComponent(s[r+1]);return{def:n,params:i}}return null}function Jt(e,t,n){let o=null,l=null,s=!1,i=null,r={},u=()=>Object.assign(Object.create(n?.ctx??{}),{render:()=>{d()}});async function d(){if(s){i={type:"refresh"};return}if(!(!o||!l)){s=!0;try{let m=l;if(typeof m.type=="function"&&m._render){let y=await m._render(m.props);if(y==null)return;let h=m._child??null,v=await O(y,r,h&&typeof h=="object"?h:null);m._child=v,L(h,v,t)}}finally{if(s=!1,i!=null){let m=i;i=null,a(m)}}}}function a(m){m.type==="nav"?c(m.path):d()}async function c(m){if(s){i={type:"nav",path:m};return}s=!0;try{let y=Gt(e,m);if(E.emit({type:"ROUTE_CHANGE",path:m,params:y?.params??{},ts:Date.now()}),!y){t.innerHTML="",o=null,l=null;return}r=u();let h=y.def.render(y.params),v=y.def.layout?y.def.layout(h):h,N=await O(v,r,o);o==null?$(N,t):L(o,N,t),o=N,l=N}finally{if(s=!1,i!=null){let y=i;i=null,a(y)}}}let f=()=>{c(window.location.pathname)};window.addEventListener("popstate",f);let g=n?.initialPath??window.location.pathname;return c(g),{navigate(m){window.history.pushState(null,"",m),c(m)},path:()=>window.location.pathname,refresh:()=>{c(window.location.pathname)},close:()=>{window.removeEventListener("popstate",f)}}}async function Qt(e){let t=await O(e,{}),n=[],o=0,l=()=>`s${++o}`,s=Date.now(),i=(r,u)=>{if(typeof r.type=="function"){let a=r._child??T(r)[0]??null;a&&typeof a=="object"&&!Array.isArray(a)&&i(a,u);return}if(r.type===A){for(let a of T(r))a&&typeof a=="object"&&!Array.isArray(a)&&i(a,u);return}let d=l();n.push({type:"NODE_CREATE",id:d,tag:r.type,ts:s});for(let[a,c]of Object.entries(r.props??{}))a==="key"||a==="children"||typeof c!="function"&&c!=null&&c!==!1&&n.push({type:"PROP_UPDATE",target:d,key:a,value:c,prev:"",ts:s});n.push({type:"INSERT",parent:u,child:d,ref:null,ts:s});for(let a of T(r))if(typeof a=="string"||typeof a=="number"){let c=l();n.push({type:"TEXT_CREATE",id:c,value:String(a),ts:s}),n.push({type:"INSERT",parent:d,child:c,ref:null,ts:s})}else a&&typeof a=="object"&&!Array.isArray(a)&&i(a,d)};return i(t,"root"),n}async function*Zt(e){let t=await O(e,{}),n=0,o=()=>`s${++n}`,l=Date.now(),s=function*(i,r){if(typeof i.type=="function"){let d=i._child??T(i)[0]??null;d&&typeof d=="object"&&!Array.isArray(d)&&(yield*s(d,r));return}if(i.type===A){for(let d of i.children??[])d&&typeof d=="object"&&!Array.isArray(d)&&(yield*s(d,r));return}let u=o();yield{type:"NODE_CREATE",id:u,tag:i.type,ts:l};for(let[d,a]of Object.entries(i.props??{}))d==="key"||d==="children"||typeof a!="function"&&a!=null&&a!==!1&&(yield{type:"PROP_UPDATE",target:u,key:d,value:a,prev:"",ts:l});yield{type:"INSERT",parent:r,child:u,ref:null,ts:l};for(let d of T(i))if(typeof d=="string"||typeof d=="number"){let a=o();yield{type:"TEXT_CREATE",id:a,value:String(d),ts:l},yield{type:"INSERT",parent:u,child:a,ref:null,ts:l}}else d&&typeof d=="object"&&!Array.isArray(d)&&(yield*s(d,u))};yield*s(t,"root")}function en(e){let t=new Map,n=new Map,o=new Map;for(let r of e)if(r.type==="NODE_CREATE")t.set(r.id,r.tag);else if(r.type==="PROP_UPDATE"){let u=n.get(r.target)??new Map;r.value==null||r.value===!1?u.delete(r.key):u.set(r.key,r.value),n.set(r.target,u)}else r.type==="TEXT_CREATE"&&o.set(r.id,r.value);let l=new Map;for(let r of e)if(r.type==="INSERT"){let u=l.get(r.parent)??[];u.push(r.child),l.set(r.parent,u)}let s=r=>r.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""),i=r=>{let u=t.get(r);if(u){let d=n.get(r),a=d?[...d.entries()].filter(([f,g])=>typeof g!="function"&&f!=="data-v3-id"&&f!=="key"&&f!=="ref").map(([f,g])=>` ${f}="${s(String(g))}"`).join(""):"",c=(l.get(r)??[]).map(i).join("");return`<${u}${a}>${c}</${u}>`}return s(o.get(r)??"")};return(l.get("root")??[]).map(i).join("")}function tn(e){return JSON.stringify(e)}function nn(e){return JSON.parse(e)}function on(e,t="recorded-render"){let n=[...new Set(e.map(a=>a.type))],o=new Map(e.filter(a=>a.type==="NODE_CREATE").map(a=>[a.id,a.tag])),l=new Map;for(let a of e)if(a.type==="INSERT"){let c=l.get(a.parent)??[];c.push(a.child),l.set(a.parent,c)}let s=new Set,i=a=>{s.add(a);for(let c of l.get(a)??[])i(c)};for(let a of e)a.type==="REMOVE"&&i(a.child);let r=new Map;for(let[a,c]of o)s.has(a)||r.set(c,(r.get(c)??0)+1);let u=[...r.entries()].map(([a,c])=>` assert.equal(root.querySelectorAll('${a}').length, ${c}, '${a} \xD7 ${c}\uFF08\u4E8B\u4EF6\u6D41\u63A8\u5BFC\uFF09')`).join(`
|
|
7
|
+
`),d=JSON.stringify(e);return`/**
|
|
8
|
+
* \u81EA\u52A8\u751F\u6210\u6D4B\u8BD5\uFF08vdom3 recordToTest\uFF09\u2014\u2014\u4E8B\u4EF6\u6D41\u5F55\u5236\u8F6C\u56DE\u5F52
|
|
9
|
+
* \u6E32\u67D3\u8FC7\u7A0B\uFF1A${n.join(" \u2192 ")}
|
|
10
|
+
*/
|
|
11
|
+
import { test, before } from 'node:test'
|
|
12
|
+
import assert from 'node:assert'
|
|
13
|
+
import { setupJsdom } from './client/setup.ts'
|
|
14
|
+
import { replay, eventsOf } from '../ui-dom/vdom3/index.ts'
|
|
15
|
+
|
|
16
|
+
before(setupJsdom)
|
|
17
|
+
|
|
18
|
+
test('${t}\uFF1A\u4E8B\u4EF6\u6D41\u56DE\u653E\uFF08DOM = fold\uFF09+ \u6E32\u67D3\u5E8F\u5217\u65AD\u8A00', () => {
|
|
19
|
+
const events = ${d}
|
|
20
|
+
|
|
21
|
+
// \u56DE\u653E\uFF1A\u4E8B\u4EF6\u6D41 \u2192 DOM\uFF08\u96F6\u731C\u6D4B\u91CD\u5EFA\uFF09
|
|
22
|
+
const root = document.createElement('div')
|
|
23
|
+
document.body.appendChild(root)
|
|
24
|
+
replay(events, root)
|
|
25
|
+
assert.ok(root.childNodes.length > 0, '\u56DE\u653E\u6E32\u67D3\u975E\u7A7A')
|
|
26
|
+
|
|
27
|
+
// \u5185\u5BB9\u65AD\u8A00\uFF1Atag \u8BA1\u6570\u4E0E\u5F55\u5236\u4E00\u81F4\uFF08DOM = fold \u76F4\u63A5\u9A8C\u8BC1\uFF09
|
|
28
|
+
${u}
|
|
29
|
+
|
|
30
|
+
// \u6E32\u67D3\u7C7B\u578B\u65AD\u8A00\uFF1A\u6E32\u67D3\u8FC7\u7A0B\u5305\u542B\u7684\u5173\u952E\u4E8B\u4EF6\uFF08\u7CBE\u786E\u63CF\u8FF0\u6E32\u67D3\u505A\u4E86\u4EC0\u4E48\uFF09
|
|
31
|
+
const keyTypes = ['NODE_CREATE', 'PROP_UPDATE', 'INSERT']
|
|
32
|
+
for (const t of keyTypes) {
|
|
33
|
+
assert.ok(eventsOf(events, t).length > 0, '\u5305\u542B ' + t + ' \u4E8B\u4EF6')
|
|
34
|
+
}
|
|
35
|
+
assert.ok(eventsOf(events, 'TEXT_CREATE').length > 0, '\u5305\u542B\u6587\u672C\u521B\u5EFA\u4E8B\u4EF6\uFF08\u6709\u6587\u672C\u5185\u5BB9\uFF09')
|
|
36
|
+
|
|
37
|
+
document.body.removeChild(root)
|
|
38
|
+
})
|
|
39
|
+
`}function rn(e){let t={};for(let n of e)t[n.type]=(t[n.type]??0)+1;return Object.entries(t).map(([n,o])=>`${n}\xD7${o}`).join(" ")}function rt(e,t){let n=new V;n.register(V.ROOT,e),e.innerHTML="";let o=0,l=[];return{sync(){let s=t(),i=s.slice(o);l=i;for(let r of i)oe(r,e,n);return o=s.length,i.length},applied(){return o},lastBatch(){return[...l]}}}function sn(e,t,n){let o=rt(e,t);return o.sync(),n(()=>{o.sync()})}function ln(e){return async(t,n)=>{let o={...n,ui:{render:()=>n.render?.()}};return e(t,o)}}function an(e){return async(t,n)=>{let o={...n,render:()=>n.ui?.render?.()};return e(t,o)}}export{A as Fragment,V as NodeRegistry,F as Portal,ne as Scheduler,oe as applyEvent,sn as autoSync,O as buildVNode,ln as compat,Ne as createEventStream,yt as createPortal,Ft as createRoot,Jt as createRouter,rt as createSync,ge as createV3Ui,nn as deserializeEvents,U as ensurePortalContainer,Xt as eventsOf,en as eventsToHtml,zt as expectEventSequence,mt as h,Kt as hasEvent,D as isVNode,$ as mount,H as nextNodeId,L as patch,on as recordToTest,Zt as renderToEventStream,Qt as renderToEvents,$t as replay,Y as scheduler,tn as serializeEvents,E as stream,rn as summarizeEvents,an as toV2,Bt as undo};
|
package/docs/frontend.md
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# 前端 API 核心(weifuwu/ui-dom)
|
|
2
2
|
|
|
3
|
+
> ⚠️ **引擎演进(2026-08)**:下一代引擎 **vdom3**(vnode + stream——渲染执行 = 事件流,
|
|
4
|
+
> 可回放/可逆/可断言)已进入转正阶段——入口 `weifuwu/ui-dom/vdom3`(createRouter +
|
|
5
|
+
> createRoot + 事件流)。vdom2(本文档)为当前生产引擎(冻结中——bug 修复在 vdom3)。
|
|
6
|
+
> 迁移路线图见仓库 `design/vdom3-migration-plan.md`。
|
|
7
|
+
|
|
3
8
|
> ⚠️ **`weifuwu/client` 已并入 `weifuwu/ui-dom`**(`src/client/` 已删除)——本页 import 均用 `weifuwu/ui-dom`。前端运行时唯一入口是 **`weifuwu/ui-dom`**(UIRouter 纯路由 + uiServe 渲染运行时 + SSR/hydration),权威参考见 **[docs/frontend-ui-dom.md](frontend-ui-dom.md)**。
|
|
4
9
|
|
|
5
10
|
> 以下为完整 API 参考,按需查阅。新手建议先阅读 README 的「核心概念」和「快速开始」。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weifuwu",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.83.0",
|
|
5
5
|
"description": "AI SaaS framework — (req, ctx) => Response",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -27,7 +27,11 @@
|
|
|
27
27
|
"default": "./dist/components/index.js"
|
|
28
28
|
},
|
|
29
29
|
"./components/style.css": "./dist/components/style.css",
|
|
30
|
-
"./dev": "./dist/dev/index.js"
|
|
30
|
+
"./dev": "./dist/dev/index.js",
|
|
31
|
+
"./ui-dom/vdom3": {
|
|
32
|
+
"types": "./dist/ui-dom/vdom3/index.d.ts",
|
|
33
|
+
"default": "./dist/ui-dom/vdom3.js"
|
|
34
|
+
}
|
|
31
35
|
},
|
|
32
36
|
"files": [
|
|
33
37
|
"dist/",
|