@astrale-os/shell-react 0.3.1 → 0.3.2-beta.1

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 (202) hide show
  1. package/dist/application/apps/app-host.d.ts +0 -1
  2. package/dist/application/apps/app-logo.d.ts +0 -1
  3. package/dist/application/apps/apps.hook.d.ts +0 -1
  4. package/dist/application/apps/open-app.hook.d.ts +0 -1
  5. package/dist/application/index.d.ts +0 -1
  6. package/dist/application/spaces/current-space.hook.d.ts +0 -1
  7. package/dist/application/spaces/current-space.store.d.ts +0 -1
  8. package/dist/application/spaces/space.hook.d.ts +0 -1
  9. package/dist/application/spaces/spaces.hook.d.ts +0 -1
  10. package/dist/application/user/user.hook.d.ts +0 -1
  11. package/dist/application/user/user.store.d.ts +0 -1
  12. package/dist/auth/act-as.context.d.ts +0 -1
  13. package/dist/auth/auth.hook.d.ts +0 -1
  14. package/dist/auth/can.hook.d.ts +0 -1
  15. package/dist/auth/index.d.ts +0 -1
  16. package/dist/auth/self.hook.d.ts +0 -1
  17. package/dist/auth/session-kernel.d.ts +0 -1
  18. package/dist/components/astrale.d.ts +0 -1
  19. package/dist/components/boundaries.d.ts +0 -1
  20. package/dist/components/can.d.ts +0 -1
  21. package/dist/components/index.d.ts +0 -1
  22. package/dist/graph/action.d.ts +0 -1
  23. package/dist/graph/async.d.ts +0 -1
  24. package/dist/graph/call/call.hook.d.ts +0 -1
  25. package/dist/graph/call/stream.hook.d.ts +0 -1
  26. package/dist/graph/graph.context.d.ts +0 -1
  27. package/dist/graph/guards.error.d.ts +0 -1
  28. package/dist/graph/index.d.ts +0 -1
  29. package/dist/graph/memory/read/envelope.d.ts +0 -1
  30. package/dist/graph/memory/read/idle.d.ts +0 -1
  31. package/dist/graph/query-definition.hook.d.ts +2 -2
  32. package/dist/graph/query-definition.hook.js +18 -4
  33. package/dist/graph/resource.d.ts +0 -1
  34. package/dist/graph/store.d.ts +0 -1
  35. package/dist/host/actions.hook.d.ts +0 -1
  36. package/dist/host/components.d.ts +0 -1
  37. package/dist/host/index.d.ts +0 -1
  38. package/dist/index.d.ts +2 -3
  39. package/dist/index.js +1 -1
  40. package/dist/intents/emit-intent.hook.d.ts +0 -1
  41. package/dist/intents/envelope.d.ts +0 -1
  42. package/dist/intents/index.d.ts +0 -1
  43. package/dist/intents/listen-intent.hook.d.ts +0 -1
  44. package/dist/intents/reply.d.ts +0 -1
  45. package/dist/intents/resolve-intent-target.d.ts +0 -1
  46. package/dist/intents/send-intent.hook.d.ts +0 -1
  47. package/dist/navigation/adapters/adapter.d.ts +0 -1
  48. package/dist/navigation/adapters/memory.adapter.d.ts +0 -1
  49. package/dist/navigation/adapters/url.adapter.d.ts +0 -1
  50. package/dist/navigation/codec.d.ts +0 -1
  51. package/dist/navigation/history.d.ts +0 -1
  52. package/dist/navigation/hooks/ancestors.hook.d.ts +0 -1
  53. package/dist/navigation/hooks/location.hook.d.ts +0 -1
  54. package/dist/navigation/hooks/navigate.hook.d.ts +0 -1
  55. package/dist/navigation/hooks/scope.hook.d.ts +0 -1
  56. package/dist/navigation/index.d.ts +0 -1
  57. package/dist/navigation/link.d.ts +0 -1
  58. package/dist/navigation/location.d.ts +0 -1
  59. package/dist/navigation/scope.context.d.ts +0 -1
  60. package/dist/navigation/snapshot.d.ts +0 -1
  61. package/dist/navigation/view-key.d.ts +0 -1
  62. package/dist/schema/action.hook.d.ts +4 -12
  63. package/dist/schema/action.hook.js +21 -5
  64. package/dist/schema/domain.context.d.ts +10 -0
  65. package/dist/schema/domain.context.js +17 -0
  66. package/dist/schema/domain.hook.d.ts +0 -1
  67. package/dist/schema/index.d.ts +2 -1
  68. package/dist/schema/index.js +1 -0
  69. package/dist/schema/kernel.hook.d.ts +0 -1
  70. package/dist/schema/mutation.hook.d.ts +2 -2
  71. package/dist/schema/mutation.hook.js +6 -3
  72. package/dist/schema/object.hook.d.ts +0 -1
  73. package/dist/schema/relation.hook.d.ts +0 -1
  74. package/dist/selection/index.d.ts +0 -1
  75. package/dist/selection/live.d.ts +0 -1
  76. package/dist/selection/scope.context.d.ts +0 -1
  77. package/dist/selection/selection.hook.d.ts +0 -1
  78. package/dist/session/boot/boot.d.ts +0 -1
  79. package/dist/session/boot/ownership.d.ts +0 -1
  80. package/dist/session/boot/status.d.ts +0 -1
  81. package/dist/session/connection/connection.hook.d.ts +0 -1
  82. package/dist/session/connection/connection.store.d.ts +0 -1
  83. package/dist/session/index.d.ts +0 -1
  84. package/dist/session/kernel-client.hook.d.ts +0 -1
  85. package/dist/session/kernel-instance.hook.d.ts +0 -1
  86. package/dist/session/provider.d.ts +0 -1
  87. package/dist/session/session.context.d.ts +0 -1
  88. package/dist/session/shell.hook.d.ts +0 -1
  89. package/dist/window/adopt.d.ts +0 -1
  90. package/dist/window/hooks/close-guard.hook.d.ts +0 -1
  91. package/dist/window/hooks/target-node.hook.d.ts +0 -1
  92. package/dist/window/hooks/views-for.hook.d.ts +0 -1
  93. package/dist/window/hooks/window.hook.d.ts +0 -1
  94. package/dist/window/hooks/windows.hook.d.ts +0 -1
  95. package/dist/window/host.d.ts +0 -1
  96. package/dist/window/hub.d.ts +0 -1
  97. package/dist/window/index.d.ts +0 -1
  98. package/dist/window/lifecycle/mount.d.ts +0 -1
  99. package/dist/window/lifecycle/states.d.ts +0 -1
  100. package/dist/window/placement.d.ts +0 -1
  101. package/dist/window/stage.d.ts +0 -1
  102. package/package.json +16 -18
  103. package/src/graph/query-definition.hook.ts +29 -10
  104. package/src/index.ts +2 -0
  105. package/src/schema/action.hook.ts +26 -15
  106. package/src/schema/domain.context.tsx +31 -0
  107. package/src/schema/index.ts +2 -0
  108. package/src/schema/mutation.hook.ts +9 -4
  109. package/dist/application/apps/app-host.d.ts.map +0 -1
  110. package/dist/application/apps/app-logo.d.ts.map +0 -1
  111. package/dist/application/apps/apps.hook.d.ts.map +0 -1
  112. package/dist/application/apps/open-app.hook.d.ts.map +0 -1
  113. package/dist/application/index.d.ts.map +0 -1
  114. package/dist/application/spaces/current-space.hook.d.ts.map +0 -1
  115. package/dist/application/spaces/current-space.store.d.ts.map +0 -1
  116. package/dist/application/spaces/space.hook.d.ts.map +0 -1
  117. package/dist/application/spaces/spaces.hook.d.ts.map +0 -1
  118. package/dist/application/user/user.hook.d.ts.map +0 -1
  119. package/dist/application/user/user.store.d.ts.map +0 -1
  120. package/dist/auth/act-as.context.d.ts.map +0 -1
  121. package/dist/auth/auth.hook.d.ts.map +0 -1
  122. package/dist/auth/can.hook.d.ts.map +0 -1
  123. package/dist/auth/index.d.ts.map +0 -1
  124. package/dist/auth/self.hook.d.ts.map +0 -1
  125. package/dist/auth/session-kernel.d.ts.map +0 -1
  126. package/dist/components/astrale.d.ts.map +0 -1
  127. package/dist/components/boundaries.d.ts.map +0 -1
  128. package/dist/components/can.d.ts.map +0 -1
  129. package/dist/components/index.d.ts.map +0 -1
  130. package/dist/graph/action.d.ts.map +0 -1
  131. package/dist/graph/async.d.ts.map +0 -1
  132. package/dist/graph/call/call.hook.d.ts.map +0 -1
  133. package/dist/graph/call/stream.hook.d.ts.map +0 -1
  134. package/dist/graph/graph.context.d.ts.map +0 -1
  135. package/dist/graph/guards.error.d.ts.map +0 -1
  136. package/dist/graph/index.d.ts.map +0 -1
  137. package/dist/graph/memory/read/envelope.d.ts.map +0 -1
  138. package/dist/graph/memory/read/idle.d.ts.map +0 -1
  139. package/dist/graph/query-definition.hook.d.ts.map +0 -1
  140. package/dist/graph/resource.d.ts.map +0 -1
  141. package/dist/graph/store.d.ts.map +0 -1
  142. package/dist/host/actions.hook.d.ts.map +0 -1
  143. package/dist/host/components.d.ts.map +0 -1
  144. package/dist/host/index.d.ts.map +0 -1
  145. package/dist/index.d.ts.map +0 -1
  146. package/dist/intents/emit-intent.hook.d.ts.map +0 -1
  147. package/dist/intents/envelope.d.ts.map +0 -1
  148. package/dist/intents/index.d.ts.map +0 -1
  149. package/dist/intents/listen-intent.hook.d.ts.map +0 -1
  150. package/dist/intents/reply.d.ts.map +0 -1
  151. package/dist/intents/resolve-intent-target.d.ts.map +0 -1
  152. package/dist/intents/send-intent.hook.d.ts.map +0 -1
  153. package/dist/navigation/adapters/adapter.d.ts.map +0 -1
  154. package/dist/navigation/adapters/memory.adapter.d.ts.map +0 -1
  155. package/dist/navigation/adapters/url.adapter.d.ts.map +0 -1
  156. package/dist/navigation/codec.d.ts.map +0 -1
  157. package/dist/navigation/history.d.ts.map +0 -1
  158. package/dist/navigation/hooks/ancestors.hook.d.ts.map +0 -1
  159. package/dist/navigation/hooks/location.hook.d.ts.map +0 -1
  160. package/dist/navigation/hooks/navigate.hook.d.ts.map +0 -1
  161. package/dist/navigation/hooks/scope.hook.d.ts.map +0 -1
  162. package/dist/navigation/index.d.ts.map +0 -1
  163. package/dist/navigation/link.d.ts.map +0 -1
  164. package/dist/navigation/location.d.ts.map +0 -1
  165. package/dist/navigation/scope.context.d.ts.map +0 -1
  166. package/dist/navigation/snapshot.d.ts.map +0 -1
  167. package/dist/navigation/view-key.d.ts.map +0 -1
  168. package/dist/schema/action.hook.d.ts.map +0 -1
  169. package/dist/schema/domain.hook.d.ts.map +0 -1
  170. package/dist/schema/index.d.ts.map +0 -1
  171. package/dist/schema/kernel.hook.d.ts.map +0 -1
  172. package/dist/schema/mutation.hook.d.ts.map +0 -1
  173. package/dist/schema/object.hook.d.ts.map +0 -1
  174. package/dist/schema/relation.hook.d.ts.map +0 -1
  175. package/dist/selection/index.d.ts.map +0 -1
  176. package/dist/selection/live.d.ts.map +0 -1
  177. package/dist/selection/scope.context.d.ts.map +0 -1
  178. package/dist/selection/selection.hook.d.ts.map +0 -1
  179. package/dist/session/boot/boot.d.ts.map +0 -1
  180. package/dist/session/boot/ownership.d.ts.map +0 -1
  181. package/dist/session/boot/status.d.ts.map +0 -1
  182. package/dist/session/connection/connection.hook.d.ts.map +0 -1
  183. package/dist/session/connection/connection.store.d.ts.map +0 -1
  184. package/dist/session/index.d.ts.map +0 -1
  185. package/dist/session/kernel-client.hook.d.ts.map +0 -1
  186. package/dist/session/kernel-instance.hook.d.ts.map +0 -1
  187. package/dist/session/provider.d.ts.map +0 -1
  188. package/dist/session/session.context.d.ts.map +0 -1
  189. package/dist/session/shell.hook.d.ts.map +0 -1
  190. package/dist/window/adopt.d.ts.map +0 -1
  191. package/dist/window/hooks/close-guard.hook.d.ts.map +0 -1
  192. package/dist/window/hooks/target-node.hook.d.ts.map +0 -1
  193. package/dist/window/hooks/views-for.hook.d.ts.map +0 -1
  194. package/dist/window/hooks/window.hook.d.ts.map +0 -1
  195. package/dist/window/hooks/windows.hook.d.ts.map +0 -1
  196. package/dist/window/host.d.ts.map +0 -1
  197. package/dist/window/hub.d.ts.map +0 -1
  198. package/dist/window/index.d.ts.map +0 -1
  199. package/dist/window/lifecycle/mount.d.ts.map +0 -1
  200. package/dist/window/lifecycle/states.d.ts.map +0 -1
  201. package/dist/window/placement.d.ts.map +0 -1
  202. package/dist/window/stage.d.ts.map +0 -1
