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.
Files changed (392) hide show
  1. package/README.md +111 -135
  2. package/dist/client/components/ActionSheet/ActionSheet.d.ts +1 -1
  3. package/dist/client/components/AiChat/AiChat.d.ts +3 -4
  4. package/dist/client/components/ChatInput/ChatInput.d.ts +5 -0
  5. package/dist/client/components/CitationCard/CitationCard.d.ts +1 -1
  6. package/dist/client/components/Command/Command.d.ts +1 -1
  7. package/dist/client/components/ContextMenu/ContextMenu.d.ts +1 -1
  8. package/dist/client/components/DatePicker/DatePicker.d.ts +1 -1
  9. package/dist/client/components/Dropdown/Dropdown.d.ts +1 -1
  10. package/dist/client/components/Editor/model/html.d.ts +10 -0
  11. package/dist/client/components/ImageCropper/ImageCropper.d.ts +6 -2
  12. package/dist/client/components/Menu/Menu.d.ts +1 -1
  13. package/dist/client/components/NavMenu/NavMenu.d.ts +1 -1
  14. package/dist/client/components/Popconfirm/Popconfirm.d.ts +1 -1
  15. package/dist/client/components/SlideCanvas/SlideCanvas.d.ts +1 -1
  16. package/dist/client/components/Tour/Tour.d.ts +1 -1
  17. package/dist/client/components/TreeSelect/TreeSelect.d.ts +1 -1
  18. package/dist/client/components/index.js +41 -41
  19. package/dist/client/components/style.css +298 -644
  20. package/dist/client/layout/weifuwu-layout.css +286 -640
  21. package/dist/client/vdom/browser/Browser.d.ts +2 -0
  22. package/dist/client/vdom/commands.d.ts +4 -1
  23. package/dist/client/vdom/context/UIContext.d.ts +8 -0
  24. package/dist/client/vdom/core/diff/attrs.d.ts +10 -2
  25. package/dist/client/vdom/core/field/attributes.d.ts +12 -0
  26. package/dist/client/vdom/core/field/events.d.ts +8 -0
  27. package/dist/client/vdom/core/field/input-sync.d.ts +14 -0
  28. package/dist/client/vdom/core/field/key.d.ts +3 -0
  29. package/dist/client/vdom/core/field/props.d.ts +13 -1
  30. package/dist/client/vdom/core/field/ref.d.ts +6 -0
  31. package/dist/client/vdom/core/field/style.d.ts +7 -1
  32. package/dist/client/vdom/core/node/component.d.ts +3 -4
  33. package/dist/client/vdom/core/node/native.d.ts +6 -1
  34. package/dist/client/vdom/core/patch/index.d.ts +24 -1
  35. package/dist/client/vdom/core/patch/processors.d.ts +8 -1
  36. package/dist/client/vdom/core/protocol.d.ts +45 -0
  37. package/dist/client/vdom/core/router.d.ts +7 -0
  38. package/dist/client/vdom/core/ssr/absorb.d.ts +31 -4
  39. package/dist/client/vdom/core/transform/index.d.ts +6 -6
  40. package/dist/client/vdom/core/v2/cycle.d.ts +54 -0
  41. package/dist/client/vdom/core/v2/diff.d.ts +80 -0
  42. package/dist/client/vdom/core/v2/integrate.d.ts +24 -0
  43. package/dist/client/vdom/core/v2/render.d.ts +28 -0
  44. package/dist/client/vdom/core/v2/schedule.d.ts +33 -0
  45. package/dist/client/vdom/core/v2/serve.d.ts +4 -0
  46. package/dist/client/vdom/core/v2/spy.d.ts +21 -0
  47. package/dist/client/vdom/core/v2/ssr.d.ts +14 -0
  48. package/dist/client/vdom/core/vnode.d.ts +9 -6
  49. package/dist/client/vdom/dev/error-counter.d.ts +27 -0
  50. package/dist/client/vdom/dev/render-health.d.ts +60 -0
  51. package/dist/client/vdom/hooks/chat.d.ts +32 -5
  52. package/dist/client/vdom/hooks/drag-media.d.ts +3 -1
  53. package/dist/client/vdom/hooks/env.d.ts +32 -0
  54. package/dist/client/vdom/hooks/popup-manager.d.ts +21 -0
  55. package/dist/client/vdom/hooks/popup.d.ts +4 -1
  56. package/dist/client/vdom/hooks/stable.d.ts +4 -0
  57. package/dist/client/vdom/hooks/use-observable.d.ts +13 -0
  58. package/dist/client/vdom/index.d.ts +14 -6
  59. package/dist/client/vdom/index.js +4 -7
  60. package/dist/client/vdom/jsx-runtime.js +1 -1
  61. package/dist/client/vdom/middlewares/api.d.ts +8 -0
  62. package/dist/client/vdom/middlewares/auth-i18n.d.ts +7 -0
  63. package/dist/client/vdom/middlewares/ws.d.ts +41 -1
  64. package/dist/client/vdom/observable/index.d.ts +13 -0
  65. package/dist/client/vdom/observable/observable.d.ts +26 -0
  66. package/dist/client/vdom/observable/operators.d.ts +76 -0
  67. package/dist/client/vdom/observable/sources.d.ts +54 -0
  68. package/dist/client/vdom/observable/types.d.ts +45 -0
  69. package/dist/client/vdom/store.d.ts +17 -2
  70. package/dist/client/vdom/testing.js +2 -2
  71. package/dist/server/ai/agent.d.ts +18 -0
  72. package/dist/server/ai/client.d.ts +14 -2
  73. package/dist/server/ai/contracts.d.ts +2 -2
  74. package/dist/server/ai/sse.d.ts +6 -0
  75. package/dist/server/core/collect.d.ts +31 -0
  76. package/dist/server/core/error-counter.d.ts +11 -0
  77. package/dist/server/core/hub.d.ts +2 -0
  78. package/dist/server/core/router.d.ts +12 -9
  79. package/dist/server/db/contracts.d.ts +24 -0
  80. package/dist/server/db/memory-redis.d.ts +3 -4
  81. package/dist/server/db/memory-sql.d.ts +20 -4
  82. package/dist/server/db/postgres-server.d.ts +2 -0
  83. package/dist/server/db/query.d.ts +21 -0
  84. package/dist/server/db/redis-server.d.ts +4 -2
  85. package/dist/server/db/sql-parser.d.ts +2 -1
  86. package/dist/server/email/index.d.ts +2 -0
  87. package/dist/server/index.d.ts +4 -1
  88. package/dist/server/index.js +3927 -1982
  89. package/dist/server/messager/index.d.ts +21 -2
  90. package/dist/server/middleware/compress.d.ts +25 -0
  91. package/dist/server/ui/index.d.ts +8 -1
  92. package/dist/server/user/index.d.ts +4 -0
  93. package/dist/shared/router/chain.d.ts +9 -0
  94. package/dist/shared/router/context.d.ts +35 -0
  95. package/dist/shared/router/ctx-fields.d.ts +20 -0
  96. package/dist/shared/router/pipeline.d.ts +70 -0
  97. package/dist/shared/router/trie.d.ts +11 -3
  98. package/dist/shared/router/types.d.ts +23 -0
  99. package/docs/style-guide.md +44 -41
  100. package/package.json +13 -10
  101. package/content/apps/admin.md +0 -55
  102. package/content/apps/agent-platform.md +0 -35
  103. package/content/apps/auth.md +0 -49
  104. package/content/apps/multi.md +0 -44
  105. package/content/apps/todo.md +0 -51
  106. package/content/backend/ai.md +0 -28
  107. package/content/backend/auth.md +0 -20
  108. package/content/backend/email.md +0 -23
  109. package/content/backend/graphql.md +0 -23
  110. package/content/backend/http.md +0 -23
  111. package/content/backend/limit.md +0 -23
  112. package/content/backend/middleware.md +0 -17
  113. package/content/backend/queue.md +0 -23
  114. package/content/backend/redis.md +0 -26
  115. package/content/backend/router.md +0 -23
  116. package/content/backend/schedule.md +0 -23
  117. package/content/backend/sql.md +0 -27
  118. package/content/backend/sse.md +0 -26
  119. package/content/backend/ws.md +0 -26
  120. package/content/capabilities/app-node.md +0 -21
  121. package/content/capabilities/data.md +0 -21
  122. package/content/capabilities/events.md +0 -21
  123. package/content/capabilities/hooks.md +0 -22
  124. package/content/capabilities/i18n.md +0 -21
  125. package/content/capabilities/popup.md +0 -21
  126. package/content/capabilities/render-only.md +0 -23
  127. package/content/capabilities/router.md +0 -22
  128. package/content/capabilities/self-id.md +0 -21
  129. package/content/capabilities/store.md +0 -21
  130. package/content/capabilities/theme.md +0 -21
  131. package/content/capabilities/two-phase.md +0 -21
  132. package/content/components/accordion.md +0 -50
  133. package/content/components/actionsheet.md +0 -46
  134. package/content/components/affix.md +0 -51
  135. package/content/components/aichat.md +0 -57
  136. package/content/components/alert.md +0 -52
  137. package/content/components/alertgroup.md +0 -45
  138. package/content/components/anchor.md +0 -52
  139. package/content/components/app.md +0 -37
  140. package/content/components/approvalcard.md +0 -56
  141. package/content/components/appshell.md +0 -50
  142. package/content/components/aspectratio.md +0 -47
  143. package/content/components/authpage.md +0 -61
  144. package/content/components/autocomplete-v2.md +0 -40
  145. package/content/components/autocomplete.md +0 -56
  146. package/content/components/avatar.md +0 -51
  147. package/content/components/avatargroup.md +0 -47
  148. package/content/components/backtop.md +0 -53
  149. package/content/components/badge.md +0 -55
  150. package/content/components/breadcrumb.md +0 -49
  151. package/content/components/button.md +0 -63
  152. package/content/components/calendar-v2.md +0 -40
  153. package/content/components/calendar.md +0 -50
  154. package/content/components/card.md +0 -58
  155. package/content/components/carousel.md +0 -52
  156. package/content/components/cascader-v2.md +0 -39
  157. package/content/components/cascader.md +0 -54
  158. package/content/components/chart.md +0 -53
  159. package/content/components/chatinput.md +0 -63
  160. package/content/components/checkbox.md +0 -51
  161. package/content/components/checkboxgroup.md +0 -52
  162. package/content/components/citationcard.md +0 -48
  163. package/content/components/codeblock.md +0 -48
  164. package/content/components/codeeditor.md +0 -47
  165. package/content/components/collapse.md +0 -49
  166. package/content/components/colorpicker.md +0 -50
  167. package/content/components/command.md +0 -50
  168. package/content/components/confirm.md +0 -57
  169. package/content/components/contextmenu.md +0 -48
  170. package/content/components/copybutton.md +0 -51
  171. package/content/components/datepicker.md +0 -52
  172. package/content/components/descriptions-v2.md +0 -39
  173. package/content/components/descriptions.md +0 -52
  174. package/content/components/diffview-v2.md +0 -39
  175. package/content/components/diffview.md +0 -50
  176. package/content/components/divider.md +0 -48
  177. package/content/components/drawer.md +0 -55
  178. package/content/components/dropdown.md +0 -53
  179. package/content/components/editor.md +0 -49
  180. package/content/components/emptystate.md +0 -51
  181. package/content/components/exportcsv.md +0 -38
  182. package/content/components/field.md +0 -54
  183. package/content/components/filepreview-office.md +0 -37
  184. package/content/components/filepreview.md +0 -49
  185. package/content/components/filetree.md +0 -56
  186. package/content/components/fileupload-v2.md +0 -39
  187. package/content/components/fileupload.md +0 -57
  188. package/content/components/floatbutton.md +0 -52
  189. package/content/components/form-v2.md +0 -41
  190. package/content/components/form.md +0 -60
  191. package/content/components/grid.md +0 -51
  192. package/content/components/highlight-v2.md +0 -39
  193. package/content/components/highlight.md +0 -46
  194. package/content/components/hovercard.md +0 -51
  195. package/content/components/icon.md +0 -50
  196. package/content/components/imagecropper.md +0 -45
  197. package/content/components/img.md +0 -56
  198. package/content/components/infinitescroll-v2.md +0 -40
  199. package/content/components/infinitescroll.md +0 -54
  200. package/content/components/input.md +0 -65
  201. package/content/components/inputnumber.md +0 -58
  202. package/content/components/inview.md +0 -56
  203. package/content/components/jsonschemaform.md +0 -53
  204. package/content/components/jsonviewer-v2.md +0 -39
  205. package/content/components/jsonviewer.md +0 -49
  206. package/content/components/kanban.md +0 -46
  207. package/content/components/label.md +0 -48
  208. package/content/components/layout.md +0 -54
  209. package/content/components/layoutcontent.md +0 -43
  210. package/content/components/layoutheader.md +0 -43
  211. package/content/components/layoutsider.md +0 -43
  212. package/content/components/link.md +0 -52
  213. package/content/components/list.md +0 -44
  214. package/content/components/loading.md +0 -45
  215. package/content/components/logviewer-v2.md +0 -39
  216. package/content/components/logviewer.md +0 -53
  217. package/content/components/markdown.md +0 -51
  218. package/content/components/markdowneditor.md +0 -47
  219. package/content/components/math.md +0 -42
  220. package/content/components/mentions-v2.md +0 -39
  221. package/content/components/mentions.md +0 -52
  222. package/content/components/menu.md +0 -56
  223. package/content/components/menubar.md +0 -44
  224. package/content/components/messagebubble.md +0 -50
  225. package/content/components/modal.md +0 -59
  226. package/content/components/navmenu.md +0 -47
  227. package/content/components/notification.md +0 -51
  228. package/content/components/pageheader.md +0 -53
  229. package/content/components/pagination.md +0 -49
  230. package/content/components/paragraph.md +0 -45
  231. package/content/components/passwordinput.md +0 -57
  232. package/content/components/pininput-v2.md +0 -39
  233. package/content/components/pininput.md +0 -50
  234. package/content/components/pipeline.md +0 -49
  235. package/content/components/popconfirm.md +0 -58
  236. package/content/components/popover.md +0 -61
  237. package/content/components/progressbar.md +0 -50
  238. package/content/components/prompttemplate.md +0 -49
  239. package/content/components/qrcode.md +0 -50
  240. package/content/components/radiogroup.md +0 -53
  241. package/content/components/rate.md +0 -53
  242. package/content/components/reasoningblock.md +0 -47
  243. package/content/components/relationgraph.md +0 -52
  244. package/content/components/resizable.md +0 -53
  245. package/content/components/result.md +0 -49
  246. package/content/components/scrollbar.md +0 -49
  247. package/content/components/searchinput.md +0 -51
  248. package/content/components/segmentedcontrol.md +0 -59
  249. package/content/components/select-searchable.md +0 -47
  250. package/content/components/select.md +0 -66
  251. package/content/components/sessionlist.md +0 -52
  252. package/content/components/sheetgrid.md +0 -44
  253. package/content/components/skeleton.md +0 -55
  254. package/content/components/slidecanvas.md +0 -44
  255. package/content/components/slider.md +0 -62
  256. package/content/components/sortablelist.md +0 -39
  257. package/content/components/space.md +0 -52
  258. package/content/components/sparkline.md +0 -52
  259. package/content/components/statcard-countdown.md +0 -39
  260. package/content/components/statcard.md +0 -56
  261. package/content/components/steps.md +0 -48
  262. package/content/components/switch.md +0 -50
  263. package/content/components/tabbar.md +0 -45
  264. package/content/components/table-v2.md +0 -40
  265. package/content/components/table.md +0 -66
  266. package/content/components/tabs.md +0 -56
  267. package/content/components/tag.md +0 -51
  268. package/content/components/tagsinput-v2.md +0 -39
  269. package/content/components/tagsinput.md +0 -54
  270. package/content/components/text.md +0 -45
  271. package/content/components/textarea.md +0 -57
  272. package/content/components/themeswitch.md +0 -69
  273. package/content/components/timeline.md +0 -50
  274. package/content/components/title.md +0 -45
  275. package/content/components/toast.md +0 -52
  276. package/content/components/toggle-togglegroup.md +0 -52
  277. package/content/components/togglegroup.md +0 -47
  278. package/content/components/toolcallcard.md +0 -51
  279. package/content/components/tooltip.md +0 -50
  280. package/content/components/tour.md +0 -50
  281. package/content/components/transfer.md +0 -52
  282. package/content/components/tree-v2.md +0 -39
  283. package/content/components/tree.md +0 -59
  284. package/content/components/treeselect.md +0 -54
  285. package/content/components/typography.md +0 -51
  286. package/content/components/videoplayer.md +0 -52
  287. package/content/components/virtuallist.md +0 -52
  288. package/content/components/virtualtable-v2.md +0 -39
  289. package/content/components/virtualtable.md +0 -55
  290. package/content/components/watermark.md +0 -53
  291. package/content/components/wave.md +0 -43
  292. package/content/guides/ai-chat-family.md +0 -24
  293. package/content/guides/choose.md +0 -67
  294. package/content/guides/component-model.md +0 -32
  295. package/content/guides/component-standards.md +0 -123
  296. package/content/guides/components-guide.md +0 -813
  297. package/content/guides/custom-component.md +0 -321
  298. package/content/guides/data-guide.md +0 -281
  299. package/content/guides/file-preview-family.md +0 -18
  300. package/content/guides/frontend.md +0 -968
  301. package/content/guides/layout-choice.md +0 -64
  302. package/content/guides/layout-guide.md +0 -241
  303. package/content/guides/middleware.md +0 -459
  304. package/content/guides/mobile-guide.md +0 -105
  305. package/content/guides/page-building.md +0 -98
  306. package/content/guides/production.md +0 -37
  307. package/content/guides/quality.md +0 -60
  308. package/content/guides/realtime-guide.md +0 -296
  309. package/content/guides/render-only.md +0 -44
  310. package/content/guides/saas-guide.md +0 -253
  311. package/content/guides/server-guide.md +0 -359
  312. package/content/guides/start.md +0 -41
  313. package/content/guides/styling.md +0 -154
  314. package/content/guides/ui-dom-guide.md +0 -157
  315. package/content/index.json +0 -4344
  316. package/content/index.md +0 -181
  317. package/content/layout/align.md +0 -20
  318. package/content/layout/anchor.md +0 -19
  319. package/content/layout/app-shell.md +0 -23
  320. package/content/layout/border.md +0 -20
  321. package/content/layout/center.md +0 -19
  322. package/content/layout/cluster.md +0 -19
  323. package/content/layout/container.md +0 -19
  324. package/content/layout/fill.md +0 -19
  325. package/content/layout/grid.md +0 -19
  326. package/content/layout/hidden.md +0 -22
  327. package/content/layout/layer.md +0 -19
  328. package/content/layout/position.md +0 -22
  329. package/content/layout/row.md +0 -23
  330. package/content/layout/safe-area.md +0 -20
  331. package/content/layout/scroll.md +0 -21
  332. package/content/layout/spacing.md +0 -22
  333. package/content/layout/split.md +0 -19
  334. package/content/layout/stack.md +0 -19
  335. package/content/layout/surface.md +0 -23
  336. package/content/layout/text.md +0 -22
  337. package/content/patterns/app-shell.md +0 -34
  338. package/content/patterns/dashboard.md +0 -36
  339. package/content/patterns/data-screen.md +0 -30
  340. package/content/patterns/detail-page.md +0 -31
  341. package/content/patterns/docs.md +0 -34
  342. package/content/patterns/focus-task.md +0 -34
  343. package/content/patterns/landing.md +0 -35
  344. package/content/patterns/list-page.md +0 -32
  345. package/content/patterns/mobile.md +0 -31
  346. package/content/patterns/settings-page.md +0 -33
  347. package/content/patterns/workspace.md +0 -32
  348. package/dist/cli/content-sync.test.d.ts +0 -1
  349. package/dist/cli/docs-cli.test.d.ts +0 -1
  350. package/dist/cli/docs.d.ts +0 -2
  351. package/dist/cli/docs.mjs +0 -10961
  352. package/dist/client/vdom/core/build.d.ts +0 -36
  353. package/dist/client/vdom/core/diff/children.d.ts +0 -29
  354. package/dist/client/vdom/core/diff/index.d.ts +0 -22
  355. package/dist/client/vdom/core/diff/output.d.ts +0 -30
  356. package/dist/client/vdom/core/diff/same.d.ts +0 -22
  357. package/dist/client/vdom/core/serve.d.ts +0 -75
  358. package/dist/client/vdom/core/ssr/index.d.ts +0 -25
  359. package/examples/apps/admin/README.md +0 -23
  360. package/examples/apps/admin/api.ts +0 -27
  361. package/examples/apps/admin/app.tsx +0 -144
  362. package/examples/apps/admin/main.tsx +0 -8
  363. package/examples/apps/admin/server.ts +0 -37
  364. package/examples/apps/auth/README.md +0 -23
  365. package/examples/apps/auth/api.ts +0 -49
  366. package/examples/apps/auth/app.tsx +0 -137
  367. package/examples/apps/auth/main.tsx +0 -8
  368. package/examples/apps/auth/server.ts +0 -37
  369. package/examples/apps/multi/README.md +0 -23
  370. package/examples/apps/multi/app.tsx +0 -83
  371. package/examples/apps/multi/main.tsx +0 -8
  372. package/examples/apps/multi/server.ts +0 -33
  373. package/examples/apps/todo/README.md +0 -23
  374. package/examples/apps/todo/api.ts +0 -26
  375. package/examples/apps/todo/app.tsx +0 -128
  376. package/examples/apps/todo/main.tsx +0 -9
  377. package/examples/apps/todo/server.ts +0 -39
  378. package/examples/hello-world/README.md +0 -9
  379. package/examples/hello-world/client.ts +0 -14
  380. package/examples/hello-world/routes.tsx +0 -26
  381. package/examples/hello-world/server.ts +0 -46
  382. package/examples/patterns/AppShell.tsx +0 -224
  383. package/examples/patterns/Dashboard.tsx +0 -153
  384. package/examples/patterns/DataScreen.tsx +0 -104
  385. package/examples/patterns/DetailPage.tsx +0 -79
  386. package/examples/patterns/Docs.tsx +0 -105
  387. package/examples/patterns/FocusTask.tsx +0 -67
  388. package/examples/patterns/Landing.tsx +0 -90
  389. package/examples/patterns/ListPage.tsx +0 -77
  390. package/examples/patterns/Mobile.tsx +0 -154
  391. package/examples/patterns/SettingsPage.tsx +0 -98
  392. package/examples/patterns/SplitWorkspace.tsx +0 -113
