akanjs 3.0.2 → 3.1.0-rc.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 (378) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/base/baseEnv.ts +0 -4
  3. package/base/primitiveRegistry.ts +2 -2
  4. package/client/cookie.ts +5 -1
  5. package/client/csrLocation.ts +122 -0
  6. package/client/csrTypes.ts +32 -4
  7. package/client/device.ts +2 -1
  8. package/client/frameConfig.ts +78 -7
  9. package/client/index.ts +3 -0
  10. package/client/makePageProto.tsx +3 -2
  11. package/client/native/external-view.ts +1 -0
  12. package/client/route/RootLayoutDefinition.ts +7 -1
  13. package/client/route/RouteHead.ts +108 -0
  14. package/client/route/index.ts +1 -0
  15. package/client/router.ts +36 -23
  16. package/client/rscNavigation.ts +8 -2
  17. package/client/viewportMeta.ts +60 -0
  18. package/client/webManifest.ts +18 -0
  19. package/common/Logger.ts +7 -2
  20. package/common/PipelineNames.ts +31 -0
  21. package/common/PipelinePattern.ts +70 -0
  22. package/common/PipelinePlanSchema.ts +490 -0
  23. package/common/backoff.ts +14 -0
  24. package/common/index.ts +39 -0
  25. package/common/pipelinePlan.ts +259 -0
  26. package/common/routeConvention.ts +1 -0
  27. package/common/types.ts +17 -0
  28. package/constant/constantRegistry.ts +26 -6
  29. package/dictionary/base.dictionary.ts +8 -0
  30. package/dictionary/trans.ts +9 -1
  31. package/document/into.ts +5 -0
  32. package/fetch/client/fetchClient.ts +135 -31
  33. package/fetch/client/httpClient.ts +45 -0
  34. package/fetch/client/wsClient.ts +125 -16
  35. package/fetch/fetchType/buildFetch.type.ts +1 -0
  36. package/index.ts +243 -10
  37. package/package.json +1 -5
  38. package/server/akanApp.ts +5 -2
  39. package/server/akanServer.ts +44 -8
  40. package/server/artifact/builderRpc.ts +8 -3
  41. package/server/artifact/ipcTypes.ts +5 -2
  42. package/server/di/diLifecycle.ts +39 -3
  43. package/server/di/utils.ts +28 -1
  44. package/server/ed25519Key.ts +48 -0
  45. package/server/index.ts +1 -0
  46. package/server/machine/index.ts +2 -0
  47. package/server/machine/machineAccount.ts +27 -0
  48. package/server/machine/machineToken.ts +151 -0
  49. package/server/mcp/McpApps.ts +256 -0
  50. package/server/mcp/McpDispatcher.ts +31 -7
  51. package/server/mcp/McpRouter.ts +209 -46
  52. package/server/ops/opsToken.ts +3 -10
  53. package/server/resolver/database.resolver.ts +3 -0
  54. package/server/resolver/signal.resolver.ts +40 -3
  55. package/server/routeElementComposer.tsx +78 -2
  56. package/server/routeState.ts +6 -0
  57. package/server/routeTreeBuilder.ts +26 -9
  58. package/server/routing/apiRouter.ts +6 -3
  59. package/server/routing/roomReplay.ts +88 -0
  60. package/server/rscClient.tsx +53 -8
  61. package/server/rscWorker.tsx +141 -27
  62. package/server/rscWorkerHost.ts +18 -5
  63. package/server/sitemap.ts +14 -0
  64. package/server/ssrFromRscRenderer.tsx +12 -6
  65. package/server/ssrTypes.ts +3 -1
  66. package/server/systemPageDocument.tsx +38 -30
  67. package/server/types.tsx +2 -0
  68. package/server/webRouter.ts +74 -5
  69. package/service/injectInfo.ts +9 -1
  70. package/service/ipcTypes.ts +2 -1
  71. package/service/predefinedAdaptor/database.adaptor.ts +1 -146
  72. package/service/predefinedAdaptor/queue.adaptor.ts +44 -6
  73. package/service/predefinedAdaptor/queueBackoff.ts +12 -0
  74. package/service/predefinedAdaptor/solidQueue.adaptor.ts +17 -13
  75. package/service/predefinedAdaptor/sql/SqlDocumentStore.ts +44 -2
  76. package/service/predefinedAdaptor/sql/dialect/postgres.ts +3 -0
  77. package/service/predefinedAdaptor/sql/dialect/sqlite.ts +5 -2
  78. package/service/predefinedAdaptor/sql/search/fts5.ts +1 -1
  79. package/service/predefinedAdaptor/sql/types.ts +8 -6
  80. package/service/predefinedAdaptor/sql/values.ts +0 -23
  81. package/service/serve.ts +5 -1
  82. package/signal/agent.signal.ts +1 -1
  83. package/signal/base.signal.ts +2 -2
  84. package/signal/endpointIdempotency.ts +53 -0
  85. package/signal/internalArg.ts +14 -0
  86. package/signal/mcp/McpDocument.ts +38 -1
  87. package/signal/mcp/mcpProtocol.ts +18 -0
  88. package/signal/signalContext.ts +58 -30
  89. package/signal/signalRegistry.ts +14 -4
  90. package/signal/types.ts +18 -3
  91. package/store/agent/StoreSurfaceSource.ts +1 -1
  92. package/store/agentic/StToolBuilder.ts +3 -0
  93. package/test/conformance.ts +9 -33
  94. package/types/base/baseEnv.d.ts +0 -4
  95. package/types/base/primitiveRegistry.d.ts +1 -1
  96. package/types/client/csrLocation.d.ts +32 -0
  97. package/types/client/csrTypes.d.ts +40 -4
  98. package/types/client/frameConfig.d.ts +14 -2
  99. package/types/client/index.d.ts +3 -0
  100. package/types/client/native/external-view.d.ts +1 -0
  101. package/types/client/route/RootLayoutDefinition.d.ts +2 -1
  102. package/types/client/route/RouteHead.d.ts +13 -0
  103. package/types/client/route/index.d.ts +1 -0
  104. package/types/client/router.d.ts +6 -0
  105. package/types/client/rscNavigation.d.ts +4 -0
  106. package/types/client/viewportMeta.d.ts +18 -0
  107. package/types/client/webManifest.d.ts +4 -0
  108. package/types/common/PipelineNames.d.ts +6 -0
  109. package/types/common/PipelinePattern.d.ts +14 -0
  110. package/types/common/PipelinePlanSchema.d.ts +9 -0
  111. package/types/common/backoff.d.ts +10 -0
  112. package/types/common/index.d.ts +5 -0
  113. package/types/common/pipelinePlan.d.ts +224 -0
  114. package/types/common/types.d.ts +16 -0
  115. package/types/constant/constantRegistry.d.ts +5 -2
  116. package/types/dictionary/base.dictionary.d.ts +1 -1
  117. package/types/dictionary/dictionary.d.ts +8 -8
  118. package/types/document/into.d.ts +9 -0
  119. package/types/fetch/client/fetchClient.d.ts +31 -4
  120. package/types/fetch/client/httpClient.d.ts +8 -0
  121. package/types/fetch/client/wsClient.d.ts +26 -2
  122. package/types/fetch/fetchType/buildFetch.type.d.ts +1 -0
  123. package/types/index.d.ts +230 -9
  124. package/types/server/akanServer.d.ts +16 -1
  125. package/types/server/artifact/builderRpc.d.ts +7 -2
  126. package/types/server/artifact/ipcTypes.d.ts +5 -1
  127. package/types/server/di/utils.d.ts +1 -0
  128. package/types/server/ed25519Key.d.ts +13 -0
  129. package/types/server/index.d.ts +1 -0
  130. package/types/server/machine/index.d.ts +2 -0
  131. package/types/server/machine/machineAccount.d.ts +5 -0
  132. package/types/server/machine/machineToken.d.ts +29 -0
  133. package/types/server/machine.d.ts +1 -0
  134. package/types/server/mcp/McpApps.d.ts +50 -0
  135. package/types/server/mcp/McpDispatcher.d.ts +4 -1
  136. package/types/server/mcp/McpRouter.d.ts +4 -0
  137. package/types/server/resolver/signal.resolver.d.ts +2 -1
  138. package/types/server/routeElementComposer.d.ts +24 -4
  139. package/types/server/routeState.d.ts +4 -1
  140. package/types/server/routing/roomReplay.d.ts +24 -0
  141. package/types/server/rscWorkerHost.d.ts +5 -2
  142. package/types/server/sitemap.d.ts +2 -0
  143. package/types/server/ssrFromRscRenderer.d.ts +3 -3
  144. package/types/server/ssrTypes.d.ts +4 -1
  145. package/types/server/systemPageDocument.d.ts +2 -0
  146. package/types/server/types.d.ts +4 -1
  147. package/types/server/webRouter.d.ts +3 -1
  148. package/types/service/ipcTypes.d.ts +2 -0
  149. package/types/service/predefinedAdaptor/database.adaptor.d.ts +1 -24
  150. package/types/service/predefinedAdaptor/queue.adaptor.d.ts +10 -3
  151. package/types/service/predefinedAdaptor/queueBackoff.d.ts +4 -0
  152. package/types/service/predefinedAdaptor/solidQueue.adaptor.d.ts +3 -3
  153. package/types/service/predefinedAdaptor/sql/SqlDocumentStore.d.ts +6 -1
  154. package/types/service/predefinedAdaptor/sql/dialect/postgres.d.ts +1 -0
  155. package/types/service/predefinedAdaptor/sql/dialect/sqlite.d.ts +1 -0
  156. package/types/service/predefinedAdaptor/sql/search/fts5.d.ts +1 -1
  157. package/types/service/predefinedAdaptor/sql/types.d.ts +9 -5
  158. package/types/service/predefinedAdaptor/sql/values.d.ts +0 -3
  159. package/types/service/serve.d.ts +3 -0
  160. package/types/signal/endpointIdempotency.d.ts +7 -0
  161. package/types/signal/internalArg.d.ts +10 -0
  162. package/types/signal/mcp/McpDocument.d.ts +8 -0
  163. package/types/signal/mcp/mcpProtocol.d.ts +17 -0
  164. package/types/signal/signalContext.d.ts +5 -3
  165. package/types/signal/signalRegistry.d.ts +4 -4
  166. package/types/signal/types.d.ts +21 -1
  167. package/types/store/agentic/StToolBuilder.d.ts +2 -0
  168. package/types/test/conformance.d.ts +7 -10
  169. package/types/ui/Agent/Chat.d.ts +5 -1
  170. package/types/ui/Agent/EmbedApproval.d.ts +1 -0
  171. package/types/ui/Agent/index.d.ts +3 -0
  172. package/types/ui/Agent/useKeyboardFrame.d.ts +2 -0
  173. package/types/ui/Agent/useScreenActions.d.ts +18 -0
  174. package/types/ui/BottomSheet.d.ts +1 -0
  175. package/types/ui/Constant/Doc.d.ts +11 -17
  176. package/types/ui/Constant/index.d.ts +7 -2
  177. package/types/ui/Constant/schemaDoc.d.ts +11 -0
  178. package/types/ui/Dialog/Modal.d.ts +6 -1
  179. package/types/ui/Dialog/index.d.ts +1 -1
  180. package/types/ui/Dialog/modalSurface.d.ts +12 -0
  181. package/types/ui/Layout/BottomTab.d.ts +11 -2
  182. package/types/ui/Layout/FrameSlotFallback.d.ts +9 -0
  183. package/types/ui/Layout/Navbar.d.ts +4 -1
  184. package/types/ui/Layout/TopInset.d.ts +1 -1
  185. package/types/ui/Layout/index.d.ts +3 -3
  186. package/types/ui/Link/Action.d.ts +5 -1
  187. package/types/ui/Link/Anchor.d.ts +5 -3
  188. package/types/ui/Link/activePath.d.ts +13 -0
  189. package/types/ui/Link/index.d.ts +1 -1
  190. package/types/ui/Modal.d.ts +6 -1
  191. package/types/ui/Model/EditModal.d.ts +6 -1
  192. package/types/ui/Model/New.d.ts +6 -1
  193. package/types/ui/Model/ViewEditModal.d.ts +6 -1
  194. package/types/ui/Model/ViewModal.d.ts +6 -1
  195. package/types/ui/Model/newFormOrigin.d.ts +7 -0
  196. package/types/ui/Portal.d.ts +3 -1
  197. package/types/ui/Reference/origin.d.ts +12 -0
  198. package/types/ui/Signal/Doc.d.ts +23 -18
  199. package/types/ui/Signal/Listener.d.ts +2 -6
  200. package/types/ui/Signal/Object.d.ts +6 -10
  201. package/types/ui/Signal/Response.d.ts +3 -6
  202. package/types/ui/Signal/RestApi.d.ts +11 -15
  203. package/types/ui/Signal/WebSocket.d.ts +11 -21
  204. package/types/ui/Signal/endpointEntries.d.ts +8 -0
  205. package/types/ui/Signal/index.d.ts +35 -12
  206. package/types/ui/Signal/signalText.d.ts +178 -0
  207. package/types/ui/System/CSR.d.ts +2 -2
  208. package/types/ui/System/Client.d.ts +4 -3
  209. package/types/ui/System/Common.d.ts +27 -6
  210. package/types/ui/System/SSR.d.ts +6 -6
  211. package/types/ui/Tooltip.d.ts +4 -2
  212. package/types/ui/index.d.ts +2 -1
  213. package/types/ui/overlayLayer.d.ts +6 -0
  214. package/types/ui/overlayPosition.d.ts +17 -0
  215. package/types/vendor/@akanjs/native/packages/cli/src/api.d.ts +14 -3
  216. package/types/vendor/@akanjs/native/packages/cli/src/commands/update.d.ts +1 -1
  217. package/types/vendor/@akanjs/native/packages/cli/src/config.d.ts +30 -5
  218. package/types/vendor/@akanjs/native/packages/cli/src/lib/compat.d.ts +8 -0
  219. package/types/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.d.ts +5 -0
  220. package/types/vendor/@akanjs/native/packages/cli/src/lib/distribution.d.ts +22 -0
  221. package/types/vendor/@akanjs/native/packages/cli/src/lib/project.d.ts +4 -0
  222. package/types/vendor/@akanjs/native/packages/cli/src/lib/publish.d.ts +16 -10
  223. package/types/vendor/@akanjs/native/packages/cli/src/lib/updates.d.ts +51 -7
  224. package/types/vendor/@akanjs/native/packages/cli/src/lib/vectors.d.ts +1 -1
  225. package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.d.ts +7 -0
  226. package/types/vendor/@akanjs/native/packages/cli/src/platforms/windows.d.ts +5 -0
  227. package/types/vendor/@akanjs/native/packages/core/src/kernel.d.ts +36 -0
  228. package/types/vendor/@akanjs/native/packages/desktop/src/plugin.d.ts +2 -0
  229. package/types/vendor/@akanjs/native/packages/desktop/src/server.d.ts +11 -0
  230. package/types/vendor/@akanjs/native/plugins/external-view/src/desktop.d.ts +17 -0
  231. package/types/vendor/@akanjs/native/plugins/external-view/src/index.d.ts +132 -0
  232. package/types/vendor/@akanjs/native/plugins/external-view/src.d.ts +1 -0
  233. package/types/vendor/@akanjs/native/plugins/updates/src/index.d.ts +8 -0
  234. package/types/vendor/@akanjs/native/plugins/window/src/desktop.d.ts +4 -1
  235. package/types/vendor/@akanjs/native/plugins/window/src/index.d.ts +49 -0
  236. package/types/vendor/use-agentic/types.d.ts +2 -0
  237. package/types/webkit/CsrStack.d.ts +1 -1
  238. package/types/webkit/McpAppAgent.d.ts +14 -0
  239. package/types/webkit/McpAppApprovals.d.ts +8 -0
  240. package/types/webkit/McpAppBridge.d.ts +101 -0
  241. package/types/webkit/McpAppView.d.ts +21 -0
  242. package/types/webkit/index.d.ts +1 -0
  243. package/types/webkit/useLocation.d.ts +1 -1
  244. package/types/webkit/useVisualViewportFrame.d.ts +13 -0
  245. package/ui/Agent/Chat.tsx +29 -10
  246. package/ui/Agent/Composer.tsx +2 -1
  247. package/ui/Agent/EmbedApproval.tsx +17 -0
  248. package/ui/Agent/RichInput.tsx +1 -1
  249. package/ui/Agent/index.ts +2 -0
  250. package/ui/Agent/useKeyboardFrame.ts +10 -0
  251. package/ui/Agent/useScreenActions.ts +45 -0
  252. package/ui/BottomSheet.tsx +82 -53
  253. package/ui/Constant/Doc.tsx +113 -60
  254. package/ui/Constant/index.ts +2 -2
  255. package/ui/Constant/schemaDoc.ts +86 -26
  256. package/ui/Dialog/LegacyModal.tsx +53 -52
  257. package/ui/Dialog/Modal.tsx +93 -49
  258. package/ui/Dialog/modalSurface.ts +61 -0
  259. package/ui/DragAction.tsx +1 -1
  260. package/ui/DraggableList.tsx +1 -1
  261. package/ui/Dropdown.tsx +4 -6
  262. package/ui/KeyboardAvoiding.tsx +1 -1
  263. package/ui/Layout/BottomInset.tsx +20 -14
  264. package/ui/Layout/BottomTab.tsx +42 -16
  265. package/ui/Layout/FrameSlotFallback.tsx +59 -0
  266. package/ui/Layout/Navbar.tsx +37 -11
  267. package/ui/Layout/Sider.tsx +1 -1
  268. package/ui/Layout/TopInset.tsx +15 -14
  269. package/ui/Link/Action.tsx +15 -5
  270. package/ui/Link/Anchor.tsx +25 -13
  271. package/ui/Link/activePath.ts +25 -0
  272. package/ui/Link/index.tsx +1 -1
  273. package/ui/Load/Pagination.tsx +1 -1
  274. package/ui/Load/Units.tsx +1 -1
  275. package/ui/Loading/ProgressBar.tsx +1 -1
  276. package/ui/Modal.tsx +9 -0
  277. package/ui/Model/EditModal.tsx +16 -1
  278. package/ui/Model/New.tsx +25 -2
  279. package/ui/Model/NewWrapper_Client.tsx +2 -0
  280. package/ui/Model/ViewEditModal.tsx +9 -0
  281. package/ui/Model/ViewModal.tsx +16 -1
  282. package/ui/Model/newFormOrigin.ts +45 -0
  283. package/ui/Popconfirm.tsx +5 -7
  284. package/ui/Portal.tsx +4 -7
  285. package/ui/Reference/origin.ts +31 -0
  286. package/ui/ScreenNavigator.tsx +1 -1
  287. package/ui/Select.tsx +2 -7
  288. package/ui/Signal/Arg.tsx +2 -2
  289. package/ui/Signal/Doc.tsx +125 -63
  290. package/ui/Signal/Endpoint.tsx +11 -10
  291. package/ui/Signal/Listener.tsx +7 -10
  292. package/ui/Signal/Object.tsx +7 -14
  293. package/ui/Signal/Response.tsx +24 -24
  294. package/ui/Signal/RestApi.tsx +63 -52
  295. package/ui/Signal/WebSocket.tsx +65 -72
  296. package/ui/Signal/endpointEntries.ts +25 -0
  297. package/ui/Signal/index.ts +23 -6
  298. package/ui/Signal/signalText.ts +59 -0
  299. package/ui/System/CSR.tsx +34 -8
  300. package/ui/System/Client.tsx +36 -5
  301. package/ui/System/Common.tsx +76 -32
  302. package/ui/System/SSR.tsx +73 -31
  303. package/ui/Toast.tsx +1 -1
  304. package/ui/Tooltip.tsx +84 -30
  305. package/ui/index.ts +11 -1
  306. package/ui/overlayLayer.ts +25 -2
  307. package/ui/overlayPosition.ts +90 -0
  308. package/ui/recipe/inputRecipe.ts +8 -1
  309. package/ui/styles.css +152 -0
  310. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeActivity.kt +22 -2
  311. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeKernel.kt +37 -0
  312. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdateReports.kt +169 -0
  313. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeUpdates.kt +110 -38
  314. package/vendor/@akanjs/native/native/android/src/com/akanjs/runtime/AkanNativeVectors.kt +20 -0
  315. package/vendor/@akanjs/native/native/desktop/Cargo.lock +16 -16
  316. package/vendor/@akanjs/native/native/desktop/src/external.rs +651 -0
  317. package/vendor/@akanjs/native/native/desktop/src/json.rs +23 -0
  318. package/vendor/@akanjs/native/native/desktop/src/lib.rs +228 -5
  319. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeApp.swift +2 -1
  320. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeKernel.swift +47 -1
  321. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdateReports.swift +145 -0
  322. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeUpdates.swift +112 -43
  323. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeVectors.swift +18 -0
  324. package/vendor/@akanjs/native/native/ios/Sources/AkanNativeViewController.swift +24 -2
  325. package/vendor/@akanjs/native/packages/cli/src/api.ts +22 -6
  326. package/vendor/@akanjs/native/packages/cli/src/commands/build.ts +24 -8
  327. package/vendor/@akanjs/native/packages/cli/src/commands/update.ts +11 -9
  328. package/vendor/@akanjs/native/packages/cli/src/config.ts +35 -7
  329. package/vendor/@akanjs/native/packages/cli/src/lib/compat.ts +2 -0
  330. package/vendor/@akanjs/native/packages/cli/src/lib/configkeys.ts +6 -4
  331. package/vendor/@akanjs/native/packages/cli/src/lib/desktop-server.ts +11 -1
  332. package/vendor/@akanjs/native/packages/cli/src/lib/distribution.ts +73 -0
  333. package/vendor/@akanjs/native/packages/cli/src/lib/project.ts +15 -3
  334. package/vendor/@akanjs/native/packages/cli/src/lib/publish.ts +70 -23
  335. package/vendor/@akanjs/native/packages/cli/src/lib/updates.ts +159 -23
  336. package/vendor/@akanjs/native/packages/cli/src/lib/vectors.ts +2 -0
  337. package/vendor/@akanjs/native/packages/cli/src/platforms/android.ts +9 -4
  338. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop-update.ts +1 -1
  339. package/vendor/@akanjs/native/packages/cli/src/platforms/desktop.ts +4 -2
  340. package/vendor/@akanjs/native/packages/cli/src/platforms/ios.ts +9 -4
  341. package/vendor/@akanjs/native/packages/cli/src/platforms/windows-installer.ts +25 -11
  342. package/vendor/@akanjs/native/packages/cli/src/platforms/windows.ts +14 -3
  343. package/vendor/@akanjs/native/packages/core/src/kernel.ts +49 -0
  344. package/vendor/@akanjs/native/packages/core/vectors/updates.json +31 -0
  345. package/vendor/@akanjs/native/packages/desktop/src/main.ts +3 -0
  346. package/vendor/@akanjs/native/packages/desktop/src/plugin.ts +2 -0
  347. package/vendor/@akanjs/native/packages/desktop/src/server.ts +70 -6
  348. package/vendor/@akanjs/native/plugins/external-view/native-plugin.json +23 -0
  349. package/vendor/@akanjs/native/plugins/external-view/src/desktop.ts +321 -0
  350. package/vendor/@akanjs/native/plugins/external-view/src/index.ts +106 -0
  351. package/vendor/@akanjs/native/plugins/updates/android/UpdatesPlugin.kt +133 -41
  352. package/vendor/@akanjs/native/plugins/updates/ios/UpdatesPlugin.swift +101 -36
  353. package/vendor/@akanjs/native/plugins/updates/native-plugin.json +4 -2
  354. package/vendor/@akanjs/native/plugins/updates/src/desktop.ts +15 -1
  355. package/vendor/@akanjs/native/plugins/updates/src/index.ts +7 -1
  356. package/vendor/@akanjs/native/plugins/window/native-plugin.json +4 -0
  357. package/vendor/@akanjs/native/plugins/window/src/desktop.ts +68 -1
  358. package/vendor/@akanjs/native/plugins/window/src/index.ts +47 -0
  359. package/vendor/use-agentic/ToolRunner.ts +8 -1
  360. package/vendor/use-agentic/types.ts +2 -0
  361. package/webkit/CsrRouteTable.ts +1 -0
  362. package/webkit/CsrStack.ts +9 -2
  363. package/webkit/McpAppAgent.ts +138 -0
  364. package/webkit/McpAppApprovals.ts +56 -0
  365. package/webkit/McpAppBridge.ts +291 -0
  366. package/webkit/McpAppView.ts +258 -0
  367. package/webkit/bootCsr.tsx +54 -5
  368. package/webkit/index.ts +1 -0
  369. package/webkit/useCsrValues.ts +16 -10
  370. package/webkit/useFrameRuntime.ts +10 -1
  371. package/webkit/useLocation.ts +4 -3
  372. package/webkit/useVisualViewportFrame.tsx +52 -0
  373. package/service/predefinedAdaptor/sql/driver/libsql.ts +0 -45
  374. package/types/service/predefinedAdaptor/sql/driver/libsql.d.ts +0 -20
  375. package/types/ui/Agent/useKeyboardInset.d.ts +0 -1
  376. package/types/ui/ServerPortal.d.ts +0 -15
  377. package/ui/Agent/useKeyboardInset.ts +0 -19
  378. package/ui/ServerPortal.tsx +0 -49
