@astrale-os/shell-react 0.2.9 → 0.2.10-beta.2

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 (339) hide show
  1. package/dist/application/apps/app-host.d.ts +4 -15
  2. package/dist/application/apps/app-host.d.ts.map +1 -1
  3. package/dist/application/apps/app-host.js +1 -1
  4. package/dist/application/apps/apps.hook.d.ts +7 -4
  5. package/dist/application/apps/apps.hook.d.ts.map +1 -1
  6. package/dist/application/apps/apps.hook.js +10 -2
  7. package/dist/application/apps/domains.hook.d.ts +1 -1
  8. package/dist/application/apps/domains.hook.d.ts.map +1 -1
  9. package/dist/application/apps/domains.hook.js +1 -1
  10. package/dist/application/apps/open-app.hook.d.ts +2 -3
  11. package/dist/application/apps/open-app.hook.d.ts.map +1 -1
  12. package/dist/application/index.d.ts +2 -4
  13. package/dist/application/index.d.ts.map +1 -1
  14. package/dist/application/index.js +2 -3
  15. package/dist/application/spaces/space.hook.d.ts +2 -2
  16. package/dist/application/spaces/space.hook.d.ts.map +1 -1
  17. package/dist/application/spaces/space.hook.js +2 -2
  18. package/dist/application/spaces/spaces.hook.d.ts +2 -3
  19. package/dist/application/spaces/spaces.hook.d.ts.map +1 -1
  20. package/dist/application/spaces/spaces.hook.js +10 -3
  21. package/dist/auth/act-as.context.d.ts +15 -32
  22. package/dist/auth/act-as.context.d.ts.map +1 -1
  23. package/dist/auth/act-as.context.js +22 -66
  24. package/dist/auth/auth.hook.d.ts +1 -0
  25. package/dist/auth/auth.hook.d.ts.map +1 -1
  26. package/dist/auth/auth.hook.js +2 -22
  27. package/dist/auth/can.hook.d.ts +10 -38
  28. package/dist/auth/can.hook.d.ts.map +1 -1
  29. package/dist/auth/can.hook.js +35 -110
  30. package/dist/auth/index.d.ts +1 -0
  31. package/dist/auth/index.d.ts.map +1 -1
  32. package/dist/auth/self.hook.d.ts +2 -2
  33. package/dist/auth/self.hook.d.ts.map +1 -1
  34. package/dist/auth/self.hook.js +0 -7
  35. package/dist/auth/session-kernel.d.ts +2 -3
  36. package/dist/auth/session-kernel.d.ts.map +1 -1
  37. package/dist/auth/session-kernel.js +4 -13
  38. package/dist/components/boundaries.d.ts +47 -0
  39. package/dist/components/boundaries.d.ts.map +1 -0
  40. package/dist/components/boundaries.js +55 -0
  41. package/dist/components/can.d.ts +11 -0
  42. package/dist/components/can.d.ts.map +1 -0
  43. package/dist/components/can.js +5 -0
  44. package/dist/components/index.d.ts +7 -0
  45. package/dist/components/index.d.ts.map +1 -0
  46. package/dist/components/index.js +4 -0
  47. package/dist/components/mount-domain-frontend.d.ts +22 -0
  48. package/dist/components/mount-domain-frontend.d.ts.map +1 -0
  49. package/dist/components/mount-domain-frontend.js +85 -0
  50. package/dist/components/view-app.d.ts +16 -0
  51. package/dist/components/view-app.d.ts.map +1 -0
  52. package/dist/components/view-app.js +16 -0
  53. package/dist/graph/call/call.hook.d.ts +8 -18
  54. package/dist/graph/call/call.hook.d.ts.map +1 -1
  55. package/dist/graph/call/call.hook.js +7 -13
  56. package/dist/graph/call/stream.hook.d.ts +12 -20
  57. package/dist/graph/call/stream.hook.d.ts.map +1 -1
  58. package/dist/graph/call/stream.hook.js +55 -111
  59. package/dist/graph/graph.context.d.ts +4 -3
  60. package/dist/graph/graph.context.d.ts.map +1 -1
  61. package/dist/graph/graph.context.js +2 -8
  62. package/dist/graph/guards.error.d.ts +7 -8
  63. package/dist/graph/guards.error.d.ts.map +1 -1
  64. package/dist/graph/guards.error.js +11 -7
  65. package/dist/graph/index.d.ts +8 -16
  66. package/dist/graph/index.d.ts.map +1 -1
  67. package/dist/graph/index.js +3 -7
  68. package/dist/graph/memory/read/envelope.d.ts +22 -54
  69. package/dist/graph/memory/read/envelope.d.ts.map +1 -1
  70. package/dist/graph/memory/read/envelope.js +26 -20
  71. package/dist/graph/memory/read/idle.d.ts +1 -15
  72. package/dist/graph/memory/read/idle.d.ts.map +1 -1
  73. package/dist/graph/memory/read/idle.js +4 -13
  74. package/dist/graph/query-definition.hook.d.ts +11 -0
  75. package/dist/graph/query-definition.hook.d.ts.map +1 -0
  76. package/dist/graph/query-definition.hook.js +205 -0
  77. package/dist/graph/resource.d.ts +34 -0
  78. package/dist/graph/resource.d.ts.map +1 -0
  79. package/dist/graph/resource.js +244 -0
  80. package/dist/graph/store.d.ts +25 -0
  81. package/dist/graph/store.d.ts.map +1 -0
  82. package/dist/graph/store.js +69 -0
  83. package/dist/host/actions.hook.d.ts +34 -0
  84. package/dist/host/actions.hook.d.ts.map +1 -0
  85. package/dist/host/actions.hook.js +125 -0
  86. package/dist/host/components.d.ts +15 -0
  87. package/dist/host/components.d.ts.map +1 -0
  88. package/dist/host/components.js +14 -0
  89. package/dist/host/index.d.ts +5 -0
  90. package/dist/host/index.d.ts.map +1 -0
  91. package/dist/host/index.js +3 -0
  92. package/dist/index.d.ts +26 -37
  93. package/dist/index.d.ts.map +1 -1
  94. package/dist/index.js +20 -31
  95. package/dist/intents/envelope.d.ts +7 -19
  96. package/dist/intents/envelope.d.ts.map +1 -1
  97. package/dist/intents/envelope.js +2 -3
  98. package/dist/intents/send-intent.hook.d.ts +5 -7
  99. package/dist/intents/send-intent.hook.d.ts.map +1 -1
  100. package/dist/intents/send-intent.hook.js +17 -75
  101. package/dist/navigation/adapters/adapter.d.ts +5 -0
  102. package/dist/navigation/adapters/adapter.d.ts.map +1 -1
  103. package/dist/navigation/adapters/memory.adapter.d.ts.map +1 -1
  104. package/dist/navigation/adapters/memory.adapter.js +4 -0
  105. package/dist/navigation/adapters/url.adapter.d.ts.map +1 -1
  106. package/dist/navigation/adapters/url.adapter.js +57 -10
  107. package/dist/navigation/codec.d.ts +60 -0
  108. package/dist/navigation/codec.d.ts.map +1 -0
  109. package/dist/navigation/codec.js +121 -0
  110. package/dist/navigation/history.d.ts +11 -9
  111. package/dist/navigation/history.d.ts.map +1 -1
  112. package/dist/navigation/history.js +6 -8
  113. package/dist/navigation/hooks/ancestors.hook.d.ts +5 -7
  114. package/dist/navigation/hooks/ancestors.hook.d.ts.map +1 -1
  115. package/dist/navigation/hooks/ancestors.hook.js +7 -51
  116. package/dist/navigation/hooks/location.hook.d.ts.map +1 -1
  117. package/dist/navigation/hooks/location.hook.js +4 -6
  118. package/dist/navigation/hooks/scope.hook.d.ts.map +1 -1
  119. package/dist/navigation/hooks/scope.hook.js +4 -6
  120. package/dist/navigation/index.d.ts +4 -2
  121. package/dist/navigation/index.d.ts.map +1 -1
  122. package/dist/navigation/index.js +2 -1
  123. package/dist/navigation/link.d.ts +12 -0
  124. package/dist/navigation/link.d.ts.map +1 -1
  125. package/dist/navigation/link.js +13 -2
  126. package/dist/navigation/location.d.ts +13 -40
  127. package/dist/navigation/location.d.ts.map +1 -1
  128. package/dist/navigation/location.js +14 -76
  129. package/dist/navigation/scope.context.d.ts +17 -26
  130. package/dist/navigation/scope.context.d.ts.map +1 -1
  131. package/dist/navigation/scope.context.js +140 -108
  132. package/dist/navigation/snapshot.d.ts +14 -19
  133. package/dist/navigation/snapshot.d.ts.map +1 -1
  134. package/dist/navigation/snapshot.js +48 -44
  135. package/dist/schema/action.hook.d.ts +44 -0
  136. package/dist/schema/action.hook.d.ts.map +1 -0
  137. package/dist/schema/action.hook.js +72 -0
  138. package/dist/schema/domain.hook.d.ts +12 -7
  139. package/dist/schema/domain.hook.d.ts.map +1 -1
  140. package/dist/schema/domain.hook.js +101 -4
  141. package/dist/schema/index.d.ts +9 -8
  142. package/dist/schema/index.d.ts.map +1 -1
  143. package/dist/schema/index.js +5 -7
  144. package/dist/schema/kernel.hook.d.ts +4 -9
  145. package/dist/schema/kernel.hook.d.ts.map +1 -1
  146. package/dist/schema/kernel.hook.js +4 -6
  147. package/dist/schema/mutation.hook.d.ts +9 -0
  148. package/dist/schema/mutation.hook.d.ts.map +1 -0
  149. package/dist/schema/mutation.hook.js +41 -0
  150. package/dist/schema/object.hook.d.ts +16 -0
  151. package/dist/schema/object.hook.d.ts.map +1 -0
  152. package/dist/schema/object.hook.js +46 -0
  153. package/dist/schema/relation.hook.d.ts +46 -0
  154. package/dist/schema/relation.hook.d.ts.map +1 -0
  155. package/dist/schema/relation.hook.js +136 -0
  156. package/dist/selection/live.d.ts +9 -17
  157. package/dist/selection/live.d.ts.map +1 -1
  158. package/dist/selection/live.js +65 -112
  159. package/dist/selection/scope.context.js +5 -4
  160. package/dist/session/boot/boot.d.ts +1 -13
  161. package/dist/session/boot/boot.d.ts.map +1 -1
  162. package/dist/session/boot/boot.js +9 -27
  163. package/dist/session/index.d.ts +1 -0
  164. package/dist/session/index.d.ts.map +1 -1
  165. package/dist/session/kernel-instance.hook.d.ts +1 -4
  166. package/dist/session/kernel-instance.hook.d.ts.map +1 -1
  167. package/dist/session/kernel-instance.hook.js +1 -5
  168. package/dist/session/provider.d.ts +9 -23
  169. package/dist/session/provider.d.ts.map +1 -1
  170. package/dist/session/provider.js +29 -75
  171. package/dist/session/session.context.d.ts +5 -0
  172. package/dist/session/session.context.d.ts.map +1 -1
  173. package/dist/window/adopt.d.ts +0 -1
  174. package/dist/window/adopt.d.ts.map +1 -1
  175. package/dist/window/hooks/target-node.hook.d.ts +10 -6
  176. package/dist/window/hooks/target-node.hook.d.ts.map +1 -1
  177. package/dist/window/hooks/target-node.hook.js +14 -72
  178. package/dist/window/hooks/views-for.hook.d.ts +4 -3
  179. package/dist/window/hooks/views-for.hook.d.ts.map +1 -1
  180. package/dist/window/hooks/views-for.hook.js +6 -22
  181. package/dist/window/hooks/windows.hook.d.ts.map +1 -1
  182. package/dist/window/hooks/windows.hook.js +3 -4
  183. package/dist/window/host.d.ts +9 -11
  184. package/dist/window/host.d.ts.map +1 -1
  185. package/dist/window/host.js +26 -62
  186. package/dist/window/hub.d.ts +2 -0
  187. package/dist/window/hub.d.ts.map +1 -1
  188. package/dist/window/hub.js +33 -0
  189. package/dist/window/index.d.ts +2 -2
  190. package/dist/window/index.d.ts.map +1 -1
  191. package/dist/window/index.js +2 -2
  192. package/dist/window/lifecycle/mount.d.ts +5 -44
  193. package/dist/window/lifecycle/mount.d.ts.map +1 -1
  194. package/dist/window/lifecycle/mount.js +14 -120
  195. package/dist/window/lifecycle/states.d.ts +0 -5
  196. package/dist/window/lifecycle/states.d.ts.map +1 -1
  197. package/package.json +9 -8
  198. package/src/application/apps/app-host.tsx +11 -15
  199. package/src/application/apps/apps.hook.ts +13 -6
  200. package/src/application/apps/domains.hook.ts +1 -1
  201. package/src/application/apps/open-app.hook.ts +3 -4
  202. package/src/application/index.ts +4 -6
  203. package/src/application/spaces/space.hook.ts +5 -6
  204. package/src/application/spaces/spaces.hook.ts +14 -9
  205. package/src/auth/act-as.context.tsx +37 -91
  206. package/src/auth/auth.hook.ts +2 -30
  207. package/src/auth/can.hook.ts +44 -135
  208. package/src/auth/index.ts +1 -0
  209. package/src/auth/self.hook.ts +2 -9
  210. package/src/auth/session-kernel.ts +6 -16
  211. package/src/components/boundaries.tsx +113 -0
  212. package/src/components/can.tsx +16 -0
  213. package/src/components/index.ts +14 -0
  214. package/src/components/mount-domain-frontend.tsx +158 -0
  215. package/src/components/view-app.tsx +49 -0
  216. package/src/graph/call/call.hook.ts +22 -27
  217. package/src/graph/call/stream.hook.ts +66 -143
  218. package/src/graph/graph.context.ts +6 -11
  219. package/src/graph/guards.error.ts +17 -55
  220. package/src/graph/index.ts +23 -17
  221. package/src/graph/memory/read/envelope.ts +40 -65
  222. package/src/graph/memory/read/idle.ts +5 -18
  223. package/src/graph/query-definition.hook.ts +270 -0
  224. package/src/graph/resource.ts +358 -0
  225. package/src/graph/store.ts +97 -0
  226. package/src/host/actions.hook.ts +165 -0
  227. package/src/host/components.tsx +29 -0
  228. package/src/host/index.ts +17 -0
  229. package/src/index.ts +136 -124
  230. package/src/intents/envelope.ts +7 -23
  231. package/src/intents/send-intent.hook.ts +24 -79
  232. package/src/navigation/adapters/adapter.ts +3 -0
  233. package/src/navigation/adapters/memory.adapter.ts +4 -0
  234. package/src/navigation/adapters/url.adapter.ts +48 -8
  235. package/src/navigation/codec.ts +190 -0
  236. package/src/navigation/history.ts +20 -11
  237. package/src/navigation/hooks/ancestors.hook.ts +10 -60
  238. package/src/navigation/hooks/location.hook.ts +4 -6
  239. package/src/navigation/hooks/scope.hook.ts +4 -6
  240. package/src/navigation/index.ts +18 -2
  241. package/src/navigation/link.tsx +27 -2
  242. package/src/navigation/location.ts +26 -93
  243. package/src/navigation/scope.context.tsx +151 -136
  244. package/src/navigation/snapshot.ts +69 -50
  245. package/src/schema/action.hook.ts +146 -0
  246. package/src/schema/domain.hook.ts +127 -11
  247. package/src/schema/index.ts +9 -30
  248. package/src/schema/kernel.hook.ts +6 -13
  249. package/src/schema/mutation.hook.ts +63 -0
  250. package/src/schema/object.hook.ts +85 -0
  251. package/src/schema/relation.hook.ts +253 -0
  252. package/src/selection/live.ts +75 -125
  253. package/src/selection/scope.context.tsx +4 -4
  254. package/src/session/boot/boot.ts +8 -33
  255. package/src/session/index.ts +1 -0
  256. package/src/session/kernel-instance.hook.ts +2 -11
  257. package/src/session/provider.tsx +34 -103
  258. package/src/session/session.context.ts +6 -0
  259. package/src/window/adopt.ts +0 -1
  260. package/src/window/hooks/target-node.hook.ts +20 -85
  261. package/src/window/hooks/views-for.hook.ts +12 -25
  262. package/src/window/hooks/windows.hook.ts +3 -4
  263. package/src/window/host.tsx +35 -77
  264. package/src/window/hub.ts +33 -0
  265. package/src/window/index.ts +3 -3
  266. package/src/window/lifecycle/mount.ts +15 -160
  267. package/src/window/lifecycle/states.ts +1 -5
  268. package/dist/application/roles.hook.d.ts +0 -7
  269. package/dist/application/roles.hook.d.ts.map +0 -1
  270. package/dist/application/roles.hook.js +0 -23
  271. package/dist/graph/memory/base.d.ts +0 -21
  272. package/dist/graph/memory/base.d.ts.map +0 -1
  273. package/dist/graph/memory/base.js +0 -33
  274. package/dist/graph/memory/read/read.d.ts +0 -9
  275. package/dist/graph/memory/read/read.d.ts.map +0 -1
  276. package/dist/graph/memory/read/read.js +0 -87
  277. package/dist/graph/memory/scope.d.ts +0 -7
  278. package/dist/graph/memory/scope.d.ts.map +0 -1
  279. package/dist/graph/memory/scope.js +0 -25
  280. package/dist/graph/mutate/move.hook.d.ts +0 -7
  281. package/dist/graph/mutate/move.hook.d.ts.map +0 -1
  282. package/dist/graph/mutate/move.hook.js +0 -49
  283. package/dist/graph/mutate/mutate.hook.d.ts +0 -17
  284. package/dist/graph/mutate/mutate.hook.d.ts.map +0 -1
  285. package/dist/graph/mutate/mutate.hook.js +0 -45
  286. package/dist/graph/query/children.hook.d.ts +0 -29
  287. package/dist/graph/query/children.hook.d.ts.map +0 -1
  288. package/dist/graph/query/children.hook.js +0 -64
  289. package/dist/graph/query/graph.hook.d.ts +0 -9
  290. package/dist/graph/query/graph.hook.d.ts.map +0 -1
  291. package/dist/graph/query/graph.hook.js +0 -5
  292. package/dist/graph/query/neighbors.hook.d.ts +0 -7
  293. package/dist/graph/query/neighbors.hook.d.ts.map +0 -1
  294. package/dist/graph/query/neighbors.hook.js +0 -104
  295. package/dist/graph/query/node.hook.d.ts +0 -14
  296. package/dist/graph/query/node.hook.d.ts.map +0 -1
  297. package/dist/graph/query/node.hook.js +0 -43
  298. package/dist/graph/query/query.hook.d.ts +0 -14
  299. package/dist/graph/query/query.hook.d.ts.map +0 -1
  300. package/dist/graph/query/query.hook.js +0 -23
  301. package/dist/schema/bind-read.d.ts +0 -37
  302. package/dist/schema/bind-read.d.ts.map +0 -1
  303. package/dist/schema/bind-read.js +0 -205
  304. package/dist/schema/binding.d.ts +0 -21
  305. package/dist/schema/binding.d.ts.map +0 -1
  306. package/dist/schema/binding.js +0 -99
  307. package/dist/schema/function.hook.d.ts +0 -9
  308. package/dist/schema/function.hook.d.ts.map +0 -1
  309. package/dist/schema/function.hook.js +0 -40
  310. package/dist/schema/method.hook.d.ts +0 -14
  311. package/dist/schema/method.hook.d.ts.map +0 -1
  312. package/dist/schema/method.hook.js +0 -49
  313. package/dist/schema/tag.d.ts +0 -11
  314. package/dist/schema/tag.d.ts.map +0 -1
  315. package/dist/schema/tag.js +0 -11
  316. package/dist/schema/types.d.ts +0 -73
  317. package/dist/schema/types.d.ts.map +0 -1
  318. package/dist/schema/types.js +0 -1
  319. package/dist/schema/write.d.ts +0 -16
  320. package/dist/schema/write.d.ts.map +0 -1
  321. package/dist/schema/write.js +0 -56
  322. package/src/application/roles.hook.ts +0 -41
  323. package/src/graph/memory/base.ts +0 -50
  324. package/src/graph/memory/read/read.ts +0 -103
  325. package/src/graph/memory/scope.ts +0 -29
  326. package/src/graph/mutate/move.hook.ts +0 -70
  327. package/src/graph/mutate/mutate.hook.ts +0 -69
  328. package/src/graph/query/children.hook.ts +0 -136
  329. package/src/graph/query/graph.hook.ts +0 -13
  330. package/src/graph/query/neighbors.hook.ts +0 -159
  331. package/src/graph/query/node.hook.ts +0 -83
  332. package/src/graph/query/query.hook.ts +0 -42
  333. package/src/schema/bind-read.ts +0 -319
  334. package/src/schema/binding.ts +0 -146
  335. package/src/schema/function.hook.ts +0 -68
  336. package/src/schema/method.hook.ts +0 -103
  337. package/src/schema/tag.ts +0 -19
  338. package/src/schema/types.ts +0 -150
  339. package/src/schema/write.ts +0 -96