@@ -1,5 +1,6 @@
1
1
  export { useKernel } from './kernel.hook.js';
2
2
  export { useDomain, useDomains, useDynamicDomain } from './domain.hook.js';
3
+ export { DomainProvider } from './domain.context.js';
3
4
  export { queryRefresh, useAction } from './action.hook.js';
4
5
  export { useMutation } from './mutation.hook.js';
5
6
  export { useDynamicObject, useObject } from './object.hook.js';
@@ -2,4 +2,3 @@ import type { DomainBinding } from '@astrale-os/shell';
2
2
  import { KernelSchema } from '@astrale-os/sdk/schema';
3
3
  /** The verified, exactly typed Kernel Domain binding. */
4
4
  export declare function useKernel(): DomainBinding<typeof KernelSchema>;
5
- //# sourceMappingURL=kernel.hook.d.ts.map
@@ -1,9 +1,9 @@
1
1
  import type { Mutation } from '@astrale-os/sdk/mutation';
2
+ import type { Domain } from '@astrale-os/sdk/schema';
2
3
  import type { DomainAction } from './action.hook.js';
3
4
  export interface MutationOptions {
4
5
  readonly optimistic?: boolean;
5
6
  readonly onError?: (error: unknown) => void;
6
7
  }
7
8
  /** Execute one named SDK Mutation definition through GraphStore optimism/invalidation. */
