@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.
- package/dist/application/apps/app-host.d.ts +0 -1
- package/dist/application/apps/app-logo.d.ts +0 -1
- package/dist/application/apps/apps.hook.d.ts +0 -1
- package/dist/application/apps/open-app.hook.d.ts +0 -1
- package/dist/application/index.d.ts +0 -1
- package/dist/application/spaces/current-space.hook.d.ts +0 -1
- package/dist/application/spaces/current-space.store.d.ts +0 -1
- package/dist/application/spaces/space.hook.d.ts +0 -1
- package/dist/application/spaces/spaces.hook.d.ts +0 -1
- package/dist/application/user/user.hook.d.ts +0 -1
- package/dist/application/user/user.store.d.ts +0 -1
- package/dist/auth/act-as.context.d.ts +0 -1
- package/dist/auth/auth.hook.d.ts +0 -1
- package/dist/auth/can.hook.d.ts +0 -1
- package/dist/auth/index.d.ts +0 -1
- package/dist/auth/self.hook.d.ts +0 -1
- package/dist/auth/session-kernel.d.ts +0 -1
- package/dist/components/astrale.d.ts +0 -1
- package/dist/components/boundaries.d.ts +0 -1
- package/dist/components/can.d.ts +0 -1
- package/dist/components/index.d.ts +0 -1
- package/dist/graph/action.d.ts +0 -1
- package/dist/graph/async.d.ts +0 -1
- package/dist/graph/call/call.hook.d.ts +0 -1
- package/dist/graph/call/stream.hook.d.ts +0 -1
- package/dist/graph/graph.context.d.ts +0 -1
- package/dist/graph/guards.error.d.ts +0 -1
- package/dist/graph/index.d.ts +0 -1
- package/dist/graph/memory/read/envelope.d.ts +0 -1
- package/dist/graph/memory/read/idle.d.ts +0 -1
- package/dist/graph/query-definition.hook.d.ts +2 -2
- package/dist/graph/query-definition.hook.js +18 -4
- package/dist/graph/resource.d.ts +0 -1
- package/dist/graph/store.d.ts +0 -1
- package/dist/host/actions.hook.d.ts +0 -1
- package/dist/host/components.d.ts +0 -1
- package/dist/host/index.d.ts +0 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.js +1 -1
- package/dist/intents/emit-intent.hook.d.ts +0 -1
- package/dist/intents/envelope.d.ts +0 -1
- package/dist/intents/index.d.ts +0 -1
- package/dist/intents/listen-intent.hook.d.ts +0 -1
- package/dist/intents/reply.d.ts +0 -1
- package/dist/intents/resolve-intent-target.d.ts +0 -1
- package/dist/intents/send-intent.hook.d.ts +0 -1
- package/dist/navigation/adapters/adapter.d.ts +0 -1
- package/dist/navigation/adapters/memory.adapter.d.ts +0 -1
- package/dist/navigation/adapters/url.adapter.d.ts +0 -1
- package/dist/navigation/codec.d.ts +0 -1
- package/dist/navigation/history.d.ts +0 -1
- package/dist/navigation/hooks/ancestors.hook.d.ts +0 -1
- package/dist/navigation/hooks/location.hook.d.ts +0 -1
- package/dist/navigation/hooks/navigate.hook.d.ts +0 -1
- package/dist/navigation/hooks/scope.hook.d.ts +0 -1
- package/dist/navigation/index.d.ts +0 -1
- package/dist/navigation/link.d.ts +0 -1
- package/dist/navigation/location.d.ts +0 -1
- package/dist/navigation/scope.context.d.ts +0 -1
- package/dist/navigation/snapshot.d.ts +0 -1
- package/dist/navigation/view-key.d.ts +0 -1
- package/dist/schema/action.hook.d.ts +4 -12
- package/dist/schema/action.hook.js +21 -5
- package/dist/schema/domain.context.d.ts +10 -0
- package/dist/schema/domain.context.js +17 -0
- package/dist/schema/domain.hook.d.ts +0 -1
- package/dist/schema/index.d.ts +2 -1
- package/dist/schema/index.js +1 -0
- package/dist/schema/kernel.hook.d.ts +0 -1
- package/dist/schema/mutation.hook.d.ts +2 -2
- package/dist/schema/mutation.hook.js +6 -3
- package/dist/schema/object.hook.d.ts +0 -1
- package/dist/schema/relation.hook.d.ts +0 -1
- package/dist/selection/index.d.ts +0 -1
- package/dist/selection/live.d.ts +0 -1
- package/dist/selection/scope.context.d.ts +0 -1
- package/dist/selection/selection.hook.d.ts +0 -1
- package/dist/session/boot/boot.d.ts +0 -1
- package/dist/session/boot/ownership.d.ts +0 -1
- package/dist/session/boot/status.d.ts +0 -1
- package/dist/session/connection/connection.hook.d.ts +0 -1
- package/dist/session/connection/connection.store.d.ts +0 -1
- package/dist/session/index.d.ts +0 -1
- package/dist/session/kernel-client.hook.d.ts +0 -1
- package/dist/session/kernel-instance.hook.d.ts +0 -1
- package/dist/session/provider.d.ts +0 -1
- package/dist/session/session.context.d.ts +0 -1
- package/dist/session/shell.hook.d.ts +0 -1
- package/dist/window/adopt.d.ts +0 -1
- package/dist/window/hooks/close-guard.hook.d.ts +0 -1
- package/dist/window/hooks/target-node.hook.d.ts +0 -1
- package/dist/window/hooks/views-for.hook.d.ts +0 -1
- package/dist/window/hooks/window.hook.d.ts +0 -1
- package/dist/window/hooks/windows.hook.d.ts +0 -1
- package/dist/window/host.d.ts +0 -1
- package/dist/window/hub.d.ts +0 -1
- package/dist/window/index.d.ts +0 -1
- package/dist/window/lifecycle/mount.d.ts +0 -1
- package/dist/window/lifecycle/states.d.ts +0 -1
- package/dist/window/placement.d.ts +0 -1
- package/dist/window/stage.d.ts +0 -1
- package/package.json +16 -18
- package/src/graph/query-definition.hook.ts +29 -10
- package/src/index.ts +2 -0
- package/src/schema/action.hook.ts +26 -15
- package/src/schema/domain.context.tsx +31 -0
- package/src/schema/index.ts +2 -0
- package/src/schema/mutation.hook.ts +9 -4
- package/dist/application/apps/app-host.d.ts.map +0 -1
- package/dist/application/apps/app-logo.d.ts.map +0 -1
- package/dist/application/apps/apps.hook.d.ts.map +0 -1
- package/dist/application/apps/open-app.hook.d.ts.map +0 -1
- package/dist/application/index.d.ts.map +0 -1
- package/dist/application/spaces/current-space.hook.d.ts.map +0 -1
- package/dist/application/spaces/current-space.store.d.ts.map +0 -1
- package/dist/application/spaces/space.hook.d.ts.map +0 -1
- package/dist/application/spaces/spaces.hook.d.ts.map +0 -1
- package/dist/application/user/user.hook.d.ts.map +0 -1
- package/dist/application/user/user.store.d.ts.map +0 -1
- package/dist/auth/act-as.context.d.ts.map +0 -1
- package/dist/auth/auth.hook.d.ts.map +0 -1
- package/dist/auth/can.hook.d.ts.map +0 -1
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/self.hook.d.ts.map +0 -1
- package/dist/auth/session-kernel.d.ts.map +0 -1
- package/dist/components/astrale.d.ts.map +0 -1
- package/dist/components/boundaries.d.ts.map +0 -1
- package/dist/components/can.d.ts.map +0 -1
- package/dist/components/index.d.ts.map +0 -1
- package/dist/graph/action.d.ts.map +0 -1
- package/dist/graph/async.d.ts.map +0 -1
- package/dist/graph/call/call.hook.d.ts.map +0 -1
- package/dist/graph/call/stream.hook.d.ts.map +0 -1
- package/dist/graph/graph.context.d.ts.map +0 -1
- package/dist/graph/guards.error.d.ts.map +0 -1
- package/dist/graph/index.d.ts.map +0 -1
- package/dist/graph/memory/read/envelope.d.ts.map +0 -1
- package/dist/graph/memory/read/idle.d.ts.map +0 -1
- package/dist/graph/query-definition.hook.d.ts.map +0 -1
- package/dist/graph/resource.d.ts.map +0 -1
- package/dist/graph/store.d.ts.map +0 -1
- package/dist/host/actions.hook.d.ts.map +0 -1
- package/dist/host/components.d.ts.map +0 -1
- package/dist/host/index.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/intents/emit-intent.hook.d.ts.map +0 -1
- package/dist/intents/envelope.d.ts.map +0 -1
- package/dist/intents/index.d.ts.map +0 -1
- package/dist/intents/listen-intent.hook.d.ts.map +0 -1
- package/dist/intents/reply.d.ts.map +0 -1
- package/dist/intents/resolve-intent-target.d.ts.map +0 -1
- package/dist/intents/send-intent.hook.d.ts.map +0 -1
- package/dist/navigation/adapters/adapter.d.ts.map +0 -1
- package/dist/navigation/adapters/memory.adapter.d.ts.map +0 -1
- package/dist/navigation/adapters/url.adapter.d.ts.map +0 -1
- package/dist/navigation/codec.d.ts.map +0 -1
- package/dist/navigation/history.d.ts.map +0 -1
- package/dist/navigation/hooks/ancestors.hook.d.ts.map +0 -1
- package/dist/navigation/hooks/location.hook.d.ts.map +0 -1
- package/dist/navigation/hooks/navigate.hook.d.ts.map +0 -1
- package/dist/navigation/hooks/scope.hook.d.ts.map +0 -1
- package/dist/navigation/index.d.ts.map +0 -1
- package/dist/navigation/link.d.ts.map +0 -1
- package/dist/navigation/location.d.ts.map +0 -1
- package/dist/navigation/scope.context.d.ts.map +0 -1
- package/dist/navigation/snapshot.d.ts.map +0 -1
- package/dist/navigation/view-key.d.ts.map +0 -1
- package/dist/schema/action.hook.d.ts.map +0 -1
- package/dist/schema/domain.hook.d.ts.map +0 -1
- package/dist/schema/index.d.ts.map +0 -1
- package/dist/schema/kernel.hook.d.ts.map +0 -1
- package/dist/schema/mutation.hook.d.ts.map +0 -1
- package/dist/schema/object.hook.d.ts.map +0 -1
- package/dist/schema/relation.hook.d.ts.map +0 -1
- package/dist/selection/index.d.ts.map +0 -1
- package/dist/selection/live.d.ts.map +0 -1
- package/dist/selection/scope.context.d.ts.map +0 -1
- package/dist/selection/selection.hook.d.ts.map +0 -1
- package/dist/session/boot/boot.d.ts.map +0 -1
- package/dist/session/boot/ownership.d.ts.map +0 -1
- package/dist/session/boot/status.d.ts.map +0 -1
- package/dist/session/connection/connection.hook.d.ts.map +0 -1
- package/dist/session/connection/connection.store.d.ts.map +0 -1
- package/dist/session/index.d.ts.map +0 -1
- package/dist/session/kernel-client.hook.d.ts.map +0 -1
- package/dist/session/kernel-instance.hook.d.ts.map +0 -1
- package/dist/session/provider.d.ts.map +0 -1
- package/dist/session/session.context.d.ts.map +0 -1
- package/dist/session/shell.hook.d.ts.map +0 -1
- package/dist/window/adopt.d.ts.map +0 -1
- package/dist/window/hooks/close-guard.hook.d.ts.map +0 -1
- package/dist/window/hooks/target-node.hook.d.ts.map +0 -1
- package/dist/window/hooks/views-for.hook.d.ts.map +0 -1
- package/dist/window/hooks/window.hook.d.ts.map +0 -1
- package/dist/window/hooks/windows.hook.d.ts.map +0 -1
- package/dist/window/host.d.ts.map +0 -1
- package/dist/window/hub.d.ts.map +0 -1
- package/dist/window/index.d.ts.map +0 -1
- package/dist/window/lifecycle/mount.d.ts.map +0 -1
- package/dist/window/lifecycle/states.d.ts.map +0 -1
- package/dist/window/placement.d.ts.map +0 -1
- package/dist/window/stage.d.ts.map +0 -1
package/dist/schema/index.js
CHANGED
|
@@ -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
|
package/dist/selection/live.d.ts
CHANGED
|
@@ -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
|
|
@@ -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
|
package/dist/session/index.d.ts
CHANGED
|
@@ -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
|
package/dist/window/adopt.d.ts
CHANGED
|
@@ -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
|
package/dist/window/host.d.ts
CHANGED
package/dist/window/hub.d.ts
CHANGED
package/dist/window/index.d.ts
CHANGED
|
@@ -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
|
|
@@ -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
|
package/dist/window/stage.d.ts
CHANGED
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
|
-
"
|
|
29
|
-
"
|
|
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": "
|
|
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.
|
|
37
|
+
"@types/node": "^26.2.0",
|
|
36
38
|
"@types/react": "^19.2.0",
|
|
37
39
|
"@types/react-dom": "^19.2.0",
|
|
38
|
-
"@
|
|
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": "
|
|
44
|
-
"vite": "
|
|
45
|
-
"vitest": "
|
|
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.
|
|
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": "
|
|
55
|
+
"build": "tsc",
|
|
57
56
|
"clean": "rm -rf dist *.tsbuildinfo",
|
|
58
|
-
"typecheck": "
|
|
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: {
|
|
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
|
|
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 =
|
|
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
|
-
|
|
43
|
-
|
|
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,
|
|
51
|
-
definition:
|
|
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
|
|
56
|
-
[QUERY_REFRESH]: () => {
|
|
57
|
-
const
|
|
58
|
-
|
|
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
|
+
}
|
package/src/schema/index.ts
CHANGED
|
@@ -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"}
|