@@ -1,9 +1,9 @@
1
- import type { NodeRefInput } from '@astrale-os/kernel-client'
2
1
  import type {
3
2
  CloseResult,
4
- IntentRegistry,
3
+ HostCapabilities,
5
4
  MountCredential,
6
5
  MountParams,
6
+ ResolvedView,
7
7
  SandboxProfile,
8
8
  Window,
9
9
  } from '@astrale-os/shell'
@@ -14,7 +14,8 @@ import type { CSSProperties, ReactElement, ReactNode } from 'react'
14
14
  * projects that box onto a stage slot (ResizeObserver); the iframe lives in the
15
15
  * stage, so reorder/re-key never reloads a healthy frame. It drives the
16
16
  * `WindowState` machine, owns teardown (unmount closes its window), survives
17
- * StrictMode double-mount, and downgrades a fallbackable handshake to plain.
17
+ * StrictMode double-mount. The complete target-bound View is the sole source
18
+ * of mount identity, route, target, and handshake behavior.
18
19
  */
19
20
  import {
20
21
  forwardRef,
@@ -28,19 +29,12 @@ import {
28
29
  } from 'react'
29
30
 
30
31
  import type { AdoptRecord } from './adopt.js'
31
- import type { ResolvedSource, ViewSource } from './lifecycle/mount.js'
32
32
  import type { WindowState } from './lifecycle/states.js'
33
33
  import type { SlotRect, StageController, StageSlot } from './placement.js'
34
34
 
35
35
  import { useShell } from '../session/shell.hook.js'
36
36
  import { getStageHub } from './hub.js'
37
- import {
38
- isFallbackableHandshakeError,
39
- refToId,
40
- resolveSource,
41
- sendSetTarget,
42
- sourceKey,
43
- } from './lifecycle/mount.js'
37
+ import { viewMountKey } from './lifecycle/mount.js'
44
38
  import { rectOf, sameRect } from './placement.js'
45
39
 
46
40
  /** Imperative handle on a mounted `ViewHost` (API §10). */
@@ -52,17 +46,16 @@ export interface ViewHostHandle {
52
46
  }
53
47
 
54
48
  /** Static iframe sandbox flags, an explicit opt-out, or a policy over the resolved mount. */
55
- export type SandboxPolicy =
56
- | SandboxProfile
57
- | null
58
- | ((source: ResolvedSource) => SandboxProfile | null)
49
+ export type SandboxPolicy = SandboxProfile | null | ((view: ResolvedView) => SandboxProfile | null)
59
50
 
60
- export type ViewHostProps = ViewSource & {
61
- /** Node this view opens on — delivered as `targetNodeId`; a change retargets. */
62
- node?: NodeRefInput
63
- capabilities?: { intents: readonly (keyof IntentRegistry)[] }
51
+ export interface ViewHostProps {
52
+ /** One canonical target paired with one untouched View route. */
53
+ view: ResolvedView
54
+ capabilities?: HostCapabilities
64
55
  sandbox?: SandboxPolicy
65
56
  credential?: MountCredential
57
+ handshakeTimeoutMs?: number
58
+ delegationTtlSeconds?: number
66
59
  /** Rendered inside the anchor while the frame is not `ready`. */
67
60
  fallback?: (state: WindowState) => ReactNode
68
61
  onStateChange?: (state: WindowState) => void
@@ -77,7 +70,6 @@ interface LiveWindow {
77
70
  readonly windowId: string
78
71
  readonly window: Window
79
72
  readonly state: WindowState
80
- readonly targetId: string | undefined
81
73
  }
82
74
 
83
75
  export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
@@ -103,9 +95,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
103
95
  const [state, setState] = useState<WindowState>(MOUNTING)
104
96
  const [refreshNonce, setRefreshNonce] = useState(0)
105
97
 
106
- const mountKey = sourceKey(props)
107
- const targetId = refToId(props.node)
108
- const lastTargetRef = useRef<string | undefined>(undefined)
98
+ const mountKey = viewMountKey(props.view)
109
99
 
110
100
  const setStateSafe = (next: WindowState) => {
111
101
  if (!aliveRef.current) return
@@ -161,10 +151,9 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
161
151
  slot.place(rect)
162
152
  }, [])
163
153
 
164
- // ── Mount lifecycle. Keyed on the source identity + refresh nonce only — a
165
- // node (targetNodeId) change retargets via setTarget, never a remount. A
166
- // re-key/re-parent unmount+remount ADOPTS the live window through the hub
167
- // (deferred close), so a healthy iframe is never reloaded (§10).
154
+ // ── Mount lifecycle. Keyed on complete target + route provenance and
155
+ // refresh nonce. A same-selection re-key/re-parent can adopt the live
156
+ // window; any target or provenance change necessarily remounts.
168
157
  useEffect(() => {
169
158
  let cancelled = false
170
159
  let controllerWaiter: (() => void) | null = null
@@ -203,7 +192,6 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
203
192
  window: live.window,
204
193
  slot,
205
194
  state: live.state,
206
- targetId: live.targetId,
207
195
  dispose: () => closeAndRelease(live.windowId, slot),
208
196
  }
209
197
  if (refreshingRef.current) record.dispose()
@@ -229,9 +217,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
229
217
  windowId: adopted.windowId,
230
218
  window: adopted.window,
231
219
  state: adopted.state,
232
- targetId: adopted.targetId,
233
220
  }
234
- lastTargetRef.current = adopted.targetId
235
221
  hub.registry.upsert(adopted.windowId, adopted.window, adopted.state)
236
222
  lastRectRef.current = null
237
223
  measure() // reposition the surviving slot onto this host's anchor
@@ -240,43 +226,37 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
240
226
  }
241
227
  }