8
- export declare function useMutation<Input, Output>(definition: Mutation<Input, Output>, options?: MutationOptions): DomainAction<[Input], Output>;
9
- //# sourceMappingURL=mutation.hook.d.ts.map
9
+ export declare function useMutation<DomainValue extends Domain, Input, Output>(definition: Mutation<DomainValue, Input, Output>, options?: MutationOptions): DomainAction<[Input], Output>;
@@ -2,9 +2,11 @@ import { executeMutation } from '@astrale-os/sdk/mutation';
2
2
  import { useCallback, useMemo, useRef } from 'react';
3
3
  import { useAction as useAsyncAction } from '../graph/action.js';
4
4
  import { useGraphStore } from '../graph/store.js';
5
+ import { useExecutionDomain } from './domain.context.js';
5
6
  /** Execute one named SDK Mutation definition through GraphStore optimism/invalidation. */
6
7
  export function useMutation(definition, options = {}) {
7
8
  const store = useGraphStore();
9
+ const domain = useExecutionDomain();
8
10
  const definitionRef = useRef(definition);
9
11
  definitionRef.current = definition;
10
12
  const optionsRef = useRef(options);
@@ -12,16 +14,17 @@ export function useMutation(definition, options = {}) {
12
14
  const run = useCallback(async (input) => {
13
15
  try {
14
16
  return await executeMutation({
15
- mutate: (ast) => store.mutate(ast, {
17
+ mutate: (ast, graphOptions) => store.mutate(ast, {
18
+ ...graphOptions,
16
19
  optimistic: optionsRef.current.optimistic ?? true,
17
20
  }),
18
- }, definitionRef.current, input);
21
+ }, domain, definitionRef.current, input);
19
22
  }
20
23
  catch (error) {
21
24
  optionsRef.current.onError?.(error);
22
25
  throw error;
23
26
  }
24
- }, [store]);
27
+ }, [store, domain]);
25
28
  const action = useAsyncAction(run);
26
29
  return useMemo(() => project(action), [action]);
27
30
  }