@@ -1,32 +1,46 @@
1
1
  "use client";
2
- import { cn, usePage } from "akanjs/client";
2
+ import { cn, usePage, usePathCtx } from "akanjs/client";
3
3
  import { st } from "akanjs/store";
4
4
  import type { ReactNode } from "react";
5
5
 
6
6
  import { Link } from "../Link";
7
+ import { isActiveHref } from "../Link/activePath";
7
8
  import { BottomInset } from "./BottomInset";
8
9
 
9
10
  interface TabType {
10
11
  name: ReactNode;
11
- icon: ReactNode;
12
+ icon?: ReactNode;
12
13
  activeIcon?: ReactNode;
14
+ /** Drawn in the tab's link in place of icon and name, and passable from a server component, unlike `renderTab`. */
15
+ content?: ReactNode;
16
+ activeContent?: ReactNode;
13
17
  notiCount?: number;
14
18
  href: string;
19
+ /** Lights on `href` alone, not on the pages under it: a home tab at `/org/<id>` under which every org page sits. */
20
+ exact?: boolean;
21
+ /** More paths that light the tab, each with the pages under it: a "More" tab that claims several sections. */
22
+ match?: string[];
15
23
  }
16
24
 
17
25
  export interface BottomTabProps {
18
26
  className?: string;
19
27
  tabs: TabType[];
20
28
  height?: number;
29
+ /** Names the tab bar's navigation landmark for a screen reader. */
30
+ label?: string;
21
31
  /** Draws one tab inside its link. The link, the route match, and the badge placement stay the framework's. */
22
32
  renderTab?: (tab: TabType, active: boolean) => ReactNode;
23
33
  }