242
228
 
243
- async function mountWith(handshake: 'shell' | 'none', downgraded: boolean): Promise<void> {
229
+ async function mountView(): Promise<void> {
244
230
  const p = propsRef.current
245
- let resolved
246
- try {
247
- resolved = await resolveSource(shell.kernel, sourceOf(p))
248
- } catch (err) {
249
- // No window yet (source resolution failed) — windowId honestly absent.
250
- if (!cancelled) crashAndRelease(err)
251
- return
252
- }
253
- if (cancelled) return
254
-
255
- const usedHandshake = handshake === 'none' ? 'none' : resolved.handshake
256
- const deliveredTarget = refToId(p.node)
257
231
  let sandbox: SandboxProfile | null | undefined
258
232
  try {
259
- sandbox =
260
- typeof p.sandbox === 'function'
261
- ? p.sandbox({ ...resolved, handshake: usedHandshake })
262
- : p.sandbox
233
+ sandbox = typeof p.sandbox === 'function' ? p.sandbox(p.view) : p.sandbox
263
234
  } catch (err) {
264
235
  if (!cancelled) crashAndRelease(err)
265
236
  return
266
237
  }
267
238
  const params: MountParams = {
268
239
  host: slotRef.current!.element,
269
- url: resolved.url,
270
- functionId: resolved.functionId,
271
- capabilities: { intents: p.capabilities?.intents ?? [] },
272
- targetNodeId: deliveredTarget,
240
+ view: p.view,
241
+ capabilities: p.capabilities ?? {
242
+ version: 1,
243
+ navigation: {},
244
+ actions: {},
245
+ browser: {},
246
+ access: {},
247
+ },
273
248
  sandbox,
274
- handshake: usedHandshake,
275
249
  credential: p.credential,
250
+ ...(p.handshakeTimeoutMs === undefined
251
+ ? {}
252
+ : { handshakeTimeoutMs: p.handshakeTimeoutMs }),
253
+ ...(p.delegationTtlSeconds === undefined
254
+ ? {}
255
+ : { delegationTtlSeconds: p.delegationTtlSeconds }),
276
256
  }
277
257
 
278
258
  try {
279
- const win = await shell.mount(params)
259
+ const win = await shell.openView(params)
280
260
  // A StrictMode cleanup (or refresh) fired before mount resolved: adopt
281
261
  // then immediately close so no orphan window survives.
282
262
  if (cancelled) {
@@ -284,24 +264,16 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
284
264
  return
285
265
  }
286
266
  windowIdRef.current = win.windowId
287
- lastTargetRef.current = deliveredTarget
288
- const ready: WindowState = downgraded
289
- ? { phase: 'ready', windowId: win.windowId, downgraded: true }
290
- : { phase: 'ready', windowId: win.windowId }
267
+ const ready: WindowState = { phase: 'ready', windowId: win.windowId }
291
268
  liveRef.current = {
292
269
  windowId: win.windowId,
293
270
  window: win.window,
294
271
  state: ready,
295
- targetId: deliveredTarget,
296
272
  }
297
273
  hub.registry.upsert(win.windowId, win.window, ready)
298
274
  setStateSafe(ready)
299
275
  } catch (err) {
300
276
  if (cancelled) return
301
- if (usedHandshake === 'shell' && isFallbackableHandshakeError(err)) {
302
- await mountWith('none', true)
303
- return
304
- }
305
277
  crashAndRelease(err)
306
278
  }
307
279
  }
@@ -313,7 +285,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
313
285
  lastRectRef.current = null
314
286
  measure()
315
287
  setStateSafe(MOUNTING)
316
- void mountWith('shell', false)
288
+ void mountView()
317
289
  }
