@astrale-os/shell-react 0.1.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/LICENSE +202 -0
  2. package/dist/application/apps/app-host.d.ts +31 -0
  3. package/dist/application/apps/app-host.d.ts.map +1 -0
  4. package/dist/application/apps/app-host.js +59 -0
  5. package/dist/application/apps/app-logo.d.ts +19 -0
  6. package/dist/application/apps/app-logo.d.ts.map +1 -0
  7. package/dist/application/apps/app-logo.js +31 -0
  8. package/dist/application/apps/apps.hook.d.ts +12 -0
  9. package/dist/application/apps/apps.hook.d.ts.map +1 -0
  10. package/dist/application/apps/apps.hook.js +51 -0
  11. package/dist/application/apps/open-app.hook.d.ts +10 -0
  12. package/dist/application/apps/open-app.hook.d.ts.map +1 -0
  13. package/dist/application/apps/open-app.hook.js +7 -0
  14. package/dist/application/index.d.ts +18 -0
  15. package/dist/application/index.d.ts.map +1 -0
  16. package/dist/application/index.js +12 -0
  17. package/dist/application/roles.hook.d.ts +7 -0
  18. package/dist/application/roles.hook.d.ts.map +1 -0
  19. package/dist/application/roles.hook.js +23 -0
  20. package/dist/application/spaces/current-space.hook.d.ts +7 -0
  21. package/dist/application/spaces/current-space.hook.d.ts.map +1 -0
  22. package/dist/application/spaces/current-space.hook.js +27 -0
  23. package/dist/application/spaces/current-space.store.d.ts +32 -0
  24. package/dist/application/spaces/current-space.store.d.ts.map +1 -0
  25. package/dist/application/spaces/current-space.store.js +79 -0
  26. package/dist/application/spaces/space.hook.d.ts +5 -0
  27. package/dist/application/spaces/space.hook.d.ts.map +1 -0
  28. package/dist/application/spaces/space.hook.js +25 -0
  29. package/dist/application/spaces/spaces.hook.d.ts +14 -0
  30. package/dist/application/spaces/spaces.hook.d.ts.map +1 -0
  31. package/dist/application/spaces/spaces.hook.js +82 -0
  32. package/dist/application/user/user.hook.d.ts +10 -0
  33. package/dist/application/user/user.hook.d.ts.map +1 -0
  34. package/dist/application/user/user.hook.js +19 -0
  35. package/dist/application/user/user.store.d.ts +35 -0
  36. package/dist/application/user/user.store.d.ts.map +1 -0
  37. package/dist/application/user/user.store.js +51 -0
  38. package/dist/auth/act-as.context.d.ts +40 -0
  39. package/dist/auth/act-as.context.d.ts.map +1 -0
  40. package/dist/auth/act-as.context.js +84 -0
  41. package/dist/auth/auth.hook.d.ts +3 -0
  42. package/dist/auth/auth.hook.d.ts.map +1 -0
  43. package/dist/auth/auth.hook.js +25 -0
  44. package/dist/auth/can.hook.d.ts +40 -0
  45. package/dist/auth/can.hook.d.ts.map +1 -0
  46. package/dist/auth/can.hook.js +119 -0
  47. package/dist/auth/index.d.ts +6 -0
  48. package/dist/auth/index.d.ts.map +1 -0
  49. package/dist/auth/index.js +5 -0
  50. package/dist/auth/self.hook.d.ts +3 -0
  51. package/dist/auth/self.hook.d.ts.map +1 -0
  52. package/dist/auth/self.hook.js +11 -0
  53. package/dist/auth/session-kernel.d.ts +4 -0
  54. package/dist/auth/session-kernel.d.ts.map +1 -0
  55. package/dist/auth/session-kernel.js +21 -0
  56. package/dist/graph/action.d.ts +22 -0
  57. package/dist/graph/action.d.ts.map +1 -0
  58. package/dist/graph/action.js +85 -0
  59. package/dist/graph/async.d.ts +11 -0
  60. package/dist/graph/async.d.ts.map +1 -0
  61. package/dist/graph/async.js +60 -0
  62. package/dist/graph/call/call.hook.d.ts +21 -0
  63. package/dist/graph/call/call.hook.d.ts.map +1 -0
  64. package/dist/graph/call/call.hook.js +23 -0
  65. package/dist/graph/call/stream.hook.d.ts +28 -0
  66. package/dist/graph/call/stream.hook.d.ts.map +1 -0
  67. package/dist/graph/call/stream.hook.js +137 -0
  68. package/dist/graph/graph.context.d.ts +4 -0
  69. package/dist/graph/graph.context.d.ts.map +1 -0
  70. package/dist/graph/graph.context.js +10 -0
  71. package/dist/graph/guards.error.d.ts +9 -0
  72. package/dist/graph/guards.error.d.ts.map +1 -0
  73. package/dist/graph/guards.error.js +7 -0
  74. package/dist/graph/index.d.ts +20 -0
  75. package/dist/graph/index.d.ts.map +1 -0
  76. package/dist/graph/index.js +9 -0
  77. package/dist/graph/memory/base.d.ts +21 -0
  78. package/dist/graph/memory/base.d.ts.map +1 -0
  79. package/dist/graph/memory/base.js +33 -0
  80. package/dist/graph/memory/read/envelope.d.ts +71 -0
  81. package/dist/graph/memory/read/envelope.d.ts.map +1 -0
  82. package/dist/graph/memory/read/envelope.js +29 -0
  83. package/dist/graph/memory/read/idle.d.ts +18 -0
  84. package/dist/graph/memory/read/idle.d.ts.map +1 -0
  85. package/dist/graph/memory/read/idle.js +16 -0
  86. package/dist/graph/memory/read/read.d.ts +9 -0
  87. package/dist/graph/memory/read/read.d.ts.map +1 -0
  88. package/dist/graph/memory/read/read.js +87 -0
  89. package/dist/graph/memory/scope.d.ts +7 -0
  90. package/dist/graph/memory/scope.d.ts.map +1 -0
  91. package/dist/graph/memory/scope.js +25 -0
  92. package/dist/graph/mutate/move.hook.d.ts +7 -0
  93. package/dist/graph/mutate/move.hook.d.ts.map +1 -0
  94. package/dist/graph/mutate/move.hook.js +49 -0
  95. package/dist/graph/mutate/mutate.hook.d.ts +17 -0
  96. package/dist/graph/mutate/mutate.hook.d.ts.map +1 -0
  97. package/dist/graph/mutate/mutate.hook.js +45 -0
  98. package/dist/graph/query/children.hook.d.ts +29 -0
  99. package/dist/graph/query/children.hook.d.ts.map +1 -0
  100. package/dist/graph/query/children.hook.js +64 -0
  101. package/dist/graph/query/graph.hook.d.ts +9 -0
  102. package/dist/graph/query/graph.hook.d.ts.map +1 -0
  103. package/dist/graph/query/graph.hook.js +5 -0
  104. package/dist/graph/query/neighbors.hook.d.ts +7 -0
  105. package/dist/graph/query/neighbors.hook.d.ts.map +1 -0
  106. package/dist/graph/query/neighbors.hook.js +79 -0
  107. package/dist/graph/query/node.hook.d.ts +14 -0
  108. package/dist/graph/query/node.hook.d.ts.map +1 -0
  109. package/dist/graph/query/node.hook.js +43 -0
  110. package/dist/graph/query/query.hook.d.ts +14 -0
  111. package/dist/graph/query/query.hook.d.ts.map +1 -0
  112. package/dist/graph/query/query.hook.js +23 -0
  113. package/dist/index.d.ts +43 -0
  114. package/dist/index.d.ts.map +1 -0
  115. package/dist/index.js +34 -0
  116. package/dist/intents/envelope.d.ts +33 -0
  117. package/dist/intents/envelope.d.ts.map +1 -0
  118. package/dist/intents/envelope.js +19 -0
  119. package/dist/intents/index.d.ts +6 -0
  120. package/dist/intents/index.d.ts.map +1 -0
  121. package/dist/intents/index.js +3 -0
  122. package/dist/intents/listen-intent.hook.d.ts +16 -0
  123. package/dist/intents/listen-intent.hook.d.ts.map +1 -0
  124. package/dist/intents/listen-intent.hook.js +75 -0
  125. package/dist/intents/reply.d.ts +9 -0
  126. package/dist/intents/reply.d.ts.map +1 -0
  127. package/dist/intents/reply.js +14 -0
  128. package/dist/intents/send-intent.hook.d.ts +12 -0
  129. package/dist/intents/send-intent.hook.d.ts.map +1 -0
  130. package/dist/intents/send-intent.hook.js +86 -0
  131. package/dist/navigation/adapters/adapter.d.ts +15 -0
  132. package/dist/navigation/adapters/adapter.d.ts.map +1 -0
  133. package/dist/navigation/adapters/adapter.js +1 -0
  134. package/dist/navigation/adapters/memory.adapter.d.ts +9 -0
  135. package/dist/navigation/adapters/memory.adapter.d.ts.map +1 -0
  136. package/dist/navigation/adapters/memory.adapter.js +15 -0
  137. package/dist/navigation/adapters/url.adapter.d.ts +6 -0
  138. package/dist/navigation/adapters/url.adapter.d.ts.map +1 -0
  139. package/dist/navigation/adapters/url.adapter.js +59 -0
  140. package/dist/navigation/history.d.ts +63 -0
  141. package/dist/navigation/history.d.ts.map +1 -0
  142. package/dist/navigation/history.js +144 -0
  143. package/dist/navigation/hooks/ancestors.hook.d.ts +13 -0
  144. package/dist/navigation/hooks/ancestors.hook.d.ts.map +1 -0
  145. package/dist/navigation/hooks/ancestors.hook.js +56 -0
  146. package/dist/navigation/hooks/location.hook.d.ts +4 -0
  147. package/dist/navigation/hooks/location.hook.d.ts.map +1 -0
  148. package/dist/navigation/hooks/location.hook.js +17 -0
  149. package/dist/navigation/hooks/navigate.hook.d.ts +12 -0
  150. package/dist/navigation/hooks/navigate.hook.d.ts.map +1 -0
  151. package/dist/navigation/hooks/navigate.hook.js +33 -0
  152. package/dist/navigation/hooks/scope.hook.d.ts +12 -0
  153. package/dist/navigation/hooks/scope.hook.d.ts.map +1 -0
  154. package/dist/navigation/hooks/scope.hook.js +21 -0
  155. package/dist/navigation/index.d.ts +16 -0
  156. package/dist/navigation/index.d.ts.map +1 -0
  157. package/dist/navigation/index.js +10 -0
  158. package/dist/navigation/link.d.ts +11 -0
  159. package/dist/navigation/link.d.ts.map +1 -0
  160. package/dist/navigation/link.js +62 -0
  161. package/dist/navigation/location.d.ts +48 -0
  162. package/dist/navigation/location.d.ts.map +1 -0
  163. package/dist/navigation/location.js +88 -0
  164. package/dist/navigation/scope.context.d.ts +64 -0
  165. package/dist/navigation/scope.context.d.ts.map +1 -0
  166. package/dist/navigation/scope.context.js +178 -0
  167. package/dist/navigation/snapshot.d.ts +22 -0
  168. package/dist/navigation/snapshot.d.ts.map +1 -0
  169. package/dist/navigation/snapshot.js +65 -0
  170. package/dist/schema/bind-read.d.ts +37 -0
  171. package/dist/schema/bind-read.d.ts.map +1 -0
  172. package/dist/schema/bind-read.js +205 -0
  173. package/dist/schema/binding.d.ts +21 -0
  174. package/dist/schema/binding.d.ts.map +1 -0
  175. package/dist/schema/binding.js +55 -0
  176. package/dist/schema/domain.hook.d.ts +10 -0
  177. package/dist/schema/domain.hook.d.ts.map +1 -0
  178. package/dist/schema/domain.hook.js +7 -0
  179. package/dist/schema/function.hook.d.ts +9 -0
  180. package/dist/schema/function.hook.d.ts.map +1 -0
  181. package/dist/schema/function.hook.js +40 -0
  182. package/dist/schema/index.d.ts +10 -0
  183. package/dist/schema/index.d.ts.map +1 -0
  184. package/dist/schema/index.js +8 -0
  185. package/dist/schema/kernel.hook.d.ts +10 -0
  186. package/dist/schema/kernel.hook.d.ts.map +1 -0
  187. package/dist/schema/kernel.hook.js +8 -0
  188. package/dist/schema/method.hook.d.ts +14 -0
  189. package/dist/schema/method.hook.d.ts.map +1 -0
  190. package/dist/schema/method.hook.js +49 -0
  191. package/dist/schema/tag.d.ts +11 -0
  192. package/dist/schema/tag.d.ts.map +1 -0
  193. package/dist/schema/tag.js +11 -0
  194. package/dist/schema/types.d.ts +73 -0
  195. package/dist/schema/types.d.ts.map +1 -0
  196. package/dist/schema/types.js +1 -0
  197. package/dist/schema/write.d.ts +15 -0
  198. package/dist/schema/write.d.ts.map +1 -0
  199. package/dist/schema/write.js +45 -0
  200. package/dist/selection/index.d.ts +4 -0
  201. package/dist/selection/index.d.ts.map +1 -0
  202. package/dist/selection/index.js +4 -0
  203. package/dist/selection/live.d.ts +21 -0
  204. package/dist/selection/live.d.ts.map +1 -0
  205. package/dist/selection/live.js +116 -0
  206. package/dist/selection/scope.context.d.ts +26 -0
  207. package/dist/selection/scope.context.d.ts.map +1 -0
  208. package/dist/selection/scope.context.js +100 -0
  209. package/dist/selection/selection.hook.d.ts +4 -0
  210. package/dist/selection/selection.hook.d.ts.map +1 -0
  211. package/dist/selection/selection.hook.js +14 -0
  212. package/dist/session/boot/boot.d.ts +19 -0
  213. package/dist/session/boot/boot.d.ts.map +1 -0
  214. package/dist/session/boot/boot.js +45 -0
  215. package/dist/session/boot/ownership.d.ts +18 -0
  216. package/dist/session/boot/ownership.d.ts.map +1 -0
  217. package/dist/session/boot/ownership.js +39 -0
  218. package/dist/session/boot/status.d.ts +24 -0
  219. package/dist/session/boot/status.d.ts.map +1 -0
  220. package/dist/session/boot/status.js +11 -0
  221. package/dist/session/connection/connection.hook.d.ts +3 -0
  222. package/dist/session/connection/connection.hook.d.ts.map +1 -0
  223. package/dist/session/connection/connection.hook.js +12 -0
  224. package/dist/session/connection/connection.store.d.ts +24 -0
  225. package/dist/session/connection/connection.store.d.ts.map +1 -0
  226. package/dist/session/connection/connection.store.js +31 -0
  227. package/dist/session/index.d.ts +8 -0
  228. package/dist/session/index.d.ts.map +1 -0
  229. package/dist/session/index.js +6 -0
  230. package/dist/session/kernel-client.hook.d.ts +9 -0
  231. package/dist/session/kernel-client.hook.d.ts.map +1 -0
  232. package/dist/session/kernel-client.hook.js +5 -0
  233. package/dist/session/kernel-instance.hook.d.ts +9 -0
  234. package/dist/session/kernel-instance.hook.d.ts.map +1 -0
  235. package/dist/session/kernel-instance.hook.js +10 -0
  236. package/dist/session/provider.d.ts +31 -0
  237. package/dist/session/provider.d.ts.map +1 -0
  238. package/dist/session/provider.js +165 -0
  239. package/dist/session/session.context.d.ts +18 -0
  240. package/dist/session/session.context.d.ts.map +1 -0
  241. package/dist/session/session.context.js +8 -0
  242. package/dist/session/shell.hook.d.ts +4 -0
  243. package/dist/session/shell.hook.d.ts.map +1 -0
  244. package/dist/session/shell.hook.js +15 -0
  245. package/dist/window/adopt.d.ts +27 -0
  246. package/dist/window/adopt.d.ts.map +1 -0
  247. package/dist/window/adopt.js +27 -0
  248. package/dist/window/hooks/close-guard.hook.d.ts +6 -0
  249. package/dist/window/hooks/close-guard.hook.d.ts.map +1 -0
  250. package/dist/window/hooks/close-guard.hook.js +90 -0
  251. package/dist/window/hooks/target-node.hook.d.ts +7 -0
  252. package/dist/window/hooks/target-node.hook.d.ts.map +1 -0
  253. package/dist/window/hooks/target-node.hook.js +77 -0
  254. package/dist/window/hooks/views-for.hook.d.ts +8 -0
  255. package/dist/window/hooks/views-for.hook.d.ts.map +1 -0
  256. package/dist/window/hooks/views-for.hook.js +51 -0
  257. package/dist/window/hooks/window.hook.d.ts +4 -0
  258. package/dist/window/hooks/window.hook.d.ts.map +1 -0
  259. package/dist/window/hooks/window.hook.js +14 -0
  260. package/dist/window/hooks/windows.hook.d.ts +15 -0
  261. package/dist/window/hooks/windows.hook.d.ts.map +1 -0
  262. package/dist/window/hooks/windows.hook.js +25 -0
  263. package/dist/window/host.d.ts +31 -0
  264. package/dist/window/host.d.ts.map +1 -0
  265. package/dist/window/host.js +270 -0
  266. package/dist/window/hub.d.ts +41 -0
  267. package/dist/window/hub.d.ts.map +1 -0
  268. package/dist/window/hub.js +100 -0
  269. package/dist/window/index.d.ts +15 -0
  270. package/dist/window/index.d.ts.map +1 -0
  271. package/dist/window/index.js +10 -0
  272. package/dist/window/lifecycle/mount.d.ts +47 -0
  273. package/dist/window/lifecycle/mount.d.ts.map +1 -0
  274. package/dist/window/lifecycle/mount.js +92 -0
  275. package/dist/window/lifecycle/states.d.ts +33 -0
  276. package/dist/window/lifecycle/states.d.ts.map +1 -0
  277. package/dist/window/lifecycle/states.js +7 -0
  278. package/dist/window/placement.d.ts +33 -0
  279. package/dist/window/placement.d.ts.map +1 -0
  280. package/dist/window/placement.js +57 -0
  281. package/dist/window/stage.d.ts +3 -0
  282. package/dist/window/stage.d.ts.map +1 -0
  283. package/dist/window/stage.js +41 -0
  284. package/package.json +59 -0
  285. package/src/application/apps/app-host.tsx +113 -0
  286. package/src/application/apps/app-logo.tsx +56 -0
  287. package/src/application/apps/apps.hook.ts +81 -0
  288. package/src/application/apps/open-app.hook.ts +18 -0
  289. package/src/application/index.ts +22 -0
  290. package/src/application/roles.hook.ts +41 -0
  291. package/src/application/spaces/current-space.hook.ts +43 -0
  292. package/src/application/spaces/current-space.store.ts +110 -0
  293. package/src/application/spaces/space.hook.ts +41 -0
  294. package/src/application/spaces/spaces.hook.ts +113 -0
  295. package/src/application/user/user.hook.ts +27 -0
  296. package/src/application/user/user.store.ts +85 -0
  297. package/src/auth/act-as.context.tsx +124 -0
  298. package/src/auth/auth.hook.ts +36 -0
  299. package/src/auth/can.hook.ts +149 -0
  300. package/src/auth/index.ts +6 -0
  301. package/src/auth/self.hook.ts +14 -0
  302. package/src/auth/session-kernel.ts +24 -0
  303. package/src/graph/action.ts +127 -0
  304. package/src/graph/async.ts +87 -0
  305. package/src/graph/call/call.hook.ts +42 -0
  306. package/src/graph/call/stream.hook.ts +200 -0
  307. package/src/graph/graph.context.ts +14 -0
  308. package/src/graph/guards.error.ts +58 -0
  309. package/src/graph/index.ts +20 -0
  310. package/src/graph/memory/base.ts +50 -0
  311. package/src/graph/memory/read/envelope.ts +98 -0
  312. package/src/graph/memory/read/idle.ts +24 -0
  313. package/src/graph/memory/read/read.ts +103 -0
  314. package/src/graph/memory/scope.ts +29 -0
  315. package/src/graph/mutate/move.hook.ts +70 -0
  316. package/src/graph/mutate/mutate.hook.ts +69 -0
  317. package/src/graph/query/children.hook.ts +136 -0
  318. package/src/graph/query/graph.hook.ts +13 -0
  319. package/src/graph/query/neighbors.hook.ts +124 -0
  320. package/src/graph/query/node.hook.ts +83 -0
  321. package/src/graph/query/query.hook.ts +42 -0
  322. package/src/index.ts +202 -0
  323. package/src/intents/envelope.ts +52 -0
  324. package/src/intents/index.ts +6 -0
  325. package/src/intents/listen-intent.hook.ts +92 -0
  326. package/src/intents/reply.ts +24 -0
  327. package/src/intents/send-intent.hook.ts +111 -0
  328. package/src/navigation/adapters/adapter.ts +13 -0
  329. package/src/navigation/adapters/memory.adapter.ts +22 -0
  330. package/src/navigation/adapters/url.adapter.ts +61 -0
  331. package/src/navigation/history.ts +170 -0
  332. package/src/navigation/hooks/ancestors.hook.ts +71 -0
  333. package/src/navigation/hooks/location.hook.ts +21 -0
  334. package/src/navigation/hooks/navigate.hook.ts +43 -0
  335. package/src/navigation/hooks/scope.hook.ts +34 -0
  336. package/src/navigation/index.ts +17 -0
  337. package/src/navigation/link.tsx +110 -0
  338. package/src/navigation/location.ts +122 -0
  339. package/src/navigation/scope.context.tsx +267 -0
  340. package/src/navigation/snapshot.ts +79 -0
  341. package/src/schema/bind-read.ts +319 -0
  342. package/src/schema/binding.ts +91 -0
  343. package/src/schema/domain.hook.ts +16 -0
  344. package/src/schema/function.hook.ts +68 -0
  345. package/src/schema/index.ts +25 -0
  346. package/src/schema/kernel.hook.ts +17 -0
  347. package/src/schema/method.hook.ts +103 -0
  348. package/src/schema/tag.ts +19 -0
  349. package/src/schema/types.ts +150 -0
  350. package/src/schema/write.ts +80 -0
  351. package/src/selection/index.ts +5 -0
  352. package/src/selection/live.ts +142 -0
  353. package/src/selection/scope.context.tsx +151 -0
  354. package/src/selection/selection.hook.ts +18 -0
  355. package/src/session/boot/boot.ts +57 -0
  356. package/src/session/boot/ownership.ts +54 -0
  357. package/src/session/boot/status.ts +32 -0
  358. package/src/session/connection/connection.hook.ts +16 -0
  359. package/src/session/connection/connection.store.ts +58 -0
  360. package/src/session/index.ts +8 -0
  361. package/src/session/kernel-client.hook.ts +13 -0
  362. package/src/session/kernel-instance.hook.ts +22 -0
  363. package/src/session/provider.tsx +205 -0
  364. package/src/session/session.context.ts +27 -0
  365. package/src/session/shell.hook.ts +19 -0
  366. package/src/window/adopt.ts +57 -0
  367. package/src/window/hooks/close-guard.hook.ts +100 -0
  368. package/src/window/hooks/target-node.hook.ts +94 -0
  369. package/src/window/hooks/views-for.hook.ts +82 -0
  370. package/src/window/hooks/window.hook.ts +18 -0
  371. package/src/window/hooks/windows.hook.ts +40 -0
  372. package/src/window/host.tsx +347 -0
  373. package/src/window/hub.ts +156 -0
  374. package/src/window/index.ts +17 -0
  375. package/src/window/lifecycle/mount.ts +134 -0
  376. package/src/window/lifecycle/states.ts +23 -0
  377. package/src/window/placement.ts +84 -0
  378. package/src/window/stage.tsx +46 -0