@@ -10,4 +10,3 @@ export interface RichReadOptions {
10
10
  export declare function useObject<Class extends ResolvedClass<'node'>>(definition: Class, target: PathLike | null | undefined, options?: RichReadOptions): GraphResource<BoundNode<Class> | null>;
11
11
  /** Explicitly untyped point read for inspectors; it never impersonates `useObject`. */
12
12
  export declare function useDynamicObject(target: PathLike | null | undefined, options?: RichReadOptions): GraphResource<Node | null>;
13
- //# sourceMappingURL=object.hook.d.ts.map
@@ -53,4 +53,3 @@ export interface RelationOptions<Role extends EndpointRole, To> {
53
53
  /** Traverse one directed resolved Edge Class and bind the selected opposite Nodes. */
54
54
  export declare function useRelation<Relation extends ResolvedClass<'edge'>, Role extends EndpointRole, To extends ResolvedClass<'node'>, Source extends ResolvedClass<'node'>>(relation: Relation, source: BoundNode<Source> | null | undefined, options: RelationOptions<Role, To>): RelationResource<BoundNode<To>, EffectiveCardinality<Relation, Role, To>>;
55
55
  export {};
56
- //# sourceMappingURL=relation.hook.d.ts.map
@@ -1,4 +1,3 @@
1
1
  export { SelectionScope } from './scope.context.js';
2
2
  export type { Selection, SelectionScopeProps } from './scope.context.js';
3
3
  export { useSelection } from './selection.hook.js';
4
- //# sourceMappingURL=index.d.ts.map
@@ -10,4 +10,3 @@ export interface ResolvedSelection {
10
10
  }
11
11
  /** Resolve selected identities through the authenticated GraphApi; no fake live subscription. */
12
12
  export declare function useResolvedNodes(orderedIds: readonly NodeId[]): ResolvedSelection;
13
- //# sourceMappingURL=live.d.ts.map
@@ -23,4 +23,3 @@ export interface SelectionScopeProps {
23
23
  }
24
24
  export declare const SelectionContext: import("react").Context<Selection | null>;
25
25
  export declare function SelectionScope(props: SelectionScopeProps): ReactElement;
26
- //# sourceMappingURL=scope.context.d.ts.map
@@ -1,4 +1,3 @@
1
1
  import type { Selection } from './scope.context.js';
2
2
  /** The nearest selection scope. Throws outside a `<SelectionScope>`. */
3
3
  export declare function useSelection(): Selection;
4
- //# sourceMappingURL=selection.hook.d.ts.map
@@ -4,4 +4,3 @@ export declare function isShellConfig(config: ShellConfig | Shell): config is Sh
4
4
  /** Stable ownership key. Capability objects intentionally use reference identity. */
5
5
  export declare function configIdentity(config: ShellConfig | Shell): string;
6
6
  export declare function resolveSelf(shell: Shell): Promise<SelfNode | null>;
7
- //# sourceMappingURL=boot.d.ts.map
@@ -15,4 +15,3 @@ export declare function cancelTeardown(shell: Shell): void;
15
15
  /** Defer a shell's dispose one macrotask, resetting the owning ref when it fires. */
16
16
  export declare function scheduleTeardown(shell: Shell, ref: BootRef): void;
17
17
  export declare function disposeShell(shell: Shell): void;
18
- //# sourceMappingURL=ownership.d.ts.map
@@ -21,4 +21,3 @@ export type BootAction = {
21
21
  };
22
22
  export declare const INITIAL_BOOT: BootState;
23
23
  export declare function bootReducer(state: BootState, action: BootAction): BootState;
24
- //# sourceMappingURL=status.d.ts.map
@@ -1,3 +1,2 @@
1
1
  import type { ConnectionValue } from './connection.store.js';
2
2
  export declare function useConnection(): ConnectionValue;
3
- //# sourceMappingURL=connection.hook.d.ts.map
@@ -21,4 +21,3 @@ export interface ConnectionStore {
21
21
  }
22
22
  /** The one connection store for a Shell (created on first touch). */
23
23
  export declare function connectionStore(shell: Shell): ConnectionStore;
24
- //# sourceMappingURL=connection.store.d.ts.map
@@ -6,4 +6,3 @@ export { useKernelInstance } from './kernel-instance.hook.js';
6
6
  export type { KernelInstance } from './kernel-instance.hook.js';
7
7
  export { useConnection } from './connection/connection.hook.js';
8
8
  export type { ConnectionStatus, ConnectionValue } from './connection/connection.store.js';
9
- //# sourceMappingURL=index.d.ts.map
@@ -6,4 +6,3 @@
6
6
  import type { KernelClient } from '@astrale-os/shell';
7
7
  /** `shell.kernel` — the raw bound kernel view, untouched (untyped floor). */
8
8
  export declare function useKernelClient(): KernelClient;
9
- //# sourceMappingURL=kernel-client.hook.d.ts.map
@@ -3,4 +3,3 @@ export interface KernelInstance {
3
3
  readonly url: string;
4
4
  }
5
5
  export declare function useKernelInstance(): KernelInstance;
6
- //# sourceMappingURL=kernel-instance.hook.d.ts.map
@@ -14,4 +14,3 @@ export interface ShellProviderProps {
14
14
  }
15
15
  /** Own and initialize exactly one Shell for a React subtree. */
16
16
  export declare function ShellProvider(props: ShellProviderProps): ReactElement | null;
17
- //# sourceMappingURL=provider.d.ts.map
@@ -19,4 +19,3 @@ export interface ShellRuntime {
19
19
  readonly ownsStore: boolean;
20
20
  }
21
21
  export declare const ShellContext: import("react").Context<ShellRuntime | null>;
22
- //# sourceMappingURL=session.context.d.ts.map
@@ -1,4 +1,3 @@
1
1
  import type { Shell } from '@astrale-os/shell';
2
2
  /** The live shell for this subtree. Throws outside a `<ShellProvider>`. */
3
3
  export declare function useShell(): Shell;
4
- //# sourceMappingURL=shell.hook.d.ts.map
@@ -23,4 +23,3 @@ export interface AdoptStash {
23
23
  }
24
24
  /** The pending-adoption registry — one per stage hub. */
25
25
  export declare function createAdoptStash(): AdoptStash;
26
- //# sourceMappingURL=adopt.d.ts.map
@@ -3,4 +3,3 @@ export type CloseVerdict = 'ack' | 'refuse' | {
3
3
  };
4
4
  export type CloseGuard = () => CloseVerdict | Promise<CloseVerdict>;
5
5
  export declare function useCloseGuard(guard: CloseGuard): void;
6
- //# sourceMappingURL=close-guard.hook.d.ts.map
@@ -8,4 +8,3 @@ import type { GraphResource } from '../../graph/resource.js';
8
8
  export declare function useTargetNode(): GraphResource<Node | null>;
9
9
  /** Reactive canonical target Path; null represents an explicit parent clear. */
10
10
  export declare function useTargetPath(): Path | null;
11
- //# sourceMappingURL=target-node.hook.d.ts.map
@@ -6,4 +6,3 @@ export interface ViewsForResult extends ReadState {
6
6
  readonly views: readonly ResolvedView[];
7
7
  }
8
8
  export declare function useViewsFor(node: Node | PathLike | null | undefined): ViewsForResult;
9
- //# sourceMappingURL=views-for.hook.d.ts.map
@@ -1,4 +1,3 @@
1
1
  import type { WindowView } from '../hub.js';
2
2
  /** One window's live phase + shell `Window` (null id / unknown id → no window). */
3
3
  export declare function useWindow(windowId: string | null): WindowView;
4
- //# sourceMappingURL=window.hook.d.ts.map
@@ -12,4 +12,3 @@ export interface WindowListEntry {
12
12
  * so the derived array is too (no render churn).
13
13
  */
14
14
  export declare function useWindowList(): readonly WindowListEntry[];
15
- //# sourceMappingURL=windows.hook.d.ts.map
@@ -28,4 +28,3 @@ export interface ViewHostProps {
28
28
  style?: CSSProperties;
29
29
  }
30
30
  export declare const ViewHost: import("react").ForwardRefExoticComponent<ViewHostProps & import("react").RefAttributes<ViewHostHandle>>;
31
- //# sourceMappingURL=host.d.ts.map
@@ -40,4 +40,3 @@ export interface StageHub {
40
40
  }
41
41
  /** The windows hub for a shell — one per shell object, created on first touch. */
42
42
  export declare function getStageHub(shell: Shell): StageHub;
43
- //# sourceMappingURL=hub.d.ts.map
@@ -12,4 +12,3 @@ export { useCloseGuard } from './hooks/close-guard.hook.js';
12
12
  export type { CloseGuard, CloseVerdict } from './hooks/close-guard.hook.js';
13
13
  export type { WindowState } from './lifecycle/states.js';
14
14
  export type { ResolvedView } from '@astrale-os/shell';
15
- //# sourceMappingURL=index.d.ts.map
@@ -5,4 +5,3 @@ import type { ResolvedView } from '@astrale-os/shell';
5
5
  * iframe and credential can never be adopted under a different route.
6
6
  */
7
7
  export declare function viewMountKey(view: ResolvedView): string;
8
- //# sourceMappingURL=mount.d.ts.map
@@ -25,4 +25,3 @@ export type WindowState = {
25
25
  readonly windowId: string;
26
26
  readonly refusal?: string;
27
27
  };
28
- //# sourceMappingURL=states.d.ts.map
@@ -30,4 +30,3 @@ export declare function createStageController(container: HTMLElement): StageCont
30
30
  /** Measure an anchor element's viewport box. */
31
31
  export declare function rectOf(el: HTMLElement): SlotRect;
32
32
  export declare function sameRect(a: SlotRect, b: SlotRect): boolean;
33
- //# sourceMappingURL=placement.d.ts.map
@@ -1,3 +1,2 @@
1
1
  import type { ReactElement } from 'react';
2
2
  export declare function ViewStage(): ReactElement;
3
- //# sourceMappingURL=stage.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astrale-os/shell-react",
3
- "version": "0.3.1",
3
+ "version": "0.3.2-beta.1",
4
4
  "description": "Astrale shell-react — the React face of the shell (provider, hooks, view components)",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -22,42 +22,40 @@
22
22
  }
23
23
  },
24
24
  "publishConfig": {
25
- "access": "public"
25
+ "access": "public",
26
+ "registry": "https://registry.npmjs.org"
26
27
  },
27
28
  "dependencies": {
28
- "jose": "^6.2.3",
29
- "zod": "^4.3.6"
29
+ "@astrale-os/shell": ">=0.4.2-beta <1.0.0",
30
+ "jose": "^6.2.8",
31
+ "zod": "^4.4.3"
30
32
  },
31
33
  "devDependencies": {
32
- "@astrale-os/sdk": ">=0.5.0-beta.17 <1.0.0",
34
+ "@astrale-os/sdk": "0.5.0-beta.32",
33
35
  "@testing-library/dom": "^10.4.0",
34
36
  "@testing-library/react": "^16.3.0",
35
- "@types/node": "^26.0.0",
37
+ "@types/node": "^26.2.0",
36
38
  "@types/react": "^19.2.0",
37
39
  "@types/react-dom": "^19.2.0",
38
- "@typescript/native-preview": "latest",
39
- "@vitejs/plugin-react": "^5.0.4",
40
+ "@vitejs/plugin-react": "6.0.5",
40
41
  "happy-dom": "^20.0.0",
41
42
  "react": "^19.2.0",
42
43
  "react-dom": "^19.2.0",
43
- "typescript": "~6.0.1-rc",
44
- "vite": "^7.3.6",
45
- "vitest": "^3.2.4",
46
- "@astrale-os/shell": "0.4.1"
44
+ "typescript": "7.0.2",
45
+ "vite": "8.2.1",
46
+ "vitest": "4.1.10"
47
47
  },
48
48
  "peerDependencies": {
49
- "@astrale-os/sdk": ">=0.5.0-beta.17 <1.0.0",
50
- "@astrale-os/shell": ">=0.3.8-beta.3 <1.0.0",
49
+ "@astrale-os/sdk": ">=0.5.0-beta.32 <1.0.0",
51
50
  "react": ">=18",
52
51
  "react-dom": ">=18"
53
52
  },
54
53
  "scripts": {
55
54
  "prebuild": "pnpm clean",
56
- "build": "tsgo",
55
+ "build": "tsc",
57
56
  "clean": "rm -rf dist *.tsbuildinfo",
58
- "typecheck": "tsgo --noEmit && tsgo --noEmit -p tsconfig.test.json",
57
+ "typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test.json",
59
58
  "test": "vitest run",
60
- "test:watch": "vitest",
61
- "preinstall": "node -e \"try{require('./.check-workspace.cjs')}catch{}\""
59
+ "test:watch": "vitest"
62
60
  }
63
61
  }
