weifuwu 0.71.0 → 0.72.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.
Files changed (164) hide show
  1. package/README.md +58 -47
  2. package/dist/components/Accordion/Accordion.d.ts +1 -1
  3. package/dist/components/Affix/Affix.d.ts +1 -1
  4. package/dist/components/AiChat/AiChat.d.ts +2 -2
  5. package/dist/components/Alert/Alert.d.ts +1 -1
  6. package/dist/components/AlertGroup/AlertGroup.d.ts +1 -1
  7. package/dist/components/Anchor/Anchor.d.ts +1 -1
  8. package/dist/components/ApprovalCard/ApprovalCard.d.ts +1 -1
  9. package/dist/components/AspectRatio/AspectRatio.d.ts +1 -1
  10. package/dist/components/AutoComplete/AutoComplete.d.ts +1 -1
  11. package/dist/components/Avatar/Avatar.d.ts +1 -1
  12. package/dist/components/AvatarGroup/AvatarGroup.d.ts +1 -1
  13. package/dist/components/BackTop/BackTop.d.ts +1 -1
  14. package/dist/components/Badge/Badge.d.ts +1 -1
  15. package/dist/components/Breadcrumb/Breadcrumb.d.ts +1 -1
  16. package/dist/components/Button/Button.d.ts +1 -1
  17. package/dist/components/Calendar/Calendar.d.ts +1 -1
  18. package/dist/components/Card/Card.d.ts +1 -1
  19. package/dist/components/Carousel/Carousel.d.ts +1 -1
  20. package/dist/components/Cascader/Cascader.d.ts +1 -1
  21. package/dist/components/Chart/Chart.d.ts +1 -1
  22. package/dist/components/Checkbox/Checkbox.d.ts +1 -1
  23. package/dist/components/CheckboxGroup/CheckboxGroup.d.ts +1 -1
  24. package/dist/components/CodeBlock/CodeBlock.d.ts +1 -1
  25. package/dist/components/Collapse/Collapse.d.ts +1 -1
  26. package/dist/components/ColorPicker/ColorPicker.d.ts +1 -1
  27. package/dist/components/Command/Command.d.ts +1 -1
  28. package/dist/components/Confirm/Confirm.d.ts +2 -2
  29. package/dist/components/ContextMenu/ContextMenu.d.ts +1 -1
  30. package/dist/components/CopyButton/CopyButton.d.ts +1 -1
  31. package/dist/components/DatePicker/DatePicker.d.ts +1 -1
  32. package/dist/components/Descriptions/Descriptions.d.ts +1 -1
  33. package/dist/components/DiffView/DiffView.d.ts +1 -1
  34. package/dist/components/Divider/Divider.d.ts +1 -1
  35. package/dist/components/Drawer/Drawer.d.ts +1 -1
  36. package/dist/components/Dropdown/Dropdown.d.ts +1 -1
  37. package/dist/components/Editor/Editor.d.ts +1 -1
  38. package/dist/components/Editor/tools/toolbar.d.ts +1 -1
  39. package/dist/components/EmptyState/EmptyState.d.ts +1 -1
  40. package/dist/components/Field/Field.d.ts +1 -1
  41. package/dist/components/FileUpload/FileUpload.d.ts +1 -1
  42. package/dist/components/FloatButton/FloatButton.d.ts +1 -1
  43. package/dist/components/Form/Form.d.ts +1 -1
  44. package/dist/components/Grid/Grid.d.ts +1 -1
  45. package/dist/components/Highlight/Highlight.d.ts +1 -1
  46. package/dist/components/HoverCard/HoverCard.d.ts +2 -2
  47. package/dist/components/Icon/Icon.d.ts +1 -1
  48. package/dist/components/Img/Img.d.ts +1 -1
  49. package/dist/components/InView/InView.d.ts +1 -1
  50. package/dist/components/InfiniteScroll/InfiniteScroll.d.ts +1 -1
  51. package/dist/components/Input/Input.d.ts +1 -1
  52. package/dist/components/InputNumber/InputNumber.d.ts +1 -1
  53. package/dist/components/JSONViewer/JSONViewer.d.ts +1 -1
  54. package/dist/components/Kanban/Kanban.d.ts +1 -1
  55. package/dist/components/Label/Label.d.ts +1 -1
  56. package/dist/components/Layout/Layout.d.ts +1 -1
  57. package/dist/components/Link/Link.d.ts +1 -1
  58. package/dist/components/List/List.d.ts +1 -1
  59. package/dist/components/Loading/Loading.d.ts +1 -1
  60. package/dist/components/LogViewer/LogViewer.d.ts +1 -1
  61. package/dist/components/Markdown/Markdown.d.ts +1 -1
  62. package/dist/components/Mentions/Mentions.d.ts +1 -1
  63. package/dist/components/Menu/Menu.d.ts +1 -1
  64. package/dist/components/Menubar/Menubar.d.ts +1 -1
  65. package/dist/components/MessageBubble/MessageBubble.d.ts +1 -1
  66. package/dist/components/Modal/Modal.d.ts +1 -1
  67. package/dist/components/NavMenu/NavMenu.d.ts +1 -1
  68. package/dist/components/Notification/Notification.d.ts +2 -2
  69. package/dist/components/PageHeader/PageHeader.d.ts +1 -1
  70. package/dist/components/Pagination/Pagination.d.ts +1 -1
  71. package/dist/components/PasswordInput/PasswordInput.d.ts +1 -1
  72. package/dist/components/PinInput/PinInput.d.ts +1 -1
  73. package/dist/components/Pipeline/Pipeline.d.ts +1 -1
  74. package/dist/components/Popconfirm/Popconfirm.d.ts +2 -2
  75. package/dist/components/Popover/Popover.d.ts +2 -2
  76. package/dist/components/ProgressBar/ProgressBar.d.ts +1 -1
  77. package/dist/components/QRCode/QRCode.d.ts +1 -1
  78. package/dist/components/RadioGroup/RadioGroup.d.ts +1 -1
  79. package/dist/components/Rate/Rate.d.ts +1 -1
  80. package/dist/components/Resizable/Resizable.d.ts +1 -1
  81. package/dist/components/Result/Result.d.ts +1 -1
  82. package/dist/components/Scrollbar/Scrollbar.d.ts +1 -1
  83. package/dist/components/SearchInput/SearchInput.d.ts +1 -1
  84. package/dist/components/SegmentedControl/SegmentedControl.d.ts +1 -1
  85. package/dist/components/Select/Select.d.ts +1 -1
  86. package/dist/components/Skeleton/Skeleton.d.ts +1 -1
  87. package/dist/components/Slider/Slider.d.ts +1 -1
  88. package/dist/components/Space/Space.d.ts +1 -1
  89. package/dist/components/Sparkline/Sparkline.d.ts +1 -1
  90. package/dist/components/StatCard/StatCard.d.ts +1 -1
  91. package/dist/components/Steps/Steps.d.ts +1 -1
  92. package/dist/components/Switch/Switch.d.ts +1 -1
  93. package/dist/components/Table/Table.d.ts +1 -1
  94. package/dist/components/Tabs/Tabs.d.ts +1 -1
  95. package/dist/components/Tag/Tag.d.ts +1 -1
  96. package/dist/components/TagsInput/TagsInput.d.ts +1 -1
  97. package/dist/components/Textarea/Textarea.d.ts +1 -1
  98. package/dist/components/ThemeSwitch/ThemeSwitch.d.ts +1 -1
  99. package/dist/components/Timeline/Timeline.d.ts +1 -1
  100. package/dist/components/Toast/Toast.d.ts +2 -2
  101. package/dist/components/ToggleGroup/ToggleGroup.d.ts +1 -1
  102. package/dist/components/ToolCallCard/ToolCallCard.d.ts +1 -1
  103. package/dist/components/Tooltip/Tooltip.d.ts +2 -2
  104. package/dist/components/Tour/Tour.d.ts +1 -1
  105. package/dist/components/Transfer/Transfer.d.ts +1 -1
  106. package/dist/components/Tree/Tree.d.ts +1 -1
  107. package/dist/components/TreeSelect/TreeSelect.d.ts +1 -1
  108. package/dist/components/Typography/Typography.d.ts +1 -1
  109. package/dist/components/VirtualList/VirtualList.d.ts +1 -1
  110. package/dist/components/VirtualTable/VirtualTable.d.ts +1 -1
  111. package/dist/components/Watermark/Watermark.d.ts +1 -1
  112. package/dist/components/index.js +12 -12
  113. package/dist/dev/index.js +1 -1
  114. package/dist/index.js +4 -4
  115. package/dist/ui/index.d.ts +1 -1
  116. package/dist/ui/ssr-page.d.ts +1 -1
  117. package/dist/ui/ssr.d.ts +1 -1
  118. package/dist/ui-dom/Confirm.d.ts +44 -0
  119. package/dist/ui-dom/Notification.d.ts +70 -0
  120. package/dist/ui-dom/Toast.d.ts +43 -0
  121. package/dist/ui-dom/index.d.ts +33 -0
  122. package/dist/ui-dom/index.js +18 -0
  123. package/dist/ui-dom/jsx-runtime.d.ts +4 -0
  124. package/dist/ui-dom/jsx-runtime.js +1 -0
  125. package/dist/ui-dom/popup-tracker.d.ts +36 -0
  126. package/dist/ui-dom/registry.d.ts +39 -0
  127. package/dist/{client → ui-dom}/render.d.ts +2 -1
  128. package/dist/ui-dom/router.d.ts +66 -0
  129. package/dist/ui-dom/serve.d.ts +28 -0
  130. package/dist/ui-dom/ssr.d.ts +56 -0
  131. package/dist/{client → ui-dom}/types.d.ts +22 -0
  132. package/dist/{client → ui-dom}/ui.d.ts +2 -0
  133. package/dist/{client → ui-dom}/vnode.d.ts +13 -12
  134. package/docs/custom-components.md +2 -0
  135. package/docs/frontend-middleware.md +3 -1
  136. package/docs/frontend-ui-dom.md +110 -0
  137. package/docs/frontend.md +3 -1
  138. package/docs/realtime.md +2 -0
  139. package/docs/saas.md +2 -0
  140. package/package.json +7 -7
  141. package/dist/client/app.d.ts +0 -26
  142. package/dist/client/error-boundary.d.ts +0 -23
  143. package/dist/client/index.d.ts +0 -54
  144. package/dist/client/index.js +0 -6
  145. package/dist/client/registry.d.ts +0 -49
  146. package/dist/client/router.d.ts +0 -27
  147. package/dist/client/type-flow.test.d.ts +0 -7
  148. /package/dist/{client → ui-dom}/ai.d.ts +0 -0
  149. /package/dist/{client → ui-dom}/browser.d.ts +0 -0
  150. /package/dist/{client → ui-dom}/diff.d.ts +0 -0
  151. /package/dist/{client → ui-dom}/focus-trap.d.ts +0 -0
  152. /package/dist/{client → ui-dom}/hydration.d.ts +0 -0
  153. /package/dist/{client → ui-dom}/i18n.d.ts +0 -0
  154. /package/dist/{client → ui-dom}/locale/en_US.d.ts +0 -0
  155. /package/dist/{client → ui-dom}/locale/zh_CN.d.ts +0 -0
  156. /package/dist/{client → ui-dom}/middleware/api.d.ts +0 -0
  157. /package/dist/{client → ui-dom}/middleware/auth.d.ts +0 -0
  158. /package/dist/{client → ui-dom}/middleware/ws.d.ts +0 -0
  159. /package/dist/{client → ui-dom}/motion.d.ts +0 -0
  160. /package/dist/{client → ui-dom}/popup.d.ts +0 -0
  161. /package/dist/{client → ui-dom}/reactive.d.ts +0 -0
  162. /package/dist/{client → ui-dom}/route-match.d.ts +0 -0
  163. /package/dist/{client → ui-dom}/scroll-lock.d.ts +0 -0
  164. /package/dist/{client → ui-dom}/use-chat.d.ts +0 -0