24
34
 
25
- export const BottomTab = ({ className, tabs, height = 64, renderTab }: BottomTabProps) => {
35
+ export const BottomTab = ({ className, tabs, height = 64, label, renderTab }: BottomTabProps) => {
26
36
  const { lang } = usePage();
27
- const path = st.use.path({ agent: false });
28
- const localePath = path.startsWith(`/${lang}`) ? path.slice(lang.length + 1) || "/" : path;
29
- const isActiveTab = (href: string) => (href === "/" ? localePath === href : localePath.startsWith(href));
37
+ const pathCtx = usePathCtx();
38
+ const statePathname = st.use.pathname({ agent: false });
39
+
40
+ const pathname = typeof window === "undefined" ? (pathCtx.location?.pathname ?? statePathname) : statePathname;
41
+ const prefix = pathCtx.prefix;
42
+ const isActiveTab = ({ href, exact, match }: TabType) =>
43
+ isActiveHref({ pathname, href, lang, prefix: prefix ?? "", exact, match });
30
44
 
31
45
  return (
32
46
  <BottomInset
@@ -37,35 +51,47 @@ export const BottomTab = ({ className, tabs, height = 64, renderTab }: BottomTab
37
51
  frameScope="layout"
38
52
  frameSource="bottomTab"
39
53
  >
40
- <div
54
+ <nav
55
+ aria-label={label}
41
56
  className={cn(
42
57
  "flex size-full items-center justify-around border-border border-t bg-background/95 text-foreground backdrop-blur-sm",
43
58
  className,
44
59
  )}
45
60
  >
46
61
  {tabs.map((tab) => {
47
- const active = isActiveTab(tab.href);
62
+ const active = isActiveTab(tab);
63
+ const custom = renderTab ? renderTab(tab, active) : active ? (tab.activeContent ?? tab.content) : tab.content;
64
+ const badge = tab.notiCount ? (
65
+ <span
66
+ className={cn(
67
+ "absolute flex h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 font-medium text-[10px] text-destructive-foreground leading-none",
68
+ custom !== undefined ? "top-1 left-[calc(50%+0.5rem)]" : "-top-1 -right-2",
69
+ )}
70
+ >
71
+ {tab.notiCount > 99 ? "99+" : tab.notiCount}
72
+ </span>
73
+ ) : null;
48
74
  return (
49
75
  <Link
50
76
  key={tab.href}
51
77
  href={tab.href}
52
78
  replace
79
+ aria-current={active ? "page" : undefined}
53
80
  className={cn(
54
81
  "relative flex w-full flex-col items-center justify-end gap-1 py-1.5 transition-colors",
55
82
  active ? "font-medium text-primary" : "text-foreground/55 hover:text-foreground/80",
56
83
  )}
57
84
  >
58
- {renderTab ? (
59
- renderTab(tab, active)
85
+ {custom !== undefined ? (
86
+ <>
87
+ {custom}
88
+ {badge}
89
+ </>
60
90
  ) : (
61
91
  <>
62
92
  <div className="relative inline-flex w-max text-xl">
63
93
  {active ? (tab.activeIcon ?? tab.icon) : tab.icon}
64
- {tab.notiCount ? (
65
- <span className="absolute -top-1 -right-2 flex h-4 min-w-4 items-center justify-center rounded-full bg-destructive px-1 font-medium text-[10px] text-destructive-foreground leading-none">
66
- {tab.notiCount > 99 ? "99+" : tab.notiCount}
67
- </span>
68
- ) : null}
94
+ {badge}
69
95
  </div>
70
96
  <span className="text-[11px]">{tab.name}</span>
71
97
  </>
@@ -73,7 +99,7 @@ export const BottomTab = ({ className, tabs, height = 64, renderTab }: BottomTab
73
99
  </Link>
74
100
  );
75
101
  })}
76
- </div>
102
+ </nav>
77
103
  </BottomInset>
78
104
  );
79
105
  };
@@ -0,0 +1,59 @@
1
+ import { getEnv } from "akanjs/base";
2
+ import type { CSSProperties, ReactNode } from "react";
3
+
4
+ export type FrameSlotName = "topInset" | "topLeftAction" | "bottomInset" | "keyboardInset";
5
+
6
+ const topVisibility = "var(--akan-top-inset-visibility, visible)" as CSSProperties["visibility"];
7
+ const bottomVisibility = "var(--akan-bottom-inset-visibility, visible)" as CSSProperties["visibility"];
8
+ const top: CSSProperties = {
9
+ top: "calc(var(--akan-top-safe-area) + var(--akan-viewport-offset-top, 0px))",
10
+ height: "var(--akan-top-inset)",
11
+ visibility: topVisibility,
12
+ };
13
+ const bottom: CSSProperties = {
14
+ bottom: "var(--akan-bottom-safe-area)",
15
+ height: "var(--akan-bottom-inset)",
16
+ visibility: bottomVisibility,
17
+ };
18
+ const keyboard: CSSProperties = {
19
+ bottom: "max(var(--akan-bottom-safe-area), var(--akan-keyboard-inset, 0px))",
20
+ height: "var(--akan-bottom-inset)",
21
+ visibility: bottomVisibility,
22
+ };
23
+
24
+ const outerClassNames: { [slot in FrameSlotName]: string } = {
25
+ topInset: "fixed inset-x-0 z-10 isolate overflow-hidden bg-background",
26
+ topLeftAction: "fixed left-0 z-10 isolate flex aspect-1 items-center justify-center overflow-hidden",
27
+ bottomInset: "pointer-events-none fixed inset-x-0 z-10 isolate overflow-hidden",
28
+ keyboardInset: "pointer-events-none fixed inset-x-0 z-10 isolate overflow-hidden",
29
+ } as const;
30
+
31
+ const innerClassNames: { [slot in FrameSlotName]: string } = {
32
+ topInset: "relative isolate size-full",
33
+ topLeftAction: "isolate flex size-full items-center justify-center",
34
+ bottomInset: "pointer-events-none isolate size-full",
35
+ keyboardInset: "pointer-events-none isolate size-full",
36
+ } as const;
37
+
38
+ const slotStyles: { [slot in FrameSlotName]: CSSProperties } = {
39
+ topInset: top,
40
+ topLeftAction: top,
41
+ bottomInset: bottom,
42
+ keyboardInset: keyboard,
43
+ } as const;
44
+
45
+ interface FrameSlotFallbackProps {
46
+ slot: FrameSlotName;
47
+ children: ReactNode;
48
+ }
49
+
50
+ /** Chrome drawn in place on the server, in the box its frame slot draws, until the client moves it into that slot. */
51
+ export const FrameSlotFallback = ({ slot, children }: FrameSlotFallbackProps) => {
52
+
53
+ if (getEnv().renderMode === "csr") return null;
54
+ return (
55
+ <div data-akan-frame-fallback={slot} className={outerClassNames[slot]} style={slotStyles[slot]}>
56
+ <div className={innerClassNames[slot]}>{children}</div>
57
+ </div>
58
+ );
59
+ };
@@ -6,20 +6,33 @@ import { BiChevronLeft, BiX } from "react-icons/bi";
6
6
 
7
7
  import { Link } from "../Link";
8
8
  import { Portal } from "../Portal";
9
+ import { FrameSlotFallback } from "./FrameSlotFallback";
9
10
 
10
11
  export interface NavbarProps {
11
12
  className?: string;
12
13
  children?: ReactNode;
13
14
  height?: number;
14
15
  title?: ReactNode;
16
+ /** `true` draws the framework's back button; any other node is drawn in its place. */
15
17
  back?: ReactNode;
18
+ /** Where the default back button goes when there is no history to go back to, as on a deep link. */
19
+ backFallback?: string;
16
20
  left?: ReactNode;
17
21
  right?: ReactNode;
18
22
  }
19
23
 
20
24
  const closeIconTransitions = new Set<TransitionType>(["bottomUp", "scaleOut", "fade"]);
21
25
 
22
- export const Navbar = ({ back = false, className, height, children, title, left, right }: NavbarProps) => {
26
+ export const Navbar = ({
27
+ back = false,
28
+ backFallback,
29
+ className,
30
+ height,
31
+ children,
32
+ title,
33
+ left,
34
+ right,
35
+ }: NavbarProps) => {
23
36
  const pathCtx = usePathCtx();
24
37
  const pathRoute = pathCtx.location?.pathRoute;
25
38
  const path = pathRoute?.path;
@@ -41,20 +54,33 @@ export const Navbar = ({ back = false, className, height, children, title, left,
41
54
  height,
42
55
  });
43
56
  }, [registerFrameSlot, height, path]);
57
+ const bar = (
58
+ <div className={cn("flex size-full items-center gap-2 px-5", back && "pl-14", className)}>
59
+ {left ? <div className="flex shrink-0 items-center gap-1">{left}</div> : null}
60
+ {title ? <div className="min-w-0 flex-1 truncate font-semibold text-base">{title}</div> : null}
61
+ {children}
62
+ {right ? <div className="ml-auto flex shrink-0 items-center gap-1">{right}</div> : null}
63
+ </div>
64
+ );
65
+ const backButton =
66
+ back === true ? (
67
+ <Link.Back className="text-4xl" fallback={backFallback}>
68
+ <BackIcon />
69
+ </Link.Back>
70
+ ) : (
71
+ back
72
+ );
44
73
  return (
45
74
  <>
46
- <Portal id={`topInsetContent${suffix}`}>
47
- <div className={cn("flex size-full items-center px-5", back && "pl-14", className)}>{children}</div>
75
+ <Portal id={`topInsetContent${suffix}`} fallback={<FrameSlotFallback slot="topInset">{bar}</FrameSlotFallback>}>
76
+ {bar}
48
77
  </Portal>
49
78
  {back ? (
50
- <Portal id={`topLeftActionContent${suffix}`}>
51
- {typeof back === "boolean" ? (
52
- <Link.Back className="text-4xl">
53
- <BackIcon />
54
- </Link.Back>
55
- ) : (
56
- back
57
- )}
79
+ <Portal
80
+ id={`topLeftActionContent${suffix}`}
81
+ fallback={<FrameSlotFallback slot="topLeftAction">{backButton}</FrameSlotFallback>}
82
+ >
83
+ {backButton}
58
84
  </Portal>
59
85
  ) : null}
60
86
  </>
@@ -1,12 +1,12 @@
1
1
  "use client";
2
2
  import { cn } from "akanjs/client";
3
3
  import { st } from "akanjs/store";
4
- import { animated } from "akanjs/ui";
5
4
  import { type ReactNode, useEffect, useState } from "react";
6
5
  import { AiOutlineClose, AiOutlineMenu } from "react-icons/ai";
7
6
  import { BiX } from "react-icons/bi";
8
7
  import { useSpring } from "react-spring";
9
8
  import { agentAttrs } from "../agentAttrs";
9
+ import { animated } from "../animated";
10
10
  import { buttonRecipe } from "../Button";
11
11
 
12
12
  export interface SiderProps {
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { getEnv } from "akanjs/base";
3
3
  import { cn, DEFAULT_TOP_INSET, debugFrame, usePathCtx } from "akanjs/client";
4
- import { type ReactNode, useEffect, useLayoutEffect, useState } from "react";
4
+ import { type ReactNode, useLayoutEffect } from "react";
5
5
 
6
6
  import { Portal } from "../Portal";
7
+ import { FrameSlotFallback } from "./FrameSlotFallback";
7
8
 
8
9
  export interface TopInsetProps {
9
10
  className?: string;
@@ -32,11 +33,14 @@ export const TopInset = ({ className, children, estimatedHeight = DEFAULT_TOP_IN
32
33
  });
33
34
  }, [registerFrameSlot, estimatedHeight, path]);
34
35
 
36
+ const content = (
37
+ <div data-akan-frame-slot="topInset" data-akan-frame-role="topChrome" className={cn("size-full", className)}>
38
+ {children}
39
+ </div>
40
+ );
35
41
  return (
36
- <Portal id={`topInsetContent${suffix}`}>
37
- <div data-akan-frame-slot="topInset" data-akan-frame-role="topChrome" className={cn("size-full", className)}>
38
- {children}
39
- </div>
42
+ <Portal id={`topInsetContent${suffix}`} fallback={<FrameSlotFallback slot="topInset">{content}</FrameSlotFallback>}>
43
+ {content}
40
44
  </Portal>
41
45
  );
42
46
  };
@@ -47,19 +51,16 @@ export interface TopLeftActionProps {
47
51
  }
48
52
 
49
53
  export const TopLeftAction = ({ className, children }: TopLeftActionProps) => {
50
- const [render, setRender] = useState(false);
51
54
  const pathCtx = usePathCtx();
52
55
  const path = pathCtx.location?.pathRoute?.path;
53
56
  const suffix = getEnv().renderMode === "csr" && path ? `-${pathCtx.pageKey ?? path}` : "";
54
- useEffect(() => {
55
- setRender(true);
56
- }, []);
57
-
58
- if (!render) return null;
59
-
57
+ const content = <div className={className}>{children}</div>;
60
58
  return (
61
- <Portal id={`topLeftActionContent${suffix}`}>
62
- <div className={className}>{children}</div>
59
+ <Portal
60
+ id={`topLeftActionContent${suffix}`}
61
+ fallback={<FrameSlotFallback slot="topLeftAction">{content}</FrameSlotFallback>}
62
+ >
63
+ {content}
63
64
  </Portal>
64
65
  );
65
66
  };
@@ -7,11 +7,21 @@ export interface ActionProps {
7
7
  children?: ReactNode;
8
8
  }
9
9
 
10
- export const Back = ({ className, children }: ActionProps) => (
11
- <div className={cn("cursor-pointer", className)} onClick={() => router.back()}>
12
- {children}
13
- </div>
14
- );
10
+ export interface BackProps extends ActionProps {
11
+ /** Where to go when there is no history to go back to, as on a deep link or a freshly opened app. */
12
+ fallback?: string;
13
+ }
14
+
15
+ export const Back = ({ className, children, fallback }: BackProps) =>
16
+ fallback === undefined ? (
17
+ <div className={cn("cursor-pointer", className)} onClick={() => router.back()}>
18
+ {children}
19
+ </div>
20
+ ) : (
21
+ <button type="button" className={cn("cursor-pointer", className)} onClick={() => router.backOrFallback(fallback)}>
22
+ {children}
23
+ </button>
24
+ );
15
25
 
16
26
  export const Close = ({ className, children }: ActionProps) => (
17
27
  <div className={cn("cursor-pointer", className)} onClick={() => window.close()}>
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
  import { getEnv } from "akanjs/base";
3
- import { cn, getPathInfo, router, usePage, usePathCtx } from "akanjs/client";
3
+ import { cn, csrLocation, getPathInfo, router, usePage, usePathCtx } from "akanjs/client";
4
4
  import { openExternalUrl } from "akanjs/client/native";
5
5
  import { Logger } from "akanjs/common";
6
6
  import { st } from "akanjs/store";
7
7
  import type { AnchorHTMLAttributes } from "react";
8
+ import { isActiveHref } from "./activePath";
8
9
 
9
10
  export type CommonLinkProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "href"> & {
10
11
  /** Omitted, or with `disabled`, Link renders a plain div around the same children. */
@@ -13,9 +14,11 @@ export type CommonLinkProps = Omit<AnchorHTMLAttributes<HTMLAnchorElement>, "hre
13
14
  scrollToTop?: boolean;
14
15
  /** Replaces the current history entry instead of pushing a new one. */
15
16
  replace?: boolean;
16
- /** Applied while the current path starts with `href`, or equals it with `activeExact`. */
17
+ /** Applied while the current page is `href` or below it, or exactly `href` with `activeExact`; basePath-aware. */
17
18
  activeClassName?: string;
18
19
  activeExact?: boolean;
20
+ /** More paths under which the link counts as active, as a tab does for its detail pages. */
21
+ activeMatch?: string[];
19
22
  /** @deprecated Has no effect: neither renderer reads it. */
20
23
  noCache?: boolean;
21
24
  };
@@ -29,26 +32,26 @@ export const CsrLink = ({
29
32
  activeClassName,
30
33
  scrollToTop,
31
34
  activeExact,
35
+ activeMatch,
32
36
  noCache,
33
37
  ...props
34
38
  }: AnchorProps) => {
35
39
  const { prefix } = usePathCtx();
36
- const currentPath = st.use.path({ agent: false });
40
+ const pathname = st.use.pathname({ agent: false });
37
41
  const { lang } = usePage();
38
- const { path, hash } = getPathInfo(href, lang, prefix ?? "");
42
+ const { hash } = getPathInfo(href, lang, prefix ?? "");
43
+ const active =
44
+ !!activeClassName &&
45
+ isActiveHref({ pathname, href, lang, prefix: prefix ?? "", exact: activeExact, match: activeMatch });
39
46
  return (
40
47
  <a
41
- className={cn(
42
- "cursor-pointer",
43
- className,
44
- (activeExact ? currentPath === path : currentPath.startsWith(path)) && activeClassName,
45
- )}
48
+ className={cn("cursor-pointer", className, active && activeClassName)}
46
49
  {...props}
47
50
  onClick={(event) => {
48
51
  props.onClick?.(event);
49
52
  if (event.defaultPrevented) return;
50
53
  const isExternal = href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("tel:");
51
- const url = href.startsWith("#") ? `${window.location.pathname}#${hash}` : href;
54
+ const url = href.startsWith("#") ? `${csrLocation.pathname}#${hash}` : href;
52
55
  if (isExternal) void openExternalUrl(href).catch(() => window.open(href, "_blank", "noopener,noreferrer"));
53
56
  else if (replace) router.replace(url, { scrollToTop });
54
57
  else router.push(url, { scrollToTop });
@@ -67,13 +70,17 @@ export const SsrLink = ({
67
70
  replace,
68
71
  activeClassName,
69
72
  activeExact,
73
+ activeMatch,
70
74
  noCache,
71
75
  ...props
72
76
  }: AnchorProps) => {
73
77
  const pathCtx = usePathCtx();
74
78
  const prefix = pathCtx.prefix ?? "";
75
- const { lang, path: pagePath } = usePage();
76
- const currentPath = pathCtx.location?.pathRoute?.path ?? getPathInfo(pagePath, lang, prefix).path;
79
+ const { lang } = usePage();
80
+ const statePathname = st.use.pathname({ agent: false });
81
+
82
+ const pathname = typeof window === "undefined" ? (pathCtx.location?.pathname ?? statePathname) : statePathname;
83
+ const currentPath = getPathInfo(pathname, lang, prefix).path;
77
84
  const isExternal = href.startsWith("http") || href.startsWith("mailto:") || href.startsWith("tel:");
78
85
  const internalPathInfo = getPathInfo(href, lang, prefix);
79
86
  const requestHref = getEnv().operationMode === "local" ? internalPathInfo.href : getPathInfo(href, lang, "").href;
@@ -86,7 +93,12 @@ export const SsrLink = ({
86
93
  );
87
94
  return (
88
95
  <a
89
- className={cn(className, (activeExact ? currentPath === path : currentPath.startsWith(path)) && activeClassName)}
96
+ className={cn(
97
+ className,
98
+ !!activeClassName &&
99
+ isActiveHref({ pathname, href, lang, prefix, exact: activeExact, match: activeMatch }) &&
100
+ activeClassName,
101
+ )}
90
102
  href={isExternal ? href : requestHref}
91
103
  {...props}
92
104
  onClick={(event) => {
@@ -0,0 +1,25 @@
1
+ import { getPathInfo } from "akanjs/client";
2
+
3
+ interface ActiveHrefOptions {
4
+ /** The current location's pathname, locale and basePath included or not. */
5
+ pathname: string;
6
+ href: string;
7
+ lang: string;
8
+ prefix: string;
9
+ exact?: boolean;
10
+ /** More paths that light the link, each matched as a prefix like `href`. */
11
+ match?: string[];
12
+ }
13
+
14
+ const pathOf = (url: string, lang: string, prefix: string) => getPathInfo(url, lang, prefix).path || "/";
15
+
16
+ const covers = (current: string, target: string, exact: boolean) =>
17
+ exact || target === "/"
18
+ ? current === target
19
+ : current === target || current.startsWith(`${target.replace(/\/$/, "")}/`);
20
+
21
+ /** Whether a link to `href` is the current page, with the locale and the basePath stripped from both sides. */
22
+ export const isActiveHref = ({ pathname, href, lang, prefix, exact = false, match = [] }: ActiveHrefOptions) => {
23
+ const current = pathOf(pathname, lang, prefix);
24
+ return [href, ...match].some((target, idx) => covers(current, pathOf(target, lang, prefix), idx === 0 && exact));
25
+ };
package/ui/Link/index.tsx CHANGED
@@ -6,7 +6,7 @@ import { type CommonLinkProps, CsrLink, SsrLink } from "./Anchor";
6
6
 
7
7
  export const Link = ({ className, href, disabled = false, children, ...props }: CommonLinkProps) => {
8
8
  if (disabled || !href) {
9
- const { scrollToTop, replace, activeClassName, activeExact, noCache, ...divProps } = props;
9
+ const { scrollToTop, replace, activeClassName, activeExact, activeMatch, noCache, ...divProps } = props;
10
10
  return (
11
11
  <div className={className} {...(divProps as unknown as HTMLAttributes<HTMLDivElement>)}>
12
12
  {children}
@@ -54,7 +54,7 @@ function Render<RefName extends string, Light>({ className, init, scrollToTop }:
54
54
  onSelect: (page) => {
55
55
  void storeDo[namesOfSlice.setPageOfModel](page);
56
56
  if (!scrollToTop) return;
57
- window.parent.postMessage({ type: "pathChange", page }, "*");
57
+ if (!globalThis.__AKAN_EMBED__) window.parent.postMessage({ type: "pathChange", page }, "*");
58
58
  window.scrollTo({ top: 0, behavior: "instant" });
59
59
  },
60
60
  });
package/ui/Load/Units.tsx CHANGED
@@ -168,7 +168,7 @@ function Render<RefName extends string, Light extends { id: string }>({
168
168
  onPageSelect: (page: number, option?: { scrollToTop?: boolean }) => {
169
169
  void storeDo[namesOfSlice.setPageOfModel](page);
170
170
  if (option?.scrollToTop !== false) {
171
- window.parent.postMessage({ type: "pathChange", page }, "*");
171
+ if (!globalThis.__AKAN_EMBED__) window.parent.postMessage({ type: "pathChange", page }, "*");
172
172
  window.scrollTo({ top: 0, behavior: "instant" });
173
173
  }
174
174
  },
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { cn } from "akanjs/client";
3
- import { animated } from "akanjs/ui";
4
3
  import { useSpring } from "react-spring";
4
+ import { animated } from "../animated";
5
5
 
6
6
  export interface ProgressBarProps {
7
7
  className?: string;
package/ui/Modal.tsx CHANGED
@@ -3,6 +3,7 @@
3
3
  import type { ReactNode } from "react";
4
4
 
5
5
  import { Dialog } from "./Dialog";
6
+ import type { ModalPlacement, ModalPresentation } from "./Dialog/modalSurface";
6
7
  import { createOverridable } from "./UiOverride";
7
8
 
8
9
  export interface ModalProps {
@@ -17,6 +18,10 @@ export interface ModalProps {
17
18
  bodyClassName?: string;
18
19
  children?: ReactNode;
19
20
  confirmClose?: boolean;
21
+ /** `auto` is a full-screen sheet below `md`; the default stays a centred dialog. */
22
+ presentation?: ModalPresentation;
23
+ /** `right` is a full-height side sheet from `md` up. */
24
+ placement?: ModalPlacement;
20
25
  }
21
26
 
22
27
  export const DefaultModal = ({
@@ -30,6 +35,8 @@ export const DefaultModal = ({
30
35
  bodyClassName,
31
36
  children,
32
37
  confirmClose = false,
38
+ presentation,
39
+ placement,
33
40
  }: ModalProps) => {
34
41
  return (
35
42
  <Dialog open={open}>
@@ -40,6 +47,8 @@ export const DefaultModal = ({
40
47
  bodyClassName={bodyClassName}
41
48
  confirmClose={confirmClose}
42
49
  closeButton={closeButton}
50
+ presentation={presentation}
51
+ placement={placement}
43
52
  >
44
53
  {title ? <Dialog.Title>{title}</Dialog.Title> : null}
45
54
  <Dialog.Content>{children}</Dialog.Content>
@@ -10,9 +10,11 @@ import { AiOutlinePlus, AiOutlineSave } from "react-icons/ai";
10
10
 
11
11
  import { agentAttrs } from "../agentAttrs";
12
12
  import { Button } from "../Button";
13
+ import type { ModalPlacement, ModalPresentation } from "../Dialog/modalSurface";
13
14
  import { Modal } from "../Modal";
14
15
  import DraftBar from "./DraftBar";
15
16
  import { type DraftProp, editDraftScope, newDraftScope } from "./draftScope";
17
+ import { NewFormOrigin } from "./newFormOrigin";
16
18
 
17
19
  const EDIT_PAYLOAD_MAX_AGE_MS = 60_000;
18
20
 
@@ -113,6 +115,10 @@ interface EditModalProps<Full extends { id: string }> extends EditModelProps<Ful
113
115
  disabled?: boolean;
114
116
  checkSubmit?: boolean;
115
117
  modalClassName?: string;
118
+ /** Passed to the `Modal`: `auto` is a full-screen sheet below `md`. */
119
+ presentation?: ModalPresentation;
120
+ /** Passed to the `Modal`: `right` is a side sheet from `md` up. */
121
+ placement?: ModalPlacement;
116
122
  renderTitle?: ((model: Full) => string | ReactNode) | string;
117
123
  submitText?: ReactNode;
118
124
  submitClassName?: string;
@@ -134,6 +140,8 @@ export default function EditModal<Full extends { id: string }>({
134
140
  disabled,
135
141
  checkSubmit = true,
136
142
  modalClassName,
143
+ presentation,
144
+ placement,
137
145
  edit,
138
146
  modal,
139
147
  renderTitle,
@@ -182,10 +190,15 @@ export default function EditModal<Full extends { id: string }>({
182
190
  );
183
191
  const modelFormLoading = storeUse[names.modelFormLoading]() as string | boolean;
184
192
  const modalId = id ?? ((modelEdit as DynamicRecord)?.[names.modelObj] as Full | undefined)?.id ?? undefined;
193
+ const newFormOrigin = NewFormOrigin.use(modelName);
185
194
  const isModalOpen =
186
195
  modelModal === (modal ?? "edit") &&
187
196
  (modelFormLoading === false || modelFormLoading === modalId) &&
188
- ((!modelFormId && !modalId) || modalId === modelFormId);
197
+ ((!modelFormId && !modalId && (!newFormOrigin || newFormOrigin === sliceName)) ||
198
+ (!!modalId && modalId === modelFormId));
199
+ useEffect(() => {
200
+ if (!modelModal) NewFormOrigin.clear(modelName);
201
+ }, [modelModal]);
189
202
  const isEditPayloadStale = useCallback((viewAt?: Date | null) => {
190
203
  if (isRscNavigationFromCache()) return true;
191
204
  return (
@@ -346,6 +359,8 @@ export default function EditModal<Full extends { id: string }>({
346
359
  handleCancel();
347
360
  }}
348
361
  className={modalClassName}
362
+ presentation={presentation}
363
+ placement={placement}
349
364
  title={<Title />}
350
365
  action={<Submit />}
351
366
  >
package/ui/Model/New.tsx CHANGED
@@ -2,6 +2,7 @@ import { usePage } from "akanjs/client";
2
2
  import type { SliceMeta } from "akanjs/fetch";
3
3
  import type { ReactNode } from "react";
4
4
  import { AiOutlinePlus } from "react-icons/ai";
5
+ import type { ModalPlacement, ModalPresentation } from "../Dialog/modalSurface";
5
6
  import { buttonRecipe } from "../recipe";
6
7
  import type { DraftProp } from "./draftScope";
7
8
  import EditModal from "./EditModal";
@@ -18,9 +19,24 @@ interface NewProps<Full = any> {
18
19
  namespace?: string;
19
20
  /** Draft recovery for the form. `false` turns it off; a string names the scope explicitly. */
20
21
  draft?: DraftProp;
22
+ /** Passed to the form's `Modal`: `auto` is a full-screen sheet below `md`. */
23
+ presentation?: ModalPresentation;
24
+ /** Passed to the form's `Modal`: `right` is a side sheet from `md` up. */
25
+ placement?: ModalPlacement;
21
26
  }
22
27
 
23
- export default function New({ trigger, children, slice, modal, partial, renderTitle, namespace, draft }: NewProps) {
28
+ export default function New({
29
+ trigger,
30
+ children,
31
+ slice,
32
+ modal,
33
+ partial,
34
+ renderTitle,
35
+ namespace,
36
+ draft,
37
+ presentation,
38
+ placement,
39
+ }: NewProps) {
24
40
  const { l } = usePage();
25
41
  return (
26
42
  <>
@@ -38,7 +54,14 @@ export default function New({ trigger, children, slice, modal, partial, renderTi
38
54
  </button>
39
55
  )}
40
56
  </NewWrapper>
41
- <EditModal renderTitle={renderTitle} slice={slice} draft={draft}>
57
+ <EditModal
58
+ renderTitle={renderTitle}
59
+ slice={slice}
60
+ modal={modal ?? undefined}
61
+ draft={draft}
62
+ presentation={presentation}
63
+ placement={placement}
64
+ >
42
65
  {children}
43
66
  </EditModal>
44
67
  </>