@@ -0,0 +1,15 @@
1
+ import type { Window } from '@astrale-os/shell';
2
+ /** Every host-mounted window in this shell's tree, keyed by windowId. Reactive. */
3
+ export declare function useWindows(): ReadonlyMap<string, Window>;
4
+ /** One open window as a list entry. */
5
+ export interface WindowListEntry {
6
+ readonly windowId: string;
7
+ readonly window: Window;
8
+ }
9
+ /**
10
+ * The open windows as a reactive, insertion-ordered list — the array form of
11
+ * `useWindows()`. The underlying map is referentially stable between mutations,
12
+ * so the derived array is too (no render churn).
13
+ */
14
+ export declare function useWindowList(): readonly WindowListEntry[];
15
+ //# sourceMappingURL=windows.hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"windows.hook.d.ts","sourceRoot":"","sources":["../../../src/window/hooks/windows.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAc/C,mFAAmF;AACnF,wBAAgB,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAQxD;AAED,uCAAuC;AACvC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CACxB;AAED;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,SAAS,eAAe,EAAE,CAG1D"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * useWindows / useWindowList (API §10) — reactive views over the windows a
3
+ * `ViewHost`/`AppHost` mounts through the per-shell hub. The shell exposes no
4
+ * window-change feed, so the hub registry (fed by the hosts) is the reactive
5
+ * source; windows mounted imperatively via `shell.mount` outside React are not
6
+ * tracked here — flagged in the module report as a shell foundation gap.
7
+ */
8
+ import { useMemo, useSyncExternalStore } from 'react';
9
+ import { useShell } from '../../session/shell.hook';
10
+ import { getStageHub } from '../hub';
11
+ /** Every host-mounted window in this shell's tree, keyed by windowId. Reactive. */
12
+ export function useWindows() {
13
+ const shell = useShell();
14
+ const hub = useMemo(() => getStageHub(shell), [shell]);
15
+ return useSyncExternalStore(hub.registry.subscribe, hub.registry.getSnapshot, hub.registry.getSnapshot);
16
+ }
17
+ /**
18
+ * The open windows as a reactive, insertion-ordered list — the array form of
19
+ * `useWindows()`. The underlying map is referentially stable between mutations,
20
+ * so the derived array is too (no render churn).
21
+ */
22
+ export function useWindowList() {
23
+ const windows = useWindows();
24
+ return useMemo(() => [...windows].map(([windowId, window]) => ({ windowId, window })), [windows]);
25
+ }
@@ -0,0 +1,31 @@
1
+ import type { NodeRefInput } from '@astrale-os/kernel-client';
2
+ import type { CloseResult, IntentRegistry, MountCredential, SandboxProfile } from '@astrale-os/shell';
3
+ import type { CSSProperties, ReactNode } from 'react';
4
+ import type { ViewSource } from './lifecycle/mount';
5
+ import type { WindowState } from './lifecycle/states';
6
+ /** Imperative handle on a mounted `ViewHost` (API §10). */
7
+ export interface ViewHostHandle {
8
+ readonly windowId: string | null;
9
+ close(opts?: {
10
+ force?: boolean;
11
+ timeoutMs?: number;
12
+ }): Promise<CloseResult>;
13
+ /** The one explicit remount. */
14
+ refresh(): void;
15
+ }
16
+ export type ViewHostProps = ViewSource & {
17
+ /** Node this view opens on — delivered as `targetNodeId`; a change retargets. */
18
+ node?: NodeRefInput;
19
+ capabilities?: {
20
+ intents: readonly (keyof IntentRegistry)[];
21
+ };
22
+ sandbox?: SandboxProfile | null;
23
+ credential?: MountCredential;
24
+ /** Rendered inside the anchor while the frame is not `ready`. */
25
+ fallback?: (state: WindowState) => ReactNode;
26
+ onStateChange?: (state: WindowState) => void;
27
+ className?: string;
28
+ style?: CSSProperties;
29
+ };
30
+ export declare const ViewHost: import("react").ForwardRefExoticComponent<ViewHostProps & import("react").RefAttributes<ViewHostHandle>>;
31
+ //# sourceMappingURL=host.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/window/host.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D,OAAO,KAAK,EACV,WAAW,EACX,cAAc,EACd,eAAe,EAEf,cAAc,EAEf,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,aAAa,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AAqBnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAcrD,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IAChC,KAAK,CAAC,IAAI,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;IAC3E,gCAAgC;IAChC,OAAO,IAAI,IAAI,CAAA;CAChB;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG;IACvC,iFAAiF;IACjF,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,YAAY,CAAC,EAAE;QAAE,OAAO,EAAE,SAAS,CAAC,MAAM,cAAc,CAAC,EAAE,CAAA;KAAE,CAAA;IAC7D,OAAO,CAAC,EAAE,cAAc,GAAG,IAAI,CAAA;IAC/B,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,SAAS,CAAA;IAC5C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAA;IAC5C,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB,CAAA;AAYD,eAAO,MAAM,QAAQ,0GAyQpB,CAAA"}
@@ -0,0 +1,270 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ /**
3
+ * ViewHost (API §10) — hosts one view. It renders a normal-flow anchor and
4
+ * projects that box onto a stage slot (ResizeObserver); the iframe lives in the
5
+ * stage, so reorder/re-key never reloads a healthy frame. It drives the
6
+ * `WindowState` machine, owns teardown (unmount closes its window), survives
7
+ * StrictMode double-mount, and downgrades a fallbackable handshake to plain.
8
+ */
9
+ import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, } from 'react';
10
+ import { useShell } from '../session/shell.hook';
11
+ import { getStageHub } from './hub';
12
+ import { isFallbackableHandshakeError, refToId, resolveSource, sendSetTarget, sourceKey, } from './lifecycle/mount';
13
+ import { rectOf, sameRect } from './placement';
14
+ const MOUNTING = { phase: 'mounting' };
15
+ export const ViewHost = forwardRef(function ViewHost(props, ref) {
16
+ const shell = useShell();
17
+ const hub = useMemo(() => getStageHub(shell), [shell]);
18
+ const anchorRef = useRef(null);
19
+ const slotRef = useRef(null);
20
+ const windowIdRef = useRef(null);
21
+ const aliveRef = useRef(true);
22
+ // The live window (set at ready / on adopt, cleared on close) — the unit an
23
+ // unmount stashes for a re-key/re-parent remount to adopt (§10).
24
+ const liveRef = useRef(null);
25
+ // Set by `refresh()`: the next unmount CLOSES (real remount) instead of stashing.
26
+ const refreshingRef = useRef(false);
27
+ // Last placed slot rect — reset when the slot changes; guards redundant places.
28
+ const lastRectRef = useRef(null);
29
+ const propsRef = useRef(props);
30
+ propsRef.current = props;
31
+ const [state, setState] = useState(MOUNTING);
32
+ const [refreshNonce, setRefreshNonce] = useState(0);
33
+ const mountKey = sourceKey(props);
34
+ const targetId = refToId(props.node);
35
+ const lastTargetRef = useRef(undefined);
36
+ const setStateSafe = (next) => {
37
+ if (!aliveRef.current)
38
+ return;
39
+ setState(next);
40
+ propsRef.current.onStateChange?.(next);
41
+ };
42
+ useEffect(() => {
43
+ aliveRef.current = true;
44
+ return () => {
45
+ aliveRef.current = false;
46
+ };
47
+ }, []);
48
+ useImperativeHandle(ref, () => ({
49
+ get windowId() {
50
+ return windowIdRef.current;
51
+ },
52
+ async close(opts) {
53
+ const id = windowIdRef.current;
54
+ if (id === null)
55
+ return { kind: 'noop' };
56
+ const result = await shell.close(id, opts);
57
+ if (result.kind === 'closed') {
58
+ windowIdRef.current = null;
59
+ liveRef.current = null;
60
+ hub.registry.remove(id);
61
+ setStateSafe({ phase: 'closed', windowId: id });
62
+ }
63
+ return result;
64
+ },
65
+ refresh() {
66
+ // A real remount: the next unmount closes (not stashes) so the frame reloads.
67
+ refreshingRef.current = true;
68
+ setRefreshNonce((n) => n + 1);
69
+ },
70
+ }), [shell, hub]);
71
+ // ── Placement: project the anchor box onto the current stage slot. Guarded by
72
+ // rect-equality, so it is cheap to call on every commit (a sibling reorder
73
+ // moves the anchor with no resize/scroll event — API §10).
74
+ const measure = useCallback(() => {
75
+ const slot = slotRef.current;
76
+ const anchor = anchorRef.current;
77
+ if (slot === null || anchor === null)
78
+ return;
79
+ const rect = rectOf(anchor);
80
+ const last = lastRectRef.current;
81
+ if (last !== null && sameRect(last, rect))
82
+ return;
83
+ lastRectRef.current = rect;
84
+ slot.place(rect);
85
+ }, []);
86
+ // ── Mount lifecycle. Keyed on the source identity + refresh nonce only — a
87
+ // node (targetNodeId) change retargets via setTarget, never a remount. A
88
+ // re-key/re-parent unmount+remount ADOPTS the live window through the hub
89
+ // (deferred close), so a healthy iframe is never reloaded (§10).
90
+ useEffect(() => {
91
+ let cancelled = false;
92
+ let controllerWaiter = null;
93
+ // Consume the refresh flag: this setup is the (real) remount a refresh asked
94
+ // for, so it must NOT adopt the window its own cleanup just closed.
95
+ const wasRefresh = refreshingRef.current;
96
+ refreshingRef.current = false;
97
+ /** Close the window, release its slot, drop it from the registry (unadopted). */
98
+ function closeAndRelease(id, slot) {
99
+ void shell
100
+ .close(id, { force: false })
101
+ .then((r) => (r.kind === 'closed' ? undefined : shell.close(id, { force: true })))
102
+ .catch(() => { })
103
+ .finally(() => hub.registry.remove(id));
104
+ slot.release();
105
+ }
106
+ /** Stash the live window for adoption, or (on refresh) close it outright. */
107
+ function cleanup() {
108
+ cancelled = true;
109
+ controllerWaiter?.();
110
+ const live = liveRef.current;
111
+ const slot = slotRef.current;
112
+ slotRef.current = null;
113
+ windowIdRef.current = null;
114
+ liveRef.current = null;
115
+ lastRectRef.current = null;
116
+ if (live === null || slot === null) {
117
+ // Mount never resolved: release the slot; an in-flight mount self-closes.
118
+ slot?.release();
119
+ return;
120
+ }
121
+ const record = {
122
+ windowId: live.windowId,
123
+ window: live.window,
124
+ slot,
125
+ state: live.state,
126
+ targetId: live.targetId,
127
+ dispose: () => closeAndRelease(live.windowId, slot),
128
+ };
129
+ if (refreshingRef.current)
130
+ record.dispose();
131
+ else
132
+ hub.stashForAdopt(mountKey, record);
133
+ }
134
+ // Adopt a live window a just-unmounted same-source host left behind.
135
+ if (!wasRefresh) {
136
+ const adopted = hub.takeAdopt(mountKey);
137
+ if (adopted !== null) {
138
+ slotRef.current = adopted.slot;
139
+ windowIdRef.current = adopted.windowId;
140
+ liveRef.current = {
141
+ windowId: adopted.windowId,
142
+ window: adopted.window,
143
+ state: adopted.state,
144
+ targetId: adopted.targetId,
145
+ };
146
+ lastTargetRef.current = adopted.targetId;
147
+ hub.registry.upsert(adopted.windowId, adopted.window, adopted.state);
148
+ lastRectRef.current = null;
149
+ measure(); // reposition the surviving slot onto this host's anchor
150
+ setStateSafe(adopted.state);
151
+ return cleanup;
152
+ }
153
+ }
154
+ async function mountWith(handshake, downgraded) {
155
+ const p = propsRef.current;
156
+ let resolved;
157
+ try {
158
+ resolved = await resolveSource(shell.kernel, sourceOf(p));
159
+ }
160
+ catch (err) {
161
+ // No window yet (source resolution failed) — windowId honestly absent.
162
+ if (!cancelled)
163
+ setStateSafe({ phase: 'crashed', error: err });
164
+ return;
165
+ }
166
+ if (cancelled)
167
+ return;
168
+ const usedHandshake = handshake === 'none' ? 'none' : resolved.handshake;
169
+ const deliveredTarget = refToId(p.node);
170
+ const params = {
171
+ host: slotRef.current.element,
172
+ url: resolved.url,
173
+ functionId: resolved.functionId,
174
+ capabilities: { intents: p.capabilities?.intents ?? [] },
175
+ targetNodeId: deliveredTarget,
176
+ sandbox: p.sandbox,
177
+ handshake: usedHandshake,
178
+ credential: p.credential,
179
+ };
180
+ try {
181
+ const win = await shell.mount(params);
182
+ // A StrictMode cleanup (or refresh) fired before mount resolved: adopt
183
+ // then immediately close so no orphan window survives.
184
+ if (cancelled) {
185
+ void win.close({ force: true }).catch(() => { });
186
+ return;
187
+ }
188
+ windowIdRef.current = win.windowId;
189
+ lastTargetRef.current = deliveredTarget;
190
+ const ready = downgraded
191
+ ? { phase: 'ready', windowId: win.windowId, downgraded: true }
192
+ : { phase: 'ready', windowId: win.windowId };
193
+ liveRef.current = {
194
+ windowId: win.windowId,
195
+ window: win.window,
196
+ state: ready,
197
+ targetId: deliveredTarget,
198
+ };
199
+ hub.registry.upsert(win.windowId, win.window, ready);
200
+ setStateSafe(ready);
201
+ }
202
+ catch (err) {
203
+ if (cancelled)
204
+ return;
205
+ if (usedHandshake === 'shell' && isFallbackableHandshakeError(err)) {
206
+ await mountWith('none', true);
207
+ return;
208
+ }
209
+ setStateSafe({ phase: 'crashed', windowId: windowIdRef.current ?? undefined, error: err });
210
+ }
211
+ }
212
+ function begin(controller) {
213
+ if (cancelled || slotRef.current !== null)
214
+ return;
215
+ const slot = controller.acquire();
216
+ slotRef.current = slot;
217
+ lastRectRef.current = null;
218
+ measure();
219
+ setStateSafe(MOUNTING);
220
+ void mountWith('shell', false);
221
+ }
222
+ const existing = hub.getController();
223
+ if (existing !== null)
224
+ begin(existing);
225
+ else {
226
+ controllerWaiter = hub.onController((c) => {
227
+ if (c !== null)
228
+ begin(c);
229
+ });
230
+ }
231
+ return cleanup;
232
+ // eslint-disable-next-line react-hooks/exhaustive-deps
233
+ }, [hub, shell, mountKey, refreshNonce]);
234
+ // ── Retarget: a node change after ready hot-swaps via setTarget (no remount).
235
+ useEffect(() => {
236
+ if (state.phase !== 'ready')
237
+ return;
238
+ if (targetId === lastTargetRef.current)
239
+ return;
240
+ lastTargetRef.current = targetId;
241
+ if (targetId === undefined)
242
+ return;
243
+ sendSetTarget(shell, state.windowId, targetId);
244
+ }, [shell, state, targetId]);
245
+ // ── Placement observers: reposition on resize/scroll/anchor-resize.
246
+ useLayoutEffect(() => {
247
+ measure();
248
+ const anchor = anchorRef.current;
249
+ const ro = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(measure) : null;
250
+ if (anchor !== null)
251
+ ro?.observe(anchor);
252
+ window.addEventListener('resize', measure);
253
+ window.addEventListener('scroll', measure, true);
254
+ return () => {
255
+ ro?.disconnect();
256
+ window.removeEventListener('resize', measure);
257
+ window.removeEventListener('scroll', measure, true);
258
+ };
259
+ }, [measure]);
260
+ // Re-measure on EVERY commit (rect-equality-guarded): a sibling reorder moves
261
+ // the anchor with no resize/scroll event, so the slot must chase it here (§10).
262
+ useLayoutEffect(() => {
263
+ measure();
264
+ });
265
+ return (_jsx("div", { ref: anchorRef, className: props.className, style: props.style, children: state.phase !== 'ready' ? props.fallback?.(state) : null }));
266
+ });
267
+ /** Narrow props back to the bare `ViewSource` discriminated union. */
268
+ function sourceOf(props) {
269
+ return 'url' in props ? { url: props.url } : { view: props.view };
270
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * The per-shell windows hub (API §10). `ViewStage` mounts once near the root while
3
+ * `ViewHost`s live anywhere, so they rendezvous through a hub keyed by the shared
4
+ * `Shell` instance (a `WeakMap`), not context. It owns the `WindowRegistry`
5
+ * (reactive store behind `useWindows`/`useWindow`, fed by the hosts), the stage
6
+ * controller (the slot layer, published by the stage), and the adopt stash.
7
+ */
8
+ import type { Shell, Window } from '@astrale-os/shell';
9
+ import type { AdoptRecord } from './adopt';
10
+ import type { WindowState } from './lifecycle/states';
11
+ import type { StageController } from './placement';
12
+ /** A `useWindow` projection — a window's phase plus its shell `Window` (or none). */
13
+ export type WindowView = WindowState & {
14
+ readonly window: Window | null;
15
+ };
16
+ export interface WindowRegistry {
17
+ /** Referentially stable between mutations (useSyncExternalStore contract). */
18
+ getSnapshot(): ReadonlyMap<string, Window>;
19
+ /** Stable projection for one window id (null id → a stable "no window"). */
20
+ select(windowId: string | null): WindowView;
21
+ subscribe(onChange: () => void): () => void;
22
+ /** Host writes: register/transition/drop a window. */
23
+ upsert(windowId: string, window: Window, state: WindowState): void;
24
+ patch(windowId: string, state: WindowState): void;
25
+ remove(windowId: string): void;
26
+ }
27
+ export interface StageHub {
28
+ readonly registry: WindowRegistry;
29
+ getController(): StageController | null;
30
+ /** Publish (stage mount) or retract (stage unmount) the slot layer. */
31
+ setController(controller: StageController | null): void;
32
+ /** Await the controller — fires immediately if one is already published. */
33
+ onController(cb: (controller: StageController | null) => void): () => void;
34
+ /** Stash an unmounting host's live window; disposes after one macrotask if unadopted. */
35
+ stashForAdopt(key: string, record: AdoptRecord): void;
36
+ /** Reclaim a stashed window for a remount of the same source, cancelling its dispose. */
37
+ takeAdopt(key: string): AdoptRecord | null;
38
+ }
39
+ /** The windows hub for a shell — one per shell object, created on first touch. */
40
+ export declare function getStageHub(shell: Shell): StageHub;
41
+ //# sourceMappingURL=hub.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../../src/window/hub.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAYlD,qFAAqF;AACrF,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAA;AAEzE,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,WAAW,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC1C,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,UAAU,CAAA;IAC3C,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAA;IAC3C,sDAAsD;IACtD,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IAClE,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACjD,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;CAC/B;AAqED,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAA;IACjC,aAAa,IAAI,eAAe,GAAG,IAAI,CAAA;IACvC,uEAAuE;IACvE,aAAa,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,GAAG,IAAI,CAAA;IACvD,4EAA4E;IAC5E,YAAY,CAAC,EAAE,EAAE,CAAC,UAAU,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,GAAG,MAAM,IAAI,CAAA;IAC1E,yFAAyF;IACzF,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;IACrD,yFAAyF;IACzF,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAAA;CAC3C;AAID,kFAAkF;AAClF,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,QAAQ,CAkClD"}
@@ -0,0 +1,100 @@
1
+ import { createAdoptStash } from './adopt';
2
+ const NO_WINDOW = { phase: 'closed', windowId: '', window: null };
3
+ function createWindowRegistry() {
4
+ const entries = new Map();
5
+ const listeners = new Set();
6
+ // Cached snapshots: rebuilt only on mutation, so repeated getSnapshot/select
7
+ // calls between changes return identical references (no render loop).
8
+ let windowsSnapshot = null;
9
+ let selectCache = new Map();
10
+ function invalidate() {
11
+ windowsSnapshot = null;
12
+ selectCache = new Map();
13
+ for (const l of listeners)
14
+ l();
15
+ }
16
+ return {
17
+ getSnapshot() {
18
+ if (windowsSnapshot === null) {
19
+ const map = new Map();
20
+ for (const [id, entry] of entries)
21
+ map.set(id, entry.window);
22
+ windowsSnapshot = map;
23
+ }
24
+ return windowsSnapshot;
25
+ },
26
+ select(windowId) {
27
+ if (windowId === null)
28
+ return NO_WINDOW;
29
+ const cached = selectCache.get(windowId);
30
+ if (cached !== undefined)
31
+ return cached;
32
+ const entry = entries.get(windowId);
33
+ const view = entry
34
+ ? { ...entry.state, window: entry.window }
35
+ : { phase: 'closed', windowId, window: null };
36
+ selectCache.set(windowId, view);
37
+ return view;
38
+ },
39
+ subscribe(onChange) {
40
+ listeners.add(onChange);
41
+ return () => {
42
+ listeners.delete(onChange);
43
+ };
44
+ },
45
+ upsert(windowId, window, state) {
46
+ entries.set(windowId, { window, state });
47
+ invalidate();
48
+ },
49
+ patch(windowId, state) {
50
+ const entry = entries.get(windowId);
51
+ if (entry === undefined)
52
+ return;
53
+ entries.set(windowId, { window: entry.window, state });
54
+ invalidate();
55
+ },
56
+ remove(windowId) {
57
+ if (!entries.delete(windowId))
58
+ return;
59
+ invalidate();
60
+ },
61
+ };
62
+ }
63
+ const HUBS = new WeakMap();
64
+ /** The windows hub for a shell — one per shell object, created on first touch. */
65
+ export function getStageHub(shell) {
66
+ const existing = HUBS.get(shell);
67
+ if (existing !== undefined)
68
+ return existing;
69
+ const registry = createWindowRegistry();
70
+ let controller = null;
71
+ const waiters = new Set();
72
+ const adopt = createAdoptStash();
73
+ const hub = {
74
+ registry,
75
+ getController() {
76
+ return controller;
77
+ },
78
+ setController(next) {
79
+ controller = next;
80
+ for (const w of waiters)
81
+ w(next);
82
+ },
83
+ onController(cb) {
84
+ waiters.add(cb);
85
+ if (controller !== null)
86
+ cb(controller);
87
+ return () => {
88
+ waiters.delete(cb);
89
+ };
90
+ },
91
+ stashForAdopt(key, record) {
92
+ adopt.stash(key, record);
93
+ },
94
+ takeAdopt(key) {
95
+ return adopt.take(key);
96
+ },
97
+ };
98
+ HUBS.set(shell, hub);
99
+ return hub;
100
+ }
@@ -0,0 +1,15 @@
1
+ export { ViewStage } from './stage';
2
+ export { ViewHost } from './host';
3
+ export type { ViewHostProps, ViewHostHandle } from './host';
4
+ export { useWindows, useWindowList } from './hooks/windows.hook';
5
+ export type { WindowListEntry } from './hooks/windows.hook';
6
+ export { useWindow } from './hooks/window.hook';
7
+ export type { WindowView } from './hub';
8
+ export { useViewsFor } from './hooks/views-for.hook';
9
+ export type { ViewsForResult } from './hooks/views-for.hook';
10
+ export { useTargetNode } from './hooks/target-node.hook';
11
+ export { useCloseGuard } from './hooks/close-guard.hook';
12
+ export type { CloseGuard, CloseVerdict } from './hooks/close-guard.hook';
13
+ export type { ViewDescriptor, ViewSource, Node } from './lifecycle/mount';
14
+ export type { WindowState } from './lifecycle/states';
15
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/window/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AACjC,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,YAAY,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AACxD,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACxE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAA;AACzE,YAAY,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,10 @@
1
+ // window — API §10. ViewStage/ViewHost (the physical iframe-slot layer + a host
2
+ // that projects placement into a slot), the reactive window hooks, the child-side
3
+ // target-node + close-guard, and the (G5) view-resolution hook.
4
+ export { ViewStage } from './stage';
5
+ export { ViewHost } from './host';
6
+ export { useWindows, useWindowList } from './hooks/windows.hook';
7
+ export { useWindow } from './hooks/window.hook';
8
+ export { useViewsFor } from './hooks/views-for.hook';
9
+ export { useTargetNode } from './hooks/target-node.hook';
10
+ export { useCloseGuard } from './hooks/close-guard.hook';
@@ -0,0 +1,47 @@
1
+ import type { NodeRefInput } from '@astrale-os/kernel-client';
2
+ /**
3
+ * Mount orchestration (API §10) — resolve a `ViewSource` to something `shell.mount`
4
+ * accepts (url + handshake + functionId), the stable remount key, the delivered
5
+ * target id, the handshake-fallback predicate, and the parent→child setTarget
6
+ * hot-swap. A one-call `View.resolve` kernel contract does not exist yet — the
7
+ * bare-ref path is the honest subset, G5.
8
+ */
9
+ import type { KernelClient, Shell } from '@astrale-os/shell';
10
+ /** A live graph node, derived from the shell kernel read surface (G8 seam). */
11
+ export type Node = NonNullable<Awaited<ReturnType<KernelClient['get']>>>;
12
+ /** A View function resolved to something mountable (url + optional handshake). */
13
+ export interface ViewDescriptor {
14
+ readonly id: string;
15
+ readonly path: string;
16
+ readonly url?: string;
17
+ readonly handshake?: string;
18
+ }
19
+ /**
20
+ * What a `ViewHost` mounts:
21
+ * - `{ view }` — a View function (descriptor or ref), resolved to url + handshake.
22
+ * - `{ url }` — a handshake-less hosted view; mounts immediately (no 5s wait).
23
+ */
24
+ export type ViewSource = {
25
+ readonly view: NodeRefInput | ViewDescriptor;
26
+ } | {
27
+ readonly url: string;
28
+ };
29
+ export interface ResolvedSource {
30
+ readonly url: string;
31
+ readonly handshake: 'shell' | 'none';
32
+ readonly functionId: string;
33
+ }
34
+ /** Resolve a source; may hit the kernel for a bare/urless View ref (G5). */
35
+ export declare function resolveSource(kernel: KernelClient, source: ViewSource): Promise<ResolvedSource>;
36
+ /** A stable remount key: the same source identity must not remount. */
37
+ export declare function sourceKey(source: ViewSource): string;
38
+ /** The bare node id delivered as `targetNodeId` at mount / retarget. */
39
+ export declare function refToId(ref: NodeRefInput | undefined): string | undefined;
40
+ /**
41
+ * Fallbackable = the view didn't speak the shell protocol (timeout/failed), not a
42
+ * security refusal (origin mismatch) — only the former downgrades to plain.
43
+ */
44
+ export declare function isFallbackableHandshakeError(err: unknown): boolean;
45
+ /** Parent → child hot-swap of the target node (no remount) — API §10 setTarget. */
46
+ export declare function sendSetTarget(shell: Shell, windowId: string, nodeId: string): void;
47
+ //# sourceMappingURL=mount.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/window/lifecycle/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE5D,+EAA+E;AAC/E,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAExE,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AA6CD,4EAA4E;AAC5E,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAOpD;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKzE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlE;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMlF"}