318
290
 
319
291
  const existing = hub.getController()
@@ -328,15 +300,6 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
328
300
  // eslint-disable-next-line react-hooks/exhaustive-deps
329
301
  }, [hub, shell, mountKey, refreshNonce])
330
302
 
331
- // ── Retarget: a node change after ready hot-swaps via setTarget (no remount).
332
- useEffect(() => {
333
- if (state.phase !== 'ready') return
334
- if (targetId === lastTargetRef.current) return
335
- lastTargetRef.current = targetId
336
- if (targetId === undefined) return
337
- sendSetTarget(shell, state.windowId, targetId)
338
- }, [shell, state, targetId])
339
-
340
303
  // ── Placement observers: reposition on resize/scroll/anchor-resize.
341
304
  useLayoutEffect(() => {
342
305
  measure()
@@ -365,8 +328,3 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
365
328
  )
366
329
  },
367
330
  )
368
-
369
- /** Narrow props back to the bare `ViewSource` discriminated union. */
370
- function sourceOf(props: ViewHostProps): ViewSource {
371
- return 'url' in props ? { url: props.url } : { view: props.view }
372
- }
package/src/window/hub.ts CHANGED
@@ -34,6 +34,8 @@ export interface WindowRegistry {
34
34
  upsert(windowId: string, window: Window, state: WindowState): void
35
35
  patch(windowId: string, state: WindowState): void
36
36
  remove(windowId: string): void
37
+ /** Shell writes: replace host and imperatively mounted windows from authoritative snapshots. */
38
+ sync(windows: ReadonlyMap<string, Window>): void
37
39
  }
