@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.
- package/dist/application/apps/app-host.d.ts +4 -15
- package/dist/application/apps/app-host.d.ts.map +1 -1
- package/dist/application/apps/app-host.js +1 -1
- package/dist/application/apps/apps.hook.d.ts +7 -4
- package/dist/application/apps/apps.hook.d.ts.map +1 -1
- package/dist/application/apps/apps.hook.js +10 -2
- package/dist/application/apps/domains.hook.d.ts +1 -1
- package/dist/application/apps/domains.hook.d.ts.map +1 -1
- package/dist/application/apps/domains.hook.js +1 -1
- package/dist/application/apps/open-app.hook.d.ts +2 -3
- package/dist/application/apps/open-app.hook.d.ts.map +1 -1
- package/dist/application/index.d.ts +2 -4
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +2 -3
- package/dist/application/spaces/space.hook.d.ts +2 -2
- package/dist/application/spaces/space.hook.d.ts.map +1 -1
- package/dist/application/spaces/space.hook.js +2 -2
- package/dist/application/spaces/spaces.hook.d.ts +2 -3
- package/dist/application/spaces/spaces.hook.d.ts.map +1 -1
- package/dist/application/spaces/spaces.hook.js +10 -3
- package/dist/auth/act-as.context.d.ts +15 -32
- package/dist/auth/act-as.context.d.ts.map +1 -1
- package/dist/auth/act-as.context.js +22 -66
- package/dist/auth/auth.hook.d.ts +1 -0
- package/dist/auth/auth.hook.d.ts.map +1 -1
- package/dist/auth/auth.hook.js +2 -22
- package/dist/auth/can.hook.d.ts +10 -38
- package/dist/auth/can.hook.d.ts.map +1 -1
- package/dist/auth/can.hook.js +35 -110
- package/dist/auth/index.d.ts +1 -0
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/self.hook.d.ts +2 -2
- package/dist/auth/self.hook.d.ts.map +1 -1
- package/dist/auth/self.hook.js +0 -7
- package/dist/auth/session-kernel.d.ts +2 -3
- package/dist/auth/session-kernel.d.ts.map +1 -1
- package/dist/auth/session-kernel.js +4 -13
- package/dist/components/boundaries.d.ts +47 -0
- package/dist/components/boundaries.d.ts.map +1 -0
- package/dist/components/boundaries.js +55 -0
- package/dist/components/can.d.ts +11 -0
- package/dist/components/can.d.ts.map +1 -0
- package/dist/components/can.js +5 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +4 -0
- package/dist/components/mount-domain-frontend.d.ts +22 -0
- package/dist/components/mount-domain-frontend.d.ts.map +1 -0
- package/dist/components/mount-domain-frontend.js +85 -0
- package/dist/components/view-app.d.ts +16 -0
- package/dist/components/view-app.d.ts.map +1 -0
- package/dist/components/view-app.js +16 -0
- package/dist/graph/call/call.hook.d.ts +8 -18
- package/dist/graph/call/call.hook.d.ts.map +1 -1
- package/dist/graph/call/call.hook.js +7 -13
- package/dist/graph/call/stream.hook.d.ts +12 -20
- package/dist/graph/call/stream.hook.d.ts.map +1 -1
- package/dist/graph/call/stream.hook.js +55 -111
- package/dist/graph/graph.context.d.ts +4 -3
- package/dist/graph/graph.context.d.ts.map +1 -1
- package/dist/graph/graph.context.js +2 -8
- package/dist/graph/guards.error.d.ts +7 -8
- package/dist/graph/guards.error.d.ts.map +1 -1
- package/dist/graph/guards.error.js +11 -7
- package/dist/graph/index.d.ts +8 -16
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/index.js +3 -7
- package/dist/graph/memory/read/envelope.d.ts +22 -54
- package/dist/graph/memory/read/envelope.d.ts.map +1 -1
- package/dist/graph/memory/read/envelope.js +26 -20
- package/dist/graph/memory/read/idle.d.ts +1 -15
- package/dist/graph/memory/read/idle.d.ts.map +1 -1
- package/dist/graph/memory/read/idle.js +4 -13
- package/dist/graph/query-definition.hook.d.ts +11 -0
- package/dist/graph/query-definition.hook.d.ts.map +1 -0
- package/dist/graph/query-definition.hook.js +205 -0
- package/dist/graph/resource.d.ts +34 -0
- package/dist/graph/resource.d.ts.map +1 -0
- package/dist/graph/resource.js +244 -0
- package/dist/graph/store.d.ts +25 -0
- package/dist/graph/store.d.ts.map +1 -0
- package/dist/graph/store.js +69 -0
- package/dist/host/actions.hook.d.ts +34 -0
- package/dist/host/actions.hook.d.ts.map +1 -0
- package/dist/host/actions.hook.js +125 -0
- package/dist/host/components.d.ts +15 -0
- package/dist/host/components.d.ts.map +1 -0
- package/dist/host/components.js +14 -0
- package/dist/host/index.d.ts +5 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +3 -0
- package/dist/index.d.ts +26 -37
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +20 -31
- package/dist/intents/envelope.d.ts +7 -19
- package/dist/intents/envelope.d.ts.map +1 -1
- package/dist/intents/envelope.js +2 -3
- package/dist/intents/send-intent.hook.d.ts +5 -7
- package/dist/intents/send-intent.hook.d.ts.map +1 -1
- package/dist/intents/send-intent.hook.js +17 -75
- package/dist/navigation/adapters/adapter.d.ts +5 -0
- package/dist/navigation/adapters/adapter.d.ts.map +1 -1
- package/dist/navigation/adapters/memory.adapter.d.ts.map +1 -1
- package/dist/navigation/adapters/memory.adapter.js +4 -0
- package/dist/navigation/adapters/url.adapter.d.ts.map +1 -1
- package/dist/navigation/adapters/url.adapter.js +57 -10
- package/dist/navigation/codec.d.ts +60 -0
- package/dist/navigation/codec.d.ts.map +1 -0
- package/dist/navigation/codec.js +121 -0
- package/dist/navigation/history.d.ts +11 -9
- package/dist/navigation/history.d.ts.map +1 -1
- package/dist/navigation/history.js +6 -8
- package/dist/navigation/hooks/ancestors.hook.d.ts +5 -7
- package/dist/navigation/hooks/ancestors.hook.d.ts.map +1 -1
- package/dist/navigation/hooks/ancestors.hook.js +7 -51
- package/dist/navigation/hooks/location.hook.d.ts.map +1 -1
- package/dist/navigation/hooks/location.hook.js +4 -6
- package/dist/navigation/hooks/scope.hook.d.ts.map +1 -1
- package/dist/navigation/hooks/scope.hook.js +4 -6
- package/dist/navigation/index.d.ts +4 -2
- package/dist/navigation/index.d.ts.map +1 -1
- package/dist/navigation/index.js +2 -1
- package/dist/navigation/link.d.ts +12 -0
- package/dist/navigation/link.d.ts.map +1 -1
- package/dist/navigation/link.js +13 -2
- package/dist/navigation/location.d.ts +13 -40
- package/dist/navigation/location.d.ts.map +1 -1
- package/dist/navigation/location.js +14 -76
- package/dist/navigation/scope.context.d.ts +17 -26
- package/dist/navigation/scope.context.d.ts.map +1 -1
- package/dist/navigation/scope.context.js +140 -108
- package/dist/navigation/snapshot.d.ts +14 -19
- package/dist/navigation/snapshot.d.ts.map +1 -1
- package/dist/navigation/snapshot.js +48 -44
- package/dist/schema/action.hook.d.ts +44 -0
- package/dist/schema/action.hook.d.ts.map +1 -0
- package/dist/schema/action.hook.js +72 -0
- package/dist/schema/domain.hook.d.ts +12 -7
- package/dist/schema/domain.hook.d.ts.map +1 -1
- package/dist/schema/domain.hook.js +101 -4
- package/dist/schema/index.d.ts +9 -8
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +5 -7
- package/dist/schema/kernel.hook.d.ts +4 -9
- package/dist/schema/kernel.hook.d.ts.map +1 -1
- package/dist/schema/kernel.hook.js +4 -6
- package/dist/schema/mutation.hook.d.ts +9 -0
- package/dist/schema/mutation.hook.d.ts.map +1 -0
- package/dist/schema/mutation.hook.js +41 -0
- package/dist/schema/object.hook.d.ts +16 -0
- package/dist/schema/object.hook.d.ts.map +1 -0
- package/dist/schema/object.hook.js +46 -0
- package/dist/schema/relation.hook.d.ts +46 -0
- package/dist/schema/relation.hook.d.ts.map +1 -0
- package/dist/schema/relation.hook.js +136 -0
- package/dist/selection/live.d.ts +9 -17
- package/dist/selection/live.d.ts.map +1 -1
- package/dist/selection/live.js +65 -112
- package/dist/selection/scope.context.js +5 -4
- package/dist/session/boot/boot.d.ts +1 -13
- package/dist/session/boot/boot.d.ts.map +1 -1
- package/dist/session/boot/boot.js +9 -27
- package/dist/session/index.d.ts +1 -0
- package/dist/session/index.d.ts.map +1 -1
- package/dist/session/kernel-instance.hook.d.ts +1 -4
- package/dist/session/kernel-instance.hook.d.ts.map +1 -1
- package/dist/session/kernel-instance.hook.js +1 -5
- package/dist/session/provider.d.ts +9 -23
- package/dist/session/provider.d.ts.map +1 -1
- package/dist/session/provider.js +29 -75
- package/dist/session/session.context.d.ts +5 -0
- package/dist/session/session.context.d.ts.map +1 -1
- package/dist/window/adopt.d.ts +0 -1
- package/dist/window/adopt.d.ts.map +1 -1
- package/dist/window/hooks/target-node.hook.d.ts +10 -6
- package/dist/window/hooks/target-node.hook.d.ts.map +1 -1
- package/dist/window/hooks/target-node.hook.js +14 -72
- package/dist/window/hooks/views-for.hook.d.ts +4 -3
- package/dist/window/hooks/views-for.hook.d.ts.map +1 -1
- package/dist/window/hooks/views-for.hook.js +6 -22
- package/dist/window/hooks/windows.hook.d.ts.map +1 -1
- package/dist/window/hooks/windows.hook.js +3 -4
- package/dist/window/host.d.ts +9 -11
- package/dist/window/host.d.ts.map +1 -1
- package/dist/window/host.js +26 -62
- package/dist/window/hub.d.ts +2 -0
- package/dist/window/hub.d.ts.map +1 -1
- package/dist/window/hub.js +33 -0
- package/dist/window/index.d.ts +2 -2
- package/dist/window/index.d.ts.map +1 -1
- package/dist/window/index.js +2 -2
- package/dist/window/lifecycle/mount.d.ts +5 -44
- package/dist/window/lifecycle/mount.d.ts.map +1 -1
- package/dist/window/lifecycle/mount.js +14 -120
- package/dist/window/lifecycle/states.d.ts +0 -5
- package/dist/window/lifecycle/states.d.ts.map +1 -1
- package/package.json +9 -8
- package/src/application/apps/app-host.tsx +11 -15
- package/src/application/apps/apps.hook.ts +13 -6
- package/src/application/apps/domains.hook.ts +1 -1
- package/src/application/apps/open-app.hook.ts +3 -4
- package/src/application/index.ts +4 -6
- package/src/application/spaces/space.hook.ts +5 -6
- package/src/application/spaces/spaces.hook.ts +14 -9
- package/src/auth/act-as.context.tsx +37 -91
- package/src/auth/auth.hook.ts +2 -30
- package/src/auth/can.hook.ts +44 -135
- package/src/auth/index.ts +1 -0
- package/src/auth/self.hook.ts +2 -9
- package/src/auth/session-kernel.ts +6 -16
- package/src/components/boundaries.tsx +113 -0
- package/src/components/can.tsx +16 -0
- package/src/components/index.ts +14 -0
- package/src/components/mount-domain-frontend.tsx +158 -0
- package/src/components/view-app.tsx +49 -0
- package/src/graph/call/call.hook.ts +22 -27
- package/src/graph/call/stream.hook.ts +66 -143
- package/src/graph/graph.context.ts +6 -11
- package/src/graph/guards.error.ts +17 -55
- package/src/graph/index.ts +23 -17
- package/src/graph/memory/read/envelope.ts +40 -65
- package/src/graph/memory/read/idle.ts +5 -18
- package/src/graph/query-definition.hook.ts +270 -0
- package/src/graph/resource.ts +358 -0
- package/src/graph/store.ts +97 -0
- package/src/host/actions.hook.ts +165 -0
- package/src/host/components.tsx +29 -0
- package/src/host/index.ts +17 -0
- package/src/index.ts +136 -124
- package/src/intents/envelope.ts +7 -23
- package/src/intents/send-intent.hook.ts +24 -79
- package/src/navigation/adapters/adapter.ts +3 -0
- package/src/navigation/adapters/memory.adapter.ts +4 -0
- package/src/navigation/adapters/url.adapter.ts +48 -8
- package/src/navigation/codec.ts +190 -0
- package/src/navigation/history.ts +20 -11
- package/src/navigation/hooks/ancestors.hook.ts +10 -60
- package/src/navigation/hooks/location.hook.ts +4 -6
- package/src/navigation/hooks/scope.hook.ts +4 -6
- package/src/navigation/index.ts +18 -2
- package/src/navigation/link.tsx +27 -2
- package/src/navigation/location.ts +26 -93
- package/src/navigation/scope.context.tsx +151 -136
- package/src/navigation/snapshot.ts +69 -50
- package/src/schema/action.hook.ts +146 -0
- package/src/schema/domain.hook.ts +127 -11
- package/src/schema/index.ts +9 -30
- package/src/schema/kernel.hook.ts +6 -13
- package/src/schema/mutation.hook.ts +63 -0
- package/src/schema/object.hook.ts +85 -0
- package/src/schema/relation.hook.ts +253 -0
- package/src/selection/live.ts +75 -125
- package/src/selection/scope.context.tsx +4 -4
- package/src/session/boot/boot.ts +8 -33
- package/src/session/index.ts +1 -0
- package/src/session/kernel-instance.hook.ts +2 -11
- package/src/session/provider.tsx +34 -103
- package/src/session/session.context.ts +6 -0
- package/src/window/adopt.ts +0 -1
- package/src/window/hooks/target-node.hook.ts +20 -85
- package/src/window/hooks/views-for.hook.ts +12 -25
- package/src/window/hooks/windows.hook.ts +3 -4
- package/src/window/host.tsx +35 -77
- package/src/window/hub.ts +33 -0
- package/src/window/index.ts +3 -3
- package/src/window/lifecycle/mount.ts +15 -160
- package/src/window/lifecycle/states.ts +1 -5
- package/dist/application/roles.hook.d.ts +0 -7
- package/dist/application/roles.hook.d.ts.map +0 -1
- package/dist/application/roles.hook.js +0 -23
- package/dist/graph/memory/base.d.ts +0 -21
- package/dist/graph/memory/base.d.ts.map +0 -1
- package/dist/graph/memory/base.js +0 -33
- package/dist/graph/memory/read/read.d.ts +0 -9
- package/dist/graph/memory/read/read.d.ts.map +0 -1
- package/dist/graph/memory/read/read.js +0 -87
- package/dist/graph/memory/scope.d.ts +0 -7
- package/dist/graph/memory/scope.d.ts.map +0 -1
- package/dist/graph/memory/scope.js +0 -25
- package/dist/graph/mutate/move.hook.d.ts +0 -7
- package/dist/graph/mutate/move.hook.d.ts.map +0 -1
- package/dist/graph/mutate/move.hook.js +0 -49
- package/dist/graph/mutate/mutate.hook.d.ts +0 -17
- package/dist/graph/mutate/mutate.hook.d.ts.map +0 -1
- package/dist/graph/mutate/mutate.hook.js +0 -45
- package/dist/graph/query/children.hook.d.ts +0 -29
- package/dist/graph/query/children.hook.d.ts.map +0 -1
- package/dist/graph/query/children.hook.js +0 -64
- package/dist/graph/query/graph.hook.d.ts +0 -9
- package/dist/graph/query/graph.hook.d.ts.map +0 -1
- package/dist/graph/query/graph.hook.js +0 -5
- package/dist/graph/query/neighbors.hook.d.ts +0 -7
- package/dist/graph/query/neighbors.hook.d.ts.map +0 -1
- package/dist/graph/query/neighbors.hook.js +0 -104
- package/dist/graph/query/node.hook.d.ts +0 -14
- package/dist/graph/query/node.hook.d.ts.map +0 -1
- package/dist/graph/query/node.hook.js +0 -43
- package/dist/graph/query/query.hook.d.ts +0 -14
- package/dist/graph/query/query.hook.d.ts.map +0 -1
- package/dist/graph/query/query.hook.js +0 -23
- package/dist/schema/bind-read.d.ts +0 -37
- package/dist/schema/bind-read.d.ts.map +0 -1
- package/dist/schema/bind-read.js +0 -205
- package/dist/schema/binding.d.ts +0 -21
- package/dist/schema/binding.d.ts.map +0 -1
- package/dist/schema/binding.js +0 -99
- package/dist/schema/function.hook.d.ts +0 -9
- package/dist/schema/function.hook.d.ts.map +0 -1
- package/dist/schema/function.hook.js +0 -40
- package/dist/schema/method.hook.d.ts +0 -14
- package/dist/schema/method.hook.d.ts.map +0 -1
- package/dist/schema/method.hook.js +0 -49
- package/dist/schema/tag.d.ts +0 -11
- package/dist/schema/tag.d.ts.map +0 -1
- package/dist/schema/tag.js +0 -11
- package/dist/schema/types.d.ts +0 -73
- package/dist/schema/types.d.ts.map +0 -1
- package/dist/schema/types.js +0 -1
- package/dist/schema/write.d.ts +0 -16
- package/dist/schema/write.d.ts.map +0 -1
- package/dist/schema/write.js +0 -56
- package/src/application/roles.hook.ts +0 -41
- package/src/graph/memory/base.ts +0 -50
- package/src/graph/memory/read/read.ts +0 -103
- package/src/graph/memory/scope.ts +0 -29
- package/src/graph/mutate/move.hook.ts +0 -70
- package/src/graph/mutate/mutate.hook.ts +0 -69
- package/src/graph/query/children.hook.ts +0 -136
- package/src/graph/query/graph.hook.ts +0 -13
- package/src/graph/query/neighbors.hook.ts +0 -159
- package/src/graph/query/node.hook.ts +0 -83
- package/src/graph/query/query.hook.ts +0 -42
- package/src/schema/bind-read.ts +0 -319
- package/src/schema/binding.ts +0 -146
- package/src/schema/function.hook.ts +0 -68
- package/src/schema/method.hook.ts +0 -103
- package/src/schema/tag.ts +0 -19
- package/src/schema/types.ts +0 -150
- package/src/schema/write.ts +0 -96
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BoundInstanceOf, Definition, EdgeEndpointAcceptedDefinitionsOf } from '@astrale-os/sdk/domain';
|
|
2
|
+
import type { LinkedCountOf } from '@astrale-os/sdk/query';
|
|
3
|
+
import type { GraphResource } from '../graph/resource.js';
|
|
4
|
+
type DefinitionCoordinates = Pick<Definition<'class' | 'interface'>, 'kind' | 'origin' | 'name' | 'key' | 'schemaRef' | 'definition'>;
|
|
5
|
+
type NodeDefinition = DefinitionCoordinates & {
|
|
6
|
+
readonly family: 'node';
|
|
7
|
+
};
|
|
8
|
+
type EdgeDefinition = DefinitionCoordinates & {
|
|
9
|
+
readonly family: 'edge';
|
|
10
|
+
};
|
|
11
|
+
type EndpointRole = 'source' | 'target';
|
|
12
|
+
type Opposite<Role extends EndpointRole> = Role extends 'source' ? 'target' : 'source';
|
|
13
|
+
type Accepted<Definition extends EdgeDefinition, Role extends EndpointRole> = EdgeEndpointAcceptedDefinitionsOf<Definition, Opposite<Role>>;
|
|
14
|
+
type StartingDefinition<Relation extends EdgeDefinition, Role extends EndpointRole> = EdgeEndpointAcceptedDefinitionsOf<Relation, Role> & NodeDefinition;
|
|
15
|
+
type RelatedDefinition<Relation extends EdgeDefinition, Role extends EndpointRole> = Accepted<Relation, Role> & NodeDefinition;
|
|
16
|
+
type EffectiveCardinality<Relation extends EdgeDefinition, Role extends EndpointRole, To extends RelatedDefinition<Relation, Role>> = LinkedCountOf<Relation, Role, To>;
|
|
17
|
+
export interface RelationUnavailable {
|
|
18
|
+
readonly kind: 'required-hidden-or-invalid';
|
|
19
|
+
readonly cardinality: '1' | '1..*';
|
|
20
|
+
}
|
|
21
|
+
export declare class RelationUnavailableError extends Error {
|
|
22
|
+
readonly unavailable: RelationUnavailable;
|
|
23
|
+
readonly code: 'SHELL_REACT_RELATION_UNAVAILABLE';
|
|
24
|
+
constructor(unavailable: RelationUnavailable);
|
|
25
|
+
}
|
|
26
|
+
export type RelationResource<T, C extends string> = C extends '1' | '0..1' ? GraphResource<T | null> & {
|
|
27
|
+
readonly cardinality: C;
|
|
28
|
+
readonly unavailable?: RelationUnavailable;
|
|
29
|
+
require(): T;
|
|
30
|
+
} : GraphResource<readonly T[]> & {
|
|
31
|
+
readonly cardinality: C;
|
|
32
|
+
readonly unavailable?: RelationUnavailable;
|
|
33
|
+
require(): readonly T[];
|
|
34
|
+
};
|
|
35
|
+
export interface RelationOptions<Role extends EndpointRole, To> {
|
|
36
|
+
readonly from: Role;
|
|
37
|
+
/** Exact rich opposite-endpoint definition used to admit and brand returned nodes. */
|
|
38
|
+
readonly to: To;
|
|
39
|
+
readonly page?: {
|
|
40
|
+
readonly size: number;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/** Traverse one exact rich Edge definition with endpoint and cardinality inference. */
|
|
44
|
+
export declare function useRelation<Definition extends EdgeDefinition, Role extends EndpointRole, To extends RelatedDefinition<Definition, Role>>(definition: Definition, source: BoundInstanceOf<StartingDefinition<Definition, Role>> | null | undefined, options: RelationOptions<Role, To>): RelationResource<BoundInstanceOf<To>, EffectiveCardinality<Definition, Role, To>>;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=relation.hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relation.hook.d.ts","sourceRoot":"","sources":["../../src/schema/relation.hook.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,iCAAiC,EAClC,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAO1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAKzD,KAAK,qBAAqB,GAAG,IAAI,CAC/B,UAAU,CAAC,OAAO,GAAG,WAAW,CAAC,EACjC,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,WAAW,GAAG,YAAY,CAChE,CAAA;AACD,KAAK,cAAc,GAAG,qBAAqB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AACzE,KAAK,cAAc,GAAG,qBAAqB,GAAG;IAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AACzE,KAAK,YAAY,GAAG,QAAQ,GAAG,QAAQ,CAAA;AAWvC,KAAK,QAAQ,CAAC,IAAI,SAAS,YAAY,IAAI,IAAI,SAAS,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAA;AACtF,KAAK,QAAQ,CACX,UAAU,SAAS,cAAc,EACjC,IAAI,SAAS,YAAY,IACvB,iCAAiC,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAA;AACjE,KAAK,kBAAkB,CACrB,QAAQ,SAAS,cAAc,EAC/B,IAAI,SAAS,YAAY,IACvB,iCAAiC,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,cAAc,CAAA;AACtE,KAAK,iBAAiB,CAAC,QAAQ,SAAS,cAAc,EAAE,IAAI,SAAS,YAAY,IAAI,QAAQ,CAC3F,QAAQ,EACR,IAAI,CACL,GACC,cAAc,CAAA;AAChB,KAAK,oBAAoB,CACvB,QAAQ,SAAS,cAAc,EAC/B,IAAI,SAAS,YAAY,EACzB,EAAE,SAAS,iBAAiB,CAAC,QAAQ,EAAE,IAAI,CAAC,IAC1C,aAAa,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAA;AAErC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAA;IAC3C,QAAQ,CAAC,WAAW,EAAE,GAAG,GAAG,MAAM,CAAA;CACnC;AAED,qBAAa,wBAAyB,SAAQ,KAAK;IAErC,QAAQ,CAAC,WAAW,EAAE,mBAAmB;IADrD,QAAQ,CAAC,IAAI,EAAG,kCAAkC,CAAS;IAC3D,YAAqB,WAAW,EAAE,mBAAmB,EAKpD;CACF;AAED,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,GAAG,GAAG,MAAM,GACtE,aAAa,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG;IACxB,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,mBAAmB,CAAA;IAC1C,OAAO,IAAI,CAAC,CAAA;CACb,GACD,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC,GAAG;IAC5B,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,mBAAmB,CAAA;IAC1C,OAAO,IAAI,SAAS,CAAC,EAAE,CAAA;CACxB,CAAA;AAEL,MAAM,WAAW,eAAe,CAAC,IAAI,SAAS,YAAY,EAAE,EAAE;IAC5D,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAA;IACf,QAAQ,CAAC,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAA;CAC1C;AAED,uFAAuF;AACvF,wBAAgB,WAAW,CACzB,UAAU,SAAS,cAAc,EACjC,IAAI,SAAS,YAAY,EACzB,EAAE,SAAS,iBAAiB,CAAC,UAAU,EAAE,IAAI,CAAC,EAE9C,UAAU,EAAE,UAAU,EACtB,MAAM,EAAE,eAAe,CAAC,kBAAkB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,EAChF,OAAO,EAAE,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,GACjC,gBAAgB,CAAC,eAAe,CAAC,EAAE,CAAC,EAAE,oBAAoB,CAAC,UAAU,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CA6EnF"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { NodeId } from '@astrale-os/sdk/graph/node';
|
|
2
|
+
import { Path } from '@astrale-os/sdk/graph/path';
|
|
3
|
+
import { Query } from '@astrale-os/sdk/query';
|
|
4
|
+
import { useCallback, useMemo } from 'react';
|
|
5
|
+
import { useStoreResource } from '../graph/resource.js';
|
|
6
|
+
import { bindingFor } from './domain.hook.js';
|
|
7
|
+
export class RelationUnavailableError extends Error {
|
|
8
|
+
unavailable;
|
|
9
|
+
code = 'SHELL_REACT_RELATION_UNAVAILABLE';
|
|
10
|
+
constructor(unavailable) {
|
|
11
|
+
super(`Required relation (${unavailable.cardinality}) is hidden or violates the installed schema.`);
|
|
12
|
+
this.unavailable = unavailable;
|
|
13
|
+
this.name = 'RelationUnavailableError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
/** Traverse one exact rich Edge definition with endpoint and cardinality inference. */
|
|
17
|
+
export function useRelation(definition, source, options) {
|
|
18
|
+
const binding = bindingFor(definition);
|
|
19
|
+
if (source !== null && source !== undefined) {
|
|
20
|
+
admitSource(binding, definition, options.from, source);
|
|
21
|
+
}
|
|
22
|
+
admitRelatedDefinition(binding, definition, options.from, options.to);
|
|
23
|
+
const path = source === null || source === undefined ? null : Path.id(NodeId(source.id));
|
|
24
|
+
const query = useMemo(() => {
|
|
25
|
+
if (path === null)
|
|
26
|
+
return null;
|
|
27
|
+
const root = Query.from({ kind: 'node', paths: [path], binding: 'relation_source' });
|
|
28
|
+
const admitted = root.filter({ satisfies: source.$.definition.schemaRef });
|
|
29
|
+
const expanded = admitted.expand({
|
|
30
|
+
via: [definition.schemaRef],
|
|
31
|
+
direction: options.from === 'source' ? 'outgoing' : 'incoming',
|
|
32
|
+
});
|
|
33
|
+
return expanded
|
|
34
|
+
.filter({ satisfies: options.to.schemaRef })
|
|
35
|
+
.select({ kind: 'graph', binding: expanded.node });
|
|
36
|
+
}, [definition, options.from, options.to, path?.raw, source]);
|
|
37
|
+
const cardinality = effectiveCardinality(binding, definition, options.from, options.to);
|
|
38
|
+
const project = useCallback((response) => {
|
|
39
|
+
const result = response.result;
|
|
40
|
+
if (result.kind !== 'graph' || result.selection.kind !== 'node') {
|
|
41
|
+
return cardinality === '0..1'
|
|
42
|
+
? null
|
|
43
|
+
: cardinality === '0..*'
|
|
44
|
+
? Object.freeze([])
|
|
45
|
+
: undefined;
|
|
46
|
+
}
|
|
47
|
+
const byId = new Map(result.graph.nodes.map((node) => [node.id, node]));
|
|
48
|
+
const values = result.selection.ids.flatMap((id) => {
|
|
49
|
+
const node = byId.get(id);
|
|
50
|
+
if (node === undefined)
|
|
51
|
+
return [];
|
|
52
|
+
const bind = binding.$.bind;
|
|
53
|
+
return [bind(options.to, node)];
|
|
54
|
+
});
|
|
55
|
+
if (cardinality === '0..1')
|
|
56
|
+
return values[0] ?? null;
|
|
57
|
+
if (cardinality === '1')
|
|
58
|
+
return values[0];
|
|
59
|
+
if (cardinality === '1..*' && values.length === 0)
|
|
60
|
+
return undefined;
|
|
61
|
+
return Object.freeze(values);
|
|
62
|
+
}, [binding, cardinality, options.to, query]);
|
|
63
|
+
const resource = useStoreResource(query, options.page?.size ?? 50, project);
|
|
64
|
+
const unavailable = (cardinality === '1' &&
|
|
65
|
+
resource.data === undefined &&
|
|
66
|
+
resource.state !== 'idle' &&
|
|
67
|
+
resource.state !== 'loading') ||
|
|
68
|
+
(cardinality === '1..*' &&
|
|
69
|
+
resource.data === undefined &&
|
|
70
|
+
resource.state !== 'idle' &&
|
|
71
|
+
resource.state !== 'loading')
|
|
72
|
+
? Object.freeze({ kind: 'required-hidden-or-invalid', cardinality })
|
|
73
|
+
: undefined;
|
|
74
|
+
const require = () => {
|
|
75
|
+
if (unavailable !== undefined)
|
|
76
|
+
throw new RelationUnavailableError(unavailable);
|
|
77
|
+
if (resource.data === undefined || resource.data === null) {
|
|
78
|
+
throw new Error('Relation resource is not settled with an available value.');
|
|
79
|
+
}
|
|
80
|
+
return resource.data;
|
|
81
|
+
};
|
|
82
|
+
return Object.freeze({
|
|
83
|
+
...resource,
|
|
84
|
+
cardinality,
|
|
85
|
+
...(unavailable === undefined ? {} : { unavailable }),
|
|
86
|
+
require,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
function admitSource(binding, relation, from, source) {
|
|
90
|
+
const accepted = edgeEndpoints(relation)[from].accepts;
|
|
91
|
+
const matches = accepted.some((ref) => {
|
|
92
|
+
const candidate = binding.$.inspect(ref);
|
|
93
|
+
return source.$.definition.satisfies(candidate);
|
|
94
|
+
});
|
|
95
|
+
if (!matches)
|
|
96
|
+
throw new TypeError('Relation source does not satisfy the selected endpoint.');
|
|
97
|
+
}
|
|
98
|
+
function endpointCardinality(definition, side) {
|
|
99
|
+
const endpoint = edgeEndpoints(definition)[side];
|
|
100
|
+
const cardinality = side === 'source' ? endpoint.outgoing : endpoint.incoming;
|
|
101
|
+
if (cardinality === undefined) {
|
|
102
|
+
throw new TypeError(`Relation ${side} endpoint does not expose its traversal cardinality.`);
|
|
103
|
+
}
|
|
104
|
+
return cardinality;
|
|
105
|
+
}
|
|
106
|
+
function effectiveCardinality(binding, relation, from, to) {
|
|
107
|
+
const base = endpointCardinality(relation, from);
|
|
108
|
+
if (base !== '1' && base !== '1..*') {
|
|
109
|
+
return base;
|
|
110
|
+
}
|
|
111
|
+
const opposite = from === 'source' ? 'target' : 'source';
|
|
112
|
+
const coversEndpoint = edgeEndpoints(relation)[opposite].accepts.every((ref) => {
|
|
113
|
+
const candidate = binding.$.inspect(ref);
|
|
114
|
+
return candidate.satisfies(to);
|
|
115
|
+
});
|
|
116
|
+
return (coversEndpoint ? base : base === '1' ? '0..1' : '0..*');
|
|
117
|
+
}
|
|
118
|
+
function admitRelatedDefinition(binding, relation, from, to) {
|
|
119
|
+
const opposite = from === 'source' ? 'target' : 'source';
|
|
120
|
+
const accepted = edgeEndpoints(relation)[opposite].accepts;
|
|
121
|
+
const matches = accepted.some((ref) => {
|
|
122
|
+
const candidate = binding.$.inspect(ref);
|
|
123
|
+
return to.satisfies(candidate);
|
|
124
|
+
});
|
|
125
|
+
if (!matches)
|
|
126
|
+
throw new TypeError('Relation target definition is not admitted by the opposite endpoint.');
|
|
127
|
+
}
|
|
128
|
+
function edgeEndpoints(relation) {
|
|
129
|
+
const declaration = relation.definition;
|
|
130
|
+
const source = declaration.endpoints?.source;
|
|
131
|
+
const target = declaration.endpoints?.target;
|
|
132
|
+
if (declaration.family !== 'edge' || source === undefined || target === undefined) {
|
|
133
|
+
throw new TypeError('Relation definition does not expose admitted Edge endpoints.');
|
|
134
|
+
}
|
|
135
|
+
return Object.freeze({ source, target });
|
|
136
|
+
}
|
package/dist/selection/live.d.ts
CHANGED
|
@@ -1,21 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
export type
|
|
4
|
-
export
|
|
5
|
-
/**
|
|
6
|
-
* The in-scope graph memory, structurally narrowed. Reads the base memory the
|
|
7
|
-
* provider seats in `GraphContext`, defensively so selection also works under a
|
|
8
|
-
* bare/fake context (tests) or before one is mounted.
|
|
9
|
-
*/
|
|
10
|
-
export declare function useMemory(): GraphMemory | null;
|
|
11
|
-
export interface LiveSnapshot {
|
|
1
|
+
import type { Node, NodeId } from '@astrale-os/sdk/graph/node';
|
|
2
|
+
export type SelectionNode = Node;
|
|
3
|
+
export type { NodeId };
|
|
4
|
+
export interface ResolvedSelection {
|
|
12
5
|
readonly aliveIds: readonly NodeId[];
|
|
13
6
|
readonly nodes: readonly SelectionNode[];
|
|
7
|
+
readonly pending: boolean;
|
|
8
|
+
readonly error: unknown;
|
|
9
|
+
refetch(): Promise<void>;
|
|
14
10
|
}
|
|
15
|
-
/**
|
|
16
|
-
|
|
17
|
-
* keeps a stable reference across renders when membership and node identities
|
|
18
|
-
* are unchanged (useSyncExternalStore contract).
|
|
19
|
-
*/
|
|
20
|
-
export declare function useLiveNodes(orderedIds: readonly NodeId[], memory: GraphMemory | null): LiveSnapshot;
|
|
11
|
+
/** Resolve selected identities through the authenticated GraphApi; no fake live subscription. */
|
|
12
|
+
export declare function useResolvedNodes(orderedIds: readonly NodeId[]): ResolvedSelection;
|
|
21
13
|
//# sourceMappingURL=live.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/selection/live.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/selection/live.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAA;AAO9D,MAAM,MAAM,aAAa,GAAG,IAAI,CAAA;AAChC,YAAY,EAAE,MAAM,EAAE,CAAA;AAEtB,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IACpC,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAA;IACxC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACzB;AAUD,iGAAiG;AACjG,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,GAAG,iBAAiB,CAgEjF"}
|
package/dist/selection/live.js
CHANGED
|
@@ -1,116 +1,69 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
* bare/fake context (tests) or before one is mounted.
|
|
33
|
-
*/
|
|
34
|
-
export function useMemory() {
|
|
35
|
-
const ctx = useContext(GraphContext);
|
|
36
|
-
return ctx !== null &&
|
|
37
|
-
typeof ctx.subscribe === 'function' &&
|
|
38
|
-
typeof ctx.getSnapshot === 'function'
|
|
39
|
-
? ctx
|
|
40
|
-
: null;
|
|
41
|
-
}
|
|
42
|
-
function unchanged(prev, aliveIds, nodes) {
|
|
43
|
-
// `aliveIds` and `nodes` can differ in length (a cold id is alive with no node
|
|
44
|
-
// yet), so compare the two lists independently.
|
|
45
|
-
if (prev.aliveIds.length !== aliveIds.length || prev.nodes.length !== nodes.length)
|
|
46
|
-
return false;
|
|
47
|
-
for (let i = 0; i < aliveIds.length; i += 1)
|
|
48
|
-
if (prev.aliveIds[i] !== aliveIds[i])
|
|
49
|
-
return false;
|
|
50
|
-
for (let i = 0; i < nodes.length; i += 1)
|
|
51
|
-
if (prev.nodes[i] !== nodes[i])
|
|
52
|
-
return false;
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Subscribe to each id's node shape and project the surviving nodes. The result
|
|
57
|
-
* keeps a stable reference across renders when membership and node identities
|
|
58
|
-
* are unchanged (useSyncExternalStore contract).
|
|
59
|
-
*/
|
|
60
|
-
export function useLiveNodes(orderedIds, memory) {
|
|
61
|
-
// Stands in for `orderedIds` in the callback deps (a fresh array each render).
|
|
62
|
-
const idsKey = orderedIds.join(' ');
|
|
63
|
-
const cache = useRef(null);
|
|
64
|
-
// Ids whose shape has been seen warm at least once — a later null is a deletion
|
|
65
|
-
// (confirmed absence), whereas a never-warm null is merely cold. Monotonic, so
|
|
66
|
-
// re-reading getSnapshot within a render is idempotent (useSyncExternalStore-safe).
|
|
67
|
-
const everWarm = useRef(new Set());
|
|
68
|
-
const getSnapshot = useCallback(() => {
|
|
69
|
-
let aliveIds;
|
|
70
|
-
let nodes;
|
|
71
|
-
if (memory === null) {
|
|
72
|
-
// No liveness source: keep the ids, resolve no nodes.
|
|
73
|
-
aliveIds = orderedIds;
|
|
74
|
-
nodes = EMPTY_NODES;
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
const seen = everWarm.current;
|
|
78
|
-
const a = [];
|
|
79
|
-
const n = [];
|
|
80
|
-
for (const id of orderedIds) {
|
|
81
|
-
const snap = memory.getSnapshot(nodeShape(id), LIVE_OPTS);
|
|
82
|
-
const node = snap.node;
|
|
83
|
-
if (node !== null) {
|
|
84
|
-
seen.add(id);
|
|
85
|
-
a.push(id);
|
|
86
|
-
n.push(node);
|
|
87
|
-
}
|
|
88
|
-
else if (!isConfirmedAbsent(snap, id, seen)) {
|
|
89
|
-
// Cold / not-yet-fetched: keep the id alive, no node yet — never a
|
|
90
|
-
// premature drop (the critical self-clear this guards against).
|
|
91
|
-
a.push(id);
|
|
92
|
-
}
|
|
93
|
-
// else: settled absence (deleted/masked) → drops from ids and nodes.
|
|
1
|
+
import { Path } from '@astrale-os/sdk/graph/path';
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
3
|
+
import { useSessionKernel } from '../auth/session-kernel.js';
|
|
4
|
+
/** Resolve selected identities through the authenticated GraphApi; no fake live subscription. */
|
|
5
|
+
export function useResolvedNodes(orderedIds) {
|
|
6
|
+
const graph = useSessionKernel().graph;
|
|
7
|
+
const key = orderedIds.join('\u0000');
|
|
8
|
+
const idsRef = useRef(orderedIds);
|
|
9
|
+
idsRef.current = orderedIds;
|
|
10
|
+
const generation = useRef(0);
|
|
11
|
+
const alive = useRef(true);
|
|
12
|
+
const [state, setState] = useState({
|
|
13
|
+
key,
|
|
14
|
+
aliveIds: orderedIds,
|
|
15
|
+
nodes: [],
|
|
16
|
+
pending: orderedIds.length > 0,
|
|
17
|
+
error: undefined,
|
|
18
|
+
});
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
alive.current = true;
|
|
21
|
+
return () => {
|
|
22
|
+
alive.current = false;
|
|
23
|
+
};
|
|
24
|
+
}, []);
|
|
25
|
+
const load = useCallback(async () => {
|
|
26
|
+
const ids = idsRef.current;
|
|
27
|
+
const currentKey = ids.join('\u0000');
|
|
28
|
+
const id = ++generation.current;
|
|
29
|
+
if (ids.length === 0) {
|
|
30
|
+
if (alive.current) {
|
|
31
|
+
setState({ key: currentKey, aliveIds: [], nodes: [], pending: false, error: undefined });
|
|
94
32
|
}
|
|
95
|
-
|
|
96
|
-
nodes = n;
|
|
33
|
+
return;
|
|
97
34
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
35
|
+
setState({ key: currentKey, aliveIds: ids, nodes: [], pending: true, error: undefined });
|
|
36
|
+
try {
|
|
37
|
+
const values = await Promise.all(ids.map((nodeId) => graph.get(Path.id(nodeId))));
|
|
38
|
+
if (!alive.current || id !== generation.current)
|
|
39
|
+
return;
|
|
40
|
+
const aliveIds = [];
|
|
41
|
+
const nodes = [];
|
|
42
|
+
values.forEach((node, index) => {
|
|
43
|
+
if (node === null)
|
|
44
|
+
return;
|
|
45
|
+
aliveIds.push(ids[index]);
|
|
46
|
+
nodes.push(node);
|
|
47
|
+
});
|
|
48
|
+
setState({
|
|
49
|
+
key: currentKey,
|
|
50
|
+
aliveIds: Object.freeze(aliveIds),
|
|
51
|
+
nodes: Object.freeze(nodes),
|
|
52
|
+
pending: false,
|
|
53
|
+
error: undefined,
|
|
54
|
+
});
|
|
101
55
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
|
|
56
|
+
catch (error) {
|
|
57
|
+
if (alive.current && id === generation.current) {
|
|
58
|
+
setState({ key: currentKey, aliveIds: ids, nodes: [], pending: false, error });
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}, [graph]);
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
void load();
|
|
64
|
+
}, [key, load]);
|
|
65
|
+
if (state.key !== key) {
|
|
66
|
+
return { aliveIds: orderedIds, nodes: [], pending: true, error: undefined, refetch: load };
|
|
67
|
+
}
|
|
68
|
+
return { ...state, refetch: load };
|
|
116
69
|
}
|
|
@@ -6,7 +6,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
6
6
|
* math stays caller-side (read `anchor`). Seats the selection context.
|
|
7
7
|
*/
|
|
8
8
|
import { createContext, useCallback, useEffect, useMemo, useReducer, useRef } from 'react';
|
|
9
|
-
import {
|
|
9
|
+
import { useResolvedNodes } from './live.js';
|
|
10
10
|
export const SelectionContext = createContext(null);
|
|
11
11
|
SelectionContext.displayName = 'AstraleSelectionContext';
|
|
12
12
|
function dedupe(ids) {
|
|
@@ -67,14 +67,15 @@ function initState(initial) {
|
|
|
67
67
|
export function SelectionScope(props) {
|
|
68
68
|
const { initial, onChange, children } = props;
|
|
69
69
|
const [state, dispatch] = useReducer(reducer, initial, initState);
|
|
70
|
-
const
|
|
71
|
-
const { aliveIds, nodes } = useLiveNodes(state.ids, memory);
|
|
70
|
+
const { aliveIds, nodes, pending, error } = useResolvedNodes(state.ids);
|
|
72
71
|
// Re-canonicalize stored state when liveness drops a node (or its anchor).
|
|
73
72
|
useEffect(() => {
|
|
74
73
|
const anchorDead = state.anchor !== null && !aliveIds.includes(state.anchor);
|
|
74
|
+
if (pending || error !== undefined)
|
|
75
|
+
return;
|
|
75
76
|
if (!sameIds(state.ids, aliveIds) || anchorDead)
|
|
76
77
|
dispatch({ t: 'prune', alive: aliveIds });
|
|
77
|
-
}, [aliveIds, state.ids, state.anchor]);
|
|
78
|
+
}, [aliveIds, pending, error, state.ids, state.anchor]);
|
|
78
79
|
// Report changes (explicit ops AND liveness drops), skipping the initial mount.
|
|
79
80
|
const onChangeRef = useRef(onChange);
|
|
80
81
|
onChangeRef.current = onChange;
|
|
@@ -1,19 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The boot machine inputs (API §2): config identity (what triggers a reboot) and
|
|
3
|
-
* whoami resolution (`createShell → init → whoami → OS-user preresolve`). Kept
|
|
4
|
-
* pure of React so the provider's boot effect composes them.
|
|
5
|
-
*/
|
|
6
1
|
import type { Shell, ShellConfig } from '@astrale-os/shell';
|
|
7
2
|
import type { SelfNode } from '../session.context.js';
|
|
8
3
|
export declare function isShellConfig(config: ShellConfig | Shell): config is ShellConfig;
|
|
9
|
-
/**
|
|
10
|
-
* Identity of a config — primitive fields only, so re-passing an inline `fetch`,
|
|
11
|
-
* `adapter`, `getCredential`, or `parentWindow` each render does not reboot;
|
|
12
|
-
* changing the kernel/credential does. A principal switch driven by a NEW
|
|
13
|
-
* `getCredential` closure (rather than a new `credential` string) is therefore
|
|
14
|
-
* NOT observed here — remount the provider (React `key`) to rebind it.
|
|
15
|
-
*/
|
|
4
|
+
/** Stable ownership key. Capability objects intentionally use reference identity. */
|
|
16
5
|
export declare function configIdentity(config: ShellConfig | Shell): string;
|
|
17
|
-
/** Resolve whoami when the bound kernel exposes an auth surface; else null. */
|
|
18
6
|
export declare function resolveSelf(shell: Shell): Promise<SelfNode | null>;
|
|
19
7
|
//# sourceMappingURL=boot.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../../src/session/boot/boot.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../../../src/session/boot/boot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAErD,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,MAAM,IAAI,WAAW,CAEhF;AAcD,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,MAAM,CAKlE;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAGxE"}
|
|
@@ -3,43 +3,25 @@ export function isShellConfig(config) {
|
|
|
3
3
|
}
|
|
4
4
|
let prebuiltCounter = 0;
|
|
5
5
|
const prebuiltIds = new WeakMap();
|
|
6
|
-
/** Stable id per prebuilt-Shell object reference (a new object reboots). */
|
|
7
6
|
function prebuiltId(shell) {
|
|
8
7
|
let id = prebuiltIds.get(shell);
|
|
9
8
|
if (id === undefined) {
|
|
10
|
-
|
|
11
|
-
id = `prebuilt#${prebuiltCounter}`;
|
|
9
|
+
id = `prebuilt#${++prebuiltCounter}`;
|
|
12
10
|
prebuiltIds.set(shell, id);
|
|
13
11
|
}
|
|
14
12
|
return id;
|
|
15
13
|
}
|
|
16
|
-
/**
|
|
17
|
-
* Identity of a config — primitive fields only, so re-passing an inline `fetch`,
|
|
18
|
-
* `adapter`, `getCredential`, or `parentWindow` each render does not reboot;
|
|
19
|
-
* changing the kernel/credential does. A principal switch driven by a NEW
|
|
20
|
-
* `getCredential` closure (rather than a new `credential` string) is therefore
|
|
21
|
-
* NOT observed here — remount the provider (React `key`) to rebind it.
|
|
22
|
-
*/
|
|
14
|
+
/** Stable ownership key. Capability objects intentionally use reference identity. */
|
|
23
15
|
export function configIdentity(config) {
|
|
24
16
|
if (!isShellConfig(config))
|
|
25
17
|
return prebuiltId(config);
|
|
26
|
-
if (config.mode === '
|
|
27
|
-
return
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
config.mintIdentity ?? '',
|
|
32
|
-
config.windowId ?? '',
|
|
33
|
-
].join('|');
|
|
34
|
-
}
|
|
35
|
-
return `sandboxed|${config.initTimeoutMs ?? ''}`;
|
|
18
|
+
if (config.mode === 'sandboxed')
|
|
19
|
+
return prebuiltId(config);
|
|
20
|
+
if (config.client !== undefined)
|
|
21
|
+
return `standalone-client|${prebuiltId(config.client)}`;
|
|
22
|
+
return `standalone-session|${prebuiltId(config.session)}`;
|
|
36
23
|
}
|
|
37
|
-
/** Resolve whoami when the bound kernel exposes an auth surface; else null. */
|
|
38
24
|
export async function resolveSelf(shell) {
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
const whoami = auth?.whoami;
|
|
42
|
-
if (typeof whoami !== 'function')
|
|
43
|
-
return null;
|
|
44
|
-
return whoami.call(auth);
|
|
25
|
+
const auth = shell.kernel.auth;
|
|
26
|
+
return typeof auth.whoami === 'function' ? auth.whoami() : null;
|
|
45
27
|
}
|
package/dist/session/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export { useKernelClient } from './kernel-client.hook.js';
|
|
|
5
5
|
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
|
+
export type { ConnectionStatus, ConnectionValue } from './connection/connection.store.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/session/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAC7C,YAAY,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAA;AAC7D,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAA;AAC/D,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAA"}
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
+
/** Public, non-secret identity of the connected source Kernel. */
|
|
1
2
|
export interface KernelInstance {
|
|
2
|
-
/** Kernel envelope endpoint this shell is bound to. */
|
|
3
3
|
readonly url: string;
|
|
4
|
-
/** Current kernel credential. Never cache; read per request. */
|
|
5
|
-
token(): string;
|
|
6
4
|
}
|
|
7
|
-
/** Low-level access for direct kernel-envelope calls and token exchange code. */
|
|
8
5
|
export declare function useKernelInstance(): KernelInstance;
|
|
9
6
|
//# sourceMappingURL=kernel-instance.hook.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kernel-instance.hook.d.ts","sourceRoot":"","sources":["../../src/session/kernel-instance.hook.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,
|
|
1
|
+
{"version":3,"file":"kernel-instance.hook.d.ts","sourceRoot":"","sources":["../../src/session/kernel-instance.hook.ts"],"names":[],"mappings":"AAIA,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CACrB;AAED,wBAAgB,iBAAiB,IAAI,cAAc,CAGlD"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
import { useKernelClient } from './kernel-client.hook.js';
|
|
3
|
-
/** Low-level access for direct kernel-envelope calls and token exchange code. */
|
|
4
3
|
export function useKernelInstance() {
|
|
5
4
|
const kernel = useKernelClient();
|
|
6
|
-
return useMemo(() => ({
|
|
7
|
-
url: kernel.url,
|
|
8
|
-
token: () => kernel.authToken(),
|
|
9
|
-
}), [kernel]);
|
|
5
|
+
return useMemo(() => Object.freeze({ url: kernel.url }), [kernel]);
|
|
10
6
|
}
|
|
@@ -1,31 +1,17 @@
|
|
|
1
1
|
import type { Shell, ShellConfig } from '@astrale-os/shell';
|
|
2
2
|
import type { ReactElement, ReactNode } from 'react';
|
|
3
|
-
/** Global error channel payload (API §2). */
|
|
4
3
|
export type ShellError = {
|
|
5
|
-
kind: '
|
|
6
|
-
|
|
7
|
-
error: unknown;
|
|
8
|
-
} | {
|
|
9
|
-
kind: 'mutation';
|
|
10
|
-
mutationId: string;
|
|
11
|
-
error: unknown;
|
|
12
|
-
} | {
|
|
13
|
-
kind: 'connection';
|
|
14
|
-
error: unknown;
|
|
4
|
+
readonly kind: 'connection';
|
|
5
|
+
readonly error: unknown;
|
|
15
6
|
};
|
|
16
7
|
export interface ShellProviderProps {
|
|
17
|
-
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
fallback?: ReactNode;
|
|
24
|
-
/** Rendered when boot fails; `retry` re-runs init. Default: rethrow to the nearest boundary. */
|
|
25
|
-
errorFallback?: (error: unknown, retry: () => void) => ReactNode;
|
|
26
|
-
/** Global error channel: warm-read refresh failures, rolled-back mutations, watch drops. */
|
|
27
|
-
onError?: (error: ShellError) => void;
|
|
28
|
-
children: ReactNode;
|
|
8
|
+
/** A Shell configuration or an already-constructed Shell capability. */
|
|
9
|
+
readonly config: ShellConfig | Shell;
|
|
10
|
+
readonly fallback?: ReactNode;
|
|
11
|
+
readonly errorFallback?: (error: unknown, retry: () => void) => ReactNode;
|
|
12
|
+
readonly onError?: (error: ShellError) => void;
|
|
13
|
+
readonly children: ReactNode;
|
|
29
14
|
}
|
|
15
|
+
/** Own and initialize exactly one Shell for a React subtree. */
|
|
30
16
|
export declare function ShellProvider(props: ShellProviderProps): ReactElement | null;
|
|
31
17
|
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/session/provider.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/session/provider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAiBpD,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAEjF,MAAM,WAAW,kBAAkB;IACjC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAA;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,CAAA;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,IAAI,KAAK,SAAS,CAAA;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAA;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC7B;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,YAAY,GAAG,IAAI,CAyG5E"}
|