@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,119 @@
1
+ import { rawOf } from '@astrale-os/kernel-client/graph';
2
+ /**
3
+ * useCan (API §4) — deduped standing-grant permission checks. `auth.check`-backed:
4
+ * `undefined` while the first check is in flight (or `on` is idle), then a boolean.
5
+ * Deduped per (principal, perms, nodeId) across the whole tree via the principal's
6
+ * check ledger (folded in here as the dedup substrate). Standing-grant semantics:
7
+ * the dispatched call remains the gatekeeper — this is a UI affordance, not the
8
+ * enforcement point (SPEC §6.2). A local grant/revoke invalidates the ledger.
9
+ */
10
+ import { useCallback, useMemo, useSyncExternalStore } from 'react';
11
+ import { isIdleInput } from '../graph/memory/read/idle';
12
+ import { useIdentityBinding } from './act-as.context';
13
+ const NOOP_UNSUB = () => undefined;
14
+ /** A node value carries the id/class/path triple (mirrors the memory's `isNodeValue`). */
15
+ export function isNodeValue(x) {
16
+ return typeof x === 'object' && x !== null && 'id' in x && 'class' in x && 'path' in x;
17
+ }
18
+ /** Normalize a `useCan` subject to a dispatchable `Ref` plus a stable dedup key. */
19
+ export function toRef(on) {
20
+ if (isNodeValue(on))
21
+ return { ref: on.path, key: `@${on.id}` };
22
+ return { ref: on, key: rawOf(on) };
23
+ }
24
+ // ── check ledger (the dedup substrate) ───────────────────────────────────────
25
+ /** One deduped check — its last-known value plus the subscribers watching it. */
26
+ class CheckCell {
27
+ auth;
28
+ perms;
29
+ on;
30
+ value = undefined;
31
+ inFlight = false;
32
+ listeners = new Set();
33
+ constructor(auth, perms, on) {
34
+ this.auth = auth;
35
+ this.perms = perms;
36
+ this.on = on;
37
+ }
38
+ subscribe = (onChange) => {
39
+ this.listeners.add(onChange);
40
+ this.ensure();
41
+ return () => this.listeners.delete(onChange);
42
+ };
43
+ getSnapshot = () => this.value;
44
+ /** Run the check once when the value is unknown and nothing is in flight. */
45
+ ensure() {
46
+ if (this.value !== undefined || this.inFlight)
47
+ return;
48
+ this.run();
49
+ }
50
+ /** Force a re-check (local grant/revoke on this principal). */
51
+ invalidate() {
52
+ if (this.listeners.size === 0) {
53
+ this.value = undefined; // recompute lazily on the next subscribe
54
+ return;
55
+ }
56
+ this.run();
57
+ }
58
+ run() {
59
+ this.inFlight = true;
60
+ void this.auth
61
+ .check({ on: this.on, perms: this.perms })
62
+ .then((ok) => {
63
+ this.value = ok;
64
+ }, () => {
65
+ // A failed check leaves the value unknown (undefined) — never a false grant.
66
+ this.value = undefined;
67
+ })
68
+ .finally(() => {
69
+ this.inFlight = false;
70
+ for (const l of this.listeners)
71
+ l();
72
+ });
73
+ }
74
+ }
75
+ /** Per-principal cell registry — dedup across the whole tree for one kernel handle. */
76
+ export class CheckLedger {
77
+ auth;
78
+ cells = new Map();
79
+ constructor(auth) {
80
+ this.auth = auth;
81
+ }
82
+ cell(key, perms, on) {
83
+ let cell = this.cells.get(key);
84
+ if (cell === undefined) {
85
+ cell = new CheckCell(this.auth, perms, on);
86
+ this.cells.set(key, cell);
87
+ }
88
+ return cell;
89
+ }
90
+ /** Re-check every observed cell — conservative Tier-0 sweep after a local grant/revoke. */
91
+ invalidateAll() {
92
+ for (const cell of this.cells.values())
93
+ cell.invalidate();
94
+ }
95
+ }
96
+ // One ledger per bound kernel object → per principal. `session.as(cred)` mints a
97
+ // fresh view per ActAs, so acted-as principals never share a ledger with the root.
98
+ const ledgers = new WeakMap();
99
+ export function ledgerFor(kernel) {
100
+ let ledger = ledgers.get(kernel);
101
+ if (ledger === undefined) {
102
+ ledger = new CheckLedger(kernel.auth);
103
+ ledgers.set(kernel, ledger);
104
+ }
105
+ return ledger;
106
+ }
107
+ // ── useCan ────────────────────────────────────────────────────────────────────
108
+ export function useCan(perms, on) {
109
+ const binding = useIdentityBinding();
110
+ const ref = isIdleInput(on) ? null : toRef(on);
111
+ // The shared cell for (principal, perms, nodeId): identical to every other
112
+ // useCan reading the same triple, so one check serves the whole tree.
113
+ const cell = useMemo(() => ref === null ? null : ledgerFor(binding.kernel).cell(`${perms}\0${ref.key}`, perms, ref.ref),
114
+ // ref is rebuilt per render; its `key` string is the stable identity.
115
+ [binding.kernel, perms, ref?.key]);
116
+ const subscribe = useCallback((onChange) => (cell === null ? NOOP_UNSUB : cell.subscribe(onChange)), [cell]);
117
+ const getSnapshot = useCallback(() => cell?.getSnapshot(), [cell]);
118
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
119
+ }
@@ -0,0 +1,6 @@
1
+ export { ActAs } from './act-as.context';
2
+ export type { ActAsProps } from './act-as.context';
3
+ export { useAuth } from './auth.hook';
4
+ export { useCan } from './can.hook';
5
+ export { useSelf } from './self.hook';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAA;AACxC,YAAY,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ // auth — API §4 (useSelf, useCan, useAuth, ActAs). See SHELL_REACT_API.md.
2
+ export { ActAs } from './act-as.context';
3
+ export { useAuth } from './auth.hook';
4
+ export { useCan } from './can.hook';
5
+ export { useSelf } from './self.hook';
@@ -0,0 +1,3 @@
1
+ import type { NodeValue } from './act-as.context';
2
+ export declare function useSelf(): NodeValue;
3
+ //# sourceMappingURL=self.hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self.hook.d.ts","sourceRoot":"","sources":["../../src/auth/self.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAWjD,wBAAgB,OAAO,IAAI,SAAS,CAEnC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * useSelf (API §4) — the caller's identity node, resolved at boot and read
3
+ * synchronously (never suspends). An <ActAs> subtree returns the acted-as
4
+ * identity. FLAG: today this is the boot-resolved whoami snapshot; it becomes a
5
+ * live memory shape once the graph plane subscribes the self node — no signature
6
+ * change.
7
+ */
8
+ import { useIdentityBinding } from './act-as.context';
9
+ export function useSelf() {
10
+ return useIdentityBinding().self;
11
+ }
@@ -0,0 +1,4 @@
1
+ import type { SessionView } from './act-as.context';
2
+ /** The EFFECTIVE dispatch kernel for this subtree. Throws outside a provider. */
3
+ export declare function useSessionKernel(): SessionView;
4
+ //# sourceMappingURL=session-kernel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-kernel.d.ts","sourceRoot":"","sources":["../../src/auth/session-kernel.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKnD,iFAAiF;AACjF,wBAAgB,gBAAgB,IAAI,WAAW,CAQ9C"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * useSessionKernel (API §4) — the dispatch-floor resolver. Inside an `<ActAs>` it
3
+ * is the acted-as principal's bound session view; otherwise the root
4
+ * `shell.kernel`. Every dispatch floor (schema bindings, useCall/useStream, useMove,
5
+ * typed method dispatch) routes through this so a call runs as the subtree's
6
+ * principal — not the root — and its scoped memory.
7
+ */
8
+ import { useContext } from 'react';
9
+ import { ShellContext } from '../session/session.context';
10
+ import { IdentityContext } from './act-as.context';
11
+ /** The EFFECTIVE dispatch kernel for this subtree. Throws outside a provider. */
12
+ export function useSessionKernel() {
13
+ const binding = useContext(IdentityContext);
14
+ const runtime = useContext(ShellContext);
15
+ if (binding !== null)
16
+ return binding.kernel;
17
+ if (runtime === null) {
18
+ throw new Error('session hooks must be used within a <ShellProvider>');
19
+ }
20
+ return runtime.shell.kernel;
21
+ }
@@ -0,0 +1,22 @@
1
+ /** The stateful callable every write/dispatch hook returns. */
2
+ export interface Action<A extends unknown[], R> {
3
+ /** Invoke; rejects on failure AND records it on `.error`. */
4
+ (...args: A): Promise<R>;
5
+ /** ≥1 invocation in flight (the OR across concurrent calls). */
6
+ readonly pending: boolean;
7
+ /** Last rejection; cleared when the next invocation starts. */
8
+ readonly error: unknown;
9
+ /** Last successful resolution. */
10
+ readonly result: R | undefined;
11
+ /** Clears error/result. */
12
+ reset(): void;
13
+ }
14
+ /**
15
+ * Wrap an async function in the Action envelope. Concurrent invocations are
16
+ * allowed — each returns its own promise; `pending` is the OR of the in-flight
17
+ * count and `result`/`error` reflect the latest settlement. The callable keeps
18
+ * ONE identity for the hook's lifetime (safe in deps arrays); its snapshot
19
+ * fields are re-stamped each render, so reads stay current across settlements.
20
+ */
21
+ export declare function useAction<A extends unknown[], R>(fn: (...args: A) => Promise<R>): Action<A, R>;
22
+ //# sourceMappingURL=action.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action.d.ts","sourceRoot":"","sources":["../../src/graph/action.ts"],"names":[],"mappings":"AASA,+DAA+D;AAC/D,MAAM,WAAW,MAAM,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC;IAC5C,6DAA6D;IAC7D,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;IACxB,gEAAgE;IAChE,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,+DAA+D;IAC/D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,CAAC,GAAG,SAAS,CAAA;IAC9B,2BAA2B;IAC3B,KAAK,IAAI,IAAI,CAAA;CACd;AA4CD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAsD9F"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * The Action envelope (API §1.2) — a graph-plane primitive, not a context (rule
3
+ * 5). Holds the `Action<A,R>` type (public — it appears in every write/dispatch
4
+ * hook signature) and the `useAction` stateful-callable factory (internal): a
5
+ * render-stable callable whose pending/error/result snapshot is re-stamped each
6
+ * render, safe in deps arrays.
7
+ */
8
+ import { useCallback, useEffect, useReducer, useRef } from 'react';
9
+ const IDLE_SNAPSHOT = {
10
+ pending: false,
11
+ error: undefined,
12
+ result: undefined,
13
+ };
14
+ function actionReducer(state, event) {
15
+ switch (event.type) {
16
+ case 'start':
17
+ // §1.2: a new invocation clears the error and keeps the last result.
18
+ return { pending: true, error: undefined, result: state.result };
19
+ case 'resolve':
20
+ // Latest settlement wins: a success records the result and clears error.
21
+ return { pending: event.inFlight > 0, error: undefined, result: event.value };
22
+ case 'reject':
23
+ return { pending: event.inFlight > 0, error: event.error, result: state.result };
24
+ case 'reset':
25
+ return { pending: state.pending, error: undefined, result: undefined };
26
+ }
27
+ }
28
+ /**
29
+ * Wrap an async function in the Action envelope. Concurrent invocations are
30
+ * allowed — each returns its own promise; `pending` is the OR of the in-flight
31
+ * count and `result`/`error` reflect the latest settlement. The callable keeps
32
+ * ONE identity for the hook's lifetime (safe in deps arrays); its snapshot
33
+ * fields are re-stamped each render, so reads stay current across settlements.
34
+ */
35
+ export function useAction(fn) {
36
+ // Latest-closure ref so the stable callable always dispatches the current fn.
37
+ const fnRef = useRef(fn);
38
+ fnRef.current = fn;
39
+ const [snapshot, dispatch] = useReducer(actionReducer, IDLE_SNAPSHOT);
40
+ const inFlight = useRef(0);
41
+ const alive = useRef(true);
42
+ useEffect(() => {
43
+ alive.current = true;
44
+ return () => {
45
+ alive.current = false;
46
+ };
47
+ }, []);
48
+ const call = useCallback((...args) => {
49
+ inFlight.current += 1;
50
+ dispatch({ type: 'start' });
51
+ let promise;
52
+ try {
53
+ promise = Promise.resolve(fnRef.current(...args));
54
+ }
55
+ catch (err) {
56
+ promise = Promise.reject(err);
57
+ }
58
+ void promise.then((value) => {
59
+ inFlight.current -= 1;
60
+ if (alive.current)
61
+ dispatch({ type: 'resolve', value, inFlight: inFlight.current });
62
+ }, (err) => {
63
+ inFlight.current -= 1;
64
+ if (alive.current)
65
+ dispatch({ type: 'reject', error: err, inFlight: inFlight.current });
66
+ });
67
+ return promise;
68
+ }, []);
69
+ const reset = useCallback(() => dispatch({ type: 'reset' }), []);
70
+ // One render-stable callable: built once (call/reset are themselves stable),
71
+ // then its snapshot fields re-stamped every render. Re-renders are driven by
72
+ // the reducer, so the stamped pending/error/result stay fresh WITHOUT minting
73
+ // a new function identity — the documented "safe in deps arrays" guarantee.
74
+ const actionRef = useRef(null);
75
+ if (actionRef.current === null) {
76
+ const action = ((...args) => call(...args));
77
+ action.reset = reset;
78
+ actionRef.current = action;
79
+ }
80
+ const action = actionRef.current;
81
+ action.pending = snapshot.pending;
82
+ action.error = snapshot.error;
83
+ action.result = snapshot.result;
84
+ return action;
85
+ }
@@ -0,0 +1,11 @@
1
+ import type { ReadState } from './memory/read/envelope';
2
+ export interface AsyncResource<T> extends ReadState {
3
+ readonly data: T;
4
+ }
5
+ /**
6
+ * Subscribe a component to `load()`. `null` loader → idle. The loader runs on
7
+ * mount and whenever `deps` change (stale responses discarded); last-good data is
8
+ * retained through a pending refetch or a failure (§1.1).
9
+ */
10
+ export declare function useAsyncResource<T>(load: (() => Promise<T>) | null, empty: T, deps: readonly unknown[]): AsyncResource<T>;
11
+ //# sourceMappingURL=async.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async.d.ts","sourceRoot":"","sources":["../../src/graph/async.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAA;AAEvD,MAAM,WAAW,aAAa,CAAC,CAAC,CAAE,SAAQ,SAAS;IACjD,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;CACjB;AAQD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAChC,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,EAC/B,KAAK,EAAE,CAAC,EACR,IAAI,EAAE,SAAS,OAAO,EAAE,GACvB,aAAa,CAAC,CAAC,CAAC,CAyDlB"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * useAsyncResource (API §1.1) — a one-shot async read projected into the §1 read
3
+ * envelope (`ReadState`): the non-memory sibling of `useRead`, stale-guarded and
4
+ * `refetch`-able, with a `null` loader as idle. Shared by `application/` and the
5
+ * window `useViewsFor` dispatch; homed here (below both) to keep rule 9 acyclic.
6
+ */
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+ /**
9
+ * Subscribe a component to `load()`. `null` loader → idle. The loader runs on
10
+ * mount and whenever `deps` change (stale responses discarded); last-good data is
11
+ * retained through a pending refetch or a failure (§1.1).
12
+ */
13
+ export function useAsyncResource(load, empty, deps) {
14
+ const [state, setState] = useState({
15
+ data: empty,
16
+ pending: load !== null,
17
+ error: undefined,
18
+ });
19
+ const loadRef = useRef(load);
20
+ loadRef.current = load;
21
+ const emptyRef = useRef(empty);
22
+ emptyRef.current = empty;
23
+ const seq = useRef(0);
24
+ const alive = useRef(true);
25
+ useEffect(() => {
26
+ alive.current = true;
27
+ return () => {
28
+ alive.current = false;
29
+ };
30
+ }, []);
31
+ const refetch = useCallback(() => {
32
+ const run = loadRef.current;
33
+ if (run === null) {
34
+ setState({ data: emptyRef.current, pending: false, error: undefined });
35
+ return Promise.resolve();
36
+ }
37
+ const my = ++seq.current;
38
+ setState((s) => ({ data: s.data, pending: true, error: undefined }));
39
+ return run().then((data) => {
40
+ if (alive.current && my === seq.current)
41
+ setState({ data, pending: false, error: undefined });
42
+ }, (error) => {
43
+ if (alive.current && my === seq.current) {
44
+ setState((s) => ({ data: s.data, pending: false, error }));
45
+ }
46
+ });
47
+ }, []);
48
+ useEffect(() => {
49
+ void refetch();
50
+ // eslint-disable-next-line react-hooks/exhaustive-deps
51
+ }, deps);
52
+ return useMemo(() => ({
53
+ data: state.data,
54
+ pending: state.pending,
55
+ error: state.error,
56
+ live: false,
57
+ seq: 0,
58
+ refetch,
59
+ }), [state.data, state.pending, state.error, refetch]);
60
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * useCall (API §7) — unary domain-function dispatch over `kernel.call`, in the
3
+ * Action envelope. No result caching, no liveness — domain function reads are not
4
+ * structurally invalidatable (FRONTEND §5.7); a consumer that needs freshness
5
+ * owns its own refetch policy. Dispatch is a graph operation (rule 2).
6
+ */
7
+ import type { CallFns, FnMap } from '@astrale-os/kernel-client';
8
+ import type { Action } from '../action';
9
+ export interface CallOptions {
10
+ /** Per-call timeout (ms), forwarded to the kernel dispatch. */
11
+ timeout?: number;
12
+ /** Side-channel notified on rejection (the Action also records `.error`). */
13
+ onError?(error: unknown): void;
14
+ }
15
+ /**
16
+ * Unary domain-function dispatch as an {@link Action}. `method` is a typed FnMap
17
+ * `call` path or any string (the untyped floor); `null` yields an idle action
18
+ * that rejects if invoked. Params/result are typed from the FnMap entry.
19
+ */
20
+ export declare function useCall<K extends CallFns<FnMap>>(method: K | null, opts?: CallOptions): Action<[FnMap[K]['params']], FnMap[K]['result']>;
21
+ //# sourceMappingURL=call.hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"call.hook.d.ts","sourceRoot":"","sources":["../../../src/graph/call/call.hook.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAKvC,MAAM,WAAW,WAAW;IAC1B,+DAA+D;IAC/D,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,6EAA6E;IAC7E,OAAO,CAAC,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAAA;CAC/B;AAED;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,OAAO,CAAC,KAAK,CAAC,EAC9C,MAAM,EAAE,CAAC,GAAG,IAAI,EAChB,IAAI,CAAC,EAAE,WAAW,GACjB,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAalD"}
@@ -0,0 +1,23 @@
1
+ import { useSessionKernel } from '../../auth/session-kernel';
2
+ import { useAction } from '../action';
3
+ /**
4
+ * Unary domain-function dispatch as an {@link Action}. `method` is a typed FnMap
5
+ * `call` path or any string (the untyped floor); `null` yields an idle action
6
+ * that rejects if invoked. Params/result are typed from the FnMap entry.
7
+ */
8
+ export function useCall(method, opts) {
9
+ const kernel = useSessionKernel();
10
+ // A fresh closure per render captures the current method/opts; `useAction`
11
+ // keeps ONE stable callable and always dispatches this latest closure.
12
+ return useAction(async (params) => {
13
+ if (method === null)
14
+ throw new Error('useCall: method is null (idle action invoked)');
15
+ try {
16
+ return await kernel.call(method, params, { timeout: opts?.timeout });
17
+ }
18
+ catch (error) {
19
+ opts?.onError?.(error);
20
+ throw error;
21
+ }
22
+ });
23
+ }
@@ -0,0 +1,28 @@
1
+ import type { FnMap, StreamFns } from '@astrale-os/kernel-client';
2
+ export interface StreamOptions<T> {
3
+ /** Notified per chunk as it arrives (in addition to `chunks` accumulation). */
4
+ onChunk?(chunk: T): void;
5
+ }
6
+ export interface StreamHandle<T> {
7
+ /** Begin a run: resets chunks, then resolves when the stream ends / rejects on failure. */
8
+ start(params: unknown): Promise<void>;
9
+ /** Chunks accumulated in the current run; reset on the next `start`. */
10
+ readonly chunks: readonly T[];
11
+ /** The most recent chunk, or null before the first. */
12
+ readonly last: T | null;
13
+ /** A run is in flight. */
14
+ readonly streaming: boolean;
15
+ /** Last run failure; retained until the next `start`. */
16
+ readonly error: unknown;
17
+ /** Close the stream (returns the iterator); a later `start` begins fresh. */
18
+ cancel(): void;
19
+ }
20
+ /**
21
+ * Streaming domain-function dispatch. `start(params)` opens a run over
22
+ * `kernel.stream`; chunks accumulate on `chunks`; `cancel()` closes the iterator
23
+ * and a later `start` begins fresh. A superseding `start` (or unmount) closes the
24
+ * prior run and discards its late chunks/errors — only the current run drives
25
+ * state. Never live; the handle keeps one identity for the hook's lifetime.
26
+ */
27
+ export declare function useStream<K extends StreamFns<FnMap>>(method: K | null, opts?: StreamOptions<FnMap[K]['result']>): StreamHandle<FnMap[K]['result']>;
28
+ //# sourceMappingURL=stream.hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream.hook.d.ts","sourceRoot":"","sources":["../../../src/graph/call/stream.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAA;AAYjE,MAAM,WAAW,aAAa,CAAC,CAAC;IAC9B,+EAA+E;IAC/E,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAA;CACzB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC;IAC7B,2FAA2F;IAC3F,KAAK,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,CAAA;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACvB,0BAA0B;IAC1B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,6EAA6E;IAC7E,MAAM,IAAI,IAAI,CAAA;CACf;AA2DD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,SAAS,CAAC,KAAK,CAAC,EAClD,MAAM,EAAE,CAAC,GAAG,IAAI,EAChB,IAAI,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GACvC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAoGlC"}
@@ -0,0 +1,137 @@
1
+ /**
2
+ * useStream (API §7) — streaming domain-function dispatch over `kernel.stream`,
3
+ * an AsyncIterable driven by an explicit start/cancel handle. A superseding
4
+ * `start` (or unmount) closes the prior run and discards its late chunks/errors;
5
+ * never live. Dispatch is a graph operation (rule 2).
6
+ */
7
+ import { useCallback, useEffect, useReducer, useRef } from 'react';
8
+ import { useSessionKernel } from '../../auth/session-kernel';
9
+ const IDLE_STREAM = {
10
+ chunks: [],
11
+ last: null,
12
+ streaming: false,
13
+ error: undefined,
14
+ };
15
+ function streamReducer(state, event) {
16
+ switch (event.type) {
17
+ case 'start':
18
+ return { chunks: [], last: null, streaming: true, error: undefined };
19
+ case 'chunk':
20
+ return {
21
+ chunks: [...state.chunks, event.value],
22
+ last: event.value,
23
+ streaming: true,
24
+ error: undefined,
25
+ };
26
+ case 'end':
27
+ return { ...state, streaming: false };
28
+ case 'error':
29
+ // Chunks accumulated before the failure are preserved.
30
+ return { ...state, streaming: false, error: event.error };
31
+ case 'cancel':
32
+ return { ...state, streaming: false };
33
+ }
34
+ }
35
+ /**
36
+ * Streaming domain-function dispatch. `start(params)` opens a run over
37
+ * `kernel.stream`; chunks accumulate on `chunks`; `cancel()` closes the iterator
38
+ * and a later `start` begins fresh. A superseding `start` (or unmount) closes the
39
+ * prior run and discards its late chunks/errors — only the current run drives
40
+ * state. Never live; the handle keeps one identity for the hook's lifetime.
41
+ */
42
+ export function useStream(method, opts) {
43
+ const kernel = useSessionKernel();
44
+ // Latest-closure refs so the stable start/cancel dispatch the current inputs.
45
+ const kernelRef = useRef(kernel);
46
+ kernelRef.current = kernel;
47
+ const methodRef = useRef(method);
48
+ methodRef.current = method;
49
+ const optsRef = useRef(opts);
50
+ optsRef.current = opts;
51
+ const [snapshot, dispatch] = useReducer(streamReducer, IDLE_STREAM);
52
+ // `runId` supersession token; only the run whose id is still current drives state.
53
+ const runIdRef = useRef(0);
54
+ const currentRef = useRef(null);
55
+ const alive = useRef(true);
56
+ const stop = useCallback(() => {
57
+ const run = currentRef.current;
58
+ if (run !== null) {
59
+ run.controller.abort();
60
+ void run.iterator?.return?.(undefined);
61
+ currentRef.current = null;
62
+ }
63
+ }, []);
64
+ useEffect(() => {
65
+ alive.current = true;
66
+ return () => {
67
+ alive.current = false;
68
+ stop();
69
+ };
70
+ }, [stop]);
71
+ const cancel = useCallback(() => {
72
+ runIdRef.current += 1;
73
+ stop();
74
+ if (alive.current)
75
+ dispatch({ type: 'cancel' });
76
+ }, [stop]);
77
+ const start = useCallback((params) => {
78
+ const method_ = methodRef.current;
79
+ if (method_ === null) {
80
+ return Promise.reject(new Error('useStream: method is null (idle handle started)'));
81
+ }
82
+ runIdRef.current += 1;
83
+ const runId = runIdRef.current;
84
+ stop(); // close any prior run before opening the new one
85
+ dispatch({ type: 'start' });
86
+ const controller = new AbortController();
87
+ const run = { controller, iterator: null };
88
+ currentRef.current = run;
89
+ const current = () => runIdRef.current === runId;
90
+ return (async () => {
91
+ try {
92
+ const iterable = await kernelRef.current.stream(method_, params, {
93
+ signal: controller.signal,
94
+ });
95
+ if (!current())
96
+ return;
97
+ const iterator = iterable[Symbol.asyncIterator]();
98
+ run.iterator = iterator;
99
+ for (;;) {
100
+ const next = await iterator.next();
101
+ if (!current())
102
+ return;
103
+ if (next.done === true)
104
+ break;
105
+ if (alive.current)
106
+ dispatch({ type: 'chunk', value: next.value });
107
+ optsRef.current?.onChunk?.(next.value);
108
+ }
109
+ if (current()) {
110
+ currentRef.current = null;
111
+ if (alive.current)
112
+ dispatch({ type: 'end' });
113
+ }
114
+ }
115
+ catch (error) {
116
+ if (!current())
117
+ return; // a superseded/cancelled run's failure is discarded
118
+ currentRef.current = null;
119
+ if (alive.current)
120
+ dispatch({ type: 'error', error });
121
+ throw error;
122
+ }
123
+ })();
124
+ }, [stop]);
125
+ // One render-stable handle: built once (start/cancel are stable), then its
126
+ // snapshot fields re-stamped each render so reads stay current across chunks.
127
+ const handleRef = useRef(null);
128
+ if (handleRef.current === null) {
129
+ handleRef.current = { start, cancel };
130
+ }
131
+ const handle = handleRef.current;
132
+ handle.chunks = snapshot.chunks;
133
+ handle.last = snapshot.last;
134
+ handle.streaming = snapshot.streaming;
135
+ handle.error = snapshot.error;
136
+ return handle;
137
+ }
@@ -0,0 +1,4 @@
1
+ import type { GraphMemory } from '@astrale-os/kernel-client/store';
2
+ export type { GraphMemory };
3
+ export declare const GraphContext: import("react").Context<GraphMemory | null>;
4
+ //# sourceMappingURL=graph.context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph.context.d.ts","sourceRoot":"","sources":["../../src/graph/graph.context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAWlE,YAAY,EAAE,WAAW,EAAE,CAAA;AAC3B,eAAO,MAAM,YAAY,6CAA0C,CAAA"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * GraphContext (ex MemoryContext) — the root of the graph plane. Seats the base
3
+ * (default-scope) memory the provider builds; the SAME handle the graph/schema/
4
+ * nav hooks read through `memory/scope.ts`, and selection's liveness source.
5
+ * Under `<ActAs>` the read hooks re-scope via `forScope`; selection reads the
6
+ * base scope here.
7
+ */
8
+ import { createContext } from 'react';
9
+ export const GraphContext = createContext(null);
10
+ GraphContext.displayName = 'AstraleGraphContext';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Error taxonomy (API §1.4) — re-exported from kernel-client so shell-react
3
+ * consumers narrow dispatch failures through the single import surface. The
4
+ * dispatched kernel call stays the source of truth; these guards drive UI
5
+ * affordances (retry, request-access, toast). Names match kernel-client exactly.
6
+ */
7
+ export { AuthBatchError, AuthenticationError, ClientSessionError, ConnectionError, DisconnectedError, InvalidTransportError, InvariantViolationError, KernelError, NodeUnavailableError, NotFoundError, PermissionDeniedError, TimeoutError, UnsupportedTransportError, ValidationError, WebOSError, classifyKernelError, isAuthBatchError, isAuthenticationError, isClientSessionError, isDelegationMintError, isDelegationPolicyError, isDelegationRefusedError, isHopLimitExceededError, isIdentityError, isInternalKernelError, isInvalidRequestError, isInvalidTransportError, isInvariantViolationError, isKernelError, isNodeUnavailableError, isNotFoundError, isParseError, isPermissionDeniedError, isPersistenceLoadFailedError, isPoolClosedError, isRedirectPolicyError, isRedirectRefusedError, isRegistryWriteFailedError, isSchemaOwnershipConflictError, isTransportError, isUnsupportedTransportError, isValidationError, isWebOSError, } from '@astrale-os/kernel-client';
8
+ export type { AuthReason, ClientErrorDetails, IdentityError, KernelErrorKind, TransportError, } from '@astrale-os/kernel-client';
9
+ //# sourceMappingURL=guards.error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.error.d.ts","sourceRoot":"","sources":["../../src/graph/guards.error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EACrB,uBAAuB,EACvB,WAAW,EACX,oBAAoB,EACpB,aAAa,EACb,qBAAqB,EACrB,YAAY,EACZ,yBAAyB,EACzB,eAAe,EACf,UAAU,EACV,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACxB,uBAAuB,EACvB,eAAe,EACf,qBAAqB,EACrB,qBAAqB,EACrB,uBAAuB,EACvB,yBAAyB,EACzB,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,YAAY,EACZ,uBAAuB,EACvB,4BAA4B,EAC5B,iBAAiB,EACjB,qBAAqB,EACrB,sBAAsB,EACtB,0BAA0B,EAC1B,8BAA8B,EAC9B,gBAAgB,EAChB,2BAA2B,EAC3B,iBAAiB,EACjB,YAAY,GACb,MAAM,2BAA2B,CAAA;AAClC,YAAY,EACV,UAAU,EACV,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,cAAc,GACf,MAAM,2BAA2B,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Error taxonomy (API §1.4) — re-exported from kernel-client so shell-react
3
+ * consumers narrow dispatch failures through the single import surface. The
4
+ * dispatched kernel call stays the source of truth; these guards drive UI
5
+ * affordances (retry, request-access, toast). Names match kernel-client exactly.
6
+ */
7
+ export { AuthBatchError, AuthenticationError, ClientSessionError, ConnectionError, DisconnectedError, InvalidTransportError, InvariantViolationError, KernelError, NodeUnavailableError, NotFoundError, PermissionDeniedError, TimeoutError, UnsupportedTransportError, ValidationError, WebOSError, classifyKernelError, isAuthBatchError, isAuthenticationError, isClientSessionError, isDelegationMintError, isDelegationPolicyError, isDelegationRefusedError, isHopLimitExceededError, isIdentityError, isInternalKernelError, isInvalidRequestError, isInvalidTransportError, isInvariantViolationError, isKernelError, isNodeUnavailableError, isNotFoundError, isParseError, isPermissionDeniedError, isPersistenceLoadFailedError, isPoolClosedError, isRedirectPolicyError, isRedirectRefusedError, isRegistryWriteFailedError, isSchemaOwnershipConflictError, isTransportError, isUnsupportedTransportError, isValidationError, isWebOSError, } from '@astrale-os/kernel-client';