weifuwu 0.87.0 → 0.89.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 +111 -135
- package/dist/client/components/ActionSheet/ActionSheet.d.ts +1 -1
- package/dist/client/components/AiChat/AiChat.d.ts +3 -4
- package/dist/client/components/ChatInput/ChatInput.d.ts +5 -0
- package/dist/client/components/CitationCard/CitationCard.d.ts +1 -1
- package/dist/client/components/Command/Command.d.ts +1 -1
- package/dist/client/components/ContextMenu/ContextMenu.d.ts +1 -1
- package/dist/client/components/DatePicker/DatePicker.d.ts +1 -1
- package/dist/client/components/Dropdown/Dropdown.d.ts +1 -1
- package/dist/client/components/Editor/model/html.d.ts +10 -0
- package/dist/client/components/ImageCropper/ImageCropper.d.ts +6 -2
- package/dist/client/components/Menu/Menu.d.ts +1 -1
- package/dist/client/components/NavMenu/NavMenu.d.ts +1 -1
- package/dist/client/components/Popconfirm/Popconfirm.d.ts +1 -1
- package/dist/client/components/SlideCanvas/SlideCanvas.d.ts +1 -1
- package/dist/client/components/Tour/Tour.d.ts +1 -1
- package/dist/client/components/TreeSelect/TreeSelect.d.ts +1 -1
- package/dist/client/components/index.js +41 -41
- package/dist/client/components/style.css +298 -644
- package/dist/client/layout/weifuwu-layout.css +286 -640
- package/dist/client/vdom/browser/Browser.d.ts +2 -0
- package/dist/client/vdom/commands.d.ts +4 -1
- package/dist/client/vdom/context/UIContext.d.ts +8 -0
- package/dist/client/vdom/core/diff/attrs.d.ts +10 -2
- package/dist/client/vdom/core/field/attributes.d.ts +12 -0
- package/dist/client/vdom/core/field/events.d.ts +8 -0
- package/dist/client/vdom/core/field/input-sync.d.ts +14 -0
- package/dist/client/vdom/core/field/key.d.ts +3 -0
- package/dist/client/vdom/core/field/props.d.ts +13 -1
- package/dist/client/vdom/core/field/ref.d.ts +6 -0
- package/dist/client/vdom/core/field/style.d.ts +7 -1
- package/dist/client/vdom/core/node/component.d.ts +3 -4
- package/dist/client/vdom/core/node/native.d.ts +6 -1
- package/dist/client/vdom/core/patch/index.d.ts +24 -1
- package/dist/client/vdom/core/patch/processors.d.ts +8 -1
- package/dist/client/vdom/core/protocol.d.ts +45 -0
- package/dist/client/vdom/core/router.d.ts +7 -0
- package/dist/client/vdom/core/ssr/absorb.d.ts +31 -4
- package/dist/client/vdom/core/transform/index.d.ts +6 -6
- package/dist/client/vdom/core/v2/cycle.d.ts +54 -0
- package/dist/client/vdom/core/v2/diff.d.ts +80 -0
- package/dist/client/vdom/core/v2/integrate.d.ts +24 -0
- package/dist/client/vdom/core/v2/render.d.ts +28 -0
- package/dist/client/vdom/core/v2/schedule.d.ts +33 -0
- package/dist/client/vdom/core/v2/serve.d.ts +4 -0
- package/dist/client/vdom/core/v2/spy.d.ts +21 -0
- package/dist/client/vdom/core/v2/ssr.d.ts +14 -0
- package/dist/client/vdom/core/vnode.d.ts +9 -6
- package/dist/client/vdom/dev/error-counter.d.ts +27 -0
- package/dist/client/vdom/dev/render-health.d.ts +60 -0
- package/dist/client/vdom/hooks/chat.d.ts +32 -5
- package/dist/client/vdom/hooks/drag-media.d.ts +3 -1
- package/dist/client/vdom/hooks/env.d.ts +32 -0
- package/dist/client/vdom/hooks/popup-manager.d.ts +21 -0
- package/dist/client/vdom/hooks/popup.d.ts +4 -1
- package/dist/client/vdom/hooks/stable.d.ts +4 -0
- package/dist/client/vdom/hooks/use-observable.d.ts +13 -0
- package/dist/client/vdom/index.d.ts +14 -6
- package/dist/client/vdom/index.js +4 -7
- package/dist/client/vdom/jsx-runtime.js +1 -1
- package/dist/client/vdom/middlewares/api.d.ts +8 -0
- package/dist/client/vdom/middlewares/auth-i18n.d.ts +7 -0
- package/dist/client/vdom/middlewares/ws.d.ts +41 -1
- package/dist/client/vdom/observable/index.d.ts +13 -0
- package/dist/client/vdom/observable/observable.d.ts +26 -0
- package/dist/client/vdom/observable/operators.d.ts +76 -0
- package/dist/client/vdom/observable/sources.d.ts +54 -0
- package/dist/client/vdom/observable/types.d.ts +45 -0
- package/dist/client/vdom/store.d.ts +17 -2
- package/dist/client/vdom/testing.js +2 -2
- package/dist/server/ai/agent.d.ts +18 -0
- package/dist/server/ai/client.d.ts +14 -2
- package/dist/server/ai/contracts.d.ts +2 -2
- package/dist/server/ai/sse.d.ts +6 -0
- package/dist/server/core/collect.d.ts +31 -0
- package/dist/server/core/error-counter.d.ts +11 -0
- package/dist/server/core/hub.d.ts +2 -0
- package/dist/server/core/router.d.ts +12 -9
- package/dist/server/db/contracts.d.ts +24 -0
- package/dist/server/db/memory-redis.d.ts +3 -4
- package/dist/server/db/memory-sql.d.ts +20 -4
- package/dist/server/db/postgres-server.d.ts +2 -0
- package/dist/server/db/query.d.ts +21 -0
- package/dist/server/db/redis-server.d.ts +4 -2
- package/dist/server/db/sql-parser.d.ts +2 -1
- package/dist/server/email/index.d.ts +2 -0
- package/dist/server/index.d.ts +4 -1
- package/dist/server/index.js +3927 -1982
- package/dist/server/messager/index.d.ts +21 -2
- package/dist/server/middleware/compress.d.ts +25 -0
- package/dist/server/ui/index.d.ts +8 -1
- package/dist/server/user/index.d.ts +4 -0
- package/dist/shared/router/chain.d.ts +9 -0
- package/dist/shared/router/context.d.ts +35 -0
- package/dist/shared/router/ctx-fields.d.ts +20 -0
- package/dist/shared/router/pipeline.d.ts +70 -0
- package/dist/shared/router/trie.d.ts +11 -3
- package/dist/shared/router/types.d.ts +23 -0
- package/docs/style-guide.md +44 -41
- package/package.json +13 -10
- package/content/apps/admin.md +0 -55
- package/content/apps/agent-platform.md +0 -35
- package/content/apps/auth.md +0 -49
- package/content/apps/multi.md +0 -44
- package/content/apps/todo.md +0 -51
- package/content/backend/ai.md +0 -28
- package/content/backend/auth.md +0 -20
- package/content/backend/email.md +0 -23
- package/content/backend/graphql.md +0 -23
- package/content/backend/http.md +0 -23
- package/content/backend/limit.md +0 -23
- package/content/backend/middleware.md +0 -17
- package/content/backend/queue.md +0 -23
- package/content/backend/redis.md +0 -26
- package/content/backend/router.md +0 -23
- package/content/backend/schedule.md +0 -23
- package/content/backend/sql.md +0 -27
- package/content/backend/sse.md +0 -26
- package/content/backend/ws.md +0 -26
- package/content/capabilities/app-node.md +0 -21
- package/content/capabilities/data.md +0 -21
- package/content/capabilities/events.md +0 -21
- package/content/capabilities/hooks.md +0 -22
- package/content/capabilities/i18n.md +0 -21
- package/content/capabilities/popup.md +0 -21
- package/content/capabilities/render-only.md +0 -23
- package/content/capabilities/router.md +0 -22
- package/content/capabilities/self-id.md +0 -21
- package/content/capabilities/store.md +0 -21
- package/content/capabilities/theme.md +0 -21
- package/content/capabilities/two-phase.md +0 -21
- package/content/components/accordion.md +0 -50
- package/content/components/actionsheet.md +0 -46
- package/content/components/affix.md +0 -51
- package/content/components/aichat.md +0 -57
- package/content/components/alert.md +0 -52
- package/content/components/alertgroup.md +0 -45
- package/content/components/anchor.md +0 -52
- package/content/components/app.md +0 -37
- package/content/components/approvalcard.md +0 -56
- package/content/components/appshell.md +0 -50
- package/content/components/aspectratio.md +0 -47
- package/content/components/authpage.md +0 -61
- package/content/components/autocomplete-v2.md +0 -40
- package/content/components/autocomplete.md +0 -56
- package/content/components/avatar.md +0 -51
- package/content/components/avatargroup.md +0 -47
- package/content/components/backtop.md +0 -53
- package/content/components/badge.md +0 -55
- package/content/components/breadcrumb.md +0 -49
- package/content/components/button.md +0 -63
- package/content/components/calendar-v2.md +0 -40
- package/content/components/calendar.md +0 -50
- package/content/components/card.md +0 -58
- package/content/components/carousel.md +0 -52
- package/content/components/cascader-v2.md +0 -39
- package/content/components/cascader.md +0 -54
- package/content/components/chart.md +0 -53
- package/content/components/chatinput.md +0 -63
- package/content/components/checkbox.md +0 -51
- package/content/components/checkboxgroup.md +0 -52
- package/content/components/citationcard.md +0 -48
- package/content/components/codeblock.md +0 -48
- package/content/components/codeeditor.md +0 -47
- package/content/components/collapse.md +0 -49
- package/content/components/colorpicker.md +0 -50
- package/content/components/command.md +0 -50
- package/content/components/confirm.md +0 -57
- package/content/components/contextmenu.md +0 -48
- package/content/components/copybutton.md +0 -51
- package/content/components/datepicker.md +0 -52
- package/content/components/descriptions-v2.md +0 -39
- package/content/components/descriptions.md +0 -52
- package/content/components/diffview-v2.md +0 -39
- package/content/components/diffview.md +0 -50
- package/content/components/divider.md +0 -48
- package/content/components/drawer.md +0 -55
- package/content/components/dropdown.md +0 -53
- package/content/components/editor.md +0 -49
- package/content/components/emptystate.md +0 -51
- package/content/components/exportcsv.md +0 -38
- package/content/components/field.md +0 -54
- package/content/components/filepreview-office.md +0 -37
- package/content/components/filepreview.md +0 -49
- package/content/components/filetree.md +0 -56
- package/content/components/fileupload-v2.md +0 -39
- package/content/components/fileupload.md +0 -57
- package/content/components/floatbutton.md +0 -52
- package/content/components/form-v2.md +0 -41
- package/content/components/form.md +0 -60
- package/content/components/grid.md +0 -51
- package/content/components/highlight-v2.md +0 -39
- package/content/components/highlight.md +0 -46
- package/content/components/hovercard.md +0 -51
- package/content/components/icon.md +0 -50
- package/content/components/imagecropper.md +0 -45
- package/content/components/img.md +0 -56
- package/content/components/infinitescroll-v2.md +0 -40
- package/content/components/infinitescroll.md +0 -54
- package/content/components/input.md +0 -65
- package/content/components/inputnumber.md +0 -58
- package/content/components/inview.md +0 -56
- package/content/components/jsonschemaform.md +0 -53
- package/content/components/jsonviewer-v2.md +0 -39
- package/content/components/jsonviewer.md +0 -49
- package/content/components/kanban.md +0 -46
- package/content/components/label.md +0 -48
- package/content/components/layout.md +0 -54
- package/content/components/layoutcontent.md +0 -43
- package/content/components/layoutheader.md +0 -43
- package/content/components/layoutsider.md +0 -43
- package/content/components/link.md +0 -52
- package/content/components/list.md +0 -44
- package/content/components/loading.md +0 -45
- package/content/components/logviewer-v2.md +0 -39
- package/content/components/logviewer.md +0 -53
- package/content/components/markdown.md +0 -51
- package/content/components/markdowneditor.md +0 -47
- package/content/components/math.md +0 -42
- package/content/components/mentions-v2.md +0 -39
- package/content/components/mentions.md +0 -52
- package/content/components/menu.md +0 -56
- package/content/components/menubar.md +0 -44
- package/content/components/messagebubble.md +0 -50
- package/content/components/modal.md +0 -59
- package/content/components/navmenu.md +0 -47
- package/content/components/notification.md +0 -51
- package/content/components/pageheader.md +0 -53
- package/content/components/pagination.md +0 -49
- package/content/components/paragraph.md +0 -45
- package/content/components/passwordinput.md +0 -57
- package/content/components/pininput-v2.md +0 -39
- package/content/components/pininput.md +0 -50
- package/content/components/pipeline.md +0 -49
- package/content/components/popconfirm.md +0 -58
- package/content/components/popover.md +0 -61
- package/content/components/progressbar.md +0 -50
- package/content/components/prompttemplate.md +0 -49
- package/content/components/qrcode.md +0 -50
- package/content/components/radiogroup.md +0 -53
- package/content/components/rate.md +0 -53
- package/content/components/reasoningblock.md +0 -47
- package/content/components/relationgraph.md +0 -52
- package/content/components/resizable.md +0 -53
- package/content/components/result.md +0 -49
- package/content/components/scrollbar.md +0 -49
- package/content/components/searchinput.md +0 -51
- package/content/components/segmentedcontrol.md +0 -59
- package/content/components/select-searchable.md +0 -47
- package/content/components/select.md +0 -66
- package/content/components/sessionlist.md +0 -52
- package/content/components/sheetgrid.md +0 -44
- package/content/components/skeleton.md +0 -55
- package/content/components/slidecanvas.md +0 -44
- package/content/components/slider.md +0 -62
- package/content/components/sortablelist.md +0 -39
- package/content/components/space.md +0 -52
- package/content/components/sparkline.md +0 -52
- package/content/components/statcard-countdown.md +0 -39
- package/content/components/statcard.md +0 -56
- package/content/components/steps.md +0 -48
- package/content/components/switch.md +0 -50
- package/content/components/tabbar.md +0 -45
- package/content/components/table-v2.md +0 -40
- package/content/components/table.md +0 -66
- package/content/components/tabs.md +0 -56
- package/content/components/tag.md +0 -51
- package/content/components/tagsinput-v2.md +0 -39
- package/content/components/tagsinput.md +0 -54
- package/content/components/text.md +0 -45
- package/content/components/textarea.md +0 -57
- package/content/components/themeswitch.md +0 -69
- package/content/components/timeline.md +0 -50
- package/content/components/title.md +0 -45
- package/content/components/toast.md +0 -52
- package/content/components/toggle-togglegroup.md +0 -52
- package/content/components/togglegroup.md +0 -47
- package/content/components/toolcallcard.md +0 -51
- package/content/components/tooltip.md +0 -50
- package/content/components/tour.md +0 -50
- package/content/components/transfer.md +0 -52
- package/content/components/tree-v2.md +0 -39
- package/content/components/tree.md +0 -59
- package/content/components/treeselect.md +0 -54
- package/content/components/typography.md +0 -51
- package/content/components/videoplayer.md +0 -52
- package/content/components/virtuallist.md +0 -52
- package/content/components/virtualtable-v2.md +0 -39
- package/content/components/virtualtable.md +0 -55
- package/content/components/watermark.md +0 -53
- package/content/components/wave.md +0 -43
- package/content/guides/ai-chat-family.md +0 -24
- package/content/guides/choose.md +0 -67
- package/content/guides/component-model.md +0 -32
- package/content/guides/component-standards.md +0 -123
- package/content/guides/components-guide.md +0 -813
- package/content/guides/custom-component.md +0 -321
- package/content/guides/data-guide.md +0 -281
- package/content/guides/file-preview-family.md +0 -18
- package/content/guides/frontend.md +0 -968
- package/content/guides/layout-choice.md +0 -64
- package/content/guides/layout-guide.md +0 -241
- package/content/guides/middleware.md +0 -459
- package/content/guides/mobile-guide.md +0 -105
- package/content/guides/page-building.md +0 -98
- package/content/guides/production.md +0 -37
- package/content/guides/quality.md +0 -60
- package/content/guides/realtime-guide.md +0 -296
- package/content/guides/render-only.md +0 -44
- package/content/guides/saas-guide.md +0 -253
- package/content/guides/server-guide.md +0 -359
- package/content/guides/start.md +0 -41
- package/content/guides/styling.md +0 -154
- package/content/guides/ui-dom-guide.md +0 -157
- package/content/index.json +0 -4344
- package/content/index.md +0 -181
- package/content/layout/align.md +0 -20
- package/content/layout/anchor.md +0 -19
- package/content/layout/app-shell.md +0 -23
- package/content/layout/border.md +0 -20
- package/content/layout/center.md +0 -19
- package/content/layout/cluster.md +0 -19
- package/content/layout/container.md +0 -19
- package/content/layout/fill.md +0 -19
- package/content/layout/grid.md +0 -19
- package/content/layout/hidden.md +0 -22
- package/content/layout/layer.md +0 -19
- package/content/layout/position.md +0 -22
- package/content/layout/row.md +0 -23
- package/content/layout/safe-area.md +0 -20
- package/content/layout/scroll.md +0 -21
- package/content/layout/spacing.md +0 -22
- package/content/layout/split.md +0 -19
- package/content/layout/stack.md +0 -19
- package/content/layout/surface.md +0 -23
- package/content/layout/text.md +0 -22
- package/content/patterns/app-shell.md +0 -34
- package/content/patterns/dashboard.md +0 -36
- package/content/patterns/data-screen.md +0 -30
- package/content/patterns/detail-page.md +0 -31
- package/content/patterns/docs.md +0 -34
- package/content/patterns/focus-task.md +0 -34
- package/content/patterns/landing.md +0 -35
- package/content/patterns/list-page.md +0 -32
- package/content/patterns/mobile.md +0 -31
- package/content/patterns/settings-page.md +0 -33
- package/content/patterns/workspace.md +0 -32
- package/dist/cli/content-sync.test.d.ts +0 -1
- package/dist/cli/docs-cli.test.d.ts +0 -1
- package/dist/cli/docs.d.ts +0 -2
- package/dist/cli/docs.mjs +0 -10961
- package/dist/client/vdom/core/build.d.ts +0 -36
- package/dist/client/vdom/core/diff/children.d.ts +0 -29
- package/dist/client/vdom/core/diff/index.d.ts +0 -22
- package/dist/client/vdom/core/diff/output.d.ts +0 -30
- package/dist/client/vdom/core/diff/same.d.ts +0 -22
- package/dist/client/vdom/core/serve.d.ts +0 -75
- package/dist/client/vdom/core/ssr/index.d.ts +0 -25
- package/examples/apps/admin/README.md +0 -23
- package/examples/apps/admin/api.ts +0 -27
- package/examples/apps/admin/app.tsx +0 -144
- package/examples/apps/admin/main.tsx +0 -8
- package/examples/apps/admin/server.ts +0 -37
- package/examples/apps/auth/README.md +0 -23
- package/examples/apps/auth/api.ts +0 -49
- package/examples/apps/auth/app.tsx +0 -137
- package/examples/apps/auth/main.tsx +0 -8
- package/examples/apps/auth/server.ts +0 -37
- package/examples/apps/multi/README.md +0 -23
- package/examples/apps/multi/app.tsx +0 -83
- package/examples/apps/multi/main.tsx +0 -8
- package/examples/apps/multi/server.ts +0 -33
- package/examples/apps/todo/README.md +0 -23
- package/examples/apps/todo/api.ts +0 -26
- package/examples/apps/todo/app.tsx +0 -128
- package/examples/apps/todo/main.tsx +0 -9
- package/examples/apps/todo/server.ts +0 -39
- package/examples/hello-world/README.md +0 -9
- package/examples/hello-world/client.ts +0 -14
- package/examples/hello-world/routes.tsx +0 -26
- package/examples/hello-world/server.ts +0 -46
- package/examples/patterns/AppShell.tsx +0 -224
- package/examples/patterns/Dashboard.tsx +0 -153
- package/examples/patterns/DataScreen.tsx +0 -104
- package/examples/patterns/DetailPage.tsx +0 -79
- package/examples/patterns/Docs.tsx +0 -105
- package/examples/patterns/FocusTask.tsx +0 -67
- package/examples/patterns/Landing.tsx +0 -90
- package/examples/patterns/ListPage.tsx +0 -77
- package/examples/patterns/Mobile.tsx +0 -154
- package/examples/patterns/SettingsPage.tsx +0 -98
- package/examples/patterns/SplitWorkspace.tsx +0 -113
|
@@ -36,6 +36,8 @@ export interface Browser {
|
|
|
36
36
|
/** 事件监听(全局——组件层统一入口) */
|
|
37
37
|
addEventListener(type: string, fn: (e: any) => void, options?: any): void;
|
|
38
38
|
removeEventListener(type: string, fn: (e: any) => void, options?: any): void;
|
|
39
|
+
/** 页面刷新(location.reload——应用层重试/回滚后刷新) */
|
|
40
|
+
reload(): void;
|
|
39
41
|
/** 滚动 */
|
|
40
42
|
scrollTo(y: number): void;
|
|
41
43
|
/** 当前滚动量(scrollingElement 优先——headless 漂移防护) */
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
* 使用:应用装配(main.tsx)注入 ctx——`ctx.toast('...')` 任意位置调用。
|
|
12
12
|
*/
|
|
13
13
|
export type ToastType = 'success' | 'error' | 'info' | 'warning';
|
|
14
|
-
/** 命令式轻提示(vdom 引擎渲染——自动消失——独立容器)
|
|
14
|
+
/** 命令式轻提示(vdom 引擎渲染——自动消失——独立容器)
|
|
15
|
+
* **自动消失定时器上流(波次 6——隐式时序歼灭)**:setTimeout 裸调用 →
|
|
16
|
+
* create<number>((obs) => { obs.next(1); obs.complete(); return () => {} }).pipe(delay(duration))——生命周期在流上——不可达的裸
|
|
17
|
+
* timer 消除(未来 close 面可直接 takeUntil——取消语义就位) */
|
|
15
18
|
export declare function toast(message: string, type?: ToastType, duration?: number): void;
|
|
16
19
|
/** 命令式注入(应用装配——ctx.toast) */
|
|
17
20
|
export declare function injectCommands<C extends Record<string, unknown>>(ctx: C): C & {
|
|
@@ -54,6 +54,14 @@ export interface UIContext {
|
|
|
54
54
|
ui: Ui;
|
|
55
55
|
/** 路由参数(页面组件——UIRouter 注入) */
|
|
56
56
|
params?: Record<string, string>;
|
|
57
|
+
/** 查询参数(UIRouter 注入——Object.fromEntries(searchParams)——随渲染替换) */
|
|
58
|
+
query?: Record<string, string>;
|
|
59
|
+
/** 路由上下文(UIRouter resolve 注入——path/params/query 三面——应用消费单点) */
|
|
60
|
+
route?: {
|
|
61
|
+
path: string;
|
|
62
|
+
params: Record<string, string>;
|
|
63
|
+
query: Record<string, string>;
|
|
64
|
+
};
|
|
57
65
|
/** 国际化(middlewares i18n 注入——可选——组件读组件文案面) */
|
|
58
66
|
i18n?: import('../middlewares/auth-i18n.ts').I18nState;
|
|
59
67
|
/** 中间件注入面(api/auth/ws/i18n...——可选链消费) */
|
|
@@ -6,5 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import type { VNode } from '../vnode.ts';
|
|
8
8
|
import type { Command } from '../command/index.ts';
|
|
9
|
-
/** 属性精准 diff(值比较——只发变化的键;函数面引用比较——prev 传递)
|
|
10
|
-
|
|
9
|
+
/** 属性精准 diff(值比较——只发变化的键;函数面引用比较——prev 传递)
|
|
10
|
+
*
|
|
11
|
+
* **表单控件 value 特判(2027-09——输入残留实证)**:opts.formControl=true
|
|
12
|
+
* 时 value 键**总是发**(即使渲染树新旧等值)——用户打字/IME 直改 DOM
|
|
13
|
+
* 值(渲染树从不感知——打字零渲染类优化)——清空到 '' 时 diff 的旧渲染
|
|
14
|
+
* 树值可能同为 '' → 不发 → DOM 残留旧文本——总是发 + patch 端现值比较
|
|
15
|
+
* (同值不上 DOM——无副作用;异值必写——程序化清空/回流修复) */
|
|
16
|
+
export declare function diffAttrs(oldV: VNode, newV: VNode, id: string, emitCommand: (cmd: Command) => void, opts?: {
|
|
17
|
+
formControl?: boolean;
|
|
18
|
+
}): void;
|
|
@@ -11,5 +11,17 @@
|
|
|
11
11
|
*/
|
|
12
12
|
/** enumerated 属性白名单(HTML 规范——空字符串语义非 true) */
|
|
13
13
|
export declare const ENUMERATED_KEYS: Set<string>;
|
|
14
|
+
/**
|
|
15
|
+
* aria-* 枚举语义属性布尔归一(ReasoningBlock CDD 实证——v1 修复 v2 迁移丢失——回归补)
|
|
16
|
+
*
|
|
17
|
+
* aria-* 是枚举语义属性(同 draggable)——boolean 必须显式 'true'/'false':
|
|
18
|
+
* boolean attribute 空字符串分支会把 aria-expanded: true 落成 aria-expanded=""
|
|
19
|
+
* (读屏语义 = false——可访问性失效);v === false 被移除同属错误
|
|
20
|
+
* (aria-expanded=false 与无属性语义不同面——状态不可丢失)。
|
|
21
|
+
* **单一实现源**:客户端 applyAttribute 与 SSR attrsToHtml 共用本判定。
|
|
22
|
+
*
|
|
23
|
+
* @returns 'true' / 'false'(命中 aria 布尔)或 null(非 aria 布尔——走原分支)
|
|
24
|
+
*/
|
|
25
|
+
export declare function ariaBoolValue(key: string, value: unknown): string | null;
|
|
14
26
|
/** attribute 通道——单键应用 */
|
|
15
27
|
export declare function applyAttribute(el: HTMLElement, key: string, value: unknown): void;
|
|
@@ -39,12 +39,20 @@ export declare class EventRegistry {
|
|
|
39
39
|
* 与 remove(nodeId)(全子树删除)区分——只删一个 (nodeId, event) 对 */
|
|
40
40
|
removeEvent(nodeId: string, event: string): void;
|
|
41
41
|
/** 子树清理(id 前缀匹配——remove/done 卸载指令) */
|
|
42
|
+
/** 子树删除(全量前缀扫描——**P1 性能升级前**的 O(N²) 路径——保留供
|
|
43
|
+
* 非 procRemove 调用方(dispose 等)——proc 消费端改用 removeOne 循环) */
|
|
42
44
|
remove(nodeId: string): void;
|
|
45
|
+
/** O(1) 单个节点删除(**P1 性能升级(2027-09——admin 全量 59s 实证)**:
|
|
46
|
+
* procRemove 子树循环逐条调用——替代 remove(全量前缀扫描 × 16k 条
|
|
47
|
+
* = O(N²))——procDone 同步改造) */
|
|
48
|
+
removeOne(nodeId: string): void;
|
|
43
49
|
/** 根监听动态注册(document 捕获——首次绑定某事件类型——容器过滤可达) */
|
|
44
50
|
private ensureRoot;
|
|
45
51
|
/** 分发(模拟冒泡——target 向上祖先链查表——currentTarget 还原——
|
|
46
52
|
* handler 内 stopPropagation 停止向上) */
|
|
47
53
|
private dispatch;
|
|
54
|
+
/** **清表(监听保留——resetRoot 整树替换式重置用)** */
|
|
55
|
+
clear(): void;
|
|
48
56
|
/** 卸载清理(移除全部根监听 + 清表)——状态机迁移:active → disposed */
|
|
49
57
|
dispose(): void;
|
|
50
58
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom core/field — input-sync(输入 DOM 组合态跟踪——IME 安全)
|
|
3
|
+
*
|
|
4
|
+
* 背景(2027-09——value 键 DOM 脱节修复的配套):diff 对表单控件 value
|
|
5
|
+
* 总是发 setProp——patch 写 DOM 前必须避开 **IME 组合中**(composition
|
|
6
|
+
* 期间渲染树 value = 组合前——强写会打断输入法候选——中文输入法中断)。
|
|
7
|
+
* 机制:document 捕获监听 composition 事件 → 组合中的元素 WeakSet——
|
|
8
|
+
* patch 写 value 前查询(组合中跳过——组合结束后的渲染自然写回)。
|
|
9
|
+
*
|
|
10
|
+
* 零泄漏(WeakSet——元素可回收);模块级单例(document 唯一——懒挂
|
|
11
|
+
* 首次需要时——多次创建幂等)。
|
|
12
|
+
*/
|
|
13
|
+
/** 输入是否处于 IME 组合中(compositionstart ~ compositionend) */
|
|
14
|
+
export declare function isComposingEl(doc: Document, el: HTMLElement): boolean;
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
* (数组长度变化 + 无 key 组件项 → dev error)在 diff 层消费
|
|
11
11
|
*/
|
|
12
12
|
export declare const KEY = "key";
|
|
13
|
+
/** key 归一化(单一实现源——jsx 显式 key 参数与 props 路径同入口——
|
|
14
|
+
* 数字 key 不归一 → keyedId 的 key.replace 崩(key 必须字符串)) */
|
|
15
|
+
export declare function normalizeKey(k: unknown): string | null;
|
|
13
16
|
/** key 提取(props → vnode.key——string|number 有效——其余 warn + null) */
|
|
14
17
|
export declare function extractKey(props: Record<string, unknown> | null | undefined): string | null;
|
|
15
18
|
/** 从 props 拷贝中剥离 key(h/jsx 用——props 不泄漏 key) */
|
|
@@ -11,5 +11,17 @@
|
|
|
11
11
|
export declare const PROPERTY_KEYS: Set<string>;
|
|
12
12
|
/** 是否走 property 通道 */
|
|
13
13
|
export declare function isPropertyKey(key: string): boolean;
|
|
14
|
-
/** property 应用(值直接赋给 DOM 节点属性)
|
|
14
|
+
/** property 应用(值直接赋给 DOM 节点属性)
|
|
15
|
+
* **undefined 分区语义(2027-08——v2 直连 + v1 JSON 编解码等价对齐)**:
|
|
16
|
+
* - value 类(value/defaultValue/innerHTML/textContent/defaultChecked——DOM
|
|
17
|
+
* 现值是唯一来源——§5.3 非受控)→ 不写(保持现值——防 "undefined" 污染
|
|
18
|
+
* ——SearchInput 非受控实证)
|
|
19
|
+
* - 布尔态(disabled/checked/selected/readOnly/multiple/required/…)→
|
|
20
|
+
* false(解绑——Transfer 移到右侧按钮 disabled 残留实证——v1 JSON 丢
|
|
21
|
+
* undefined 值同样落到本函数——分区语义两引擎一致)
|
|
22
|
+
* - 其余 → 不写(保守)
|
|
23
|
+
* **value 现值比较(2027-09——DOM 脱节修复消费端)**:diff 对表单控件
|
|
24
|
+
* value 总是发——写前与 DOM 现值比较(同值不上 DOM——打字每键的差集
|
|
25
|
+
* 渲染零副作用);**IME 组合中跳过**(compositionstart~end——组合期
|
|
26
|
+
* 渲染树 value=组合前——强写打断中文输入法)——组合结束后渲染写回 */
|
|
15
27
|
export declare function applyProperty(el: HTMLElement, key: string, value: unknown): void;
|
|
@@ -31,8 +31,14 @@ export declare class RefRegistry {
|
|
|
31
31
|
mount(id: string, el: HTMLElement): void;
|
|
32
32
|
/** 卸载(ref(null) 子树——前缀匹配——表删除) */
|
|
33
33
|
unmount(id: string): void;
|
|
34
|
+
/** O(1) 单个 ref 卸载(**P1 性能升级(2027-09——admin 全量 59s 实证)**:
|
|
35
|
+
* procRemove 子树循环逐条调用——替代 unmount(全量前缀扫描 × 16k 条
|
|
36
|
+
* = O(N²))——procDone 同步改造) */
|
|
37
|
+
unmountOne(id: string): void;
|
|
34
38
|
/** move 前缀重映射(节点移动——id 路径变化——表跟随) */
|
|
35
39
|
remap(oldPrefix: string, newPrefix: string): void;
|
|
40
|
+
/** **清表(serve 整树替换式重置用)** */
|
|
41
|
+
clear(): void;
|
|
36
42
|
/** 卸载清理(serve unmount)——状态机迁移:active → disposed */
|
|
37
43
|
dispose(): void;
|
|
38
44
|
}
|
|
@@ -13,5 +13,11 @@
|
|
|
13
13
|
export declare const UNITLESS_KEYS: Set<string>;
|
|
14
14
|
/** 单值应用(kebab/camelCase 键——CSS 变量走 setProperty) */
|
|
15
15
|
export declare function applyStyleValue(el: HTMLElement, key: string, value: unknown): void;
|
|
16
|
-
/** style 应用(对象/字符串——整体替换语义)
|
|
16
|
+
/** style 应用(对象/字符串——整体替换语义)
|
|
17
|
+
*
|
|
18
|
+
* **undefined/null/false → 整体移除(2027-XX——Affix 卡 fixed 实证修复)**:
|
|
19
|
+
* diff 侧「旧有新无」发 setProp('style', undefined)——此前 undefined 分支
|
|
20
|
+
* 静默 no-op → 旧 style 残留(Affix 滚回顶 content 仍 position:fixed——
|
|
21
|
+
* sentinel --active 已移除而 inline style 残留——两种面不一致)。与对象
|
|
22
|
+
* → 空对象同属整体替换语义(A5——键消失不残留)——整属性消失 = 清空。 */
|
|
17
23
|
export declare function applyStyle(el: HTMLElement, style: unknown): void;
|
|
@@ -61,10 +61,9 @@ export interface ComponentRecord {
|
|
|
61
61
|
renderBase: number;
|
|
62
62
|
/** hook 状态缓存(per-instance——useOpen 等渲染期 hooks) */
|
|
63
63
|
hookStates: Map<number, unknown>;
|
|
64
|
-
/** 组件状态机阶段(**
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
phase: 'mounting' | 'mounted';
|
|
64
|
+
/** 组件状态机阶段(**2027-08 断代**:工厂同步——无 mounting 窗口——
|
|
65
|
+
* phase 恒 'mounted'——mount 命令是消费端确认) */
|
|
66
|
+
phase: 'mounted';
|
|
68
67
|
}
|
|
69
68
|
/** 组件实例注册表(uiServe 持有——renderToStream 写入——diff/unmount 消费) */
|
|
70
69
|
export interface ComponentRegistry {
|
|
@@ -13,7 +13,12 @@ import type { Command } from '../command/index.ts';
|
|
|
13
13
|
import type { ComponentSink } from './component.ts';
|
|
14
14
|
/** 节点 id——确定性路径(root.0.a0——锚点法——组件实例隔离) */
|
|
15
15
|
export declare function pathId(parent: string, i: number): string;
|
|
16
|
-
/** 可序列化属性面(服务端吐 HTML 用)——事件/ref/函数值排除
|
|
16
|
+
/** 可序列化属性面(服务端吐 HTML 用)——事件/ref/函数值排除
|
|
17
|
+
* **undefined 过滤(2027-08——v2 直连污染实证)**:v1 浏览器链路经
|
|
18
|
+
* JSON 编解码(undefined 键被丢弃——误过滤);v2 命令直连 applier——
|
|
19
|
+
* attrs.value=undefined → applyAttribute property 赋值 → DOM value
|
|
20
|
+
* = "undefined"(SearchInput 非受控 value: undefined——deep-search
|
|
21
|
+
* 场景实证)——序列化面向统一过滤(SSR 侧同受益) */
|
|
17
22
|
export declare function serializableAttrs(props: Record<string, unknown>): Record<string, unknown>;
|
|
18
23
|
/** 原生元素渲染(create → insert → children 递归 → close——
|
|
19
24
|
* ref prop → **ref 指令**(insert 后——挂载完成)) */
|
|
@@ -23,6 +23,27 @@ export declare class CommandApplier {
|
|
|
23
23
|
nodes: Map<string, WfNode>;
|
|
24
24
|
/** 本流已创建 id(done.full 清理) */
|
|
25
25
|
touched: Set<string>;
|
|
26
|
+
/** P1 性能索引:父子(parent id → 子 id 集合)——procRemove 子树收集
|
|
27
|
+
* O(N²)(前缀全量扫描——admin 全量 59s 实证)→ O(k) DFS。
|
|
28
|
+
* 语义:id 空间逻辑树(cmd.parent 字符串键——组件逻辑父/锚父同构——
|
|
29
|
+
* 与 DOM 树不必一致——collectDesc 从自身出发不受影响)。 */
|
|
30
|
+
childIds: Map<string, Set<string>>;
|
|
31
|
+
/** P1 反向索引(child id → parent id)——O(1) 摘除——防泄漏 */
|
|
32
|
+
byChild: Map<string, string>;
|
|
33
|
+
/** P2:插入序号(ref 组件 id 回退——「最后前缀命中 = 最新插入」的
|
|
34
|
+
* O(1) 判定——原实现靠 nodes Map 插入序全量扫描——O(N)) */
|
|
35
|
+
seq: Map<string, number>;
|
|
36
|
+
private seqCounter;
|
|
37
|
+
/** 登记父子(procInsert 成功后——幂等) */
|
|
38
|
+
registerChild(parent: string, id: string): void;
|
|
39
|
+
/** 摘除子登记(O(1)——byChild 反查父集合——空集合清键) */
|
|
40
|
+
unregisterChild(id: string): void;
|
|
41
|
+
/** 子树收集(DFS——含自身——O(k)——procRemove 主路径) */
|
|
42
|
+
collectDesc(id: string): string[];
|
|
43
|
+
/** **整树替换式重置(2027-09——tour 违例实证)**:resetRoot(innerHTML
|
|
44
|
+
* 清空)后记录表同步清——后续 build 的 parentOf 不再命中残留锚
|
|
45
|
+
* (DOM 已脱离——记录越权应用→id 空间违例)——事件/ref 清表不清监听 */
|
|
46
|
+
reset(): void;
|
|
26
47
|
/** 事件代理注册表(document 捕获监听——分发) */
|
|
27
48
|
eventRegistry: EventRegistry;
|
|
28
49
|
/** ref 全局注册表(挂载/卸载查表触发) */
|
|
@@ -41,7 +62,9 @@ export declare class CommandApplier {
|
|
|
41
62
|
clearNodeRefs(id: string): void;
|
|
42
63
|
/** 子树 id 重映射(move——nodes/事件表/refs 前缀迁移) */
|
|
43
64
|
remapSubtree(oldPrefix: string, newPrefix: string): void;
|
|
44
|
-
/** 父节点解析(root
|
|
65
|
+
/** 父节点解析(root/节点表)——**脱离记录回退(2027-09——tour 实证**:
|
|
66
|
+
* 整树替换后残留记录(DOM 已脱离——isConnected=false)——直中返回
|
|
67
|
+
* 残留锚/旧节点 → insertBefore/锚判定错误——跳过脱离记录继续回退) */
|
|
45
68
|
parentOf(cmd: {
|
|
46
69
|
parent: string;
|
|
47
70
|
}): HTMLElement | null;
|
|
@@ -35,7 +35,14 @@ export declare function procInsert(applier: CommandApplier, cmd: Extract<Command
|
|
|
35
35
|
export declare function procMove(applier: CommandApplier, cmd: Extract<Command, {
|
|
36
36
|
op: 'move';
|
|
37
37
|
}>): void;
|
|
38
|
-
/** remove 处理器(卸载——ref(null) + 事件表 + 节点移除)
|
|
38
|
+
/** remove 处理器(卸载——ref(null) + 事件表 + 节点移除)
|
|
39
|
+
* P1 性能升级(2027-09——admin 全量 59s 实证):原实现每次 remove 全量
|
|
40
|
+
* 扫描 nodes(前缀 startsWith)——16k 条 remove × 160k 节点 = 2.6B 次
|
|
41
|
+
* 匹配——O(N²)——改为 childIds 索引 DFS 收集(O(k))。
|
|
42
|
+
* 防御语义保持:子树记录清理(transform 组件→X 只发首 remove——无旧
|
|
43
|
+
* vnode 引用无法递归发命令——子节点记录残留——按 id 前缀清全部后代
|
|
44
|
+
* (keyed 子树 root.0.1.k3.0 同样路径前缀——事件/ref 表同步清)——
|
|
45
|
+
* **索引主路径 + 前缀兜底**(索引未覆盖路径——防御降级——不静默) */
|
|
39
46
|
export declare function procRemove(applier: CommandApplier, cmd: Extract<Command, {
|
|
40
47
|
op: 'remove';
|
|
41
48
|
}>): void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { VNode } from './vnode.ts';
|
|
2
|
+
import type { UIContext } from '../context/UIContext.ts';
|
|
3
|
+
import type { Command } from './command/index.ts';
|
|
4
|
+
/** 函数表还原($fn 标记 → 函数——编码/解码同进程共享) */
|
|
5
|
+
export declare function reviveFn(fnTable: Map<number, unknown>): (k: string, v: unknown) => unknown;
|
|
6
|
+
/** R1 熔断默认回退 UI(core 内建——inline style 零样式系统依赖——
|
|
7
|
+
* errorFallback 未配置时使用——错误文案 + 重试按钮(恢复路径)) */
|
|
8
|
+
export declare function defaultErrorFallback(err: Error, ctx: UIContext): VNode;
|
|
9
|
+
/** NDJSON 命令流解析(行缓冲——命令可能跨 chunk——函数表还原——
|
|
10
|
+
* 导出(测试——跨 chunk 边界/畸形行合规断言)) */
|
|
11
|
+
export declare function commandReader(reader: ReadableStreamDefaultReader<Uint8Array>, fnTable: Map<number, unknown>): AsyncGenerator<Command>;
|
|
12
|
+
/** 命令流编码(函数面 → {$fn: n}——函数表——同进程共享)
|
|
13
|
+
* 函数 → 序号(WeakMap——同函数流内复用同序号——减少重复条目) */
|
|
14
|
+
export declare function encodeCommands(stream: ReadableStream<Command>, fnTable: Map<number, unknown>): ReadableStream<Uint8Array>;
|
|
15
|
+
/** 函数表(serve 级共享——编码/解码同进程) */
|
|
16
|
+
export declare function createFnTable(): Map<number, unknown>;
|
|
17
|
+
/** uiServe 选项(v1/v2 共同——公共面契约) */
|
|
18
|
+
export interface UiServeOptions {
|
|
19
|
+
/** 根容器(选择器或元素) */
|
|
20
|
+
root: string | HTMLElement;
|
|
21
|
+
/** 错误熔断回退(R1——应用可配置) */
|
|
22
|
+
errorFallback?: (err: Error, ctx: UIContext) => VNode;
|
|
23
|
+
api?: unknown;
|
|
24
|
+
auth?: unknown;
|
|
25
|
+
ws?: unknown;
|
|
26
|
+
i18n?: unknown;
|
|
27
|
+
toast?: (message: string, type?: 'success' | 'error' | 'info' | 'warning', duration?: number) => void;
|
|
28
|
+
confirm?: unknown;
|
|
29
|
+
notification?: unknown;
|
|
30
|
+
[key: string]: unknown;
|
|
31
|
+
}
|
|
32
|
+
/** uiServe 句柄(v1/v2 共同) */
|
|
33
|
+
export interface UiServeHandle {
|
|
34
|
+
ready: Promise<void>;
|
|
35
|
+
render(): Promise<void>;
|
|
36
|
+
navigate(path: string): Promise<void>;
|
|
37
|
+
/** 卸载(清理事件代理/组件实例——DOM 清空) */
|
|
38
|
+
unmount(): void;
|
|
39
|
+
}
|
|
40
|
+
export type ServePhase = 'active' | 'unmounted';
|
|
41
|
+
export type RenderPhase = 'idle' | 'rendering';
|
|
42
|
+
/** 渲染上下文(stream = 页面作者渲染入口——vnode → command 流) */
|
|
43
|
+
export interface RenderCtx extends UIContext {
|
|
44
|
+
stream(vnode: VNode, init?: ResponseInit): Response;
|
|
45
|
+
}
|
|
@@ -22,10 +22,17 @@ export declare class UIRouter {
|
|
|
22
22
|
private notFoundHandler;
|
|
23
23
|
/** 注册路由(shared Trie——静态/:param/*——params 注入 req) */
|
|
24
24
|
get(path: string, handler: PageHandler): this;
|
|
25
|
+
/** 路由存在性(onDocClick 决策:无匹配 → 不拦截——默认完整导航——
|
|
26
|
+
* 实证:stats 页「← 填写页」链接被拦截但 navigate 落空——半跳转) */
|
|
27
|
+
has(path: string): boolean;
|
|
25
28
|
/** 404 兜底 */
|
|
26
29
|
notFound(handler: PageHandler): this;
|
|
27
30
|
/** 解析请求 → 响应(Trie 匹配 + **params/query 注入 ctx**——对齐后端
|
|
28
31
|
* `ctx = { params, query }`——`Object.fromEntries(searchParams)`——
|
|
29
32
|
* 不修改原始 Request) */
|
|
33
|
+
private _pipeline?;
|
|
34
|
+
private get pipeline();
|
|
35
|
+
/** 解析请求 → 响应(**shared pipeline 内核**——parse→match→ctx 注入→
|
|
36
|
+
* 执行→404 兜底骨架单源——非法编码 → 400(B1——对齐 server 语义)) */
|
|
30
37
|
resolve(req: Request, ctx: UIContext): Promise<Response>;
|
|
31
38
|
}
|
|
@@ -24,21 +24,48 @@
|
|
|
24
24
|
* 显式 console.error(不再静默返回 null——非法顺序是 bug)
|
|
25
25
|
*/
|
|
26
26
|
import type { WfNode } from '../patch/processors.ts';
|
|
27
|
+
import { type Observable } from '../../observable/index.ts';
|
|
27
28
|
/** 吸收阶段(状态机枚举) */
|
|
28
29
|
export type AbsorbPhase = 'inactive' | 'consuming' | 'failed';
|
|
30
|
+
/** 吸收迁移事件(**流化(2027-09)——事件序列 = 时间线——可回放**) */
|
|
31
|
+
export type AbsorbEvent = {
|
|
32
|
+
kind: 'begin';
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'next';
|
|
35
|
+
matched: boolean;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'end';
|
|
38
|
+
remaining: number;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'reset';
|
|
41
|
+
};
|
|
42
|
+
/** 吸收迁移表(**纯 reducer——状态机维度总表语义不变——波次 4 流化**):
|
|
43
|
+
* - begin:任意 → consuming(无条件——幂等——现状)
|
|
44
|
+
* - next matched:consuming → consuming(消耗);matched=false = 耗尽——failed
|
|
45
|
+
* - end:consuming → remaining>0 ? failed : inactive(mismatch 判定)
|
|
46
|
+
* - reset:任意 → inactive(回退重建)
|
|
47
|
+
* 违例语义(保持现状——不抛——消费端防御):next/end 于非 consuming =
|
|
48
|
+
* 无迁移(合法 no-op——procDone 无条件调用 end——未 begin 不报错)——
|
|
49
|
+
* next 违例的方法层保留 console.error(audit 可见——2026 审计语义) */
|
|
50
|
+
export declare function absorbReducer(s: AbsorbPhase, e: AbsorbEvent): AbsorbPhase;
|
|
29
51
|
/** 吸收状态(CommandApplier 持有——apply 层消费) */
|
|
30
52
|
export declare class AbsorbState {
|
|
31
53
|
/** DFS 序快照(root 后代——create 按序消费) */
|
|
32
54
|
queue: Node[] | null;
|
|
33
|
-
/**
|
|
34
|
-
failed: boolean;
|
|
35
|
-
/** 状态机阶段(迁移:begin→consuming;end/reset→inactive;耗尽→failed) */
|
|
55
|
+
/** 状态机阶段(**单源 = events$ 的 scan 折叠写回**——2027-09) */
|
|
36
56
|
phase: AbsorbPhase;
|
|
57
|
+
/** 迁移事件流(begin/next/end/reset 全序列——**时间线可回放**) */
|
|
58
|
+
readonly events$: Observable<AbsorbEvent>;
|
|
59
|
+
/** **吸收失败事件**(next 耗尽 / end 剩余——serve 回退闭环订阅点) */
|
|
60
|
+
readonly failed$: Observable<void>;
|
|
61
|
+
private readonly events;
|
|
62
|
+
constructor();
|
|
37
63
|
/** 启动吸收(root 有 SSR 内容——DFS 序快照——不消费 root 自身) */
|
|
38
64
|
begin(container: HTMLElement): void;
|
|
39
65
|
/** 吸收结束(done.full)——剩余节点 = SSR 输出多于命令——mismatch
|
|
40
66
|
* **inactive 时 = 合法 no-op**(procDone 无条件调用——非 SSR 客户端
|
|
41
|
-
* 渲染未 begin——end
|
|
67
|
+
* 渲染未 begin——end 无意义——不报错——reducer 无迁移);consuming 时 =
|
|
68
|
+
* 正常收尾(remaining=0 → inactive / >0 → failed 事件) */
|
|
42
69
|
end(): void;
|
|
43
70
|
/** 重置(回退重建后——恢复非吸收态) */
|
|
44
71
|
reset(): void;
|
|
@@ -22,8 +22,10 @@ export type NodeState = 'text' | 'hole' | 'element' | 'component' | 'fragment' |
|
|
|
22
22
|
export interface TransformContext {
|
|
23
23
|
/** 命令发射(旧侧让位:remove/unmountComp——diff 生成的命令序列) */
|
|
24
24
|
emit(cmd: unknown): void;
|
|
25
|
-
/**
|
|
26
|
-
|
|
25
|
+
/** **新侧渲染(记录——不构造)**(2027-09 流化:延迟构造归 transformV2
|
|
26
|
+
* ——订阅时构造——C1 fuzz seed=11 的顺序语义结构性保证——旧段 dispose
|
|
27
|
+
* 在前——不再有 await 时序不保的 pendingSink hack) */
|
|
28
|
+
emitNode(v: VNodeChild, parent: string, index: number, ref: string | null): void;
|
|
27
29
|
/** 旧节点锚/元素 id(旧树 id——diff 的 oldId 空间) */
|
|
28
30
|
oldId: string;
|
|
29
31
|
/** 新节点 id(新树 id——diff 的 newId 空间) */
|
|
@@ -39,8 +41,6 @@ export interface TransformContext {
|
|
|
39
41
|
/** 组件实例注册表(区间清理查 lastOutput——组件多根完整移除——G2) */
|
|
40
42
|
registry?: ComponentRegistry | null;
|
|
41
43
|
}
|
|
42
|
-
/** 新侧渲染 sink(与 build 的 RenderSink 同形——transform 不依赖 build) */
|
|
43
|
-
export type TransformSink = (v: VNodeChild, parent: string, index: number, ref: string | null) => Promise<void>;
|
|
44
44
|
/** 转换策略函数(各状态文件实现——**完整转换**:旧侧让位命令 + ctx.emitNode
|
|
45
|
-
*
|
|
46
|
-
export type TransitionFn = (oldNode: unknown, nextNode: VNodeChild, ctx: TransformContext) =>
|
|
45
|
+
* 新侧记录——同步执行——新侧构造由 transformV2 延迟(订阅时)) */
|
|
46
|
+
export type TransitionFn = (oldNode: unknown, nextNode: VNodeChild, ctx: TransformContext) => void | Promise<void>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom v2 — 渲染周期(applyV2Inner 管线化——波次 1:渲染全链路流视图)
|
|
3
|
+
*
|
|
4
|
+
* VDOM-OBSERVABLE-COMPLETE 波次 1:
|
|
5
|
+
* - **管线形态**:build/diff → cmds$ → toArray(原子性——生成完成才应用——
|
|
6
|
+
* 错误 → 零 DOM 变更)→ tap(apply) → tap(cleanup) → currentTree →
|
|
7
|
+
* applied$(sink 可观测)→ complete$
|
|
8
|
+
* - **度量流化**:三轴(builds/diffs/applies/unmounts)在周期计数——
|
|
9
|
+
* 删除 applyV2 手写 vt.builds/diffs(serve 同步到 __wfV2——兼容)
|
|
10
|
+
* - **sserve 解耦**:周期不含 DOM/applier——依赖注入(boot/resetRoot/
|
|
11
|
+
* build/diff/apply/dispose/active)——契约层可注入假依赖直测管线
|
|
12
|
+
*/
|
|
13
|
+
import type { VNode } from '../vnode.ts';
|
|
14
|
+
import type { Command } from '../command/index.ts';
|
|
15
|
+
import { Observable } from '../../observable/index.ts';
|
|
16
|
+
/** 周期三轴度量(渲染健康——流上取数——RENDER-HEALTH-PLAN 接管点) */
|
|
17
|
+
export interface CycleMetrics {
|
|
18
|
+
builds: number;
|
|
19
|
+
diffs: number;
|
|
20
|
+
applies: number;
|
|
21
|
+
unmounts: number;
|
|
22
|
+
}
|
|
23
|
+
/** 渲染周期依赖(serve 注入 DOM/引擎——周期纯管线) */
|
|
24
|
+
export interface RenderCycleDeps {
|
|
25
|
+
/** 首帧一次性(SSR 吸收 begin / root 清空——周期内 booted 标记) */
|
|
26
|
+
boot(): void;
|
|
27
|
+
/** root 整树替换前清空(innerHTML='' + 旧段全量 dispose——serve 实现) */
|
|
28
|
+
resetRoot(): void;
|
|
29
|
+
/** 全量构建(首帧 / 根替换 / 影子树重置后——currentTree null 时) */
|
|
30
|
+
build(vnode: VNode): Observable<Command>;
|
|
31
|
+
/** 增量 diff(currentTree 与 vnode 同型) */
|
|
32
|
+
diff(oldTree: VNode, nextTree: VNode): Observable<Command>;
|
|
33
|
+
/** 命令应用(applier.apply——副作用终态) */
|
|
34
|
+
apply(cmd: Command): void;
|
|
35
|
+
/** unmount 命令 → 段销毁(返回是否实际销毁——幂等防御) */
|
|
36
|
+
dispose(compId: string): boolean;
|
|
37
|
+
/** serve 活性(unmount 后周期零副作用) */
|
|
38
|
+
active(): boolean;
|
|
39
|
+
}
|
|
40
|
+
export interface RenderCycle {
|
|
41
|
+
/** 应用 vnode(首帧 build / 后续 diff / 异型根替换)——生成原子性 */
|
|
42
|
+
apply(vnode: VNode): Promise<void>;
|
|
43
|
+
/** 影子树重置(错误自愈 / R1 熔断 fallback 前置)——下次 apply 全量 */
|
|
44
|
+
reset(): void;
|
|
45
|
+
/** 三轴度量(builds/diffs/applies/unmounts) */
|
|
46
|
+
metrics(): CycleMetrics;
|
|
47
|
+
/** **应用后命令重发射**(sink 可观测——dev/度量订阅点——每周期一值) */
|
|
48
|
+
applied$: Observable<Command[]>;
|
|
49
|
+
/** **周期完成**(applied 后——afterRender 冲刷点——每周期一事件) */
|
|
50
|
+
complete$: Observable<void>;
|
|
51
|
+
}
|
|
52
|
+
/** 创建渲染周期(**原子性纪律**:命令生成完整(toArray)→ 应用——生成
|
|
53
|
+
* 错误 → 零 DOM 变更 + currentTree 重置(下次全量自愈——R1 语境界面)) */
|
|
54
|
+
export declare function createRenderCycle(deps: RenderCycleDeps): RenderCycle;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { VNode, VNodeChild } from '../vnode.ts';
|
|
2
|
+
import type { Component, RenderFn } from '../vnode.ts';
|
|
3
|
+
import type { Command } from '../command/index.ts';
|
|
4
|
+
import type { UIContext } from '../../context/UIContext.ts';
|
|
5
|
+
import { Observable } from '../../observable/index.ts';
|
|
6
|
+
import { type CompOutput } from '../node/component.ts';
|
|
7
|
+
/** v2 组件流段(实例复用载体——**工厂执行一次——后续复用**) */
|
|
8
|
+
export interface Segment {
|
|
9
|
+
factory: Component;
|
|
10
|
+
renderFn: RenderFn;
|
|
11
|
+
lastOutput: CompOutput | undefined;
|
|
12
|
+
hookSeq: {
|
|
13
|
+
n: number;
|
|
14
|
+
};
|
|
15
|
+
/** 渲染 hook 基准(mount 后计数——v1 renderBase 等价——**每次 renderFn 前
|
|
16
|
+
* 重置——渲染期 hook 索引跨渲染稳定——useOpen 状态保留(2027-08
|
|
17
|
+
* 漂移实证——Popover 点后 open 复位)**) */
|
|
18
|
+
renderBase: number;
|
|
19
|
+
instData: Map<unknown, unknown>;
|
|
20
|
+
/** **destroy$(2027-08——段级卸载信号——单信号全停)**:卸载时 next——
|
|
21
|
+
* **单轨清理(2027-09——onUnmounts 字段删除)**:订阅者(onUnmount
|
|
22
|
+
* 闭包栈 LIFO + 外部 takeUntil 流清理)统一由本信号驱动——不再有
|
|
23
|
+
* 平行数组 */
|
|
24
|
+
destroy$: import('../../observable/index.ts').Subject<void>;
|
|
25
|
+
disposed: boolean;
|
|
26
|
+
}
|
|
27
|
+
export type SegmentMap = Map<string, Segment>;
|
|
28
|
+
/** 创建段(mount——工厂执行——hooks 环境已注入 ctx.ui) */
|
|
29
|
+
export declare function createSegment(factory: Component, props: Record<string, unknown>, ctx: UIContext, compId: string, requestSegmentRender?: () => void): Segment;
|
|
30
|
+
/** **段重渲染(单一实现源)**:hookSeq 重置(v1 renderBase 语义——渲染期
|
|
31
|
+
* hook 索引跨渲染稳定)→ renderFn 重调(props 最新)——工厂不重跑 */
|
|
32
|
+
export declare function rerenderSegment(seg: Segment, props: Record<string, unknown>): VNodeChild;
|
|
33
|
+
/** 段销毁(unmount——destroy$ 单信号全停——onUnmount 闭包栈 LIFO + 订阅
|
|
34
|
+
* 者清理统一由信号驱动)——段接口无平行数组(单轨清理) */
|
|
35
|
+
export declare function disposeSegment(id: string, segments: SegmentMap): void;
|
|
36
|
+
/**
|
|
37
|
+
* **段输出根枚举(VDOM-CORE-EXCELLENCE KEYED-MOVE M1——单一实现源)**:
|
|
38
|
+
* keyed 组件输出的物理节点 id 清单——顺移物理 move 的命令目标。
|
|
39
|
+
* **形态映射(四形态探针实证——2027-10)**:
|
|
40
|
+
* - 单 vnode 元素/文本输出 → **槽位 id**(pathId——C2 锚点法——P 契约
|
|
41
|
+
* 槽位 remap 有效实证)
|
|
42
|
+
* - 数组输出 → **compId.i 平铺**(root.0.kk1.0/.1——与兄弟槽位隔离)
|
|
43
|
+
* - null/空洞输出 → **compId.0 锚**(G11 修正——null 锚也挂子空间)
|
|
44
|
+
* - 嵌套组件输出 → **compId.0**(单 vnode 组件输出——防冲突——HoverCard
|
|
45
|
+
* 事故实证;嵌套段在 compId.0.0 递归子空间)
|
|
46
|
+
*/
|
|
47
|
+
export declare function outputRootIds(seg: Segment | undefined, kid: string, parent: string, index: number): string[];
|
|
48
|
+
/** 任意子节点的物理输出根 id(M2 ref 链——新位置左邻定位):
|
|
49
|
+
* 元素/文本 → 槽位 id;keyed 组件 → 输出根[0](compId.0/槽位) */
|
|
50
|
+
export declare function outputRootIdOf(c: VNodeChild, parent: string, index: number, segments?: SegmentMap): string;
|
|
51
|
+
/** 节点对照(old vs new——流式增量命令) */
|
|
52
|
+
export declare function diffV2Node(oldC: VNodeChild, newC: VNodeChild, parent: string, index: number, ref: string | null, ctx: UIContext, segments: SegmentMap, registry: import('../node/component.ts').ComponentRegistry, requestRender?: () => void): Observable<Command>;
|
|
53
|
+
/** 组件 id(keyedId/pathId——单一点——v1 双实现收敛) */
|
|
54
|
+
export declare function v2CompId(vn: VNode, parent: string, index: number): string;
|
|
55
|
+
/** 根对照(v2 diff——diffStream 的 Observable 等价) */
|
|
56
|
+
export declare function diffV2(oldTree: VNode, newTree: VNode, ctx: UIContext, segments: SegmentMap, registry: import('../node/component.ts').ComponentRegistry, requestRender?: () => void): Observable<Command>;
|
|
57
|
+
/** keyed 列表对照(流式——顺移 move / 冲突重建 / key 映射对照——v1 语义等价) */
|
|
58
|
+
export declare function diffKeyedV2(oldCs: VNodeChild[], newCs: VNodeChild[], parent: string, ctx: UIContext, segments: SegmentMap, registry: import('../node/component.ts').ComponentRegistry, requestRender?: () => void): Observable<Command>;
|
|
59
|
+
/** 完整区间移除(v1 removeVNodeTree 等价——子树全部节点 remove——先子后父)
|
|
60
|
+
* **组件项 unmount 信号**:v1 removeVNodeTree 同语义(compId——消费端
|
|
61
|
+
* applier 的 registry 清理)
|
|
62
|
+
* **段 dispose 生成期(2027-08——段表是 v2 权威——同 compId 重渲染碰撞
|
|
63
|
+
* 实证:列表→编辑器切换——旧按钮内 Icon 段残留 root.0.1.0.0——新 Button
|
|
64
|
+
* 落同槽——段错配崩溃)**:段清理必须在 diff 生成期完成(命令流生产端
|
|
65
|
+
* 完整自足——不依赖消费端时序——消费端 apply 循环的 dispose 是幂等兜底 */
|
|
66
|
+
export declare function removeTreeV2(v: VNodeChild, parent: string, index: number, segments?: SegmentMap, opts?: {
|
|
67
|
+
keepSegments?: boolean;
|
|
68
|
+
}): Command[];
|
|
69
|
+
/** 列表含 keyed 项检测(v2——keyOf 桥) */
|
|
70
|
+
export declare function hasKeyedId(items: VNodeChild[]): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* v2 转换(异态——v1 transitionOf 表语义单源——流式适配)
|
|
73
|
+
* - 转换表同步执行(emit 收集让位命令 + emitNode 记录新侧)——**不 await**
|
|
74
|
+
* - **顺序纪律三段流(2027-09——C1 fuzz seed=11 结构化修复)**:
|
|
75
|
+
* concatObs([disposeOp → removeCmds → 新侧渲染])——按序订阅:① 旧段
|
|
76
|
+
* dispose(段表权威更新)② 旧侧让位命令发射 ③ 新侧渲染构造(**订阅时**
|
|
77
|
+
* ——createSegment 在 dispose 后——同 id 命中旧段/工厂错配结构性不可能)
|
|
78
|
+
* ——pendingSink 时序 hack 删除(旧实现 Promise.resolve().then 时序不保)
|
|
79
|
+
*/
|
|
80
|
+
export declare function transformV2(oldC: VNodeChild, newC: VNodeChild, parent: string, index: number, ref: string | null, ctx: UIContext, registry: import('../node/component.ts').ComponentRegistry, oldCompId?: string, segments?: SegmentMap, requestRender?: () => void): Observable<Command>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vdom v2 — 集成(v2 引擎 → 消费端链路)
|
|
3
|
+
*
|
|
4
|
+
* VDOM-V2-BLUEPRINT 阶段 2A:
|
|
5
|
+
* - **命令流同构 → 消费端复用**:renderV2/diffV2 产出 Observable<Command>
|
|
6
|
+
* ——commandToHtml / CommandApplier 直接消费(命令语义 v1 相同——零改动)
|
|
7
|
+
* - v2ToHtml:v2 渲染 → HTML(SSR 路径——契约层无 DOM 验证)
|
|
8
|
+
* - 阶段 2A 验证点:v2 HTML ≡ v1 HTML(多种子——SSR 等价)
|
|
9
|
+
*/
|
|
10
|
+
import type { VNode } from '../vnode.ts';
|
|
11
|
+
import type { Command } from '../command/index.ts';
|
|
12
|
+
import type { UIContext } from '../../context/UIContext.ts';
|
|
13
|
+
import { type ComponentRegistry } from '../node/component.ts';
|
|
14
|
+
import { Observable } from '../../observable/index.ts';
|
|
15
|
+
/** Observable<Command> → 命令数组(同步流收集——订阅到 complete) */
|
|
16
|
+
export declare function collectCommands(obs: Observable<Command>): Promise<Command[]>;
|
|
17
|
+
/** **v2 diff → ReadableStream<Command>(v1 diffStream 兼容桥——测试迁移)** */
|
|
18
|
+
export declare function diffToStreamV2(oldT: VNode, newT: VNode, ctx?: UIContext, registry?: ComponentRegistry, segments?: Map<string, import('./diff.ts').Segment>, requestRender?: () => void): ReadableStream<Command>;
|
|
19
|
+
/** **v2 渲染 → ReadableStream<Command>(v1 renderToStream 兼容桥——v1 退役迁移)**
|
|
20
|
+
* 命令式组件(toast/Confirm/Notification——独立 applier 消费——pipeTo/
|
|
21
|
+
* 读取流形态不变)——v2 引擎 + 段表(跨渲染复用) */
|
|
22
|
+
export declare function renderToStreamV2(vnode: VNode, ctx?: UIContext, registry?: ComponentRegistry, segments?: Map<string, import('./diff.ts').Segment>, requestRender?: () => void): ReadableStream<Command>;
|
|
23
|
+
/** v2 渲染 → HTML(SSR 路径——commandToHtml 复用——命令流同构) */
|
|
24
|
+
export declare function v2ToHtml(root: VNode, ctx?: UIContext, registry?: ComponentRegistry): Promise<string>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { VNode, VNodeChild } from '../vnode.ts';
|
|
2
|
+
import type { Command } from '../command/index.ts';
|
|
3
|
+
import type { UIContext } from '../../context/UIContext.ts';
|
|
4
|
+
import { type ComponentRegistry } from '../node/component.ts';
|
|
5
|
+
import { Observable } from '../../observable/index.ts';
|
|
6
|
+
import type { OperatorFn } from '../../observable/index.ts';
|
|
7
|
+
/** **输出位置单一实现源**(v1 outputBase 语义——组件输出挂哪):
|
|
8
|
+
* - 组件输出组件/数组/空洞 → compId 子空间(compId.0 起——与兄弟隔离)
|
|
9
|
+
* - 单元素/文本 → 槽位(parent/index——v1 C2 规则)
|
|
10
|
+
* v2 的渲染(段化)与 diff(输出对照)共用——**单一实现——防漂移** */
|
|
11
|
+
export declare function v2OutputPos(out: VNodeChild, compId: string, parent: string, index: number): {
|
|
12
|
+
parent: string;
|
|
13
|
+
index: number;
|
|
14
|
+
};
|
|
15
|
+
/** 节点展开(vnode → 命令流——惰性——订阅驱动) */
|
|
16
|
+
export declare function renderV2Node(v: VNodeChild, parent: string, index: number, ref: string | null, ctx: UIContext, registry: ComponentRegistry, segments?: Map<string, import('./diff.ts').Segment>, requestRender?: () => void): Observable<Command>;
|
|
17
|
+
/** 根渲染(v2)——renderToStream 的 Observable 等价 */
|
|
18
|
+
export declare function renderV2(root: VNode, ctx?: UIContext, registry?: ComponentRegistry, segments?: Map<string, import('./diff.ts').Segment>, requestRender?: () => void): Observable<Command>;
|
|
19
|
+
/** 数组 → 同步 Observable(逐项发射 + complete) */
|
|
20
|
+
export declare function fromArray<T>(items: T[]): Observable<T>;
|
|
21
|
+
/** 顺序拼接(流串联——命令序号保持)
|
|
22
|
+
* **同步完成迭代化(2027-08——大 flat 列表栈溢出实证——QRCode 页)**:
|
|
23
|
+
* 旧实现 complete → nextStream() 递归——N 个同步完成流 = N 层调用栈——
|
|
24
|
+
* 数百 rect/svg 链即溢出。新实现:同步完成由 while 循环推进(迭代——
|
|
25
|
+
* 零深栈);异步完成仍由回调驱动(新调用栈——深度 1)。 */
|
|
26
|
+
export declare function concatObs<T>(streams: Array<Observable<T>>): Observable<T>;
|
|
27
|
+
/** append 算子(concat 语义——合成尾部流) */
|
|
28
|
+
export declare function concatWith<T>(tail: Observable<T>): OperatorFn<T, T>;
|