@@ -1,12 +1,14 @@
1
1
  import type { QueryPageRequest } from '@astrale-os/sdk/client'
2
2
  import type { GraphStore, StoreQueryResponse, StoreSnapshot } from '@astrale-os/sdk/client/store'
3
3
  import type { QueryAST, QueryDefinition } from '@astrale-os/sdk/query'
4
+ import type { Domain } from '@astrale-os/sdk/schema'
4
5
 
5
6
  import { executeQuery } from '@astrale-os/sdk/query'
6
7
  import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react'
7
8
 
8
9
  import type { GraphResource, GraphResourceState } from './resource.js'
9
10
 
11
+ import { useExecutionDomain } from '../schema/domain.context.js'
10
12
  import { retainRefreshScheduler } from './resource.js'
11
13
  import { useGraphStore } from './store.js'
12
14
 
@@ -18,7 +20,10 @@ export interface QueryResourceOptions {
18
20
 
19
21
  interface TouchedShape {
20
22
  readonly ast: QueryAST
21
- readonly options: { readonly page: QueryPageRequest }
23
+ readonly options: {
24
+ readonly page: QueryPageRequest
25
+ readonly expected?: Domain['closure']
26
+ }
22
27
  }
23
28
 
24
29
  interface DefinitionSnapshot<Output> {
@@ -27,7 +32,7 @@ interface DefinitionSnapshot<Output> {
27
32
  readonly error?: unknown
28
33
  }
29
34
 
30
- class DefinitionObserver<Input, Output> {
35
+ class DefinitionObserver<DomainValue extends Domain, Input, Output> {
31
36
  private readonly listeners = new Set<() => void>()
32
37
  private subscriptions: readonly (() => void)[] = Object.freeze([])
33
38
  private touched: readonly TouchedShape[] = Object.freeze([])
@@ -39,7 +44,8 @@ class DefinitionObserver<Input, Output> {
39
44
 
40
45
  constructor(
41
46
  private readonly store: GraphStore,
42
- private readonly definition: QueryDefinition<Input, Output>,
47
+ private readonly domain: DomainValue,
48
+ private readonly definition: QueryDefinition<DomainValue, Input, Output>,
43
49
  private readonly input: Input,
44
50
  ) {}
45
51
 
@@ -75,12 +81,12 @@ class DefinitionObserver<Input, Output> {
75
81
  })
76
82
  const execute = async <Ast extends QueryAST>(
77
83
  ast: Ast,
78
- options: { readonly page: QueryPageRequest },
84
+ options: { readonly page: QueryPageRequest; readonly expected?: Domain['closure'] },
79
85
  ): Promise<StoreQueryResponse<Ast>> => {
80
86
  touched.push(Object.freeze({ ast, options }))
81
87
  return this.store.read(ast, { ...options, freshness })
82
88
  }
83
- const running = executeQuery({ query: execute }, this.definition, this.input)
89
+ const running = executeQuery({ query: execute }, this.domain, this.definition, this.input)
84
90
  .then((data) => {
85
91
  if (!this.started || generation !== this.generation) return
86
92
  this.touched = dedupeShapes(touched)
@@ -148,16 +154,17 @@ class DefinitionObserver<Input, Output> {
148
154
  }
149
155
 
150
156
  /** Execute one named SDK Query definition exclusively through the current GraphStore. */
151
- export function useQuery<Input, Output>(
152
- definition: QueryDefinition<Input, Output> | null,
157
+ export function useQuery<DomainValue extends Domain, Input, Output>(
158
+ definition: QueryDefinition<DomainValue, Input, Output> | null,
153
159
  input: Input,
154
160
  options: QueryResourceOptions = {},
155
161
  ): GraphResource<Output> {
156
162
  const store = useGraphStore()
163
+ const domain = useExecutionDomain<DomainValue>()
157
164
  const inputIdentity = stableIdentity(input)
158
165
  const observer = useMemo(
159
- () => (definition === null ? null : new DefinitionObserver(store, definition, input)),
160
- [store, definition, inputIdentity],
166
+ () => (definition === null ? null : new DefinitionObserver(store, domain, definition, input)),
167
+ [store, domain, definition, inputIdentity],
161
168
  )
162
169
  const idle = useMemo<DefinitionSnapshot<Output>>(() => Object.freeze({ state: 'idle' }), [])
163
170
  const subscribe = useCallback(
@@ -168,7 +175,8 @@ export function useQuery<Input, Output>(
168
175
  const current = useSyncExternalStore(subscribe, snapshot, snapshot)
169
176
  useEffect(() => observer?.start(), [observer])
170
177
 
171
- const identity = definition === null ? 'idle' : `${definition.id}\u0000${inputIdentity}`
178
+ const identity =
179
+ definition === null ? 'idle' : `${definitionIdentity(definition)}\u0000${inputIdentity}`
172
180
  useEffect(() => {
173
181
  if (observer === null || options.refreshInterval === undefined) return
174
182
  return retainRefreshScheduler(
@@ -210,6 +218,17 @@ export function useQuery<Input, Output>(
210
218
  )
211
219
  }
212
220
 
221
+ const definitionIdentities = new WeakMap<object, number>()
222
+ let nextDefinitionIdentity = 1
223
+
224
+ function definitionIdentity(definition: object): number {
225
+ const retained = definitionIdentities.get(definition)
226
+ if (retained !== undefined) return retained
227
+ const created = nextDefinitionIdentity++
228
+ definitionIdentities.set(definition, created)
229
+ return created
230
+ }
231
+
213
232
  function dedupeShapes(input: readonly TouchedShape[]): readonly TouchedShape[] {
214
233
  const seen = new Set<string>()
215
234
  return Object.freeze(
package/src/index.ts CHANGED
@@ -39,6 +39,7 @@ export type {
39
39
 
40
40
  // Rich exact Domain bindings.
41
41
  export {
42
+ DomainProvider,
42
43
  RelationUnavailableError,
43
44
  queryRefresh,
44
45
  useAction,
@@ -54,6 +55,7 @@ export {
54
55
  export type {
55
56
  ActionOptions,
56
57
  ActionRefresh,
58
+ DomainProviderProps,
57
59
  DomainAction,
58
60
  MutationOptions,
59
61
  QueryRefresh,
@@ -1,7 +1,8 @@
1
1
  import type { BoundNodeFor } from '@astrale-os/sdk/client'
2
2
  import type { SessionRequestOptions } from '@astrale-os/sdk/client/session'
3
3
  import type { NodeId } from '@astrale-os/sdk/graph/node'
4
- import type { QueryAST } from '@astrale-os/sdk/query'
4
+ import type { QueryAST, QueryDefinition } from '@astrale-os/sdk/query'
5
+ import type { Domain } from '@astrale-os/sdk/schema'
5
6
  import type {
6
7
  CallableInputOf,
7
8
  CallableResultOf,
@@ -13,6 +14,7 @@ import type {
13
14
 
14
15
  import { reference } from '@astrale-os/sdk/client/session'
15
16
  import { Path } from '@astrale-os/sdk/graph/path'
17
+ import { realizeQuery } from '@astrale-os/sdk/query'
16
18
  import { useCallback, useMemo, useRef } from 'react'
17
19
 
18
20
  import type { Action as AsyncAction } from '../graph/action.js'
@@ -33,29 +35,30 @@ const QUERY_REFRESH = Symbol('shell-react.query-refresh')
33
35
 
34
36
  export interface QueryRefresh {
35
37
  readonly id: string
36
- readonly [QUERY_REFRESH]: () => {
38
+ readonly [QUERY_REFRESH]: (domain: Domain) => {
37
39
  readonly ast: QueryAST
38
40
  readonly page: Readonly<{ readonly size: number }>
39
41
  }
40
42
  }
41
43
 
42
- type RefreshableQuery<Input, Query extends QueryAST> = {
43
- readonly id: string
44
- readonly page: Readonly<{ readonly size: number }>
45
- prepare?(input: Input): Input
46
- build(input: Input): Query
47
- }
44
+ const queryRefreshIdentities = new WeakMap<object, string>()
45
+ let nextQueryRefreshIdentity = 0
48
46
 
49
47
  /** Pair one exact named Query definition with its admitted input for targeted invalidation. */
50
- export function queryRefresh<Input, Query extends QueryAST>(
51
- definition: RefreshableQuery<Input, Query>,
48
+ export function queryRefresh<DomainValue extends Domain, Input, Output>(
49
+ definition: QueryDefinition<DomainValue, Input, Output>,
52
50
  input: Input,
53
51
  ): QueryRefresh {
52
+ const id = queryRefreshIdentity(definition)
54
53
  return Object.freeze({
55
- id: definition.id,
56
- [QUERY_REFRESH]: () => {
57
- const prepared = definition.prepare?.(input) ?? input
58
- return Object.freeze({ ast: definition.build(prepared), page: definition.page })
54
+ id,
55
+ [QUERY_REFRESH]: (domain: Domain) => {
56
+ const realized = realizeQuery(definition, domain as DomainValue)
57
+ if (realized.kind !== 'single') {
58
+ throw new TypeError('Targeted refresh requires a single Query recipe.')
59
+ }
60
+ const prepared = realized.prepare?.(input) ?? input
61
+ return Object.freeze({ ast: realized.build(prepared), page: realized.page })
59
62
  },
60
63
  })
61
64
  }
@@ -120,7 +123,7 @@ export function useAction<C extends Callable>(
120
123
  if (refresh === 'all') store.invalidate()
121
124
  else if (refresh !== 'none') {
122
125
  refresh.queries.forEach((query) => {
123
- const target = query[QUERY_REFRESH]()
126
+ const target = query[QUERY_REFRESH](bindingRef.current.domain)
124
127
  store.invalidate(target.ast, { page: target.page })
125
128
  })
126
129
  }
@@ -161,3 +164,11 @@ function isInstanceMethod(callable: Callable): callable is InstanceMethod {
161
164
  function receiverPath(receiver: Receiver): Path {
162
165
  return Path.id(receiver.id)
163
166
  }
167
+
168
+ function queryRefreshIdentity(definition: object): string {
169
+ const current = queryRefreshIdentities.get(definition)
170
+ if (current !== undefined) return current
171
+ const created = `query-${++nextQueryRefreshIdentity}`
172
+ queryRefreshIdentities.set(definition, created)
173
+ return created
174
+ }
@@ -0,0 +1,31 @@
1
+ import type { Domain } from '@astrale-os/sdk/schema'
2
+ import type { schema } from '@astrale-os/sdk/schema'
3
+ import type { ReactElement, ReactNode } from 'react'
4
+
5
+ import { createContext, useContext } from 'react'
6
+
7
+ import { useDomain } from './domain.hook.js'
8
+
9
+ const DomainContext = createContext<Domain | null>(null)
10
+ DomainContext.displayName = 'AstraleDomainContext'
11
+
12
+ export interface DomainProviderProps<Schema extends schema.DomainSchema> {
13
+ readonly schema: Schema
14
+ readonly children: ReactNode
15
+ }
16
+
17
+ /** Resolve one exact installed Domain for every projected recipe in the React subtree. */
18
+ export function DomainProvider<const Schema extends schema.DomainSchema>(
19
+ props: DomainProviderProps<Schema>,
20
+ ): ReactElement {
21
+ const binding = useDomain(props.schema)
22
+ return <DomainContext.Provider value={binding.domain}>{props.children}</DomainContext.Provider>
23
+ }
24
+
25
+ export function useExecutionDomain<DomainValue extends Domain>(): DomainValue {
26
+ const domain = useContext(DomainContext)
27
+ if (domain === null) {
28
+ throw new Error('Projected Query and Mutation hooks require a surrounding DomainProvider.')
29
+ }
30
+ return domain as DomainValue
31
+ }
@@ -1,5 +1,7 @@
1
1
  export { useKernel } from './kernel.hook.js'
2
2
  export { useDomain, useDomains, useDynamicDomain } from './domain.hook.js'
3
+ export { DomainProvider } from './domain.context.js'
4
+ export type { DomainProviderProps } from './domain.context.js'
3
5
  export { queryRefresh, useAction } from './action.hook.js'
4
6
  export type { ActionOptions, ActionRefresh, DomainAction, QueryRefresh } from './action.hook.js'
5
7
  export { useMutation } from './mutation.hook.js'
@@ -1,4 +1,5 @@
1
1
  import type { Mutation } from '@astrale-os/sdk/mutation'
2
+ import type { Domain } from '@astrale-os/sdk/schema'
2
3
 
3
4
  import { executeMutation } from '@astrale-os/sdk/mutation'
4
5
  import { useCallback, useMemo, useRef } from 'react'
@@ -8,6 +9,7 @@ import type { DomainAction } from './action.hook.js'
8
9
 
9
10
  import { useAction as useAsyncAction } from '../graph/action.js'
10
11
  import { useGraphStore } from '../graph/store.js'
12
+ import { useExecutionDomain } from './domain.context.js'
11
13
 
12
14
  export interface MutationOptions {
13
15
  readonly optimistic?: boolean
@@ -15,11 +17,12 @@ export interface MutationOptions {
15
17
  }
16
18
 
17
19
  /** Execute one named SDK Mutation definition through GraphStore optimism/invalidation. */
18
- export function useMutation<Input, Output>(
19
- definition: Mutation<Input, Output>,
20
+ export function useMutation<DomainValue extends Domain, Input, Output>(
21
+ definition: Mutation<DomainValue, Input, Output>,
20
22
  options: MutationOptions = {},
21
23
  ): DomainAction<[Input], Output> {
22
24
  const store = useGraphStore()
25
+ const domain = useExecutionDomain<DomainValue>()
23
26
  const definitionRef = useRef(definition)
24
27
  definitionRef.current = definition
25
28
  const optionsRef = useRef(options)
@@ -29,11 +32,13 @@ export function useMutation<Input, Output>(
29
32
  try {
30
33
  return await executeMutation(
31
34
  {
32
- mutate: (ast) =>
35
+ mutate: (ast, graphOptions) =>
33
36
  store.mutate(ast, {
37
+ ...graphOptions,
34
38
  optimistic: optionsRef.current.optimistic ?? true,
35
39
  }),
36
40
  },
41
+ domain,
37
42
  definitionRef.current,
38
43
  input,
39
44
  )
@@ -42,7 +47,7 @@ export function useMutation<Input, Output>(
42
47
  throw error
43
48
  }
44
49
  },
45
- [store],
50
+ [store, domain],
46
51
  )
47
52
  const action = useAsyncAction(run)
48
53
  return useMemo(() => project(action), [action])
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-host.d.ts","sourceRoot":"","sources":["../../../src/application/apps/app-host.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC5E,OAAO,KAAK,EAAE,aAAa,EAAgB,SAAS,EAAE,MAAM,OAAO,CAAA;AAInE,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAA;AAKnE,MAAM,MAAM,oBAAoB,GAC5B,WAAW,GACX;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GAC7B;IAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAA;CAAE,CAAA;AAEjC,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,CAAA;IACrB,gDAAgD;IAChD,IAAI,CAAC,EAAE,YAAY,CAAA;IACnB,YAAY,CAAC,EAAE,gBAAgB,CAAA;IAC/B,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,SAAS,CAAA;IACrD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;CACtB;AAED,uFAAuF;AACvF,eAAO,MAAM,OAAO,yGAoDnB,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"app-logo.d.ts","sourceRoot":"","sources":["../../../src/application/apps/app-logo.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAInE,MAAM,WAAW,YAAY;IAC3B,uEAAuE;IACvE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,yEAAyE;IACzE,QAAQ,CAAC,EAAE,SAAS,CAAA;CACrB;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,YAAY,GAAG,YAAY,CAiB7F"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"apps.hook.d.ts","sourceRoot":"","sources":["../../../src/application/apps/apps.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAI5C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAQpE,MAAM,WAAW,UAAW,SAAQ,SAAS;IAC3C,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,EAAE,CAAA;CAC9B;AAED,qFAAqF;AACrF,wBAAgB,OAAO,IAAI,UAAU,CAoBpC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"open-app.hook.d.ts","sourceRoot":"","sources":["../../../src/application/apps/open-app.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAE1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAInD,0DAA0D;AAC1D,wBAAgB,UAAU,IAAI,MAAM,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC,CAG5E"}