38
40
 
39
41
  const NO_WINDOW: WindowView = { phase: 'closed', windowId: '', window: null }
@@ -98,7 +100,36 @@ function createWindowRegistry(): WindowRegistry {
98
100
  if (!entries.delete(windowId)) return
99
101
  invalidate()
100
102
  },
103
+
104
+ sync(windows) {
105
+ let changed = false
106
+ for (const windowId of entries.keys()) {
107
+ if (!windows.has(windowId)) {
108
+ entries.delete(windowId)
109
+ changed = true
110
+ }
111
+ }
112
+ for (const [windowId, window] of windows) {
113
+ const current = entries.get(windowId)
114
+ if (current?.window === window) continue
115
+ entries.set(windowId, {
116
+ window,
117
+ state: current?.state ?? phaseFor(window),
118
+ })
119
+ changed = true
120
+ }
121
+ if (changed) invalidate()
122
+ },
123
+ }
124
+ }
125
+
126
+ function phaseFor(window: Window): WindowState {
127
+ if (window.state === 'opening') return { phase: 'mounting' }
128
+ if (window.state === 'failed') {
129
+ return { phase: 'crashed', windowId: window.windowId }
101
130
  }
131
+ if (window.state === 'closed') return { phase: 'closed', windowId: window.windowId }
132
+ return { phase: 'ready', windowId: window.windowId }
102
133
  }