@@ -1,37 +0,0 @@
1
- # 生产级案例(agent-platform)
2
-
3
- > 来源:`apps/agent-platform/`——多租户 AI Agent 平台,weifuwu 中间件全量消费方。
4
- > 定位:**实战驱动框架开发的生产级参考**——showcase 的教学模板由此提炼,框架能力先在此实战验证。
5
-
6
- ## 中间件全家桶装配(真实顺序即依赖顺序)
7
-
8
- ```ts
9
- import { serve, Router, cors, postgres, redis, ui, userSystem, ai, messager, rateLimit, verifyPassword, email } from 'weifuwu'
10
-
11
- const app = new Router()
12
- app.use(cors())
13
- app.use(postgres()) // ctx.sql——契约层(引擎实现)
14
- app.use(redis()) // ctx.redis——独立连接工厂 createConnection()
15
- app.use(userSystem()) // ctx.user/ctx.auth——登录态
16
- app.use(ai()) // ctx.ai——chat/stream/agent/approve
17
- app.use(messager()) // 实时消息
18
- app.use(rateLimit({ redis: r.redis, windowMs: 60_000, max: 100 })) // ctx.limit
19
- app.use(ui()) // ctx.ui——前端
20
- ```
21
-
22
- ## 架构决策(可复用的模式)
23
-
24
- 1. **路由按域注册**:`registerAuthRoutes / registerAgentRoutes / ...`——每域一个函数(showcase 模板的 registerXxxApi 同源)
25
- 2. **14 页 SPA**:单一前端入口 + 路由表——见 `src/ui/routes.ts`
26
- 3. **服务层独立**:services/(chat/agent-runner/sandbox)不依赖路由层——可单测
27
- 4. **沙箱隔离**:sandbox/(docker + host 管理)——Agent 执行环境
28
- 5. **商业化能力**:订阅分层/租户管理/邀请/白标/私有化——见 apps/agent-platform/README.md
29
-
30
- ## 学习路径
31
-
32
- 1. 先跑起来:`cd apps/agent-platform && node --env-file=.env server.ts`
33
- 2. 读 `src/middleware/ctx.ts`(AppCtx——中间件注入面全貌)
34
- 3. 对照 showcase 教学模板(todo/auth/admin/multi)理解"模板 = 生产架构的简化提炼"
35
-
36
- > 纪律:**实战先行、文档跟进**——框架能力变更先在 agent-platform 验证,再沉淀进 showcase 文档。
37
-
@@ -1,60 +0,0 @@
1
- # 人类质量标准(交付前验收清单)
2
-
3
- > 用途:开发完成、交付给人类用户前,逐项自查。每一项失败都必须是**拒绝交付**的理由。
4
- > 素材来源:AGENTS.md §8 设计系统纪律 + 组件走查记录(agent-browser 实测沉淀)。
5
-
6
- ## □ 1. 可访问性(键盘全程可达)
7
-
8
- - [ ] Tab 顺序合理;role="button"/tabindex 元素有 Enter/Space 处理
9
- - [ ] 方向键导航组件(Tabs/DatePicker/Menu)焦点跟随激活项
10
- - [ ] 弹层(Modal/Drawer/Dropdown/Popover/Tooltip)Escape 关闭
11
- - [ ] Modal 系焦点 trap + 关闭后焦点归还
12
- - [ ] 危险操作(Confirm)默认 maskClosable=false(防误触)
13
- - [ ] aria 语义:aria-expanded/aria-current/aria-label 正确
14
-
15
- ## □ 2. 响应式(三断点)
16
-
17
- - [ ] 375 / 768 / 1280 三断点无横向溢出
18
- - [ ] 导航正确降级(侧栏 → 顶部条)
19
- - [ ] 表格窄屏横向滚动(Table minWidth)或卡片化
20
- - [ ] 弹层视口夹紧(openPopup 自动)
21
-
22
- ## □ 3. 主题(亮/暗/自动)
23
-
24
- - [ ] 全部颜色走 `--wf-color-*` token(无裸色值)
25
- - [ ] 语义文字色用 `-text` 变体;实心填充文字用 `on-brand`
26
- - [ ] 对比度 ≥ 4.5:1(文字);focus-ring 含 primary 线(明暗均可见)
27
-
28
- ## □ 4. 动效
29
-
30
- - [ ] 时长/缓动走 `--wf-dur-*` / `--wf-ease-*`(无硬编码)
31
- - [ ] 退场类 `--exit` 成对(有 exit 类必须挂上)
32
- - [ ] reduced-motion 降级(_base.css 自动——勿覆盖)
33
-
34
- ## □ 5. 状态矩阵
35
-
36
- - [ ] loading / error / empty / disabled 四态全覆盖(无缺态渲染)
37
- - [ ] 提交按钮 loading 防重复提交
38
- - [ ] 受控组件有回调(无静默不可点)
39
-
40
- ## □ 6. 性能
41
-
42
- - [ ] 首帧预算合理(大数据列表用 VirtualList/VirtualTable/InfiniteScroll)
43
- - [ ] 无渲染循环(vdom3 防死循环守护不触发)
44
- - [ ] 事件流无 error:caught(浏览器 console 零错误)
45
-
46
- ## □ 7. 框架纪律
47
-
48
- - [ ] 无裸 `window.`/`document.`/`localStorage`(ctx.browser)
49
- - [ ] 渲染只发生在 `ctx.ui.render()` 调用处(无隐式触发)
50
- - [ ] 无 eval/new Function;无 npm 运行时依赖(前端)
51
- - [ ] 请求路径无同步 I/O(后端)
52
-
53
- ## 验证手段(agent-browser 走查纪律)
54
-
55
- 1. 真实点击(CDP)验证交互——`eval click` 绕过命中测试会掩盖问题,两者都测
56
- 2. 查 outerHTML(结构)+ getAttribute('style')(定位/显隐)+ getBoundingClientRect(真实可见性)
57
- 3. `closest('#__wf_portal')` 验证浮层 portal
58
- 4. 每次验证前 reload 清状态(会话残留制造假 bug)
59
- 5. console --level error 抓加载期错误(hook 需在页面加载前)
60
-
@@ -1,296 +0,0 @@
1
- # 实时能力指南(ws/sse)
2
-
3
- > 从 docs/realtime.md 迁移(content/ 文档库——随 npm 包发布,与框架版本同步)。
4
- > 本页为叙述性指南——组件/能力逐项参考见 content/ 各域目录。
5
-
6
- # 实时与渲染 — scheduler / ui / graphql / WebSocket(weifuwu)
7
-
8
- ## scheduler — 计划任务(即时/延时/cron)
9
-
10
- > 依赖 `queue`(触发后入队执行)。三类任务:即时(queue.add 已有)、延时(`ctx.schedule`)、定时(`ctx.cron`)。
11
-
12
- ```ts
13
- import { redis, queue, scheduler } from 'weifuwu'
14
-
15
- // 模式 A 显式注入:redis 是 scheduler 的第一方消费者(ZSET 延时队列 + HASH cron 注册表
16
- // 直接命令 redis)——必传,与 queue({ redis }) 对齐;scheduler.close() 不关闭注入的 redis
17
- const r = redis() // ctx.redis(RedisPool)
18
- const q = queue({ redis: r.redis }) // 入队执行(stream)
19
- app.use(r)
20
- app.use(q)
21
- app.use(scheduler({ redis: r.redis, queue: q })) // 守护循环走 createConnection() 独立连接
22
-
23
- // 延时任务(单次):delayMs 或指定时间
24
- await ctx.schedule('email.send', { to, body }, { delayMs: 30_000 })
25
- await ctx.schedule('report.build', {}, { when: new Date('2026-09-01T00:00:00Z') })
26
-
27
- // cron 定时任务(重复):每分钟触发 → 入队执行
28
- ctx.cron('* * * * *', 'heartbeat.check', { scope: 'health' })
29
- // 改需求 = 重新注册(同 name 覆盖更新,旧定义不残留)
30
- ctx.cron('*/5 * * * *', 'heartbeat.check', { scope: 'health' })
31
- // 停用 = cancel(删定义 + 清理 pending 触发点)
32
- await ctx.cancelCron('heartbeat.check')
33
-
34
- // 执行端:与 queue 完全一致
35
- const worker = ctx.queue.worker('email.send', async (job) => { ... })
36
- ```
37
-
38
- - **延时**:ZSET(score=触发时间戳)+ 守护循环(独立连接)→ 到期 `ZREM` 原子抢占(多实例不重复)→ `queue.add`
39
- - **多应用隔离**:`scheduler({ prefix })`——ZSET/HASH 应用级共享,多应用共用 redis 时必须各自 prefix(同应用多实例共享 prefix = 协作消费)
40
- - **连接所有权**:scheduler 内部用 `redis.createConnection()` 独立守护连接(不占池——对齐 queue worker);`scheduler.close()` 只关守护连接——**不关闭注入的 redis**(调用方负责 `r.close()`)
41
- - **cron**:HASH 注册表(**field = name,同 name 重新注册 = 覆盖更新**,改表达式不残留旧定义)+ 滚动生成触发点(`ZADD NX` 幂等)→ 复用延时链路;`nextRunAt` 原子推进
42
- - **取消**:`ctx.cancelCron(name)` 删定义 + 清理 pending 触发点(停用 cron 必须 cancel——定义无 TTL 会累积)
43
- - **崩溃恢复**:未消费触发点留在 ZSET,重启后补扫立即触发(at-least-once,幂等由业务保证)
44
- - **cron 表达式**:5 字段(分 时 日 月 周),支持 `*`/步进/列表/范围;时区 = 服务器本地;非法表达式注册即抛错
45
- - **裁剪**:❌ cron 秒/年/别名(@daily)/特殊字符(L/W/#)、时区配置、单次任务取消(v2)、分布式锁(原子命令抢占替代)
46
- - **文档红线**:cron 定义持久化在 HASH——进程重启后守护循环恢复即继续触发(无需重新注册);**停用必须 `cancelCron`**(定义无 TTL,不取消会永久触发)
47
-
48
- ## ui — SSR 渲染 + JS/CSS 编译
49
-
50
- ```ts
51
- import { ui } from 'weifuwu'
52
-
53
- app.use(ui())
54
- ```
55
-
56
- | ctx 注入 | 签名 | 说明 |
57
- |----------|------|------|
58
- | `ctx.ui.html` | `` (strings, ...values) => Response `` | HTML 模板 (转义防 XSS) |
59
- | `ctx.ui.html.unsafe(str)` | `(string) => string` | 插入原始 HTML |
60
- | `ctx.ui.js(entryPath)` | `(string) => Promise<Response>` | esbuild 编译 TSX → JS bundle |
61
- | `ctx.ui.css(entryPath)` | `(string) => Promise<Response>` | 读取 CSS 文件 → CSS Response(如安装 postcss + @tailwindcss/postcss 则自动编译) |
62
- | `ctx.ui.ssr(Comp, props?, { data })` | `(Component, props, opts?) => Promise<string>` | 服务端渲染组件 → HTML 片段(async 工厂自动 await;HtmlSafe 内联不二次转义) |
63
- | `ctx.ui.ssrData(data)` | `(Map) => string` | 序列化 SSR 数据 → `<script>window.__DATA__=...</script>`(`<` 转义防 XSS) |
64
-
65
- ### ctx.ui.html — HTML 模板
66
-
67
- 模板插值自动转义(`& < > "` → 实体),防 XSS:
68
-
69
- ```ts
70
- app.get('/page', (req, ctx) => ctx.ui.html`
71
- <h1>${title}</h1> <!-- 自动转义 -->
72
- <div>${ctx.ui.html.unsafe(richHtml)}</div> <!-- 不转义 -->
73
- `)
74
- ```
75
-
76
- ### ctx.ui.js — 编译 TSX → JS
77
-
78
- ```ts
79
- app.get('/app.js', (req, ctx) => ctx.ui.js('./src/main.tsx')) // 相对路径
80
-
81
- app.get('/app.js', (req, ctx) => ctx.ui.js('weifuwu/ui-dom')) // 或包名(exports map 解析)
82
- ```
83
-
84
- 使用 esbuild 编译:
85
- - `bundle: true`, `format: 'esm'`, `platform: 'browser'`
86
- - `jsx: 'automatic'`, `jsxImportSource: 'weifuwu/ui-dom'`
87
- - 带 mtime 缓存验证(开发时编辑文件后自动失效)
88
-
89
- ### ctx.ui.css — CSS 编译
90
-
91
- ```ts
92
- app.get('/style.css', (req, ctx) => ctx.ui.css('./src/style.css')) // 相对路径
93
- app.get('/style.css', (req, ctx) => ctx.ui.css('weifuwu/components/style.css')) // 或包名
94
- ```
95
-
96
- - 无编译工具时直接返回原始 CSS
97
- - 检测到已安装 `postcss` + `@tailwindcss/postcss` 时自动编译 Tailwind CSS
98
- - 支持包名(`weifuwu/layout/style.css`, `weifuwu/components/style.css`)或文件路径
99
- - 带 mtime 缓存验证(开发时编辑文件后自动失效)
100
-
101
- ### ctx.ui.ssr — SSR 渲染组件 → HTML
102
-
103
- 将组件(含 async 组件)在服务端渲染为完整 HTML 片段,数据经 `ctx.data` 预取并序列化进 `window.__DATA__`(客户端 hydration 时同步命中,不重跑请求):
104
-
105
- ```ts
106
- const BlogPage = async (initProps, ctx) => {
107
- const post = await ctx.data.get(`/api/posts/${ctx.params.slug}`, fetchPost)
108
- return () =>
109
- h('article', {},
110
- h('h1', {}, post.title),
111
- h('div', { innerHTML: post.body }),
112
- )
113
- }
114
-
115
- app.get('/blog/:slug', async (req, ctx) => {
116
- const data = new Map()
117
- const html = await ctx.ui.ssr(BlogPage, {}, { data }) // HtmlSafe:模板内联不二次转义
118
- return ctx.ui.html`
119
- <!DOCTYPE html>
120
- <html><body>
121
- <div id="root">${html}</div>
122
- ${ctx.ui.ssrData(data)}
123
- <script src="/static/app.js"></script>
124
- </body></html>
125
- `
126
- })
127
- ```
128
-
129
- - 事件处理器/ref 剥离,文本自动转义(XSS),`class`/`style` 对象序列化,`innerHTML` 原样输出
130
- - Fragment/Portal 子节点就地内联
131
- - `ctx.ui.ssrData(data)` 输出 `<script>window.__DATA__=...</script>`(JSON `<` 转义防 XSS)
132
- - 服务端 ctx shim:`$`(dirty no-op)、`ctx.data` 预取去重、`selfId` 请求级隔离
133
-
134
- ### Hydration — 客户端收养服务端 HTML(事件流形态)
135
-
136
- 服务端将 vnode 构建为**事件流**(`renderToEvents`)→ `eventsToHtml` 输出完整 HTML + `serializeEvents` 序列化进 `__DATA__`,客户端 `deserializeEvents` + `replay` **收养**(DOM = fold(事件流)——零 DOM 猜测、不重建、无闪跳):
137
-
138
- ```ts
139
- import { createRouter, deserializeEvents, replay } from 'weifuwu/ui-dom'
140
-
141
- const root = document.querySelector('#root')!
142
- replay(deserializeEvents((window as any).__DATA__), root) // 收养服务端 HTML(同构)
143
- createRouter(routes, root) // 之后正常交互渲染
144
- ```
145
-
146
- - **DOM = fold(事件流)**:初始 DOM + 事件序列 = 任意时刻 DOM——收养即回放(与服务端渲染完全同构)
147
- - **async 工厂 hydration**:工厂 `ctx.data.get` 从 `__DATA__` 同步命中(不重跑请求)→ 渲染与服务端一致
148
- - 收养后事件流全量可用(与纯 SPA 无差别)
149
- - 诚实裁剪:Portal 内容就地收养(不移动到 `#__wf_portal`);渲染期非确定性(Date/random)会导致 mismatch(dev 警告)
150
-
151
- ### 路由级 SSR(routes 两端共享)
152
-
153
- 同一份 RouteDef[] 路由定义,后端构建事件流即自动 SSR,无需手写 handler/模板/序列化:
154
-
155
- ```tsx
156
- // routes.ts —— 前后端共用
157
- import { h } from 'weifuwu/ui-dom'
158
-
159
- export const routes = [{ path: '/blog/:slug', render: (params) => h(BlogPage, { slug: params.slug }) }]
160
-
161
- // server.ts —— renderToEvents → eventsToHtml + serializeEvents(完整 HTML + __DATA__ + styles)
162
- import { renderToEvents, eventsToHtml, serializeEvents } from 'weifuwu/ui-dom'
163
- const events = await renderToEvents(routes[0].render({ slug: 'hello' }))
164
- const page = eventsToHtml(events)
165
-
166
- // client.ts —— deserializeEvents + replay 收养
167
- replay(deserializeEvents((window as any).__DATA__), root)
168
- ```
169
-
170
- - 组件工厂读 `ctx.params`(`/blog/:slug` → `ctx.params.slug`)——两端同源注入
171
- - SSR(事件流形态):`renderToEvents` → `eventsToHtml` + `serializeEvents`——styles/title 由页面模板控制
172
-
173
- ### weifuwu/dev — 服务端直接跑 .tsx
174
-
175
- Node 原生 TS 只剥离类型(不支持 JSX)。`weifuwu/dev` 注册 esbuild loader,服务端直接跑 `.tsx`(零构建):
176
-
177
- ```json
178
- {
179
- "scripts": {
180
- "dev": "node --import weifuwu/dev server.ts",
181
- "start": "node --import weifuwu/dev server.ts"
182
- }
183
- }
184
- ```
185
-
186
- - 前后端同一 JSX 运行时(`jsxImportSource: weifuwu/ui-dom`)→ 两端 VNode 一致 → hydration 可靠
187
- - 与 `ctx.ui.js` 前端动态编译同一理念:无构建、无产物、改代码即生效
188
-
189
- ---
190
-
191
- ## graphql — GraphQL 端点
192
-
193
- > **SDL + resolvers 绑定为自研实现**(`makeExecutableSchema`,56 行替代 @graphql-tools/schema)——支持根类型与嵌套类型字段 resolver、默认属性查找。
194
-
195
- ```ts
196
- import type { GraphQLHandler } from 'weifuwu'
197
-
198
- const handler: GraphQLHandler = async (req, ctx) => ({
199
- schema: `
200
- type Query {
201
- hello: String
202
- users: [User]
203
- }
204
- type User { id: ID, name: String }
205
- `,
206
- resolvers: {
207
- Query: {
208
- hello: () => 'world',
209
- users: () => [{ id: 1, name: 'Alice' }],
210
- },
211
- },
212
- rootValue: {},
213
- context: (req, ctx) => ({ user: ctx.user }),
214
- graphiql: true,
215
- maxDepth: 10,
216
- timeout: 30000,
217
- })
218
-
219
- // 挂载到 /
220
- app.graphql(handler)
221
-
222
- // 或挂载到自定义路径
223
- app.graphql('/graphql', handler)
224
- ```
225
-
226
- | 选项 | 类型 | 默认值 | 说明 |
227
- |------|------|--------|------|
228
- | `schema` | `string \| GraphQLSchema` | — | SDL 字符串或 Schema 对象 |
229
- | `resolvers` | `any` | — | 解析器(schema 为字符串时必填)|
230
- | `rootValue` | `any` | — | 根值 |
231
- | `context` | `(req, ctx) => object` | — | 上下文工厂 |
232
- | `graphiql` | `boolean` | — | 启用 GraphiQL IDE |
233
- | `maxDepth` | `number` | `10` | 查询深度限制(0=关闭)|
234
- | `timeout` | `number` | `30000` | 执行超时(ms,0=关闭)|
235
-
236
- GET 请求支持 query 参数查询;POST 支持 JSON body。启用 `graphiql: true` 时,GET 无 `?query=` 参数返回 GraphiQL IDE 页面。
237
-
238
- ---
239
-
240
- ## WebSocket
241
-
242
- ```ts
243
- app.ws('/chat/:room', {
244
- open(ws, ctx) {
245
- ws.send(`欢迎加入 ${ctx.params.room} 房间`)
246
- ctx.hub?.join(ctx.params.room, ws)
247
- },
248
- message(ws, ctx, data) {
249
- // data: string | Buffer
250
- ctx.hub?.send(ctx.params.room, `用户: ${data}`)
251
- },
252
- close(ws, ctx) {
253
- ctx.hub?.leave(ws)
254
- },
255
- error(ws, ctx, error) {
256
- console.error('WS error:', error)
257
- },
258
- })
259
- ```
260
-
261
- | 回调 | 参数 | 说明 |
262
- |------|------|------|
263
- | `open(ws, ctx)` | `WebSocket`, `Context` | 连接建立 |
264
- | `message(ws, ctx, data)` | `WebSocket`, `Context`, `string \| Buffer` | 收到消息 |
265
- | `close(ws, ctx)` | `WebSocket`, `Context` | 连接关闭 |
266
- | `error(ws, ctx, error)` | `WebSocket`, `Context`, `Error` | 错误 |
267
-
268
- ### Hub — WebSocket 房间
269
-
270
- ```ts
271
- // 注入 hub → ctx.hub
272
- app.ws('/chat/:room', {
273
- open(ws, ctx) { ctx.hub.join(ctx.params.room, ws) },
274
- message(ws, ctx, data) { ctx.hub.send(ctx.params.room, String(data)) },
275
- close(ws, ctx) { ctx.hub.leave(ws) },
276
- })
277
-
278
- // 自定义 Hub(Redis 后端)
279
- import type { Hub } from 'weifuwu'
280
- const redisHub: Hub = { ... }
281
- app.wsHub(redisHub)
282
- ```
283
-
284
- | Hub 方法 | 说明 |
285
- |----------|------|
286
- | `join(key, ws)` | WebSocket 加入房间 |
287
- | `leave(ws)` | WebSocket 离开所有房间 |
288
- | `send(key, message)` | 向房间广播消息 |
289
- | `close()` | 关闭 Hub |
290
-
291
- WebSocket 原生 `ws.send()` 发送,`ws.on('message', cb)` WebSocket 接收。
292
-
293
- > **实时应用推荐用 `messager()`**(SaaS 地基模块):协议内置(`connected/subscribe/ping`)+ 持久化 + 跨进程广播 + 点对点,不必自写 Hub/协议——见[消息系统章节](saas-guide.md)。
294
-
295
- ---
296
-
@@ -1,44 +0,0 @@
1
- # render-only 状态
2
-
3
- > 唯一规则:**渲染只发生在 `ctx.ui.render()` 调用处**。状态是普通 JS 对象——
4
- > 行为可静态推导(代码审查看事件回调里有无 render() 即可验证渲染逻辑)。
5
-
6
- ## 三通道
7
-
8
- | 场景 | 写法 | 触发 |
9
- |------|------|------|
10
- | 组件内部状态 | `let count` + 改后 `ctx.ui.render()` | 显式调用 |
11
- | 跨组件共享 | `createStore(init)` + `ctx.ui.useExternal(store)` | store.set/update/notify 自动 |
12
- | 跨组件精准刷新 | mount 时 `ctx.ui.selfId('name')` → 任意处 `ctx.ui.render(['name'])` | 显式调用 |
13
-
14
- ```tsx
15
- // 内部状态
16
- const Counter = (_init, ctx) => {
17
- let count = 0
18
- return (props) => h('button', {
19
- onClick: () => { count++; ctx.ui.render() },
20
- }, count)
21
- }
22
-
23
- // 共享状态(模块级单例)
24
- const store = createStore({ user: null })
25
- const UserBadge = (_init, ctx) => {
26
- const s = ctx.ui.useExternal(store) // 订阅:变化 → 自身重渲染
27
- return (props) => h('span', {}, s.state.user?.name ?? '未登录')
28
- }
29
- store.set({ user }) // 任何位置 → 订阅组件自动重渲染
30
- ```
31
-
32
- ## 不需要渲染的状态
33
-
34
- `let el` / `let timerId` 等内部缓存——改后**不**调 render()(参考 AGENTS.md §4.1 表)。
35
-
36
- ## hooks(事件驱动——非赋值自动)
37
-
38
- useMedia/useInView/useChat 等是浏览器事件驱动重渲染——与"赋值自动"本质不同,保留合理。
39
-
40
- ## 历史教训
41
-
42
- v1 的 $ Proxy 在重挂载场景捕获的 selfId 与当前实例错位 → 交互静默失效。
43
- render-only 根治:render() 闭包绑定组件 id——无 this/selfId 错位。
44
-