package/dist/dev/index.js CHANGED
@@ -11,7 +11,7 @@ registerHooks({
11
11
  const result = transformSync(code, {
12
12
  loader: url.endsWith(".tsx") ? "tsx" : "ts",
13
13
  jsx: "automatic",
14
- jsxImportSource: "weifuwu/client",
14
+ jsxImportSource: "weifuwu/ui-dom",
15
15
  format: "esm",
16
16
  sourcemap: "inline",
17
17
  target: "node22"
package/dist/index.js CHANGED
@@ -4236,7 +4236,7 @@ var HtmlSafe = class {
4236
4236
  }
4237
4237
  };
4238
4238
 
4239
- // src/client/vnode.ts
4239
+ // src/ui-dom/vnode.ts
4240
4240
  var ASYNC_MARK = "__wfAsyncComponent";
4241
4241
  function isAsyncComponent(type) {
4242
4242
  return typeof type === "function" && type?.[ASYNC_MARK] === true;
@@ -4244,7 +4244,7 @@ function isAsyncComponent(type) {
4244
4244
  var Fragment = /* @__PURE__ */ Symbol("Fragment");
4245
4245
  var Portal = /* @__PURE__ */ Symbol("Portal");
4246
4246
 
4247
- // src/client/reactive.ts
4247
+ // src/ui-dom/reactive.ts
4248
4248
  function createReactiveState(dirty) {
4249
4249
  const proxyCache = /* @__PURE__ */ new WeakMap();
4250
4250
  const watchers = /* @__PURE__ */ new Set();
@@ -4690,7 +4690,7 @@ function ui() {
4690
4690
  format: "esm",
4691
4691
  platform: "browser",
4692
4692
  jsx: "automatic",
4693
- jsxImportSource: "weifuwu/client",
4693
+ jsxImportSource: "weifuwu/ui-dom",
4694
4694
  write: false,
4695
4695
  metafile: true
4696
4696
  });
@@ -4745,7 +4745,7 @@ function ui() {
4745
4745
  };
4746
4746
  }
4747
4747
 
4748
- // src/client/route-match.ts
4748
+ // src/ui-dom/route-match.ts
4749
4749
  function joinPaths(a, b) {
4750
4750
  if (!b || b === "/") return a || "/";
4751
4751
  const left = a.endsWith("/") ? a.slice(0, -1) : a;
@@ -26,7 +26,7 @@
26
26
  * ```
27
27
  */
28
28
  import type { Middleware } from '../types.ts';
29
- import type { Component, AsyncComponent } from '../client/vnode.ts';
29
+ import type { Component, AsyncComponent } from '../ui-dom/vnode.ts';
30
30
  declare module '../types.ts' {
31
31
  interface Context {
32
32
  ui: {
@@ -8,7 +8,7 @@
8
8
  * 与客户端 router() 共用同一份路由定义(route-match.ts),SPA/SSR 一个声明。
9
9
  */
10
10
  import type { Middleware } from '../types.ts';
11
- import type { RouteDef } from '../client/types.ts';
11
+ import type { RouteDef } from '../ui-dom/types.ts';
12
12
  export interface UiSsrOptions {
13
13
  /** 前端路由定义(与 router() 共享同一份) */
14
14
  routes: RouteDef[];
package/dist/ui/ssr.d.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  *
12
12
  * 产物为 HtmlSafe 标记的安全 HTML 片段,可直接内联进 ctx.ui.html 模板。
13
13
  */
14
- import type { Component, AsyncComponent } from '../client/vnode.ts';
14
+ import type { Component, AsyncComponent } from '../ui-dom/vnode.ts';
15
15
  import { HtmlSafe } from './html-safe.ts';
16
16
  export { HtmlSafe } from './html-safe.ts';
17
17
  export interface SsrOptions {
@@ -0,0 +1,44 @@
1
+ /**
2
+ * weifuwu/components — Confirm 确认对话框
3
+ *
4
+ * 声明式:基于 Modal 封装,footer 自带「取消 / 确定」按钮。
5
+ * 命令式:confirm() 中间件注入 ctx.confirm(),返回 Promise<boolean>。
6
+ */
7
+ import type { Component } from './vnode.ts';
8
+ import type { AppMiddleware } from './types.ts';
9
+ export interface ConfirmProps {
10
+ open?: boolean;
11
+ title?: string;
12
+ /** 提示内容(文本或任意 VNode) */
13
+ message?: any;
14
+ confirmText?: string;
15
+ cancelText?: string;
16
+ variant?: 'primary' | 'danger';
17
+ /** 对话框宽度,如 '500px'、'80%',默认 Modal 的 400px */
18
+ width?: string;
19
+ /** 遮罩点击是否取消(默认 false:危险操作防误触;显式传 true 可恢复) */
20
+ maskClosable?: boolean;
21
+ onConfirm?: () => void;
22
+ onCancel?: () => void;
23
+ }
24
+ /** 命令式 ctx.confirm 的选项(ConfirmProps 的子集) */
25
+ export interface ConfirmOptions {
26
+ title?: string;
27
+ confirmText?: string;
28
+ cancelText?: string;
29
+ variant?: 'primary' | 'danger';
30
+ width?: string;
31
+ maskClosable?: boolean;
32
+ }
33
+ /** 命令式 ctx.confirm 的注入类型(AppMiddleware<{}, ConfirmInjected>) */
34
+ export interface ConfirmInjected {
35
+ confirm: (message: string, options?: ConfirmOptions) => Promise<boolean>;
36
+ }
37
+ /**
38
+ * 命令式中间件:注入 ctx.confirm()
39
+ *
40
+ * 每次调用挂载 Confirm 组件到独立容器(mountVNode),
41
+ * resolve 后 callRefCleanup 清理(含 Modal 的 portal DOM)+ 移除容器。
42
+ */
43
+ export declare function confirm(): AppMiddleware<{}, ConfirmInjected>;
44
+ export declare const Confirm: Component<ConfirmProps>;
@@ -0,0 +1,70 @@
1
+ import type { Component } from './vnode.ts';
2
+ import type { AppMiddleware } from './types.ts';
3
+ export type NotificationType = 'success' | 'error' | 'info' | 'warning';
4
+ export type NotificationPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
5
+ export interface NotificationItem {
6
+ id: string;
7
+ type: NotificationType;
8
+ title: string;
9
+ description?: string;
10
+ /** 自动关闭时间(ms),0 = 不自动关闭,默认 4500 */
11
+ duration?: number;
12
+ action?: {
13
+ label: string;
14
+ onClick: () => void;
15
+ };
16
+ }
17
+ export interface NotificationProps {
18
+ items?: NotificationItem[];
19
+ onRemove?: (id: string) => void;
20
+ position?: NotificationPosition;
21
+ /** 全局默认自动关闭时间(ms),默认 4500 */
22
+ duration?: number;
23
+ /** 最大显示条数,超出移除最早,默认 0 = 不限制 */
24
+ max?: number;
25
+ }
26
+ export interface NotificationOptions {
27
+ position?: NotificationPosition;
28
+ duration?: number;
29
+ max?: number;
30
+ }
31
+ /** 通知(对应 antd/EP Notification 队列式):title + description + icon + 操作,聚合角落 */
32
+ export declare const Notification: Component<NotificationProps>;
33
+ export interface NotificationInjected {
34
+ notification: {
35
+ (title: string, opts?: {
36
+ type?: NotificationType;
37
+ description?: string;
38
+ duration?: number;
39
+ action?: NotificationItem['action'];
40
+ }): void;
41
+ open: (opts: {
42
+ type?: NotificationType;
43
+ title: string;
44
+ description?: string;
45
+ duration?: number;
46
+ action?: NotificationItem['action'];
47
+ }) => void;
48
+ success: (opts: {
49
+ title: string;
50
+ description?: string;
51
+ duration?: number;
52
+ }) => void;
53
+ error: (opts: {
54
+ title: string;
55
+ description?: string;
56
+ duration?: number;
57
+ }) => void;
58
+ info: (opts: {
59
+ title: string;
60
+ description?: string;
61
+ duration?: number;
62
+ }) => void;
63
+ warning: (opts: {
64
+ title: string;
65
+ description?: string;
66
+ duration?: number;
67
+ }) => void;
68
+ };
69
+ }
70
+ export declare function notification(opts?: NotificationOptions): AppMiddleware<{}, NotificationInjected>;
@@ -0,0 +1,43 @@
1
+ import type { Component } from './vnode.ts';
2
+ import type { AppMiddleware } from './types.ts';
3
+ export type ToastType = 'success' | 'error' | 'info' | 'warning';
4
+ export type ToastPosition = 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left' | 'top-center';
5
+ export interface ToastItem {
6
+ id: string;
7
+ type: ToastType;
8
+ message: string;
9
+ /** 此条目的自动消失时间(ms),覆盖 Toast 的默认 duration */
10
+ duration?: number;
11
+ /** 操作按钮(如"撤销"):点击不自动关闭,由回调自行移除 */
12
+ action?: {
13
+ label: string;
14
+ onClick: () => void;
15
+ };
16
+ }
17
+ export interface ToastProps {
18
+ toasts?: ToastItem[];
19
+ onRemove?: (id: string) => void;
20
+ /** 容器位置,默认 top-right */
21
+ position?: ToastPosition;
22
+ /** 全局默认自动消失时间(ms),0 = 不自动消失,默认 0 */
23
+ duration?: number;
24
+ /** 最大显示条数,超出时移除最早条目,默认 0 = 不限制 */
25
+ max?: number;
26
+ }
27
+ /** 命令式 ctx.toast 的全局配置 */
28
+ export interface ToastOptions {
29
+ position?: ToastPosition;
30
+ /** 默认自动消失时间(ms),0 = 不消失,默认 3000 */
31
+ duration?: number;
32
+ /** 最大显示条数,超出移除最早,默认 3 */
33
+ max?: number;
34
+ }
35
+ export declare const Toast: Component<ToastProps>;
36
+ /** 命令式 ctx.toast 的注入类型(AppMiddleware<{}, ToastInjected>) */
37
+ export interface ToastInjected {
38
+ toast: (message: string, type?: ToastType, duration?: number, action?: {
39
+ label: string;
40
+ onClick: () => void;
41
+ }) => void;
42
+ }
43
+ export declare function toast(opts?: ToastOptions): AppMiddleware<{}, ToastInjected>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * weifuwu/ui-dom — 前端路由(UIRouter 纯路由 + uiServe 渲染运行时)
3
+ *
4
+ * 定稿架构(design/ui-architecture.md + ui-dom-client-align.md):
5
+ * req = window.location,res = VNode,uiServe = VDOM(落地)
6
+ * handler = 异步组件:async (location, ctx) => vnode($ 有效)
7
+ * middleware = 两阶段 async(layout 与 SSR 都是中间件)
8
+ *
9
+ * 渲染运行时复制自 client(registry/createUi/render/diff/popup-tracker 局部实例),
10
+ * VNode 契约共享(components 直接复用)。
11
+ */
12
+ export { UIRouter } from './router.ts';
13
+ export type { UIRouterOptions, RouteMatch } from './router.ts';
14
+ export { uiServe } from './serve.ts';
15
+ export type { UIServeOptions, UIServeHandle } from './serve.ts';
16
+ export { h, jsx, jsxs, jsxDEV, Fragment, Portal, createPortal } from './vnode.ts';
17
+ export type { VNode, VNodeChild, VNodeType, Component } from './vnode.ts';
18
+ export { createReactiveState } from './reactive.ts';
19
+ export { createClientBrowser } from './browser.ts';
20
+ export { mountVNode } from './render.ts';
21
+ export { callRefCleanup } from './render.ts';
22
+ export { animateOut } from './motion.ts';
23
+ export { patchValue } from './diff.ts';
24
+ export { hydrateVNode } from './hydration.ts';
25
+ export { isAsyncComponent, asyncComponent } from './vnode.ts';
26
+ export { api } from './middleware/api.ts';
27
+ export type { ApiClient, ApiOptions, ApiRequestOptions, ApiInjected } from './middleware/api.ts';
28
+ export { auth } from './middleware/auth.ts';
29
+ export type { AuthClient, AuthInjected } from './middleware/auth.ts';
30
+ export { ws } from './middleware/ws.ts';
31
+ export type { WsClient, WsInjected } from './middleware/ws.ts';
32
+ export { ssrPage, serializeData, ssrToString } from './ssr.ts';
33
+ export type { UIRequest, UIResponse, UIHandler, UIMiddleware, UIRouteDef, WfuiContext, } from './types.ts';
@@ -0,0 +1,18 @@
1
+ function wn(e){let n=[],t=(e||"/").replace(/:(\w+)/g,(o,i)=>(n.push(i),"([^/]+)")).replace(/\*/g,".*");return{re:new RegExp(`^${t}$`),keys:n}}var Ce=class{_routes=[];_middlewares=[];_injections=[];_injected=!1;_mode;_notFound;constructor(n={}){this._mode=n.mode??"history"}get mode(){return this._mode}use(n,t){if(typeof n=="string"&&t){let o=this,i=n,u=async(r,d,a)=>{let l=d.__routePath??o.getPath(),f=null;return l===i?f="/":(i==="/"?l!=="/"&&l.startsWith("/"):l.startsWith(i+"/"))&&(f=l.slice(i.length)),f===null?a:async(g,w)=>t._handle(f,g,w)};return this._middlewares.push(u),this}return n.length<=1?(this._injections.push(n),this):(this._middlewares.push(n),this)}async _ensureInjected(n){if(!this._injected){this._injected=!0;for(let t of this._injections){let o=await t(n);o&&o!==n&&Object.assign(n,o)}}}get(n,t,o){return this._routes.push({path:n,handler:t,title:o?.title}),this}notFound(n){return this._notFound=n,this}getPath(){return this._getPath(void 0)}_getPath(n){let t=n?.location??(typeof window<"u"?window.location:null);return this._mode==="hash"?(t?.hash??"").replace(/^#/,"")||"/":t?.pathname??"/"}match(n){let t=null;for(let o of this._routes){let{re:i,keys:u}=wn(o.path),r=n.match(i);if(!r)continue;let d={};for(let a=0;a<u.length;a++)d[u[a]]=decodeURIComponent(r[a+1]);t={handler:o.handler,params:d,title:o.title};break}return t||(t={handler:this._notFound??(()=>null),params:{}}),t}async _handle(n,t,o){await this._ensureInjected(o);let i=this.match(n);i.title&&typeof document<"u"&&(document.title=i.title),o.params=i.params;let r=i.handler,d=o.__routePath;o.__routePath=n;try{for(let a=this._middlewares.length-1;a>=0;a--){let l=this._middlewares[a],f=r;r=await l(t,o,f)??f}return await r(t,o)}finally{o.__routePath=d}}async execute(n,t,o){await this._ensureInjected(t);let i=this.match(o);i.title&&typeof document<"u"&&(document.title=i.title),t.params=i.params;let r=i.handler;for(let d=this._middlewares.length-1;d>=0;d--){let a=this._middlewares[d],l=r;r=await a(n,t,l)??l}return await r(n,t)}};function ee(){return{idCounter:0,idRegistry:new Map,unmountHooks:[],asyncFactoryCache:new WeakMap}}function O(e){return e?.__registry??ee()}function ae(e){return`_wf_${e.idCounter++}`}function ue(e,n){return e.unmountHooks.push(n),()=>{let t=e.unmountHooks.indexOf(n);t>=0&&e.unmountHooks.splice(t,1)}}function Te(e,n,t){let o=e.asyncFactoryCache.get(n);if(o)return o;let i={promise:null};return i.promise=Promise.resolve().then(()=>n(t)).then(u=>{if(typeof u!="function")throw new Error(`asyncComponent factory <${n.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`);return i.resolved=u,u}),e.asyncFactoryCache.set(n,i),i}async function We(e,n,t){return Te(e,n,t).promise}function De(e,n){return e.asyncFactoryCache.get(n)?.resolved}function xe(e,n,t,o){try{e(n)}catch(i){console.error(`[weifuwu] ref ${t} error in <${o??"anonymous"}>`,i)}}function bn(e,n){let t=e._child;if(t!=null)if(Array.isArray(t))for(let o of t)o&&typeof o=="object"&&U(o,n);else typeof t=="object"&&U(t,n)}function U(e,n){if(e==null||typeof e!="object")return;let t=e;if(t._id){if(t._customId&&n.idRegistry.delete(t._customId),n.idRegistry.delete(t._id),n.unmountHooks.length>0){let o=[...n.unmountHooks];for(let i of o)i(t._id);if(t._customId)for(let i of o)i(t._customId)}t._id=void 0,t._customId=void 0,t._render=void 0,t._parentNode=void 0,t._refNode=void 0}if(t._child!=null){if(Array.isArray(t._child))for(let o of t._child)o&&typeof o=="object"&&U(o,n);else U(t._child,n);t._child=void 0}if(t.props?.children&&typeof t.type=="string"){let o=Array.isArray(t.props.children)?t.props.children:[t.props.children];for(let i of o)i&&typeof i=="object"&&U(i,n)}typeof t.props?.ref=="function"&&xe(t.props.ref,null,"cleanup"),t._remoteEl&&(bn(t,n),t._remoteEl.remove(),t._remoteEl=void 0)}function je(e,n="bottom",t=6,o=!0){switch(n){case"bottom":return{top:e.bottom+t,left:o?e.left+e.width/2:e.left};case"top":return{top:e.top-t,left:o?e.left+e.width/2:e.left};case"left":return{top:o?e.top+e.height/2:e.top,left:e.left-t};case"right":return{top:o?e.top+e.height/2:e.top,left:e.right+t}}}function de(e,n,t=8){if(!n)return e;let o=n.getBoundingClientRect();if(o.width===0&&o.height===0)return e;let i=Number.parseFloat(n.style.top)||o.top,u=Number.parseFloat(n.style.left)||o.left,r=e.top-i,d=e.left-u,a={top:o.top+r,bottom:o.bottom+r,left:o.left+d,right:o.right+d},l=window.innerWidth,f=window.innerHeight,g=e.top,w=e.left;return a.bottom>f-t&&(g=Math.max(t,g-(a.bottom-(f-t)))),a.top<t&&(g=Math.max(t,g+(t-a.top))),a.right>l-t&&(w=Math.max(t,w-(a.right-(l-t)))),a.left<t&&(w=Math.max(t,w+(t-a.left))),{top:g,left:w,width:e.width}}function qe(e){let n=new Map,t=new Map,o=!1,i=0;function u(){i||(i=requestAnimationFrame(()=>{i=0;let f=[];for(let[g,w]of n){if(!w.isOpen())continue;let T=w.getEl();if(!T)continue;let m=T.getBoundingClientRect();if(m.width===0&&m.height===0)continue;let h=w.compute(m);Object.assign(w.pos,de(h,w.panel?.(),w.margin)),f.push(g)}for(let[g,w]of t){let T=w.getScroller(),m=T instanceof Window?document.scrollingElement?.scrollTop??T.scrollY??0:T.scrollTop??0;m!==w.handle.y&&(w.handle.y=m,f.push(g))}f.length>0&&e(f)}))}function r(){o||(o=!0,window.addEventListener("scroll",u,{capture:!0,passive:!0}),window.addEventListener("resize",u))}function d(){o&&(window.removeEventListener("scroll",u,{capture:!0}),window.removeEventListener("resize",u),o=!1)}function a(f){for(let g of[...n.keys()])(g.startsWith(`popup:${f}:`)||g===`popup:${f}`)&&n.delete(g);t.delete(f)}function l(){d(),i&&(cancelAnimationFrame(i),i=0),n.clear(),t.clear()}return{popupTrackers:n,scrollTrackers:t,schedulePopupRecompute:u,ensurePopupListeners:r,destroyPopupListeners:d,cleanupTrackers:a,destroy:l}}var ne=0,$e="",Fe="",Ke="",Be="",ce=0;function Ge(){return typeof window<"u"&&typeof document<"u"}function Ye(){if(ne++,ne>1||!Ge())return;ce=window.scrollY;let e=document.body;$e=e.style.overflow,Fe=e.style.position,Ke=e.style.top,Be=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=`-${ce}px`,e.style.width="100%")}function ze(){if(ne===0||(ne--,ne>0)||!Ge())return;let e=document.body;e.style.overflow=$e,e.style.position=Fe,e.style.top=Ke,e.style.width=Be,ce>0&&window.scrollTo(0,ce)}var Cn='a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';function Ee(e){let n=e.querySelectorAll(Cn);if(n.length===0)return()=>{};let t=n[0],o=n[n.length-1],i=r=>{r.key==="Tab"&&(r.shiftKey&&document.activeElement===t?(r.preventDefault(),o.focus()):!r.shiftKey&&document.activeElement===o&&(r.preventDefault(),t.focus()))},u=document.activeElement;return queueMicrotask(()=>{t.focus()}),e.addEventListener("keydown",i),()=>{e.removeEventListener("keydown",i),u?.focus()}}function G(e){let n=new WeakMap,t=new Set,o=u=>{if(u===null||typeof u!="object")return u;if(u instanceof Set||u instanceof Map){if(n.has(u))return n.get(u);let d=u instanceof Set?new Set(["add","delete","clear"]):new Set(["set","delete","clear"]),a=new Proxy(u,{get(l,f){let g=Reflect.get(l,f);return typeof g=="function"?d.has(String(f))?(...w)=>{let T=g.apply(l,w);e();for(let m of t)m();return T}:g.bind(l):g},set(l,f,g){Reflect.set(l,f,g),e();for(let w of t)w();return!0}});return n.set(u,a),a}if(u instanceof Date||u instanceof RegExp)return u;if(n.has(u))return n.get(u);let r=new Proxy(u,{set(d,a,l){if(Reflect.get(d,a)===l)return!0;Reflect.set(d,a,l),e();for(let g of t)g();return!0},get(d,a){let l=Reflect.get(d,a);return typeof l=="object"&&l!==null?o(l):l},deleteProperty(d,a){if(Reflect.has(d,a)){Reflect.deleteProperty(d,a),e();for(let l of t)l()}return!0}});return n.set(u,r),r},i=o({});return Object.defineProperty(i,"__watch",{value:u=>(t.add(u),()=>{t.delete(u)}),writable:!1,enumerable:!1}),i}function Je(e,n,t){let o=new AbortController,i=t?.signal;i&&(i.aborted?o.abort():i.addEventListener("abort",()=>o.abort(),{once:!0}));let u=t?.traceId??_n(),r=t?.record!==!1,d=[],a=(async()=>{let l;try{l=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-Trace-Id":u,Accept:"text/event-stream",...t?.headers},body:JSON.stringify(n),signal:o.signal})}catch(f){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:f instanceof Error?f.message:String(f)});return}if(!l.ok){t?.onError?.({code:Pn(l.status),message:`HTTP ${l.status} ${l.statusText}`});return}try{for await(let{name:f,data:g}of xn(l.body)){if(o.signal.aborted)return;En(d,{name:f,data:g},r),Tn(f,g,t??{})}}catch(f){if(o.signal.aborted)return;t?.onError?.({code:"provider_error",message:f instanceof Error?f.message:String(f)})}})();return{abort:()=>o.abort(),done:a,traceId:u,events:d}}function Tn(e,n,t){switch(e){case"wf:token":return t.onToken?.(n.text);case"wf:tool_call":return t.onToolCall?.(n);case"wf:tool_result":return t.onToolResult?.(n);case"wf:tool_progress":return t.onToolProgress?.(n);case"wf:step":return t.onStep?.(n);case"wf:approval_request":return t.onApproval?.(n);case"wf:usage":return t.onUsage?.(n);case"wf:done":return t.onDone?.(n);case"wf:error":return t.onError?.(n);default:return t.onEvent?.(e,n)}}async function*xn(e){let n=e.getReader(),t=new TextDecoder,o="";try{for(;;){let{done:i,value:u}=await n.read();if(i)break;o+=t.decode(u,{stream:!0});let r=o.split(`
2
+
3
+ `);o=r.pop()??"";for(let d of r){let a="message",l="";for(let f of d.split(`
4
+ `))f.startsWith("event: ")?a=f.slice(7):f.startsWith("data: ")&&(l+=f.slice(6));if(l)try{yield{name:a,data:JSON.parse(l)}}catch{}}}}finally{n.releaseLock()}}function En(e,n,t){t&&(e.length>=1e3&&e.shift(),e.push(n))}function Pn(e){return e===401||e===403?"auth_failed":e===429?"rate_limited":e>=500?"provider_error":"invalid_request"}function _n(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`trace-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function kn(e){return e.map(n=>({role:n.role,content:n.content}))}function Pe(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`msg-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Xe(e,n,t){t.initialMessages?e.messages=structuredClone(t.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 o=null;function i(){if(!e.streaming)return;let T=e.messages[e.messages.length-1];return T&&T.role==="assistant"&&T.status==="streaming"?T:void 0}function u(T,m,h){let b=i();switch(T){case"wf:token":b&&(b.content+=m.text);break;case"wf:tool_call":{b&&(b.toolCalls||(b.toolCalls=[]),b.toolCalls.push({call:m,status:"running"}));break}case"wf:tool_progress":{let N=m,s=b?.toolCalls?.find(c=>c.call.id===N.toolCallId);s&&(s.progress=N);break}case"wf:tool_result":{let N=m,s=b?.toolCalls?.find(c=>c.call.id===N.id);s&&(s.result=N,s.status=N.ok?"ok":"error");break}case"wf:approval_request":b&&(b.approval=m);break;case"wf:usage":b&&(b.usage=m);break;case"wf:step":e.step=m;break;case"wf:done":b&&(b.status="done",b.approval=void 0),e.streaming=!1,e.step=null;break;case"wf:error":b&&(b.status="error",b.error=m,b.approval=void 0),e.error=m,e.streaming=!1,e.step=null;break;default:h?.(T,m);break}}function r(){let T=t.body?t.body(e.messages):{messages:kn(e.messages)};o=n(t.url,T,{onToken:h=>u("wf:token",{text:h}),onToolCall:h=>u("wf:tool_call",h),onToolProgress:h=>u("wf:tool_progress",h),onToolResult:h=>u("wf:tool_result",h),onApproval:h=>u("wf:approval_request",h),onUsage:h=>u("wf:usage",h),onStep:h=>u("wf:step",h),onDone:h=>u("wf:done",h),onError:h=>u("wf:error",h),onEvent:(h,b)=>u(h,b,t.onEvent)},{signal:t.signal,headers:t.headers}),e.streaming=!0;let m=i();m&&o?.traceId&&(m.id=o.traceId)}function d(){if(e.streaming)return;let T=String(e.input??"").trim();T&&(e.input="",e.error=null,e.usage=null,e.step=null,e.messages.push({id:Pe(),role:"user",content:T,status:"done"},{id:Pe(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r())}function a(){o?.abort(),e.streaming=!1,e.step=null;let T=e.messages[e.messages.length-1];T&&T.role==="assistant"&&T.status==="streaming"&&(!T.content&&(!T.toolCalls||T.toolCalls.length===0)?e.messages.pop():T.status="done")}function l(){if(e.streaming)return;let T=-1;for(let m=e.messages.length-1;m>=0;m--)if(e.messages[m].role==="user"){T=m;break}T!==-1&&(e.messages.splice(T+1),e.error=null,e.usage=null,e.step=null,e.messages.push({id:Pe(),role:"assistant",content:"",status:"streaming",toolCalls:[]}),r())}function f(){o?.abort(),e.messages=[],e.input="",e.streaming=!1,e.error=null,e.usage=null,e.step=null}async function g(T,m){let h=e.messages[e.messages.length-1],b=h?.role==="assistant"?h.approval:void 0;if(b&&(h.approval=void 0,!!t.approveUrl))try{await fetch(t.approveUrl,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({id:b.id,decision:T,note:m}),signal:t.signal})}catch(N){if(t.signal?.aborted)return;e.error={code:"provider_error",message:N instanceof Error?N.message:String(N)}}}function w(){o?.abort(),o=null}return{send:d,stop:a,retry:l,clear:f,approve:g,dispose:w}}var Qe="__wfAsyncComponent";function Nn(e){let n=e;return n[Qe]=!0,n}function z(e){return typeof e=="function"&&e?.[Qe]===!0}var $=Symbol("Fragment"),j=Symbol("Portal");function _e(e,n,t){return{type:e,props:Ze(n),key:t??void 0}}var Rn=_e;function Sn(e,n,t){return _e(e,n,t)}function Mn(e,n,...t){let o=Ze(n??{});return t.length>0&&(o.children=t.length===1?t[0]:t),{type:e,props:o,key:n?.key??void 0}}function Ze(e){if(!e)return{};let n={};for(let t of Object.keys(e))t!=="key"&&(n[t]=e[t]);return n}function ke(e,n){return{type:j,props:{children:e,portalKey:n},key:n??void 0,_placement:"remote"}}var fe=new Set,te=new Map,pe=new Map,oe=new Map;function en(e){let{ctx:n,renderByIds:t,getSelfId:o,dirtyBatch:i,dirtySet:u,mediaRegistry:r,popupTrackers:d,scrollTrackers:a,schedulePopupRecompute:l,ensurePopupListeners:f,isRendering:g,isMounting:w,setMounting:T,endMounting:m}=e,h=e.registry??O(n),b=s=>ue(h,s);return{_selfId:"_wf_root",_ctxVersion:0,_dirtySet:u,setMounting:T,endMounting:m,bumpCtxVersion:function(){this._ctxVersion++},render:function(s){if(g()){if(w())return;this._pendingRender||(this._pendingRender=!0,queueMicrotask(()=>{this._pendingRender=!1,this.render(s)}));return}if(!s||s.length===0){let c=o(this);if(c)s=[c];else return}t(s)},dirty:function(s){if(!w()){if(g()){this._pendingDirty||(this._pendingDirty=!0,queueMicrotask(()=>{this._pendingDirty=!1,this.dirty(s)}));return}if(!s||s.length===0){let c=o(this);if(c)s=[c];else return}for(let c of s)c&&(i.add(c),u.add(c));this._dirtyScheduled||(this._dirtyScheduled=!0,queueMicrotask(()=>{this._dirtyScheduled=!1;let c=[...i];i.clear(),c.length>0&&t(c)}))}},$:function(){let s=this;if(!Object.prototype.hasOwnProperty.call(s,"_$cache")){let c=G(()=>{let p=s._selfVNode?._id??o(s);p&&n.ui.dirty([p])});s._$cache=c}return s._$cache},useChat:function(s){let c=this.$(),p=Xe(c,Je,s);Object.assign(c,{send:p.send,stop:p.stop,retry:p.retry,clear:p.clear,approve:p.approve,dispose:p.dispose});let y=o(this);if(y){let v=b(C=>{C===y&&(p.dispose(),v())})}return c},useMedia:function(s,c){let y=`media:${o(this)}:${s}`;if(!r.has(y)){let v=window.matchMedia(s);c(v.matches);let C=P=>c(P.matches);v.addEventListener("change",C),r.set(y,{mql:v,handler:C})}},useBreakpoint:function(s,c){let p=typeof s=="function"?{mobile:"(max-width: 639px)",tablet:"(min-width: 640px) and (max-width: 1023px)",desktop:"(min-width: 1024px)"}:s,y=typeof s=="function"?s:c,C=`bp:${o(this)}`;function P(){for(let[x,M]of Object.entries(p))if(window.matchMedia(M).matches)return x;return Object.keys(p)[0]??""}if(!r.has(C)){y(P());let x=[];for(let M of Object.values(p)){let V=window.matchMedia(M),L=()=>y(P());V.addEventListener("change",L),x.push({mql:V,handler:L})}r.set(C,{mqls:x})}},usePopupPosition:function(s){let c=o(this),p={top:0,left:0,refresh:()=>{}};if(!c)return p;let y={pos:p,getEl:s.el,isOpen:s.isOpen,compute:s.compute,panel:s.panel,margin:s.margin??8};return d.set(c,y),f(),p.refresh=()=>{let v=y.getEl();if(!v)return;let C=v.getBoundingClientRect();if(C.width===0&&C.height===0)return;let P=y.compute(C);Object.assign(p,de(P,y.panel?.(),y.margin))},p},useHoverCapable:function(){return typeof window<"u"&&!!window.matchMedia?.("(hover: hover)").matches},useStableRef:function(s,c){return y=>{y?s(y):c?.()}},useVisualViewport:function(){let s=o(this),c={height:window.innerHeight,offsetTop:0,keyboardOpen:!1},p=()=>{n.ui&&n.ui.dirty(s?[s]:void 0)},y=()=>{let C=window.visualViewport;c.height=C?.height??window.innerHeight,c.offsetTop=C?.offsetTop??0,c.keyboardOpen=c.height<window.innerHeight*.9,p()},v=window.visualViewport;if(v?.addEventListener?(v.addEventListener("resize",y),v.addEventListener("scroll",y)):window.addEventListener("resize",y),s){let C=b(P=>{P===s&&(v?.removeEventListener?(v.removeEventListener("resize",y),v.removeEventListener("scroll",y)):window.removeEventListener("resize",y),C())})}return c},usePopup:function(s){let c=o(this),p=this.useHoverCapable(),y=()=>typeof s.trigger=="function"?s.trigger():s.trigger,v=s.open!==void 0,C=()=>!!s.disabled?.(),P=()=>v?typeof s.open=="function"?!!s.open():!!s.open:s.isOpen(),x=_=>{C()||(v?s.onOpenChange?.(_):s.setOpen(_))},M=()=>{let _=s.placement;return typeof _=="function"?_():_??"bottom"},V=null,L=!1,E=n.ui.usePopupPosition({el:s.el,isOpen:()=>P(),compute:_=>{if(s.position){let A=s.position();return{top:A.y,left:A.x}}return je(_,M(),s.gap??6,s.center!==!1)},panel:()=>V,margin:s.margin??8}),S=_=>{if(s.closeOnOutside===!1||!P())return;let A=_.target;if(!(A instanceof Node))return;let q=s.el();q&&q.contains(A)||V&&V.contains(A)||x(!1)},k=_=>{s.closeOnEscape!==!1&&(_.key!=="Escape"||!P()||x(!1))};if(document.addEventListener("mousedown",S),document.addEventListener("keydown",k),c){let _=b(A=>{A===c&&(document.removeEventListener("mousedown",S),document.removeEventListener("keydown",k),_())})}let R={},I=_=>typeof _=="function"?_():_??0,H=()=>I(s.openDelay),He=()=>I(s.closeDelay),F,K,cn=()=>{clearTimeout(F),clearTimeout(K),F=void 0,K=void 0},fn=_=>{if(C())return;let A=_.currentTarget,q=_.relatedTarget;A.contains(q)||(clearTimeout(K),K=void 0,F=setTimeout(()=>{F=void 0,x(!0)},H()))},pn=_=>{if(C())return;let A=_.currentTarget,q=_.relatedTarget;A.contains(q)||(clearTimeout(F),F=void 0,K=setTimeout(()=>{K=void 0,x(!1)},He()))},mn=()=>{C()||(clearTimeout(K),K=void 0,F=setTimeout(()=>{F=void 0,x(!0)},H()))},yn=()=>{C()||(clearTimeout(F),F=void 0,K=setTimeout(()=>{K=void 0,x(!1)},He()))},Z=()=>y()==="hover";if(R.onMouseOver=_=>{Z()&&fn(_)},R.onMouseOut=_=>{Z()&&pn(_)},R.onClick=()=>{Z()?p||x(!P()):y()==="click"&&x(!0)},R.onFocus=()=>{Z()&&mn()},R.onBlur=()=>{Z()&&yn()},y()==="longpress"){let _,A=0,q=0,B=()=>{clearTimeout(_),_=void 0};R.onPointerDown=W=>{C()||(A=W.clientX??0,q=W.clientY??0,B(),_=setTimeout(()=>{_=void 0,s.onTrigger?.({clientX:A,clientY:q}),x(!0)},s.longPressDuration??500))},R.onPointerUp=B,R.onPointerLeave=B,R.onPointerMove=W=>{let we=Math.abs((W.clientX??0)-A),be=Math.abs((W.clientY??0)-q);(we>10||be>10)&&B()},R.onContextMenu=W=>{W.preventDefault(),s.onTrigger?.({clientX:W.clientX??0,clientY:W.clientY??0}),x(!0)}}if(R.onKeyDown=_=>{_.key==="Escape"&&s.closeOnEscape!==!1&&x(!1)},c){let _=b(A=>{A===c&&(cn(),_())})}let gn=_=>{if(_){V=_;let A=()=>E.refresh();_.addEventListener("animationend",A,{once:!0})}else V=null},he=null,ve=null,hn=_=>{gn(_),ve&&ve(_)};return{get open(){return P()},setOpen:x,wrapProps:R,portal:(_,A="popover")=>{if(C())return null;if(!P())return L=!1,he=null,null;let B=s.el();(!L||B!==he)&&(B?E.refresh():queueMicrotask(()=>{P()&&E.refresh()}),L=!0,he=B);let W=_.props??{};ve=W.ref??null;let we=["wf-popup",W.class].filter(Boolean).join(" "),be={...W.style??{},position:"fixed",top:`${E.top}px`,left:`${E.left}px`,maxWidth:s.width!==void 0?`min(${s.width}px, calc(100vw - 32px))`:"calc(100vw - 32px)"},vn={..._,props:{...W,class:we,style:be,ref:hn}};return ke(vn,A)},refresh:()=>E.refresh()}},useLongPress:function(s){let{onLongPress:c,duration:p=500}=s,y,v=0,C=0,P=null,x=()=>{clearTimeout(y),y=void 0};return{onPointerDown:M=>{v=M.clientX??0,C=M.clientY??0,P=M,x(),y=setTimeout(()=>{y=void 0,P&&c(P)},p)},onPointerUp:x,onPointerLeave:x,onPointerMove:M=>{let V=Math.abs((M.clientX??0)-v),L=Math.abs((M.clientY??0)-C);(V>10||L>10)&&x()},onContextMenu:M=>{M.preventDefault(),c(M)}}},useInView:function(s){let c=o(this),p={isIn:!1,ready:!1,observe:x,refresh:M,disconnect:V},y=null,v=null,C=()=>{n.ui&&n.ui.dirty(c?[c]:void 0)};function P(){if(v?.disconnect(),v=null,!y)return;let L=typeof s.rootMargin=="function"?s.rootMargin():s.rootMargin,E=typeof s.threshold=="function"?s.threshold():s.threshold;v=new IntersectionObserver(S=>{let k=S[S.length-1];if(!k)return;let R=k.isIntersecting,I=R!==p.isIn,H=!p.ready;p.isIn=R,p.ready=!0,s.onChange?.(k,R),(I||H)&&C()},{root:s.root?s.root():null,rootMargin:L??"0px",threshold:E??0}),v.observe(y)}function x(L){y=L,L?P():(v?.disconnect(),v=null,p.isIn=!1)}function M(){P()}function V(){v?.disconnect(),v=null}return p},useScrollPosition:function(s){let c=o(this),p={y:0,refresh(){let v=y.getScroller();p.y=v instanceof Window?document.scrollingElement?.scrollTop??v.scrollY??0:v.scrollTop??0}},y={handle:p,getScroller:s.getScroller??(()=>window)};return c?(a.set(c,y),f(),p.refresh(),p):(p.refresh(),p)},useAsync:function(s){let c=o(this),p=G(()=>{n.ui&&n.ui.dirty(c?[c]:void 0)});p.loading=!0;let y=0,v=()=>{let C=++y;p.loading=!0,p.error=null,Promise.resolve().then(()=>s()).then(P=>{y===C&&(p.data=P,p.loading=!1)}).catch(P=>{y===C&&(p.error=P,p.loading=!1)})};return v(),p.reload=v,p},useControlled:function(s){let c=o(this),p=s.value!==void 0;if(p&&!s.onChange&&s.name&&(fe.has(s.name)||(fe.add(s.name),console.warn(`[weifuwu/${s.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08value \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
5
+ \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 value\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onChange={(v) => setValue(v)}`))),!p&&c&&!te.has(c)){te.set(c,s.value);let v=b(C=>{C===c&&(te.delete(c),v())})}let y=v=>{if(p){s.onChange?.(v);return}c&&te.set(c,v),n.ui&&(c?n.ui.dirty([c]):n.ui.render())};return{value:p?s.value:c?te.get(c):s.value,setValue:y,controlled:p}},useControlledInput:function(s){let c=o(this),p=this.useControlled({value:s.value,onChange:s.onChange,name:s.name});if(c&&!pe.has(c)){pe.set(c,{keyword:"",selectedLabel:""});let C=b(P=>{P===c&&(pe.delete(c),C())})}let y=c?pe.get(c):{keyword:"",selectedLabel:""},v=()=>{c?n.ui?.dirty([c]):n.ui?.render()};return{...p,get keyword(){return y.keyword},setKeyword(C){y.keyword=C,v()},get selectedLabel(){return y.selectedLabel},setSelectedLabel(C){y.selectedLabel=C,v()}}},useOpen:function(s){let c=o(this);if(c&&!oe.has(c)){oe.set(c,!1);let P=b(x=>{x===c&&(oe.delete(c),P())})}let p=s.open!==void 0;p&&!s.onOpenChange&&s.name&&!fe.has(s.name)&&(fe.add(s.name),console.warn(`[weifuwu/${s.name}] \u53D7\u63A7\u6A21\u5F0F\uFF08open \u5DF2\u4F20\uFF09\u4F46\u672A\u63D0\u4F9B onOpenChange\uFF0C\u4EA4\u4E92\u65E0\u6CD5\u751F\u6548\u3002
6
+ \u975E\u53D7\u63A7\uFF1A\u53BB\u6389 open\uFF1B\u53D7\u63A7\uFF1A\u4F20\u5165 onOpenChange={(o) => setOpen(o)}`));let y=()=>p?!!s.open:c?oe.get(c)??!1:!1,v=()=>{c?n.ui?.dirty([c]):n.ui?.render()},C=P=>{if(p){s.onOpenChange?.(P);return}c&&oe.set(c,P),v()};return{get open(){return y()},setOpen:C,triggerProps:{onClick:()=>C(!0),onFocus:()=>{s.openOnFocus&&C(!0)}}}},usePresence:function(s){let c=o(this),p="closed",y,v=()=>{p="closed",n.ui&&(c?n.ui.dirty([c]):n.ui.render())};return{get phase(){return p},ref:P=>{P?y||(y=()=>{p==="exit"&&v()},P.addEventListener("animationend",y)):y=void 0},sync:P=>(P?p="open":p==="open"&&(p="exit"),p)}},useDialog:function(s){let c=o(this),p,y=null,v=this.usePresence(s);return{get phase(){return v.phase},rootRef:x=>{x?(Ye(),y&&(p=Ee(y)),v.ref(x)):(ze(),p?.(),v.ref(null))},panelRef:x=>{y=x,x&&!p&&(p=Ee(x))},sync:x=>v.sync(x)}},useGlobalKey:function(s){let c=o(this);if(typeof window>"u")return()=>{};if(window.addEventListener("keydown",s),c){let p=b(y=>{y===c&&(window.removeEventListener("keydown",s),p())})}return()=>window.removeEventListener("keydown",s)},useDrag:function(s){let c=0,p=0,y=!1,v=x=>{y&&s.onMove(x,{x:x.clientX-c,y:x.clientY-p})},C=x=>{y&&(y=!1,window.removeEventListener("pointermove",v),window.removeEventListener("pointerup",C),s.onEnd?.(x))};return{onPointerDown:x=>{y||(x.preventDefault(),y=!0,c=x.clientX,p=x.clientY,window.addEventListener("pointermove",v),window.addEventListener("pointerup",C),s.onStart?.(x))}}},useDragDrop:function(s){let c={};s.onDrop&&(c.onDrop=y=>{y.preventDefault(),s.onDrop(y)}),s.onDragOver&&(c.onDragOver=y=>{y.preventDefault(),s.onDragOver(y)}),s.onDragLeave&&(c.onDragLeave=y=>s.onDragLeave(y));let p={draggable:!0};if(s.onDragStart){let y=s.onDragStart;p.onDragStart=v=>{typeof document<"u"&&document.body.classList.add("wf-dragging"),y(v)}}if(s.onDragEnd){let y=s.onDragEnd;p.onDragEnd=v=>{typeof document<"u"&&document.body.classList.remove("wf-dragging"),y(v)}}return{dropProps:c,dragProps:p}},useReducedMotion:function(){return typeof window<"u"&&!!window.matchMedia?.("(prefers-reduced-motion: reduce)").matches},useAnimationEnd:function(s,c){let p=null,y=()=>{s(),c?.once&&p&&p.removeEventListener("animationend",y)};return C=>{C?(p=C,C.addEventListener("animationend",y)):p&&(p.removeEventListener("animationend",y),p=null)}},useTween:function(s,c){let p=o(this),y=this.useReducedMotion(),v=c?.duration??400,C=c?.ease==="linear"?E=>E:E=>1-Math.pow(1-E,3),P,x=s,M={value:y?s:0,reset:()=>{}},V=()=>{n.ui&&(p?n.ui.dirty([p]):n.ui.render())},L=E=>{if(x=E,y){M.value=E,V();return}if(E===M.value)return;P&&cancelAnimationFrame(P);let S=M.value,k=performance.now(),R=I=>{let H=Math.min(1,(I-k)/v);M.value=Math.round(S+(E-S)*C(H)),H<1?(P=requestAnimationFrame(R),V()):(P=void 0,V())};P=requestAnimationFrame(R)};return M.reset=E=>{E===x&&P||L(E)},queueMicrotask(()=>L(s)),M},selfId:function(s){if(typeof s!="string"||!s)throw new Error(`[weifuwu] selfId requires a non-empty string, got ${typeof s}`);if(h.idRegistry.has(s))throw new Error(`[weifuwu] Duplicate component ID: "${s}". Each component must have a unique custom ID.`);let c=this._selfVNode;c&&(c._customId=s,h.idRegistry.set(s,c))}}}var nn=new WeakMap;function An(e){let n=nn.get(e)??{count:0,warned:!1};n.count++,n.count>=3&&!n.warned&&(n.warned=!0,console.warn("[weifuwu] ref \u51FD\u6570\u6BCF\u6B21\u6E32\u67D3\u90FD\u53D8\u5316\uFF08\u5185\u8054 ref\uFF09\u2014\u2014ref \u56DE\u8C03\u5728\u6BCF\u6B21\u6E32\u67D3\u540E\u91CD\u65B0\u6267\u884C\uFF08\u6027\u80FD\u635F\u8017\uFF09\u3002\u628A ref \u5B9A\u4E49\u5230 mount \u4F5C\u7528\u57DF\uFF08\u7A33\u5B9A\u5F15\u7528\uFF09\uFF1Aconst listRef = (el) => {...}; return h('div', { ref: listRef })")),nn.set(e,n)}function Y(e,n,t,o,i){if(t==null){if(o==null)return null;let l=D(o,i);return l==null?null:(n&&n.parentNode?n.parentNode.insertBefore(l,n):e.appendChild(l),l)}if(o==null)return n?(U(t,O(i)),n.remove()):U(t,O(i)),null;let u=on(t),r=on(o);if(u!==r){U(t,O(i));let l=D(o,i);return l==null?null:(n?.parentNode&&n.parentNode.replaceChild(l,n),l)}if(r==="text")return n&&n.textContent!==String(o)&&(n.textContent=String(o)),n;let d=o,a=t;if(typeof d.type=="function"){let l=d.type;a._render&&a.type===d.type&&(d._render=a._render,d._id=a._id,d._id&&O(i).idRegistry.set(d._id,d)),d._parentNode=e,d._refNode=n;let f=Object.create(i);f.ui=Object.create(i.ui);let g=f.ui;if(g._selfId=d._id,g._selfVNode=d,d._ctxVersion=a._ctxVersion??g._ctxVersion??0,a._render&&a.type===d.type&&Ln(a.props,d.props)&&!g._dirtySet?.has(a._id)&&d._ctxVersion===g._ctxVersion)return d._child=a._child,n;g._dirtySet?.delete(a._id);let w;try{typeof d._render=="function"?w=d._render(d.props):w=Se(l,d.props,d,f)}catch(h){let b=i.ui?._errorHandler;b?(b(h),w=null):(console.error(`[weifuwu] Component render error in <${l?.name||"anonymous"}> (id: ${a._id??"?"}, phase: update)`,h),w=null)}let T=a._child;d._child=w;let m=Y(e,n,T,w,f);return m||(d._refNode=null),m}if(d.type===$){let l=a._childNodes,f=sn(e,a,d,i,l);return d._childNodes=f,n}if(typeof d.type=="string"){if(n&&n.nodeType===1){let l=a.props?.ref,f=d.props?.ref;l!==f&&(typeof f=="function"&&f(n),typeof l=="function"&&typeof f=="function"&&An(n)),Re(n,a.props,d.props),sn(n,a,d,i)}else if(n){U(t,O(i));let l=D(o,i);return l==null?null:(n.parentNode?.replaceChild(l,n),l)}return n}if(d.type===j)return se(a,d,i),null;if(Array.isArray(o)){let l=Array.isArray(t)?t:[];me(l,o);let f=Array.from(e.childNodes),g=n?f.indexOf(n):-1,w=g>=0?re(f.slice(g),l):re(f,l);return ye(e,l,o,i,w,n),n}return n}var tn=new Map;function In(e){let n=tn.get(e);return n||(n=`fn:${e.name||"anon"}`,tn.set(e,n)),n}function on(e){if(e==null||typeof e=="boolean")return"null";if(typeof e=="string"||typeof e=="number")return"text";if(Array.isArray(e))return"array";let n=e;return typeof n.type=="function"?In(n.type):n.type===$?"fragment":n.type===j?"portal":typeof n.type=="string"?"tag:"+n.type:"unknown"}function Re(e,n,t){let o=n?Object.keys(n).filter(r=>r!=="children"&&r!=="key"&&r!=="innerHTML"):[],i=t?Object.keys(t).filter(r=>r!=="children"&&r!=="key"&&r!=="innerHTML"):[],u=new Set(i);for(let r of o){if(!n)break;if(!u.has(r)){if(r==="ref")continue;r.startsWith("on")&&typeof n[r]=="function"?e.removeEventListener(r.slice(2).toLowerCase(),n[r]):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(r==="className"?"class":r)}}for(let r of i){if(r==="ref")continue;let d=n?.[r],a=t?.[r];if(r==="innerHTML")a!==d&&(e.innerHTML=String(a??""));else if(a!==d)if(r==="class"||r==="className")e instanceof SVGElement?e.setAttribute("class",rn(a)):e.className=rn(a);else if(r==="style"&&typeof a=="object"&&a!==null){let l=e.style,f=a;for(let g of Object.keys(f)){let w=f[g];w==null?g.startsWith("--")?l.removeProperty(g):l[g]="":g.startsWith("--")?l.setProperty(g,String(w)):l[g]=typeof w=="number"?w+"px":String(w)}}else if(r.startsWith("on")&&typeof a=="function"){let l=r.slice(2).toLowerCase();typeof d=="function"&&e.removeEventListener(l,d),e.addEventListener(l,a)}else r==="draggable"?e.setAttribute("draggable",a?"true":"false"):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(a??""):a===!0?e.setAttribute(r,""):a!=null&&a!==!1?e.setAttribute(r,String(a)):r==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value="":e.removeAttribute(r)}}function rn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function Ne(e){if(!(e==null||typeof e!="object"))return Array.isArray(e)?void 0:e.key}function me(e,n){if(!n.some(o=>o&&typeof o=="object"&&!Array.isArray(o)&&o.key!==void 0)){for(let o=0;o<n.length;o++){let i=n[o];i&&typeof i=="object"&&!Array.isArray(i)&&(i.key=String(o))}for(let o=0;o<e.length;o++){let i=e[o];i&&typeof i=="object"&&!Array.isArray(i)&&(i.key=String(o))}}}function re(e,n){let t=[],o=0;for(let i of n){if(i==null||typeof i=="boolean"){t.push(null);continue}let u=i;if(u.type===j){t.push(null);continue}if(u.type===$){let r=u._childNodes;Array.isArray(r)&&r.length>0?(t.push(r.slice()),o+=r.length):(t.push(e[o]?[e[o]]:null),o+=1)}else if(typeof u.type=="function")if(u._render){let r=u._childNodes??u._refNode;r==null?t.push(null):Array.isArray(r)?(t.push(r.slice()),o+=r.length):(t.push([r]),o+=1)}else t.push(e[o]?[e[o]]:null),o+=1;else typeof process<"u"&&process.env.DBG&&console.error("[map] idx=",o,"type=",u.type,"sourceLen=",e.length,"hit=",!!e[o]),t.push(e[o]?[e[o]]:null),o+=1}return t}function sn(e,n,t,o,i){let u=ie(n.props?.children),r=ie(t.props?.children);me(u,r);let d=i??Array.from(e.childNodes),a=re(d,u),l=ye(e,u,r,o,a,i?.[0]??null),f=[];for(let g of l)g&&g.length>0&&f.push(...g);return f}function ie(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function ln(e){return e==null?[]:e instanceof DocumentFragment?Array.from(e.childNodes):[e]}function ye(e,n,t,o,i=[],u=null){if(!t.some(m=>m&&typeof m=="object"&&!Array.isArray(m)&&m.key!==void 0&&m._placement!=="remote")){let m=Math.max(n.length,t.length);for(let h=0;h<m;h++){let b=h<n.length?n[h]:null,N=h<t.length?t[h]:null;if(N==null){if(b!=null){U(b,O(o));for(let s of i[h]??[])s.remove()}}else if(b==null){let s=D(N,o);if(s!=null){let c=null;for(let p=h+1;p<i.length;p++){let y=i[p]?.[0];if(y&&y.parentNode===e){c=y;break}}c?e.insertBefore(s,c):e.appendChild(s)}}else{let s=i[h]?.[0]??null;Y(e,s,b,N,o)}}return[]}for(let m=0;m<n.length;m++){let h=n[m];if(!(h==null||typeof h=="boolean")&&Ne(h)===void 0)for(let b of i[m]??[])b.remove()}let d=new Map,a=0;for(let m=0;m<n.length;m++){let h=Ne(n[m]);h!==void 0&&d.set(h,{vnode:n[m],nodes:i[m]??[],index:a++})}let l=t.map(m=>Ne(m)),f=new Set(l);for(let m of[...d.keys()])if(!f.has(m)){let h=d.get(m);U(h.vnode,O(o));for(let b of h.nodes)b?.remove();d.delete(m)}let g=new Array(t.length).fill(null),w=-1,T=u&&u.parentNode===e?u:e.firstChild;for(let m=0;m<t.length;m++){let h=l[m],b=t[m],N=h!==void 0?d.get(h):void 0,s=b&&typeof b=="object"&&b._placement==="remote";if(N)if(N.nodes.length>0){if(N.index<w)for(let p of N.nodes)e.insertBefore(p,T);w=Math.max(w,N.index),Y(e,N.nodes[0],N.vnode,b,o),g[m]=b._childNodes??N.nodes.filter(p=>p.parentNode===e),T=g[m][g[m].length-1]?.nextSibling??null}else if(s)se(N.vnode,b,o),g[m]=[];else{let c=Y(e,null,N.vnode,b,o);g[m]=ln(c);for(let y of g[m])e.insertBefore(y,T);T=g[m][g[m].length-1]?.nextSibling??null}else if(s)X(b,o),g[m]=[];else{let c=D(b,o);g[m]=ln(c);for(let y of g[m])e.insertBefore(y,T);T=g[m][g[m].length-1]?.nextSibling??null}}return g}function Vn(e,n){if(e===n)return!0;if(Array.isArray(e)&&Array.isArray(n)){if(e.length!==n.length)return!1;for(let t=0;t<e.length;t++)if(e[t]!==n[t])return!1;return!0}return e===n}function Ln(e,n){if(e===n)return!0;if(!e||!n)return!1;let t=new Set([...Object.keys(e),...Object.keys(n)]);for(let o of t)if(o!=="key"){if(o==="children"){if(!Vn(e[o],n[o]))return!1}else if(e[o]!==n[o])return!1}return!0}var Me="http://www.w3.org/2000/svg",Ae=new Set(["svg","path","circle","line","rect","text","g","polyline","polygon","ellipse","defs","use","clipPath","mask","linearGradient","radialGradient","stop","tspan"]);function D(e,n){if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number")return document.createTextNode(String(e));if(Array.isArray(e))return Hn(e,n);let t=e;if(t.type===j)return X(t,n),null;if(t.type===$){let r=document.createDocumentFragment(),d=t.props?.children==null?[]:Array.isArray(t.props.children)?t.props.children:[t.props.children];for(let a of d){let l=D(a,n);l!=null&&r.appendChild(l)}return t._childNodes=Array.from(r.childNodes),r}if(typeof t.type=="function")return On(t.type,t.props,t,n);let o=t.type,i=Ae.has(o)?document.createElementNS(Me,o):document.createElement(o);t.el=i;let u;for(let[r,d]of Object.entries(t.props??{}))r==="children"||r==="key"||r==="value"||r==="innerHTML"||an(i,r,d);if("value"in(t.props??{})&&i instanceof HTMLSelectElement?u=t.props.value:"value"in(t.props??{})&&an(i,"value",t.props.value),"innerHTML"in(t.props??{}))i.innerHTML=String(t.props.innerHTML??"");else{let r=Ie(t.props?.children);for(let d of r){let a=D(d,n);if(a!=null&&(i.appendChild(a),d&&typeof d=="object"&&typeof d.type=="function")){let l=d;l._parentNode||(l._parentNode=i,l._refNode=a)}}}return u!==void 0&&(i.value=String(u)),typeof t.props?.ref=="function"&&xe(t.props.ref,i,"mount",o),i}function Un(e){let n=e.ui;n&&typeof n.render=="function"&&n.render(["_wf_root"])}function Se(e,n,t,o){let i;if(z(e)){if(i=De(O(o),e),!i)return Te(O(o),e,o).promise.then(()=>Un(o),()=>{}),null}else i=e;o.ui?.setMounting?.(!0);let u;try{u=i(n,o)}finally{o.ui?.endMounting?.()}if(typeof u!="function")throw new Error(`Component ${e.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return t._render=u,u(n)}function On(e,n,t,o){if(!t._id){let a=O(o);t._id=ae(a),a.idRegistry.set(t._id,t)}let i=Object.create(o);i.ui=Object.create(o.ui);let u=i.ui;u._selfId=t._id,u._selfVNode=t,t._ctxVersion=u._ctxVersion??0;let r;try{r=Se(e,n,t,i)}catch(a){let l=o.ui?._errorHandler;l?(l(a),r=null):(console.error(`[weifuwu] Component render error in <${e.name||"anonymous"}> (id: ${t._id??"?"}, phase: mount)`,a),r=null)}if(r==null){if(t._child=null,i.ui?._errorHandler){let l=document.createComment("wf-empty");return t._refNode=l,l}return null}t._child=r;let d=D(r,i);return t._refNode||(t._refNode=d),d}function Hn(e,n){let t=document.createDocumentFragment();for(let o of e){let i=D(o,n);i!=null&&t.appendChild(i)}return t}function Wn(){let e=document.getElementById("__wf_portal");return e||(e=document.createElement("div"),e.id="__wf_portal",e.style.cssText="position:fixed;inset:0;pointer-events:none;z-index:9999",document.body.appendChild(e)),e}function X(e,n){let t=Wn(),o=document.createElement("div");o.style.pointerEvents="auto",t.appendChild(o),e._remoteEl=o;let i=ie(e.props?.children);e._child=i;for(let u of i){let r=D(u,n);r!=null&&o.appendChild(r)}}function se(e,n,t){let o=e?._remoteEl;if(n._remoteEl=o,!o){X(n,t);return}let i=ie(n.props?.children),u=e._child||[];n._child=i,me(u,i);let r=re(Array.from(o.childNodes),u);ye(o,u,i,t,r,r[0]?.[0]??null)}function Ie(e){if(e==null)return[];if(!Array.isArray(e))return[e];let n=[];for(let t of e)Array.isArray(t)?n.push(...t):n.push(t);return n}function an(e,n,t){if(n!=="ref")if(n==="class"||n==="className")e instanceof SVGElement?e.setAttribute("class",String(t??"")):e.className=String(t??"");else if(n==="style"&&typeof t=="object"&&t!==null){let o=e.style;for(let i of Object.keys(t)){let u=t[i];u!=null&&(i.startsWith("--")?o.setProperty(i,String(u)):o[i]=typeof u=="number"?u+"px":String(u))}}else n.startsWith("on")&&typeof t=="function"?e.addEventListener(n.slice(2).toLowerCase(),t):n==="draggable"?e.setAttribute("draggable",t?"true":"false"):n==="value"&&(e instanceof HTMLInputElement||e instanceof HTMLTextAreaElement||e instanceof HTMLSelectElement)?e.value=String(t??""):t===!0?e.setAttribute(n,""):t!=null&&t!==!1&&e.setAttribute(n,String(t))}function Dn(e,n,t){e.innerHTML="";let o=D(n,t);o instanceof Node&&e.appendChild(o)}function jn(e){U(e,ee())}function Ve(e){e.node=e.node?e.node.nextSibling:null}function qn(e,n){e.node&&e.node.parentNode?e.node.parentNode.insertBefore(n,e.node):e.parent.appendChild(n)}function $n(e,n){e.node&&e.node.parentNode?(e.node.parentNode.replaceChild(n,e.node),Ve(e)):e.parent.appendChild(n)}async function le(e,n,t){if(e==null||typeof e=="boolean")return null;if(typeof e=="string"||typeof e=="number"){let d=String(e);if(t.node&&t.node.nodeType===3)return t.node.textContent!==d&&(t.node.textContent=d),Ve(t),t.node;let a=document.createTextNode(d);return qn(t,a),a}if(Array.isArray(e)){let d=null;for(let a of e){let l=await le(a,n,t);l!=null&&!d&&(d=l)}return d}let o=e;if(o.type===j||o.type===$){let d=o.props?.children,a=d==null?[]:Array.isArray(d)?d:[d],l=null;for(let f of a){let g=await le(f,n,t);g!=null&&!l&&(l=g)}return l}if(typeof o.type=="function")return Fn(o,n,t);let i=o.type,u=o.props??{},r;if(t.node&&t.node.nodeType===1&&t.node.tagName.toLowerCase()===i.toLowerCase()?(r=t.node,Ve(t)):(r=Ae.has(i)?document.createElementNS(Me,i):document.createElement(i),$n(t,r)),o.el=r,Re(r,null,u),!("innerHTML"in u)){let d={parent:r,node:r.firstChild},a=Ie(u.children);for(let l of a){let f=await le(l,n,d);if(f!=null&&f.parentNode!==r&&r.appendChild(f),l&&typeof l=="object"&&typeof l.type=="function"){let g=l;g._parentNode||(g._parentNode=r,g._refNode=f)}}for(;d.node;){let l=d.node;d.node=l.nextSibling,l.parentNode?.removeChild(l)}}return"value"in u&&r instanceof HTMLSelectElement&&(r.value=String(u.value??"")),typeof u.ref=="function"&&u.ref(r),r}async function Fn(e,n,t){if(!e._id){let a=O(n);e._id=ae(a),a.idRegistry.set(e._id,e)}let o=Object.create(n);o.ui=Object.create(n.ui);let i=o.ui;i._selfId=e._id,i._selfVNode=e,e._ctxVersion=i._ctxVersion??0;let u=e.type,r;try{let a;z(u)?a=await We(O(n),u,o):a=u;let l=a(e.props??{},o);if(typeof l!="function")throw new Error(`Component ${u.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);e._render=l,r=l(e.props??{})}catch(a){let l=n.ui?._errorHandler;l?(l(a),r=null):(console.error(`[weifuwu] Component hydration error in <${u.name||"anonymous"}> (id: ${e._id??"?"})`,a),r=null)}if(r==null)return e._child=null,null;e._child=r;let d=await le(r,o,t);return e._refNode||(e._refNode=d),d}async function Le(e,n,t){let o={parent:e,node:e.firstChild};for(await le(n,t,o);o.node;){let i=o.node;o.node=i.nextSibling,i.parentNode?.removeChild(i)}}function Ue(){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,createElement:e=>typeof document<"u"?document.createElement(e):null,bodyAppend:e=>{typeof document<"u"&&document.body.appendChild(e)},bodyRemove:e=>{typeof document<"u"&&e.parentNode&&document.body.removeChild(e)},copyText:async e=>{let n=typeof window<"u"?window:null;if(n?.navigator?.clipboard?.writeText)try{return await n.navigator.clipboard.writeText(e),!0}catch{}try{if(typeof document>"u")return!1;let t=document.createElement("textarea");t.value=e,t.style.position="fixed",t.style.opacity="0",document.body.appendChild(t),t.select();let o=document.execCommand("copy");return document.body.removeChild(t),o}catch{return!1}},execCommand:(e,n)=>typeof document<"u"?document.execCommand(e,!1,n):!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,scrollTop:()=>{let e=typeof document<"u"?document:null,n=typeof window<"u"?window:null;return e?.scrollingElement?.scrollTop??n?.scrollY??0},hash:()=>typeof window<"u"?window.location?.hash??"":"",setHash:e=>{typeof window<"u"&&(window.location.hash=e)},timeout:(e,n)=>typeof window<"u"?window.setTimeout(e,n):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,n)=>{try{typeof window<"u"&&window.localStorage?.setItem(e,n)}catch{}}}}function Kn(e,n){let t=typeof n.root=="string"?document.querySelector(n.root):n.root;if(!t)throw new Error(`uiServe: root not found: ${n.root}`);let o=t,i=!!n.hydrate;i||(o.innerHTML="");let u=ee(),r=new Set,d=new Set,a=new Map,l=!1,f=!1,g=[];function w(E){g.push(f),f=E}function T(){f=g.pop()??!1}let m={params:{},query:{}},h=new Map,b=globalThis.__DATA__??window.__DATA__;if(b&&typeof b=="object")for(let[E,S]of Object.entries(b))h.set(E,{value:S});m.data={async get(E,S){let k=h.get(E);if(k&&"value"in k)return k.value;if(k?.promise)return k.promise;if(!S)return;let R=Promise.resolve().then(()=>S()).then(I=>(h.set(E,{value:I}),I));return h.set(E,{promise:R}),R},set(E,S){h.set(E,{value:S})},has(E){return h.has(E)}};let N=!1;function s(){r.size>0&&!N&&(N=!0,queueMicrotask(()=>{N=!1;let E=[...r];r.clear(),E.length>0&&c(E)}))}function c(E){if(!l){l=!0;for(let S of E){let k=u.idRegistry.get(S);if(!k||!k._render)continue;m.ui._dirtySet?.delete(S);let R=k._child,I=k._render(k.props);if(k._child=I,R&&R._placement==="remote"||I&&I._placement==="remote"){R&&I?se(R,I,m):I?X(I,m):R&&U(R,u);continue}if(!k._parentNode&&k._refNode){let H=k._refNode.parentNode;H&&(k._parentNode=H)}if(k._parentNode){let H=Y(k._parentNode,k._refNode??null,R,I,m);H&&H!==k._refNode?k._refNode=H:H||(k._refNode=null)}}l=!1,s()}}let p=null;function y(){return p||(p=qe(E=>m.ui.render(E))),p}m.browser=Ue(),m.__registry=u,m.ui=en({ctx:m,renderByIds:c,getSelfId:E=>E?._selfId??m.ui?._selfId,dirtyBatch:r,dirtySet:d,mediaRegistry:a,popupTrackers:y().popupTrackers,scrollTrackers:y().scrollTrackers,schedulePopupRecompute:y().schedulePopupRecompute,ensurePopupListeners:y().ensurePopupListeners,destroyPopupListeners:y().destroyPopupListeners,isRendering:()=>l,isMounting:()=>f,setMounting:w,endMounting:T,registry:u}),ue(u,E=>{for(let S of[...a.keys()])if(S.startsWith(`media:${E}:`)||S===`bp:${E}`){let k=a.get(S);k?.mql&&k.handler&&k.mql.removeEventListener("change",k.handler),k?.mqls?.forEach(({mql:R,handler:I})=>R.removeEventListener("change",I)),a.delete(S)}y().cleanupTrackers(E)}),m.__rerender=()=>x(),m.app={navigate:E=>{e.mode==="hash"?window.location.hash="#"+E:window.history.pushState({},"",E),x()}};let v=null,C=!1,P=!1;function x(){P||(P=!0,queueMicrotask(()=>{P=!1,M()}))}async function M(){if(!C){C=!0;try{let E=e.getPath();if(m.route={path:E,params:m.params,query:m.query},!m.__state){let k=G(()=>{C||x()});m.__state=k;let R=m.ui.$;m.ui.$=function(){return this&&this._selfVNode?R.call(this):k}}let S=await e.execute(window.location,m,E);if(v==null){if(S){let k=i&&o.firstElementChild?(Le(o,S,m),o.firstChild):D(S,m);k&&k.parentNode!==o&&o.appendChild(k)}}else Y(o,o.firstChild,v,S,m);v=S}catch(E){if(console.error("[ui-dom] render error:",E),v==null){let S=document.createElement("div");S.className="ui-dom-error",S.textContent=`\u6E32\u67D3\u9519\u8BEF: ${E?.message??String(E)}`,o.appendChild(S)}}finally{C=!1}}}let V=()=>x();window.addEventListener("popstate",V);let L=()=>x();return e.mode==="hash"&&window.addEventListener("hashchange",L),x(),{get ctx(){return m},close(){window.removeEventListener("popstate",V),e.mode==="hash"&&window.removeEventListener("hashchange",L),v&&U(v,u),y().destroy(),u.idRegistry.clear(),o.innerHTML="",v=null}}}function Bn(e,n,t=400){let o=!1,i=()=>{o||(o=!0,e.removeEventListener("animationend",i),clearTimeout(u),n())};e.addEventListener("animationend",i);let u=setTimeout(i,t)}function Q(e,n){return Object.assign(Object.create(e),n)}function Gn(e){let n={baseURL:e?.baseURL??"",headers:{"Content-Type":"application/json",...e?.headers}},t=e?.onRequest,o=e?.onResponse,i=e?.timeout??0;async function u(r,d,a,l){let f=n.baseURL+d,g={method:r,headers:{...n.headers,...l?.headers}},w=e?.token?.();w&&!g.headers.Authorization&&(g.headers.Authorization=`Bearer ${w}`);let T=i>0,m=!!l?.signal,h=null,b=null;(T||m)&&(h=new AbortController,g.signal=h.signal,T&&(b=setTimeout(()=>h.abort(new Error("Request timed out")),i)),m&&l.signal.addEventListener("abort",()=>h.abort())),a!==void 0&&r!=="GET"&&r!=="HEAD"&&(g.body=JSON.stringify(a));let N={url:f,init:g};t&&(N=t(N));try{let s=await fetch(N.url,N.init);if(o)return o(s);if(!s.ok){let y=await s.text().catch(()=>"");throw new Oe(s.status,y||s.statusText)}let c=s.headers.get("content-length");if(s.status===204||c==="0")return;let p=(s.headers.get("content-type")||"").toLowerCase();return p.includes("application/json")||p.includes("json")?s.json():s.text()}finally{b&&clearTimeout(b)}}return r=>Q(r,{api:{get:(a,l)=>u("GET",a,void 0,l),post:(a,l,f)=>u("POST",a,l,f),put:(a,l,f)=>u("PUT",a,l,f),patch:(a,l,f)=>u("PATCH",a,l,f),delete:(a,l)=>u("DELETE",a,void 0,l)}})}var Oe=class extends Error{status;body;constructor(n,t){super(`API Error ${n}: ${t}`),this.name="ApiError",this.status=n,this.body=t}};function Yn(e){try{let n=e.split(".");if(n.length!==3)return null;let t=n[1].replace(/-/g,"+").replace(/_/g,"/");return JSON.parse(atob(t))}catch{return null}}function zn(e){let n=Yn(e);return n?.exp?n.exp*1e3-3e4<Date.now():!0}function Jn(e){let n=e?.storage??localStorage,t=e?.tokenKey??"weifuwu_token",o=e?.userKey??"weifuwu_user",i=e?.refreshTokenKey??"weifuwu_refresh",u=e?.refreshEndpoint??"/api/auth/refresh";return r=>{let d=n.getItem(t),a=n.getItem(o),l={token:d,user:a?JSON.parse(a):null,get isLoggedIn(){return this.token!==null},login(f,g,w){l.token=f,l.user=g,n.setItem(t,f),n.setItem(o,JSON.stringify(g)),w&&n.setItem(i,w)},logout(){l.token=null,l.user=null,n.removeItem(t),n.removeItem(o),n.removeItem(i)},setUser(f){l.user=f,n.setItem(o,JSON.stringify(f))},async refresh(){let f=n.getItem(i);if(!f)return!1;try{let g=await fetch(u,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({refreshToken:f})});if(!g.ok)return l.logout(),!1;let w=await g.json();return l.token=w.token,n.setItem(t,w.token),w.refreshToken&&n.setItem(i,w.refreshToken),!0}catch{return!1}}};return d&&zn(d)&&l.refresh().catch(()=>{}),Q(r,{auth:l})}}function Xn(e={}){let n=e.url??"/ws",t=e.reconnectInterval??3e3,o=e.maxReconnect??10,i=e.pingInterval??3e4,u=e.pingTimeout??1e4;return r=>{let d=new Set,a=null,l=0,f=null,g=null,w=null,T=!1,m={isConnected:!1,onMessage:c=>(d.add(c),()=>{d.delete(c)}),send:c=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify(c))},_connect:h,close:()=>{T=!0,s(),a?.close(),a=null,m.isConnected=!1}};async function h(){if(!T)try{a=new WebSocket(n),a.onopen=()=>{m.isConnected=!0,l=0,b()},a.onmessage=c=>{try{let p=JSON.parse(c.data);for(let y of d)y(p)}catch{}N()},a.onclose=()=>{m.isConnected=!1,s(),!T&&l<o&&(l++,f=setTimeout(h,t*Math.min(l,5)))},a.onerror=()=>{a?.close()}}catch{T||(f=setTimeout(h,t))}}function b(){i<=0||(g=setInterval(()=>{a?.readyState===WebSocket.OPEN&&a.send(JSON.stringify({type:"ping"})),w=setTimeout(()=>{a?.close()},u)},i))}function N(){clearTimeout(w)}function s(){clearInterval(g),clearTimeout(w),clearTimeout(f)}return h(),Q(r,{ws:m})}}function ge(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}var Qn=new Set(["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"]);function Zn(e){return typeof e=="string"?e:Array.isArray(e)?e.filter(Boolean).join(" "):e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n).map(([n])=>n).join(" "):""}function et(e){return typeof e=="string"?e:e&&typeof e=="object"?Object.entries(e).filter(([,n])=>n!=null).map(([n,t])=>`${n}:${typeof t=="number"?t+"px":String(t)}`).join(";"):""}function un(e,n){let t=new Set,o={$:()=>G(()=>{}),dirty:()=>{},render:()=>{},selfId:r=>{if(t.has(r))throw new Error(`[weifuwu] Duplicate component ID: "${r}"`);t.add(r)},useMedia:()=>{},useBreakpoint:()=>{},usePopupPosition:()=>({top:0,left:0,refresh:()=>{}}),useHoverCapable:()=>!1,useVisualViewport:()=>({height:0,offsetTop:0,keyboardOpen:!1}),useLongPress:()=>({}),useInView:()=>({isIn:!1,ready:!1,observe:()=>{},refresh:()=>{},disconnect:()=>{}}),useScrollPosition:()=>({y:0,refresh:()=>{}}),useStableRef:r=>d=>{d&&r?.(d)},useGlobalKey:()=>()=>{},useReducedMotion:()=>!1,useAnimationEnd:()=>()=>{},useTween:r=>{let d={value:r,reset:a=>{d.value=a}};return d},useDrag:()=>({onPointerDown:()=>{}}),useDragDrop:()=>({dropProps:{},dragProps:{}}),useControlled:r=>({value:r.value,setValue:d=>{r.onChange?.(d)},controlled:r.value!==void 0}),useControlledInput:r=>({value:r.value,setValue:d=>{r.onChange?.(d)},controlled:r.value!==void 0,keyword:"",setKeyword:()=>{},selectedLabel:"",setSelectedLabel:()=>{}}),useOpen:r=>({get open(){return!!r.open},setOpen:d=>{r.onOpenChange?.(d)},triggerProps:{}}),useAsync:()=>({data:void 0,loading:!0,error:void 0,reload:()=>{}}),usePopup:()=>({open:!1,setOpen:()=>{},wrapProps:{},portal:()=>null,refresh:()=>{}}),usePresence:()=>({phase:"closed",ref:()=>{},sync:r=>r?"open":"closed"}),useDialog:()=>({phase:"closed",rootRef:()=>{},panelRef:()=>{},sync:r=>r?"open":"closed"}),useChat:()=>({messages:[],input:"",streaming:!1,error:null,usage:null,step:null,send:()=>{},stop:()=>{},retry:()=>{},clear:()=>{},approve:async()=>{},dispose:()=>{}})},i={activeElement:()=>null,byId:()=>null,query:()=>null,createElement:()=>null,bodyAppend:()=>{},bodyRemove:()=>{},copyText:async()=>!1,execCommand:()=>!1,selectionText:()=>null,getSelection:()=>null,queryCommandState:()=>!1,queryCommandValue:()=>"",viewportHeight:()=>0,scrollTop:()=>0,hash:()=>"",setHash:()=>{},timeout:()=>0,rootElement:()=>null,storageGet:()=>null,storageSet:()=>{}},u=Object.create(e??{});return u.ui=o,u.browser=i,u.data={async get(r,d){if(n.has(r))return n.get(r);if(!d)return;let a=await d();return n.set(r,a),a},set(r,d){n.set(r,d)},has(r){return n.has(r)}},u}async function J(e,n){if(e==null||typeof e=="boolean")return"";if(typeof e=="string"||typeof e=="number")return ge(String(e));if(Array.isArray(e)){let l="";for(let f of e)l+=await J(f,n);return l}let t=e;if(t.type===j||t.type===$)return J(t.props?.children,n);if(typeof t.type=="function"){let l;if(z(t.type)){if(l=await t.type(n),typeof l!="function")throw new Error(`asyncComponent factory <${t.type.name||"anonymous"}> must return a Component (initProps, ctx) => (props) => VNode.`)}else l=t.type;let f=Object.create(n),g=l(t.props??{},f);if(typeof g!="function")throw new Error(`Component ${t.type.name||"anonymous"} must return a render function. Use (init_props, ctx) => (props) => VNode pattern.`);return J(g(t.props??{}),f)}let o=t.type,i=t.props??{},u=[],r;for(let[l,f]of Object.entries(i))if(!(l==="children"||l==="key")&&l!=="ref"&&!(l.startsWith("on")&&typeof f=="function")){if(l==="innerHTML"){r=String(f??"");continue}if(l==="class"||l==="className"){let g=Zn(f);g&&u.push(` class="${ge(g)}"`);continue}if(l==="style"&&f&&typeof f=="object"){u.push(` style="${ge(et(f))}"`);continue}if(f===!0){u.push(` ${l}`);continue}f===!1||f==null||u.push(` ${l}="${ge(String(f))}"`)}let d=u.join("");if(Qn.has(o))return`<${o}${d}>`;if(r!==void 0)return`<${o}${d}>${r}</${o}>`;let a=await J(i.children,n);return`<${o}${d}>${a}</${o}>`}async function nt(e,n,t,o={}){let i=o.data??new Map,u=un(t,i);return await J({type:e,props:n??{},key:void 0},u)}function dn(e){return`<script>window.__DATA__=${JSON.stringify(Object.fromEntries(e)).replace(/</g,"\\u003c")};<\/script>`}async function tt(e,n){let t=new Map,i=un({params:{},query:{}},t),u=n.url.split("?")[0].split("#")[0],r=e.match(u);i.params=r.params,i.query=Object.fromEntries(new URLSearchParams(n.url.split("?")[1]??""));let d=new URL(n.url.startsWith("http")?n.url:`http://localhost${n.url.startsWith("/")?n.url:"/"+n.url}`),a=await e.execute(d,i,u),l=await J(a,i),f=dn(t),g=r.title??n.title??"",w=n.rootId??"root",T=`<!DOCTYPE html>
7
+ <html lang="${n.lang??"zh-CN"}">
8
+ <head>
9
+ <meta charset="UTF-8">
10
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
11
+ ${g?`<title>${g}</title>`:""}
12
+ </head>
13
+ <body>
14
+ <div id="${w}">${l}</div>
15
+ ${f}
16
+ <script src="/app.js"><\/script>
17
+ </body>
18
+ </html>`;return{html:l,dataScript:f,page:T}}export{$ as Fragment,j as Portal,Ce as UIRouter,Bn as animateOut,Gn as api,Nn as asyncComponent,Jn as auth,jn as callRefCleanup,Ue as createClientBrowser,ke as createPortal,G as createReactiveState,Mn as h,Le as hydrateVNode,z as isAsyncComponent,_e as jsx,Sn as jsxDEV,Rn as jsxs,Dn as mountVNode,Y as patchValue,dn as serializeData,tt as ssrPage,nt as ssrToString,Kn as uiServe,Xn as ws};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * weifuwu/ui-dom JSX 运行时(jsxImportSource: weifuwu/ui-dom)
3
+ */
4
+ export { jsx, jsxs, jsxDEV, Fragment } from './vnode.ts';
@@ -0,0 +1 @@
1
+ var r=Symbol("Fragment");function o(e,t,n){return{type:e,props:i(t),key:n??void 0}}var s=o;function p(e,t,n){return o(e,t,n)}function i(e){if(!e)return{};let t={};for(let n of Object.keys(e))n!=="key"&&(t[n]=e[n]);return t}export{r as Fragment,o as jsx,p as jsxDEV,s as jsxs};
@@ -0,0 +1,36 @@
1
+ /**
2
+ * weifuwu/ui-dom 弹层/滚动位置跟踪系统(实例化——serve 每实例一个)
3
+ *
4
+ * 复制自 client/app.ts 闭包逻辑(createUi 依赖):scroll/resize 时重算弹层
5
+ * fixed 坐标(rAF 节流)+ 滚动位置跟踪。createApp 与 uiServe 各自持有实例。
6
+ */
7
+ import type { PopupPosition } from './types.ts';
8
+ export interface PopupTrackerEntry {
9
+ pos: PopupPosition;
10
+ getEl: () => HTMLElement | null;
11
+ isOpen: () => boolean;
12
+ compute: (rect: DOMRect) => {
13
+ top: number;
14
+ left: number;
15
+ width?: number;
16
+ };
17
+ panel?: () => HTMLElement | null;
18
+ margin: number;
19
+ }
20
+ export interface ScrollTrackerEntry {
21
+ handle: {
22
+ y: number;
23
+ };
24
+ getScroller: () => HTMLElement | Window;
25
+ }
26
+ export interface PopupTrackerSystem {
27
+ popupTrackers: Map<string, PopupTrackerEntry>;
28
+ scrollTrackers: Map<string, ScrollTrackerEntry>;
29
+ schedulePopupRecompute: () => void;
30
+ ensurePopupListeners: () => void;
31
+ destroyPopupListeners: () => void;
32
+ cleanupTrackers: (id: string) => void;
33
+ destroy: () => void;
34
+ }
35
+ /** 创建跟踪系统实例(renderByIds 用于滚动/resize 后精准刷新目标组件) */
36
+ export declare function createPopupTrackerSystem(renderByIds: (ids: string[]) => void): PopupTrackerSystem;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * weifuwu/ui-dom 注册表 — 工厂版(serve 创建局部实例,隔离于 createApp 的模块级状态)
3
+ *
4
+ * 复制自 client/registry.ts(算法相同),但**无模块级单例**——uiServe 创建实例
5
+ * 注入 ctx.__registry,render/diff/ui 经 getRegistry(ctx) 读取,与 createApp 零交叉。
6
+ */
7
+ import type { VNode, Component, AsyncComponent } from './vnode.ts';
8
+ import type { WfuiContext } from './types.ts';
9
+ type UnmountHook = (id: string) => void;
10
+ interface FactoryEntry {
11
+ promise: Promise<Component<any, any>>;
12
+ resolved?: Component<any, any>;
13
+ }
14
+ /** 注册表实例状态 */
15
+ export interface Registry {
16
+ idCounter: number;
17
+ idRegistry: Map<string, VNode>;
18
+ unmountHooks: UnmountHook[];
19
+ asyncFactoryCache: WeakMap<AsyncComponent<any, any>, FactoryEntry>;
20
+ }
21
+ /** 创建局部注册表(uiServe 每实例一个——组件 id/dirty/卸载钩子与 createApp 隔离) */
22
+ export declare function createRegistry(): Registry;
23
+ /** 从 ctx 取注入的注册表(render/diff/ui 统一入口;serve 注入 __registry) */
24
+ export declare function getRegistry(ctx: any): Registry;
25
+ /** 指定实例生成组件 ID */
26
+ export declare function nextComponentIdFor(reg: Registry): string;
27
+ /** 指定实例注册卸载钩子(组件从 idRegistry 注销时触发) */
28
+ export declare function onComponentUnmountFor(reg: Registry, hook: UnmountHook): () => void;
29
+ /** 启动 async 工厂(幂等,缓存) */
30
+ export declare function startAsyncFactory(reg: Registry, Comp: AsyncComponent, ctx: WfuiContext): FactoryEntry;
31
+ /** async 模式:await 工厂定义 */
32
+ export declare function resolveAsyncFactory(reg: Registry, Comp: AsyncComponent, ctx: WfuiContext): Promise<Component>;
33
+ /** sync 模式:工厂已解析 → 定义;未解析 → undefined */
34
+ export declare function resolveAsyncFactorySync(reg: Registry, Comp: AsyncComponent): Component | undefined;
35
+ /** 包裹 ref 回调调用——用户 ref 逻辑抛错时不中断渲染/卸载管线 */
36
+ export declare function safeCallRef(ref: Function, arg: any, phase: 'mount' | 'cleanup', name?: string): void;
37
+ /** 通知 ref 清理 + Portal 子容器清理(指定实例) */
38
+ export declare function callRefCleanupFor(input: any, reg: Registry): void;
39
+ export {};
@@ -37,5 +37,6 @@ export declare function patchPortal(oldV: VNode | null, newV: VNode, ctx: WfuiCo
37
37
  /** 展平嵌套数组 */
38
38
  export declare function flattenChildren(children: VNodeChild): VNodeChild[];
39
39
  export declare function mountVNode(container: Element, vnode: VNode, ctx: WfuiContext): void;
40
- export { callRefCleanup, idRegistry, clearAsyncComponentCache, nextComponentId } from './registry.ts';
41
40
  export { patchValue } from './diff.ts';
41
+ /** 模块级兼容(无 ctx 场景——独立清理,不影响活跃 registry) */
42
+ export declare function callRefCleanup(input: any): void;
@@ -0,0 +1,66 @@
1
+ /**
2
+ * weifuwu/ui-dom UIRouter — 纯路由(无渲染状态)
3
+ *
4
+ * 定稿架构职责划分:
5
+ * UIRouter = 路由表 + 匹配 + 中间件链(产 VNode)——不碰 DOM/渲染/状态
6
+ * serveUI = 渲染运行时(VDOM 落地:registry/createUi/renderValue/patchValue)
7
+ *
8
+ * req = window.location,res = VNode,params/query 在 ctx(serve 组装 ctx 时注入)
9
+ * handler = 异步组件:async (location, ctx) => vnode($ 有效)
10
+ * middleware = 两阶段 async:(location, ctx, children) => async (location, ctx) => vnode
11
+ * layout 与 SSR 都是中间件
12
+ */
13
+ import type { UIHandler, UIMiddleware } from './types.ts';
14
+ import type { VNode, UIContext, AppMiddleware } from './types.ts';
15
+ /** UIRouter 选项 */
16
+ export interface UIRouterOptions {
17
+ mode?: 'hash' | 'history';
18
+ }
19
+ /** 匹配结果(serve 用它执行中间件链 + handler) */
20
+ export interface RouteMatch {
21
+ handler: UIHandler;
22
+ params: Record<string, string>;
23
+ title?: string;
24
+ }
25
+ /**
26
+ * 前端路由应用 — new UIRouter()(纯路由)
27
+ */
28
+ export declare class UIRouter<C extends object = {}> {
29
+ private _routes;
30
+ private _middlewares;
31
+ /** ctx 注入中间件链(toast/confirm/notification 等——对齐后端 app.use 注入 ctx.xxx) */
32
+ private _injections;
33
+ /** 注入已完成标记(应用级 ctx——首次渲染时执行一次) */
34
+ private _injected;
35
+ private _mode;
36
+ private _notFound?;
37
+ constructor(options?: UIRouterOptions);
38
+ get mode(): 'hash' | 'history';
39
+ /** ctx 注入中间件(toast/confirm 等——(ctx) => ctx,对齐后端 app.use 注入 ctx.xxx) */
40
+ use<O extends object>(mw: AppMiddleware<any, O>): UIRouter<C & O>;
41
+ /** 渲染中间件(layout/SSR 等)——包装 children 产 vnode */
42
+ use<I extends object, O extends object>(mw: UIMiddleware<I, O>): UIRouter<C & O>;
43
+ /** 子路由挂载(= 后端 mount(path, subRouter))——独立路由树:sub 的中间件/notFound/嵌套均生效 */
44
+ use(prefix: string, sub: UIRouter): this;
45
+ /** 执行 ctx 注入链(首次渲染时一次——应用级 ctx,对齐 createApp.use 链) */
46
+ private _ensureInjected;
47
+ /** 页面路由(对齐后端 get(path, handler))——handler = 异步组件 */
48
+ get(path: string, handler: UIHandler<C>, opts?: {
49
+ title?: string;
50
+ }): this;
51
+ /** 404 */
52
+ notFound(handler: UIHandler): this;
53
+ /** 当前 URL 路径(serve 调用——mode 由 UIRouter 决定) */
54
+ getPath(): string;
55
+ private _getPath;
56
+ /** 匹配 URL → { handler, params, title }(serve 执行渲染) */
57
+ match(path: string): RouteMatch;
58
+ /**
59
+ * 子路由树处理(供 use(prefix, sub) 调用):
60
+ * 相对路径匹配 + sub 的中间件链 + sub 的 notFound——支持任意嵌套。
61
+ * 返回 VNode(无渲染——serve 落地)。
62
+ */
63
+ _handle(relPath: string, location: Location, ctx: UIContext): Promise<VNode | null>;
64
+ /** 顶层执行:中间件链 + handler → VNode(serve 调用,URL 变化时) */
65
+ execute(location: Location, ctx: UIContext, path: string): Promise<VNode | null>;
66
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * weifuwu/ui-dom serve — 渲染运行时(VDOM 落地机制)
3
+ *
4
+ * 定稿架构:serveUI = VDOM(落地,对齐后端 serve(router) = HTTP 传输)。
5
+ *
6
+ * uiServe(router, { root }) 调用时路由已全部注册——serve 负责:
7
+ * 1. 创建渲染运行时:局部 registry + createUi(19 原语)+ popup-tracker + ctx.data/browser
8
+ * 2. 监听 popstate/hashchange → router.match(params 注入)→ 中间件链 → handler → vnode
9
+ * 3. renderValue / patchValue diff/patch DOM;组件 $ dirty → renderByIds(局部 registry)
10
+ *
11
+ * 与 createApp 隔离:registry/popup-tracker/dirty 集合全部局部实例(client 零改动)。
12
+ */
13
+ import type { UIRouter } from './router.ts';
14
+ import type { WfuiContext } from './types.ts';
15
+ /** uiServe 选项 */
16
+ export interface UIServeOptions {
17
+ root: string | Element;
18
+ hydrate?: boolean;
19
+ }
20
+ /** serve 句柄 */
21
+ export interface UIServeHandle<C extends object = {}> {
22
+ /** 释放全部资源(监听/渲染状态/注册表) */
23
+ close(): void;
24
+ /** 当前 ctx(调试/测试用)——含 UIRouter ctx 注入的类型扩展 */
25
+ ctx: WfuiContext & C;
26
+ }
27
+ /** uiServe — 绑定唯一根节点 + URL 驱动渲染(= VDOM 落地,对齐 serve(router)) */
28
+ export declare function uiServe<RC extends object = {}>(router: UIRouter<RC>, options: UIServeOptions): UIServeHandle<RC>;