103
134
 
104
135
  // ── Per-shell hub ────────────────────────────────────────────────────────────
@@ -151,6 +182,8 @@ export function getStageHub(shell: Shell): StageHub {
151
182
  return adopt.take(key)
152
183
  },
153
184
  }
185
+ registry.sync(shell.windows)
186
+ shell.onWindowChange(() => registry.sync(shell.windows))
154
187
  HUBS.set(shell, hub)
155
188
  return hub
156
189
  }
@@ -1,5 +1,5 @@
1
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
2
+ // that projects stage geometry into a slot), the reactive window hooks, the child-side
3
3
  // target-node + close-guard, and the (G5) view-resolution hook.
4
4
  export { ViewStage } from './stage.js'
5
5
  export { ViewHost } from './host.js'
@@ -10,8 +10,8 @@ export { useWindow } from './hooks/window.hook.js'
10
10
  export type { WindowView } from './hub.js'
11
11
  export { useViewsFor } from './hooks/views-for.hook.js'
12
12
  export type { ViewsForResult } from './hooks/views-for.hook.js'
13
- export { useTargetNode } from './hooks/target-node.hook.js'
13
+ export { useTargetNode, useTargetPath } from './hooks/target-node.hook.js'
14
14
  export { useCloseGuard } from './hooks/close-guard.hook.js'
15
15
  export type { CloseGuard, CloseVerdict } from './hooks/close-guard.hook.js'
16
- export type { ResolvedSource, ViewDescriptor, ViewSource, Node } from './lifecycle/mount.js'
17
16
  export type { WindowState } from './lifecycle/states.js'
