@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,57 +1,44 @@
1
- import type { FnMap, StreamFns } from '@astrale-os/kernel-client'
1
+ import type { Call } from '@astrale-os/kernel-client'
2
+ import type { SessionRequestOptions } from '@astrale-os/kernel-client/session'
3
+ import type { Value } from '@astrale-os/sdk/value'
4
+ import type { KernelClient } from '@astrale-os/shell'
2
5
 
3
- /**
4
- * useStream (API §7) — streaming domain-function dispatch over `kernel.stream`,
5
- * an AsyncIterable driven by an explicit start/cancel handle. A superseding
6
- * `start` (or unmount) closes the prior run and discards its late chunks/errors;
7
- * never live. Dispatch is a graph operation (rule 2).
8
- */
9
6
  import { useCallback, useEffect, useReducer, useRef } from 'react'
10
7
 
11
8
  import { useSessionKernel } from '../../auth/session-kernel.js'
12
9
 
13
- export interface StreamOptions<T> {
14
- /** Notified per chunk as it arrives (in addition to `chunks` accumulation). */
15
- onChunk?(chunk: T): void
10
+ export type KernelStream = Awaited<ReturnType<KernelClient['stream']>>
11
+ export type StreamItem = Value
12
+ export type CallAuthor<A extends unknown[]> = Call | ((...args: A) => Call)
13
+
14
+ export interface StreamOptions<T = StreamItem> extends SessionRequestOptions {
15
+ readonly onChunk?: (chunk: T) => void
16
16
  }
17
17
 
18
- export interface StreamHandle<T> {
19
- /** Begin a run: resets chunks, then resolves when the stream ends / rejects on failure. */
20
- start(params: unknown): Promise<void>
21
- /** Chunks accumulated in the current run; reset on the next `start`. */
18
+ export interface StreamHandle<A extends unknown[] = unknown[], T = StreamItem> {
19
+ start(...args: A): Promise<void>
22
20
  readonly chunks: readonly T[]
23
- /** The most recent chunk, or null before the first. */
24
21
  readonly last: T | null
25
- /** A run is in flight. */
26
22
  readonly streaming: boolean
27
- /** Last run failure; retained until the next `start`. */
28
23
  readonly error: unknown
29
- /** Close the stream (returns the iterator); a later `start` begins fresh. */
30
24
  cancel(): void
31
25
  }
32
26
 
33
- interface StreamSnapshot<T> {
27
+ interface Snapshot<T> {
34
28
  readonly chunks: readonly T[]
35
29
  readonly last: T | null
36
30
  readonly streaming: boolean
37
31
  readonly error: unknown
38
32
  }
39
33
 
40
- const IDLE_STREAM: StreamSnapshot<unknown> = {
41
- chunks: [],
42
- last: null,
43
- streaming: false,
44
- error: undefined,
45
- }
46
-
47
- type StreamEvent<T> =
34
+ type Event<T> =
48
35
  | { readonly type: 'start' }
49
36
  | { readonly type: 'chunk'; readonly value: T }
50
37
  | { readonly type: 'end' }
51
38
  | { readonly type: 'error'; readonly error: unknown }
52
39
  | { readonly type: 'cancel' }
53
40
 
54
- function streamReducer<T>(state: StreamSnapshot<T>, event: StreamEvent<T>): StreamSnapshot<T> {
41
+ function reducer<T>(state: Snapshot<T>, event: Event<T>): Snapshot<T> {
55
42
  switch (event.type) {
56
43
  case 'start':
57
44
  return { chunks: [], last: null, streaming: true, error: undefined }
@@ -63,138 +50,74 @@ function streamReducer<T>(state: StreamSnapshot<T>, event: StreamEvent<T>): Stre
63
50
  error: undefined,
64
51
  }
65
52
  case 'end':
53
+ case 'cancel':
66
54
  return { ...state, streaming: false }
67
55
  case 'error':
68
- // Chunks accumulated before the failure are preserved.
69
56
  return { ...state, streaming: false, error: event.error }
70
- case 'cancel':
71
- return { ...state, streaming: false }
72
57
  }
73
58
  }
74
59
 
75
- /** Same shape, minus `readonly`, so the render step can re-stamp the snapshot. */
76
- interface MutableStreamHandle<T> {
77
- start(params: unknown): Promise<void>
78
- chunks: readonly T[]
79
- last: T | null
80
- streaming: boolean
81
- error: unknown
82
- cancel(): void
83
- }
84
-
85
- interface StreamRun<T> {
86
- readonly controller: AbortController
87
- iterator: AsyncIterator<T> | null
88
- }
89
-
90
- /**
91
- * Streaming domain-function dispatch. `start(params)` opens a run over
92
- * `kernel.stream`; chunks accumulate on `chunks`; `cancel()` closes the iterator
93
- * and a later `start` begins fresh. A superseding `start` (or unmount) closes the
94
- * prior run and discards its late chunks/errors — only the current run drives
95
- * state. Never live; the handle keeps one identity for the hook's lifetime.
96
- */
97
- export function useStream<K extends StreamFns<FnMap>>(
98
- method: K | null,
99
- opts?: StreamOptions<FnMap[K]['result']>,
100
- ): StreamHandle<FnMap[K]['result']> {
101
- type T = FnMap[K]['result']
60
+ export function useStream<A extends unknown[] = []>(
61
+ author: CallAuthor<A> | null,
62
+ options?: StreamOptions,
63
+ ): StreamHandle<A, StreamItem> {
102
64
  const kernel = useSessionKernel()
103
-
104
- // Latest-closure refs so the stable start/cancel dispatch the current inputs.
105
65
  const kernelRef = useRef(kernel)
106
66
  kernelRef.current = kernel
107
- const methodRef = useRef(method)
108
- methodRef.current = method
109
- const optsRef = useRef(opts)
110
- optsRef.current = opts
111
-
112
- const [snapshot, dispatch] = useReducer(streamReducer<T>, IDLE_STREAM as StreamSnapshot<T>)
113
-
114
- // `runId` supersession token; only the run whose id is still current drives state.
115
- const runIdRef = useRef(0)
116
- const currentRef = useRef<StreamRun<T> | null>(null)
117
- const alive = useRef(true)
67
+ const authorRef = useRef(author)
68
+ authorRef.current = author
69
+ const optionsRef = useRef(options)
70
+ optionsRef.current = options
71
+ const [snapshot, dispatch] = useReducer(reducer<StreamItem>, {
72
+ chunks: [],
73
+ last: null,
74
+ streaming: false,
75
+ error: undefined,
76
+ })
77
+ const runId = useRef(0)
78
+ const controller = useRef<AbortController | null>(null)
118
79
 
119
- const stop = useCallback(() => {
120
- const run = currentRef.current
121
- if (run !== null) {
122
- run.controller.abort()
123
- void run.iterator?.return?.(undefined)
124
- currentRef.current = null
125
- }
80
+ const cancel = useCallback(() => {
81
+ runId.current += 1
82
+ controller.current?.abort()
83
+ controller.current = null
84
+ dispatch({ type: 'cancel' })
126
85
  }, [])
127
86
 
128
- useEffect(() => {
129
- alive.current = true
130
- return () => {
131
- alive.current = false
132
- stop()
133
- }
134
- }, [stop])
135
-
136
- const cancel = useCallback(() => {
137
- runIdRef.current += 1
138
- stop()
139
- if (alive.current) dispatch({ type: 'cancel' })
140
- }, [stop])
87
+ useEffect(() => cancel, [cancel])
141
88
 
142
89
  const start = useCallback(
143
- (params: unknown): Promise<void> => {
144
- const method_ = methodRef.current
145
- if (method_ === null) {
146
- return Promise.reject(new Error('useStream: method is null (idle handle started)'))
147
- }
148
- runIdRef.current += 1
149
- const runId = runIdRef.current
150
- stop() // close any prior run before opening the new one
90
+ async (...args: A): Promise<void> => {
91
+ const current = authorRef.current
92
+ if (current === null) throw new Error('useStream: idle handle started')
93
+ cancel()
94
+ const id = ++runId.current
95
+ const abort = new AbortController()
96
+ controller.current = abort
151
97
  dispatch({ type: 'start' })
152
-
153
- const controller = new AbortController()
154
- const run: StreamRun<T> = { controller, iterator: null }
155
- currentRef.current = run
156
- const current = (): boolean => runIdRef.current === runId
157
-
158
- return (async () => {
159
- try {
160
- const iterable = await kernelRef.current.stream(method_, params, {
161
- signal: controller.signal,
162
- })
163
- if (!current()) return
164
- const iterator = iterable[Symbol.asyncIterator]()
165
- run.iterator = iterator
166
- for (;;) {
167
- const next = await iterator.next()
168
- if (!current()) return
169
- if (next.done === true) break
170
- if (alive.current) dispatch({ type: 'chunk', value: next.value })
171
- optsRef.current?.onChunk?.(next.value)
172
- }
173
- if (current()) {
174
- currentRef.current = null
175
- if (alive.current) dispatch({ type: 'end' })
176
- }
177
- } catch (error) {
178
- if (!current()) return // a superseded/cancelled run's failure is discarded
179
- currentRef.current = null
180
- if (alive.current) dispatch({ type: 'error', error })
181
- throw error
98
+ const call = typeof current === 'function' ? current(...args) : current
99
+ try {
100
+ const { onChunk: _onChunk, ...requestOptions } = optionsRef.current ?? {}
101
+ const stream = await kernelRef.current.stream(call, {
102
+ ...requestOptions,
103
+ signal: abort.signal,
104
+ })
105
+ for await (const chunk of stream) {
106
+ if (id !== runId.current) return
107
+ dispatch({ type: 'chunk', value: chunk })
108
+ optionsRef.current?.onChunk?.(chunk)
182
109
  }
183
- })()
110
+ if (id === runId.current) dispatch({ type: 'end' })
111
+ } catch (error) {
112
+ if (id !== runId.current) return
113
+ dispatch({ type: 'error', error })
114
+ throw error
115
+ } finally {
116
+ if (id === runId.current) controller.current = null
117
+ }
184
118
  },
185
- [stop],
119
+ [cancel],
186
120
  )
187
121
 
188
- // One render-stable handle: built once (start/cancel are stable), then its
189
- // snapshot fields re-stamped each render so reads stay current across chunks.
190
- const handleRef = useRef<MutableStreamHandle<T> | null>(null)
191
- if (handleRef.current === null) {
192
- handleRef.current = { start, cancel } as MutableStreamHandle<T>
193
- }
194
- const handle = handleRef.current
195
- handle.chunks = snapshot.chunks
196
- handle.last = snapshot.last
197
- handle.streaming = snapshot.streaming
198
- handle.error = snapshot.error
199
- return handle as StreamHandle<T>
122
+ return { start, cancel, ...snapshot }
200
123
  }
@@ -1,14 +1,9 @@
1
- import type { GraphMemory } from '@astrale-os/kernel-client/store'
1
+ import type { GraphStore } from '@astrale-os/kernel-client/store'
2
2
 
3
- /**
4
- * GraphContext (ex MemoryContext) — the root of the graph plane. Seats the base
5
- * (default-scope) memory the provider builds; the SAME handle the graph/schema/
6
- * nav hooks read through `memory/scope.ts`, and selection's liveness source.
7
- * Under `<ActAs>` the read hooks re-scope via `forScope`; selection reads the
8
- * base scope here.
9
- */
10
3
  import { createContext } from 'react'
11
4
 
12
- export type { GraphMemory }
13
- export const GraphContext = createContext<GraphMemory | null>(null)
14
- GraphContext.displayName = 'AstraleGraphContext'
5
+ /** Optional exact Client GraphStore supplied by an injected Shell adapter. */
6
+ export const GraphContext = createContext<GraphStore | null>(null)
7
+ GraphContext.displayName = 'AstraleGraphStoreContext'
8
+
9
+ export type { GraphStore }
@@ -1,58 +1,20 @@
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
1
  export {
8
- AuthBatchError,
9
- AuthenticationError,
10
- ClientSessionError,
11
- ConnectionError,
12
- DisconnectedError,
13
- InvalidTransportError,
14
- InvariantViolationError,
15
- KernelError,
16
- NodeUnavailableError,
17
- NotFoundError,
18
- PermissionDeniedError,
19
- TimeoutError,
20
- UnsupportedTransportError,
21
- ValidationError,
22
- WebOSError,
23
- classifyKernelError,
24
- isAuthBatchError,
25
- isAuthenticationError,
26
- isClientSessionError,
27
- isDelegationMintError,
28
- isDelegationPolicyError,
29
- isDelegationRefusedError,
30
- isHopLimitExceededError,
31
- isIdentityError,
32
- isInternalKernelError,
33
- isInvalidRequestError,
34
- isInvalidTransportError,
35
- isInvariantViolationError,
36
- isKernelError,
37
- isNodeUnavailableError,
38
- isNotFoundError,
39
- isParseError,
40
- isPermissionDeniedError,
41
- isPersistenceLoadFailedError,
42
- isPoolClosedError,
43
- isRedirectPolicyError,
44
- isRedirectRefusedError,
45
- isRegistryWriteFailedError,
46
- isSchemaOwnershipConflictError,
47
- isTransportError,
48
- isUnsupportedTransportError,
49
- isValidationError,
50
- isWebOSError,
51
- } from '@astrale-os/kernel-client'
52
- export type {
53
- AuthReason,
54
- ClientErrorDetails,
55
- IdentityError,
56
- KernelErrorKind,
2
+ ClientError,
3
+ ProtocolError,
4
+ ResponseError,
5
+ StaleRouteError,
57
6
  TransportError,
58
7
  } from '@astrale-os/kernel-client'
8
+ export { NodeUnavailableError } from '@astrale-os/kernel-client/graph'
9
+ export { UnsupportedFeatureError } from './memory/read/envelope.js'
10
+
11
+ import { ClientError } from '@astrale-os/kernel-client'
12
+ import { NodeUnavailableError } from '@astrale-os/kernel-client/graph'
13
+
14
+ export function isClientError(error: unknown): error is ClientError {
15
+ return error instanceof ClientError
16
+ }
17
+
18
+ export function isNodeUnavailableError(error: unknown): error is NodeUnavailableError {
19
+ return error instanceof NodeUnavailableError
20
+ }
@@ -1,20 +1,26 @@
1
- // graph — the graph plane (API §5 + §7). Merged read hooks, writes, dispatch.
2
- export { useNode } from './query/node.hook.js'
3
- export type { NodeResult } from './query/node.hook.js'
4
- export { useChildren } from './query/children.hook.js'
5
- export type { ChildrenOptions, ChildrenResult } from './query/children.hook.js'
6
- export { useQuery } from './query/query.hook.js'
7
- export type { QueryResult } from './query/query.hook.js'
8
- export { useGraph } from './query/graph.hook.js'
9
- export { useMutate } from './mutate/mutate.hook.js'
10
- export type { UseMutateOptions } from './mutate/mutate.hook.js'
11
- export { useMove } from './mutate/move.hook.js'
12
- export type { MoveAction } from './mutate/move.hook.js'
1
+ export { useGraphStore } from './store.js'
2
+ export { useQuery } from './query-definition.hook.js'
3
+ export type { QueryResourceOptions } from './query-definition.hook.js'
4
+ export type { GraphResource, GraphResourceState } from './resource.js'
13
5
  export { useCall } from './call/call.hook.js'
14
- export type { CallOptions } from './call/call.hook.js'
6
+ export type { CallOptions, CallResult } from './call/call.hook.js'
15
7
  export { useStream } from './call/stream.hook.js'
16
- export type { StreamHandle, StreamOptions } from './call/stream.hook.js'
8
+ export type {
9
+ CallAuthor,
10
+ KernelStream,
11
+ StreamHandle,
12
+ StreamItem,
13
+ StreamOptions,
14
+ } from './call/stream.hook.js'
17
15
  export type { Action } from './action.js'
18
- export type { ReadState, ReadOptions, Windowed, Node } from './memory/read/envelope.js'
19
- export type { GraphMemory } from './graph.context.js'
20
- export type { ShapeInput } from '@astrale-os/kernel-client/store'
16
+ export type { GraphStore } from './graph.context.js'
17
+ export {
18
+ ClientError,
19
+ NodeUnavailableError,
20
+ ProtocolError,
21
+ ResponseError,
22
+ StaleRouteError,
23
+ TransportError,
24
+ isClientError,
25
+ isNodeUnavailableError,
26
+ } from './guards.error.js'
@@ -1,98 +1,73 @@
1
- /**
2
- * The read envelope (API §1.1, §1.5) — the shape every read hook's result
3
- * extends (`ReadState` + `Windowed`), the `ReadOptions` accepted by every read,
4
- * and the assembly of the unified `RawRead` projection over a memory shape
5
- * (empty/idle/keep-previous builders). Dependency-light so every context can
6
- * consume it without a cycle.
7
- */
8
- import type { LiveResult } from '@astrale-os/kernel-client/store'
1
+ import type { Node as KernelNode } from '@astrale-os/sdk/graph/node'
9
2
 
10
- // ── Read envelope (§1.1) ─────────────────────────────────────────────────────
11
-
12
- /** Base of every read hook's result — stale-while-revalidate + liveness + seq. */
3
+ /** Common result state for Shell React reads. */
13
4
  export interface ReadState {
14
- /** A (re)validation is in flight; data shown alongside is last-good. */
5
+ /** A request is in flight. Last-good data may still be present. */
15
6
  readonly pending: boolean
16
- /** Last refresh failure; last-good data is retained. Cleared on next success. */
7
+ /** Last request failure. Cleared when the next request begins. */
17
8
  readonly error: unknown
18
- /** A watch subscription is active for this shape (Tier ≥ 1), or Tier-0 only. */
9
+ /** True only when an upstream subscription is active. */
19
10
  readonly live: boolean
20
- /** Journal position this result reflects (FRONTEND spec §6.1). 0 until known. */
11
+ /** Reserved journal position. Direct Graph reads report zero. */
21
12
  readonly seq: number
22
- /** Manual revalidate. Rarely needed; kept for tooling and non-live reads. */
23
13
  refetch(): Promise<void>
24
14
  }
25
15
 
26
- /** Windowed reads add a cursor-fold `more`. */
27
16
  export interface Windowed {
28
17
  readonly more: {
29
18
  readonly has: boolean
30
- load(): Promise<void>
31
19
  readonly pending: boolean
20
+ load(): Promise<void>
32
21
  }
33
22
  }
34
23
 
35
- /** Options accepted by every read hook (§1.5). */
24
+ /** Options shared by point, Query, and neighbor reads. */
36
25
  export interface ReadOptions {
37
- /** default true; false = one-shot snapshot. */
38
- live?: boolean
39
- /** default true; false → pending-without-data on cold. */
40
- suspend?: boolean
41
- /** default false; show previous shape's data while a new one confirms. */
42
- keepPrevious?: boolean
43
- /** Visibility permission on the underlying AST — a kernel permission bitmask. */
44
- with?: number
26
+ readonly signal?: AbortSignal
27
+ readonly timeoutMs?: number
28
+ /** Retain the previous successful value while the next request is pending. */
29
+ readonly keepPrevious?: boolean
45
30
  }
46
31
 
47
- /** A graph node — derived from the memory result so no direct kernel-core import is needed. */
48
- export type Node = NonNullable<LiveResult['node']>
32
+ export type Node = KernelNode
49
33
 
50
- /** Read options plus the windowing lever `useChildren`/`useQuery` add. */
51
- export type CoreReadOptions = ReadOptions & { window?: 'append' | 'paged' }
34
+ export const EMPTY_NODES: readonly Node[] = Object.freeze([])
52
35
 
53
- /**
54
- * The unified read projection: every data arm the memory materializes, over
55
- * the shell-react read envelope (`ReadState` + `Windowed`). Each hook narrows
56
- * to the arms it exposes. The store's `LiveResult` is a structural superset, so
57
- * the warm path returns it directly (stable ref).
58
- */
59
- export interface RawRead extends ReadState, Windowed {
60
- readonly nodes: readonly Node[]
61
- readonly roots: readonly Node[]
62
- readonly first: Node | null
63
- readonly children: readonly Node[]
64
- gathered(alias: string): { readonly nodes: readonly Node[]; readonly first: Node | null }
65
- }
36
+ export const NO_MORE: Windowed['more'] = Object.freeze({
37
+ has: false,
38
+ pending: false,
39
+ load: () => Promise.resolve(),
40
+ })
66
41
 
67
- export const EMPTY: readonly Node[] = []
42
+ /** Stable failure for a retained hook whose required Kernel capability does not exist. */
43
+ export class UnsupportedFeatureError extends Error {
44
+ readonly code = 'SHELL_REACT_UNSUPPORTED' as const
45
+ readonly feature: string
68
46
 
69
- const idleGathered = (): { readonly nodes: readonly Node[]; readonly first: Node | null } => ({
70
- nodes: EMPTY,
71
- first: null,
72
- })
73
- const idleMore: Windowed['more'] = { has: false, pending: false, load: () => Promise.resolve() }
47
+ constructor(feature: string) {
48
+ super(`${feature} is not supported by the current Kernel Graph contract.`)
49
+ this.name = 'UnsupportedFeatureError'
50
+ this.feature = feature
51
+ }
52
+ }
74
53
 
75
- export function emptyRead(pending: boolean): RawRead {
54
+ export function idleReadState(): ReadState {
76
55
  return {
77
- nodes: EMPTY,
78
- roots: EMPTY,
79
- first: null,
80
- children: EMPTY,
81
- gathered: idleGathered,
82
- pending,
56
+ pending: false,
83
57
  error: undefined,
84
58
  live: false,
85
59
  seq: 0,
86
- more: idleMore,
87
60
  refetch: () => Promise.resolve(),
88
61
  }
89
62
  }
90
- /** The result for a null/undefined subject (§1.3) — settled, empty, no I/O. */
91
- export const IDLE_READ = emptyRead(false)
92
- /** Cold shape with `suspend:false` (§1.4) — empty data, pending true. */
93
- export const EMPTY_PENDING = emptyRead(true)
94
63
 
95
- /** Previous shape's data while a new one confirms (§1.5 `keepPrevious`). */
96
- export function withPending(prev: LiveResult): RawRead {
97
- return { ...prev, pending: true }
64
+ export function unsupportedReadState(feature: string): ReadState {
65
+ const error = new UnsupportedFeatureError(feature)
66
+ return {
67
+ pending: false,
68
+ error,
69
+ live: false,
70
+ seq: 0,
71
+ refetch: () => Promise.reject(error),
72
+ }
98
73
  }
@@ -1,24 +1,11 @@
1
- /**
2
- * The idle-input rule (API §1.3). A read hook's `null | undefined` subject is
3
- * inert: `isIdleInput` is the one gate every read branches on, and
4
- * `idleReadState` is the settled, not-live, seq-0 envelope it returns.
5
- */
6
1
  import type { ReadState } from './envelope.js'
7
2
 
8
- /**
9
- * The chaining rule: every read hook accepts `null | undefined` for its subject
10
- * and returns an *idle* result (empty data, no I/O). This predicate is the one
11
- * gate — read hooks branch on it before touching the memory.
12
- */
13
- export function isIdleInput(subject: unknown): subject is null | undefined {
14
- return subject === null || subject === undefined
3
+ import { idleReadState as idle } from './envelope.js'
4
+
5
+ export function isIdleInput(value: unknown): value is null | undefined {
6
+ return value === null || value === undefined
15
7
  }
16
8
 
17
- /**
18
- * The idle `ReadState` a read hook returns for a `null`/`undefined` subject:
19
- * settled, not live, seq 0, `refetch` a resolved no-op.
20
- */
21
9
  export function idleReadState(): ReadState {
22
- return { pending: false, error: undefined, live: false, seq: 0, refetch: idleRefetch }
10
+ return idle()
23
11
  }
24
- const idleRefetch = (): Promise<void> => Promise.resolve()