17
+ export type { ResolvedView } from '@astrale-os/shell'
@@ -1,164 +1,19 @@
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
-
11
- /** A live graph node, derived from the shell kernel read surface (G8 seam). */
12
- export type Node = NonNullable<Awaited<ReturnType<KernelClient['get']>>>
13
-
14
- /** A View function resolved to something mountable (url + optional handshake). */
15
- export interface ViewDescriptor {
16
- readonly id: string
17
- readonly path: string
18
- readonly url?: string
19
- readonly handshake?: string
20
- }
21
-
22
- /**
23
- * What a `ViewHost` mounts:
24
- * - `{ view }` — a View function (descriptor or ref), resolved to url + handshake.
25
- * - `{ url }` — a handshake-less hosted view; mounts immediately (no 5s wait).
26
- */
27
- export type ViewSource = { readonly view: NodeRefInput | ViewDescriptor } | { readonly url: string }
28
-
29
- export interface ResolvedSource {
30
- readonly url: string
31
- readonly handshake: 'shell' | 'none'
32
- readonly functionId: string
33
- }
34
-
35
- function isViewDescriptor(view: NodeRefInput | ViewDescriptor): view is ViewDescriptor {
36
- return typeof view === 'object' && view !== null && 'id' in view && 'path' in view
37
- }
38
-
39
- /** Last path segment or host, alnum-only — a stable-ish functionId from a url. */
40
- function slugOfUrl(url: string): string {
41
- const trimmed = url.replace(/[#?].*$/, '').replace(/\/+$/, '')
42
- const tail = trimmed.split('/').filter(Boolean).pop() ?? 'view'
43
- return tail.replace(/[^a-z0-9]/gi, '').slice(-32) || 'view'
44
- }
45
-
46
- /** A ref addressable by the kernel read surface (`get`). `@<id>` for bare ids. */
47
- function toPath(ref: NodeRefInput): string {
48
- if (typeof ref === 'string') {
49
- return ref.startsWith('/') || ref.startsWith('@') ? ref : `@${ref}`
50
- }
51
- const obj = ref as { id?: string; path?: { raw?: string } }
52
- if (obj.path?.raw !== undefined) return obj.path.raw
53
- if (obj.id !== undefined) return `@${obj.id}`
54
- throw new Error('ViewHost: unresolvable view ref')
55
- }
56
-
57
- async function resolveViewRef(
58
- kernel: KernelClient,
59
- ref: NodeRefInput,
60
- handshakeHint?: string,
61
- ): Promise<ResolvedSource> {
62
- const node = await kernel.get(toPath(ref))
63
- if (node === null) throw new Error(`ViewHost: view not found (${toPath(ref)})`)
64
- const props = (node as { id?: string; props?: Record<string, unknown> }).props ?? {}
65
- const url = viewUrl(props)
66
- if (typeof url !== 'string' || url.length === 0) {
67
- throw new Error('ViewHost: resolved view has no url')
68
- }
69
- const handshake = normalizeHandshake(handshakeHint ?? props.handshake)
70
- const id = (node as { id?: string }).id ?? slugOfUrl(url)
71
- return { url, handshake, functionId: id }
72
- }
73
-
74
- /** Resolve both the legacy flat url and the canonical Function binding. */
75
- function viewUrl(props: Record<string, unknown>): string | undefined {
76
- if (typeof props.url === 'string' && props.url.length > 0) return props.url
77
-
78
- const direct = remoteUrlOf(props.binding)
79
- if (direct !== undefined) return direct
80
-
81
- // Raw graph props can be keyed by the property's canonical graph key rather
82
- // than its local slug. The binding value remains self-describing.
83
- for (const value of Object.values(props)) {
84
- const remoteUrl = remoteUrlOf(value)
85
- if (remoteUrl !== undefined) return remoteUrl
86
- }
87
- return undefined
88
- }
89
-
90
- function remoteUrlOf(value: unknown): string | undefined {
91
- let binding = value
92
- if (typeof binding === 'string') {
93
- try {
94
- binding = JSON.parse(binding)
95
- } catch {
96
- return undefined
97
- }
98
- }
99
- if (binding === null || typeof binding !== 'object') return undefined
100
- const remoteUrl = (binding as { remoteUrl?: unknown }).remoteUrl
101
- return typeof remoteUrl === 'string' && remoteUrl.length > 0 ? remoteUrl : undefined
102
- }
103
-
104
- function normalizeHandshake(value: unknown): 'shell' | 'none' {
105
- return value === 'none' ? 'none' : 'shell'
106
- }
107
-
108
- /** Resolve a source; may hit the kernel for a bare/urless View ref (G5). */
109
- export async function resolveSource(
110
- kernel: KernelClient,
111
- source: ViewSource,
112
- ): Promise<ResolvedSource> {
113
- if ('url' in source) {
114
- return { url: source.url, handshake: 'none', functionId: slugOfUrl(source.url) }
115
- }
116
- const view = source.view
117
- if (isViewDescriptor(view)) {
118
- if (view.url !== undefined && view.url.length > 0) {
119
- return {
120
- url: view.url,
121
- handshake: normalizeHandshake(view.handshake),
122
- functionId: view.id,
123
- }
124
- }
125
- return resolveViewRef(kernel, view.id, view.handshake)
126
- }
127
- return resolveViewRef(kernel, view)
128
- }
129
-
130
- /** A stable remount key: the same source identity must not remount. */
131
- export function sourceKey(source: ViewSource): string {
132
- if ('url' in source) return `url:${source.url}`
133
- const view = source.view
134
- if (isViewDescriptor(view)) return `view:${view.id}:${view.url ?? ''}:${view.handshake ?? ''}`
135
- if (typeof view === 'string') return `ref:${view}`
136
- const obj = view as { id?: string; path?: { raw?: string } }
137
- return `ref:${obj.id ?? obj.path?.raw ?? '?'}`
138
- }
139
-
140
- /** The bare node id delivered as `targetNodeId` at mount / retarget. */
141
- export function refToId(ref: NodeRefInput | undefined): string | undefined {
142
- if (ref === undefined) return undefined
143
- if (typeof ref === 'string') return ref.startsWith('@') ? ref.slice(1) : ref
144
- const obj = ref as { id?: string }
145
- return obj.id
146
- }
1
+ import type { ResolvedView } from '@astrale-os/shell'
147
2
 
148
3
  /**
149
- * Fallbackable = the view didn't speak the shell protocol (timeout/failed), not a
150
- * security refusal (origin mismatch) — only the former downgrades to plain.
4
+ * Stable identity for one target-bound, provenance-complete View route.
5
+ * A change to any routing or semantic witness forces a fresh mount; an old
6
+ * iframe and credential can never be adopted under a different route.
151
7
  */
152
- export function isFallbackableHandshakeError(err: unknown): boolean {
153
- const code = (err as { code?: unknown } | null)?.code
154
- return code === 'HANDSHAKE_TIMEOUT' || code === 'HANDSHAKE_FAILED'
155
- }
156
-
157
- /** Parent → child hot-swap of the target node (no remount) — API §10 setTarget. */
158
- export function sendSetTarget(shell: Shell, windowId: string, nodeId: string): void {
159
- shell.children.send(windowId, {
160
- type: 'intent',
161
- version: 1,
162
- envelope: { name: 'setTarget', payload: { nodeId }, sender: { windowId: '<parent>' } },
163
- })
8
+ export function viewMountKey(view: ResolvedView): string {
9
+ const { route, target } = view
10
+ return [
11
+ target,
12
+ route.key,
13
+ route.href,
14
+ route.handshake,
15
+ route.issuer,
16
+ route.etag,
17
+ route.revision,
18
+ ].join('\u0000')
164
19
  }
@@ -8,16 +8,12 @@
8
8
  /**
9
9
  * Lifecycle of a hosted view as the React face observes it (API §10).
10
10
  *
11
- * `ready.downgraded` marks a mount that fell back to a plain iframe after a
12
- * fallbackable handshake error. It rides here (not on the shell `Window`) until
13
- * the shell `Window` grows a first-class flag — flagged in the module report.
14
- *
15
11
  * `crashed.windowId` is OPTIONAL: a crash before a window exists (a session-open
16
12
  * failure, a pre-mount source-resolution failure) has no id to report — the type
17
13
  * says so rather than carrying a placeholder `''`.
18
14
  */
19
15
  export type WindowState =
20
16
  | { readonly phase: 'mounting' }
21
- | { readonly phase: 'ready'; readonly windowId: string; readonly downgraded?: boolean }
17
+ | { readonly phase: 'ready'; readonly windowId: string }
22
18
  | { readonly phase: 'crashed'; readonly windowId?: string; readonly error?: unknown }
23
19
  | { readonly phase: 'closed'; readonly windowId: string; readonly refusal?: string }
@@ -1,7 +0,0 @@
1
- import type { RoleNode } from '@astrale-os/shell';
2
- import type { ReadState } from '../graph/memory/read/envelope.js';
3
- export interface RolesResult extends ReadState {
4
- readonly roles: readonly RoleNode[];
5
- }
6
- export declare function useRoles(): RolesResult;
7
- //# sourceMappingURL=roles.hook.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"roles.hook.d.ts","sourceRoot":"","sources":["../../src/application/roles.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAQjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAQjE,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;CACpC;AAED,wBAAgB,QAAQ,IAAI,WAAW,CAoBtC"}
@@ -1,23 +0,0 @@
1
- /**
2
- * useRoles (API §12.2) — the roles self holds (`has_role` out-edges), over the
3
- * async OS namespace (one-shot today, §12 flag).
4
- */
5
- import { useMemo } from 'react';
6
- import { useAsyncResource } from '../graph/async.js';
7
- import { useShell } from '../session/shell.hook.js';
8
- import { isOsPlaneAvailable } from './user/user.store.js';
9
- const NO_ROLES = [];
10
- export function useRoles() {
11
- const shell = useShell();
12
- // OS plane unavailable (§12.2) → idle: no roles read.
13
- const available = isOsPlaneAvailable(shell);
14
- const res = useAsyncResource(available ? () => shell.user.roles() : null, NO_ROLES, [shell, available]);
15
- return useMemo(() => ({
16
- roles: res.data,
17
- pending: res.pending,
18
- error: res.error,
19
- live: false,
20
- seq: 0,
21
- refetch: res.refetch,
22
- }), [res]);
23
- }
@@ -1,21 +0,0 @@
1
- import type { GraphMemory, MemoryEvent } from '@astrale-os/kernel-client/store';
2
- /**
3
- * The base memory (API §5.4). One `GraphMemory` per live Shell — the partial
4
- * client copy of the graph every graph/schema/nav hook reads through, so they all
5
- * share one cache, one dedupe, one optimistic overlay. Derived from `shell.kernel`
6
- * and memoized on the Shell object. Its `onError` fans out through a per-Shell
7
- * sink the provider registers, so warm-refresh failures and rolled-back mutations
8
- * reach the provider's `onError` channel (§2).
9
- */
10
- import type { Shell } from '@astrale-os/shell';
11
- /** Register (or clear) the provider's memory-event bridge for a Shell. */
12
- export declare function setMemoryErrorSink(shell: Shell, sink: ((event: MemoryEvent) => void) | null): void;
13
- /**
14
- * The base (default-scope) memory for a Shell — the SAME instance every graph/
15
- * schema/nav hook reads through `useMemory`, so the provider can seat it in
16
- * `GraphContext` (selection's liveness source) without minting a rival copy.
17
- * Its `onError` fans out through the per-Shell sink so warm-refresh failures and
18
- * rolled-back mutations reach `ShellProvider`'s `onError` channel (§2).
19
- */
20
- export declare function baseMemoryFor(shell: Shell): GraphMemory;
21
- //# sourceMappingURL=base.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/graph/memory/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAC/E;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAc9C,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAC1C,IAAI,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CASvD"}
@@ -1,33 +0,0 @@
1
- import { createMemory } from '@astrale-os/kernel-client/store';
2
- /** One memory per Shell reference — shared by every hook under that provider. */
3
- const memoryByShell = new WeakMap();
4
- /**
5
- * Per-Shell error sink (API §2/§8). The provider registers a bridge here; the
6
- * memory emits refresh/mutation/divergence events through it, read lazily at
7
- * emit time so registration order doesn't matter. Cleared on provider unmount.
8
- */
9
- const errorSinks = new WeakMap();
10
- /** Register (or clear) the provider's memory-event bridge for a Shell. */
11
- export function setMemoryErrorSink(shell, sink) {
12
- if (sink === null)
13
- errorSinks.delete(shell);
14
- else
15
- errorSinks.set(shell, sink);
16
- }
17
- /**
18
- * The base (default-scope) memory for a Shell — the SAME instance every graph/
19
- * schema/nav hook reads through `useMemory`, so the provider can seat it in
20
- * `GraphContext` (selection's liveness source) without minting a rival copy.
21
- * Its `onError` fans out through the per-Shell sink so warm-refresh failures and
22
- * rolled-back mutations reach `ShellProvider`'s `onError` channel (§2).
23
- */
24
- export function baseMemoryFor(shell) {
25
- let memory = memoryByShell.get(shell);
26
- if (memory === undefined) {
27
- memory = createMemory(shell.kernel, {
28
- onError: (event) => errorSinks.get(shell)?.(event),
29
- });
30
- memoryByShell.set(shell, memory);
31
- }
32
- return memory;
33
- }
@@ -1,9 +0,0 @@
1
- import type { ShapeInput } from '@astrale-os/kernel-client/store';
2
- import type { CoreReadOptions, RawRead } from './envelope.js';
3
- /**
4
- * Subscribe to a memory shape and project it. `null`/`undefined` shape → idle.
5
- * Cold + `suspend` (default) throws the cold-shape promise; `suspend:false`
6
- * returns empty-pending; `keepPrevious` returns the last data while confirming.
7
- */
8
- export declare function useRead(shape: ShapeInput | null | undefined, opts?: CoreReadOptions): RawRead;
9
- //# sourceMappingURL=read.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../../src/graph/memory/read/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,UAAU,EACX,MAAM,iCAAiC,CAAA;AAYxC,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAiC7D;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAgD7F"}