@astrale-os/shell-react 0.2.8 → 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 +7 -15
- package/dist/application/apps/app-host.d.ts.map +1 -1
- package/dist/application/apps/app-host.js +3 -2
- 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 +11 -11
- package/dist/window/host.d.ts.map +1 -1
- package/dist/window/host.js +38 -54
- 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 +3 -3
- 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/dist/window/stage.d.ts.map +1 -1
- package/dist/window/stage.js +1 -0
- package/package.json +9 -8
- package/src/application/apps/app-host.tsx +17 -18
- 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 +137 -123
- 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 +51 -68
- package/src/window/hub.ts +33 -0
- package/src/window/index.ts +4 -4
- package/src/window/lifecycle/mount.ts +15 -160
- package/src/window/lifecycle/states.ts +1 -5
- package/src/window/stage.tsx +1 -0
- 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
package/src/window/host.tsx
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { NodeRefInput } from '@astrale-os/kernel-client'
|
|
2
1
|
import type {
|
|
3
2
|
CloseResult,
|
|
4
|
-
|
|
3
|
+
HostCapabilities,
|
|
5
4
|
MountCredential,
|
|
6
5
|
MountParams,
|
|
6
|
+
ResolvedView,
|
|
7
7
|
SandboxProfile,
|
|
8
8
|
Window,
|
|
9
9
|
} from '@astrale-os/shell'
|
|
@@ -14,7 +14,8 @@ import type { CSSProperties, ReactElement, ReactNode } from 'react'
|
|
|
14
14
|
* projects that box onto a stage slot (ResizeObserver); the iframe lives in the
|
|
15
15
|
* stage, so reorder/re-key never reloads a healthy frame. It drives the
|
|
16
16
|
* `WindowState` machine, owns teardown (unmount closes its window), survives
|
|
17
|
-
* StrictMode double-mount
|
|
17
|
+
* StrictMode double-mount. The complete target-bound View is the sole source
|
|
18
|
+
* of mount identity, route, target, and handshake behavior.
|
|
18
19
|
*/
|
|
19
20
|
import {
|
|
20
21
|
forwardRef,
|
|
@@ -28,19 +29,12 @@ import {
|
|
|
28
29
|
} from 'react'
|
|
29
30
|
|
|
30
31
|
import type { AdoptRecord } from './adopt.js'
|
|
31
|
-
import type { ViewSource } from './lifecycle/mount.js'
|
|
32
32
|
import type { WindowState } from './lifecycle/states.js'
|
|
33
33
|
import type { SlotRect, StageController, StageSlot } from './placement.js'
|
|
34
34
|
|
|
35
35
|
import { useShell } from '../session/shell.hook.js'
|
|
36
36
|
import { getStageHub } from './hub.js'
|
|
37
|
-
import {
|
|
38
|
-
isFallbackableHandshakeError,
|
|
39
|
-
refToId,
|
|
40
|
-
resolveSource,
|
|
41
|
-
sendSetTarget,
|
|
42
|
-
sourceKey,
|
|
43
|
-
} from './lifecycle/mount.js'
|
|
37
|
+
import { viewMountKey } from './lifecycle/mount.js'
|
|
44
38
|
import { rectOf, sameRect } from './placement.js'
|
|
45
39
|
|
|
46
40
|
/** Imperative handle on a mounted `ViewHost` (API §10). */
|
|
@@ -51,12 +45,17 @@ export interface ViewHostHandle {
|
|
|
51
45
|
refresh(): void
|
|
52
46
|
}
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
48
|
+
/** Static iframe sandbox flags, an explicit opt-out, or a policy over the resolved mount. */
|
|
49
|
+
export type SandboxPolicy = SandboxProfile | null | ((view: ResolvedView) => SandboxProfile | null)
|
|
50
|
+
|
|
51
|
+
export interface ViewHostProps {
|
|
52
|
+
/** One canonical target paired with one untouched View route. */
|
|
53
|
+
view: ResolvedView
|
|
54
|
+
capabilities?: HostCapabilities
|
|
55
|
+
sandbox?: SandboxPolicy
|
|
59
56
|
credential?: MountCredential
|
|
57
|
+
handshakeTimeoutMs?: number
|
|
58
|
+
delegationTtlSeconds?: number
|
|
60
59
|
/** Rendered inside the anchor while the frame is not `ready`. */
|
|
61
60
|
fallback?: (state: WindowState) => ReactNode
|
|
62
61
|
onStateChange?: (state: WindowState) => void
|
|
@@ -71,7 +70,6 @@ interface LiveWindow {
|
|
|
71
70
|
readonly windowId: string
|
|
72
71
|
readonly window: Window
|
|
73
72
|
readonly state: WindowState
|
|
74
|
-
readonly targetId: string | undefined
|
|
75
73
|
}
|
|
76
74
|
|
|
77
75
|
export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
@@ -97,9 +95,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
97
95
|
const [state, setState] = useState<WindowState>(MOUNTING)
|
|
98
96
|
const [refreshNonce, setRefreshNonce] = useState(0)
|
|
99
97
|
|
|
100
|
-
const mountKey =
|
|
101
|
-
const targetId = refToId(props.node)
|
|
102
|
-
const lastTargetRef = useRef<string | undefined>(undefined)
|
|
98
|
+
const mountKey = viewMountKey(props.view)
|
|
103
99
|
|
|
104
100
|
const setStateSafe = (next: WindowState) => {
|
|
105
101
|
if (!aliveRef.current) return
|
|
@@ -155,10 +151,9 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
155
151
|
slot.place(rect)
|
|
156
152
|
}, [])
|
|
157
153
|
|
|
158
|
-
// ── Mount lifecycle. Keyed on
|
|
159
|
-
//
|
|
160
|
-
//
|
|
161
|
-
// (deferred close), so a healthy iframe is never reloaded (§10).
|
|
154
|
+
// ── Mount lifecycle. Keyed on complete target + route provenance and
|
|
155
|
+
// refresh nonce. A same-selection re-key/re-parent can adopt the live
|
|
156
|
+
// window; any target or provenance change necessarily remounts.
|
|
162
157
|
useEffect(() => {
|
|
163
158
|
let cancelled = false
|
|
164
159
|
let controllerWaiter: (() => void) | null = null
|
|
@@ -197,13 +192,21 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
197
192
|
window: live.window,
|
|
198
193
|
slot,
|
|
199
194
|
state: live.state,
|
|
200
|
-
targetId: live.targetId,
|
|
201
195
|
dispose: () => closeAndRelease(live.windowId, slot),
|
|
202
196
|
}
|
|
203
197
|
if (refreshingRef.current) record.dispose()
|
|
204
198
|
else hub.stashForAdopt(mountKey, record)
|
|
205
199
|
}
|
|
206
200
|
|
|
201
|
+
/** A pre-ready failure must not leave an empty stage slot over the fallback UI. */
|
|
202
|
+
function crashAndRelease(error: unknown): void {
|
|
203
|
+
const slot = slotRef.current
|
|
204
|
+
slotRef.current = null
|
|
205
|
+
lastRectRef.current = null
|
|
206
|
+
slot?.release()
|
|
207
|
+
setStateSafe({ phase: 'crashed', windowId: windowIdRef.current ?? undefined, error })
|
|
208
|
+
}
|
|
209
|
+
|
|
207
210
|
// Adopt a live window a just-unmounted same-source host left behind.
|
|
208
211
|
if (!wasRefresh) {
|
|
209
212
|
const adopted = hub.takeAdopt(mountKey)
|
|
@@ -214,9 +217,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
214
217
|
windowId: adopted.windowId,
|
|
215
218
|
window: adopted.window,
|
|
216
219
|
state: adopted.state,
|
|
217
|
-
targetId: adopted.targetId,
|
|
218
220
|
}
|
|
219
|
-
lastTargetRef.current = adopted.targetId
|
|
220
221
|
hub.registry.upsert(adopted.windowId, adopted.window, adopted.state)
|
|
221
222
|
lastRectRef.current = null
|
|
222
223
|
measure() // reposition the surviving slot onto this host's anchor
|
|
@@ -225,33 +226,37 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
225
226
|
}
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
async function
|
|
229
|
+
async function mountView(): Promise<void> {
|
|
229
230
|
const p = propsRef.current
|
|
230
|
-
let
|
|
231
|
+
let sandbox: SandboxProfile | null | undefined
|
|
231
232
|
try {
|
|
232
|
-
|
|
233
|
+
sandbox = typeof p.sandbox === 'function' ? p.sandbox(p.view) : p.sandbox
|
|
233
234
|
} catch (err) {
|
|
234
|
-
|
|
235
|
-
if (!cancelled) setStateSafe({ phase: 'crashed', error: err })
|
|
235
|
+
if (!cancelled) crashAndRelease(err)
|
|
236
236
|
return
|
|
237
237
|
}
|
|
238
|
-
if (cancelled) return
|
|
239
|
-
|
|
240
|
-
const usedHandshake = handshake === 'none' ? 'none' : resolved.handshake
|
|
241
|
-
const deliveredTarget = refToId(p.node)
|
|
242
238
|
const params: MountParams = {
|
|
243
239
|
host: slotRef.current!.element,
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
240
|
+
view: p.view,
|
|
241
|
+
capabilities: p.capabilities ?? {
|
|
242
|
+
version: 1,
|
|
243
|
+
navigation: {},
|
|
244
|
+
actions: {},
|
|
245
|
+
browser: {},
|
|
246
|
+
access: {},
|
|
247
|
+
},
|
|
248
|
+
sandbox,
|
|
250
249
|
credential: p.credential,
|
|
250
|
+
...(p.handshakeTimeoutMs === undefined
|
|
251
|
+
? {}
|
|
252
|
+
: { handshakeTimeoutMs: p.handshakeTimeoutMs }),
|
|
253
|
+
...(p.delegationTtlSeconds === undefined
|
|
254
|
+
? {}
|
|
255
|
+
: { delegationTtlSeconds: p.delegationTtlSeconds }),
|
|
251
256
|
}
|
|
252
257
|
|
|
253
258
|
try {
|
|
254
|
-
const win = await shell.
|
|
259
|
+
const win = await shell.openView(params)
|
|
255
260
|
// A StrictMode cleanup (or refresh) fired before mount resolved: adopt
|
|
256
261
|
// then immediately close so no orphan window survives.
|
|
257
262
|
if (cancelled) {
|
|
@@ -259,25 +264,17 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
259
264
|
return
|
|
260
265
|
}
|
|
261
266
|
windowIdRef.current = win.windowId
|
|
262
|
-
|
|
263
|
-
const ready: WindowState = downgraded
|
|
264
|
-
? { phase: 'ready', windowId: win.windowId, downgraded: true }
|
|
265
|
-
: { phase: 'ready', windowId: win.windowId }
|
|
267
|
+
const ready: WindowState = { phase: 'ready', windowId: win.windowId }
|
|
266
268
|
liveRef.current = {
|
|
267
269
|
windowId: win.windowId,
|
|
268
270
|
window: win.window,
|
|
269
271
|
state: ready,
|
|
270
|
-
targetId: deliveredTarget,
|
|
271
272
|
}
|
|
272
273
|
hub.registry.upsert(win.windowId, win.window, ready)
|
|
273
274
|
setStateSafe(ready)
|
|
274
275
|
} catch (err) {
|
|
275
276
|
if (cancelled) return
|
|
276
|
-
|
|
277
|
-
await mountWith('none', true)
|
|
278
|
-
return
|
|
279
|
-
}
|
|
280
|
-
setStateSafe({ phase: 'crashed', windowId: windowIdRef.current ?? undefined, error: err })
|
|
277
|
+
crashAndRelease(err)
|
|
281
278
|
}
|
|
282
279
|
}
|
|
283
280
|
|
|
@@ -288,7 +285,7 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
288
285
|
lastRectRef.current = null
|
|
289
286
|
measure()
|
|
290
287
|
setStateSafe(MOUNTING)
|
|
291
|
-
void
|
|
288
|
+
void mountView()
|
|
292
289
|
}
|
|
293
290
|
|
|
294
291
|
const existing = hub.getController()
|
|
@@ -303,15 +300,6 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
303
300
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
304
301
|
}, [hub, shell, mountKey, refreshNonce])
|
|
305
302
|
|
|
306
|
-
// ── Retarget: a node change after ready hot-swaps via setTarget (no remount).
|
|
307
|
-
useEffect(() => {
|
|
308
|
-
if (state.phase !== 'ready') return
|
|
309
|
-
if (targetId === lastTargetRef.current) return
|
|
310
|
-
lastTargetRef.current = targetId
|
|
311
|
-
if (targetId === undefined) return
|
|
312
|
-
sendSetTarget(shell, state.windowId, targetId)
|
|
313
|
-
}, [shell, state, targetId])
|
|
314
|
-
|
|
315
303
|
// ── Placement observers: reposition on resize/scroll/anchor-resize.
|
|
316
304
|
useLayoutEffect(() => {
|
|
317
305
|
measure()
|
|
@@ -340,8 +328,3 @@ export const ViewHost = forwardRef<ViewHostHandle, ViewHostProps>(
|
|
|
340
328
|
)
|
|
341
329
|
},
|
|
342
330
|
)
|
|
343
|
-
|
|
344
|
-
/** Narrow props back to the bare `ViewSource` discriminated union. */
|
|
345
|
-
function sourceOf(props: ViewHostProps): ViewSource {
|
|
346
|
-
return 'url' in props ? { url: props.url } : { view: props.view }
|
|
347
|
-
}
|
package/src/window/hub.ts
CHANGED
|
@@ -34,6 +34,8 @@ export interface WindowRegistry {
|
|
|
34
34
|
upsert(windowId: string, window: Window, state: WindowState): void
|
|
35
35
|
patch(windowId: string, state: WindowState): void
|
|
36
36
|
remove(windowId: string): void
|
|
37
|
+
/** Shell writes: replace host and imperatively mounted windows from authoritative snapshots. */
|
|
38
|
+
sync(windows: ReadonlyMap<string, Window>): void
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
const NO_WINDOW: WindowView = { phase: 'closed', windowId: '', window: null }
|
|
@@ -98,7 +100,36 @@ function createWindowRegistry(): WindowRegistry {
|
|
|
98
100
|
if (!entries.delete(windowId)) return
|
|
99
101
|
invalidate()
|
|
100
102
|
},
|
|
103
|
+
|
|
104
|
+
sync(windows) {
|
|
105
|
+
let changed = false
|
|
106
|
+
for (const windowId of entries.keys()) {
|
|
107
|
+
if (!windows.has(windowId)) {
|
|
108
|
+
entries.delete(windowId)
|
|
109
|
+
changed = true
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (const [windowId, window] of windows) {
|
|
113
|
+
const current = entries.get(windowId)
|
|
114
|
+
if (current?.window === window) continue
|
|
115
|
+
entries.set(windowId, {
|
|
116
|
+
window,
|
|
117
|
+
state: current?.state ?? phaseFor(window),
|
|
118
|
+
})
|
|
119
|
+
changed = true
|
|
120
|
+
}
|
|
121
|
+
if (changed) invalidate()
|
|
122
|
+
},
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function phaseFor(window: Window): WindowState {
|
|
127
|
+
if (window.state === 'opening') return { phase: 'mounting' }
|
|
128
|
+
if (window.state === 'failed') {
|
|
129
|
+
return { phase: 'crashed', windowId: window.windowId }
|
|
101
130
|
}
|
|
131
|
+
if (window.state === 'closed') return { phase: 'closed', windowId: window.windowId }
|
|
132
|
+
return { phase: 'ready', windowId: window.windowId }
|
|
102
133
|
}
|
|
103
134
|
|
|
104
135
|
// ── Per-shell hub ────────────────────────────────────────────────────────────
|
|
@@ -151,6 +182,8 @@ export function getStageHub(shell: Shell): StageHub {
|
|
|
151
182
|
return adopt.take(key)
|
|
152
183
|
},
|
|
153
184
|
}
|
|
185
|
+
registry.sync(shell.windows)
|
|
186
|
+
shell.onWindowChange(() => registry.sync(shell.windows))
|
|
154
187
|
HUBS.set(shell, hub)
|
|
155
188
|
return hub
|
|
156
189
|
}
|
package/src/window/index.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// window — API §10. ViewStage/ViewHost (the physical iframe-slot layer + a host
|
|
2
|
-
// that projects
|
|
2
|
+
// that projects stage geometry into a slot), the reactive window hooks, the child-side
|
|
3
3
|
// target-node + close-guard, and the (G5) view-resolution hook.
|
|
4
4
|
export { ViewStage } from './stage.js'
|
|
5
5
|
export { ViewHost } from './host.js'
|
|
6
|
-
export type { ViewHostProps, ViewHostHandle } from './host.js'
|
|
6
|
+
export type { SandboxPolicy, ViewHostProps, ViewHostHandle } from './host.js'
|
|
7
7
|
export { useWindows, useWindowList } from './hooks/windows.hook.js'
|
|
8
8
|
export type { WindowListEntry } from './hooks/windows.hook.js'
|
|
9
9
|
export { useWindow } from './hooks/window.hook.js'
|
|
10
10
|
export type { WindowView } from './hub.js'
|
|
11
11
|
export { useViewsFor } from './hooks/views-for.hook.js'
|
|
12
12
|
export type { ViewsForResult } from './hooks/views-for.hook.js'
|
|
13
|
-
export { useTargetNode } from './hooks/target-node.hook.js'
|
|
13
|
+
export { useTargetNode, useTargetPath } from './hooks/target-node.hook.js'
|
|
14
14
|
export { useCloseGuard } from './hooks/close-guard.hook.js'
|
|
15
15
|
export type { CloseGuard, CloseVerdict } from './hooks/close-guard.hook.js'
|
|
16
|
-
export type { ViewDescriptor, ViewSource, Node } from './lifecycle/mount.js'
|
|
17
16
|
export type { WindowState } from './lifecycle/states.js'
|
|
17
|
+
export type { ResolvedView } from '@astrale-os/shell'
|
|
@@ -1,164 +1,19 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
/**
|
|
3
|
-
* Mount orchestration (API §10) — resolve a `ViewSource` to something `shell.mount`
|
|
4
|
-
* accepts (url + handshake + functionId), the stable remount key, the delivered
|
|
5
|
-
* target id, the handshake-fallback predicate, and the parent→child setTarget
|
|
6
|
-
* hot-swap. A one-call `View.resolve` kernel contract does not exist yet — the
|
|
7
|
-
* bare-ref path is the honest subset, G5.
|
|
8
|
-
*/
|
|
9
|
-
import type { KernelClient, Shell } from '@astrale-os/shell'
|
|
10
|
-
|
|
11
|
-
/** A live graph node, derived from the shell kernel read surface (G8 seam). */
|
|
12
|
-
export type Node = NonNullable<Awaited<ReturnType<KernelClient['get']>>>
|
|
13
|
-
|
|
14
|
-
/** A View function resolved to something mountable (url + optional handshake). */
|
|
15
|
-
export interface ViewDescriptor {
|
|
16
|
-
readonly id: string
|
|
17
|
-
readonly path: string
|
|
18
|
-
readonly url?: string
|
|
19
|
-
readonly handshake?: string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* What a `ViewHost` mounts:
|
|
24
|
-
* - `{ view }` — a View function (descriptor or ref), resolved to url + handshake.
|
|
25
|
-
* - `{ url }` — a handshake-less hosted view; mounts immediately (no 5s wait).
|
|
26
|
-
*/
|
|
27
|
-
export type ViewSource = { readonly view: NodeRefInput | ViewDescriptor } | { readonly url: string }
|
|
28
|
-
|
|
29
|
-
export interface ResolvedSource {
|
|
30
|
-
readonly url: string
|
|
31
|
-
readonly handshake: 'shell' | 'none'
|
|
32
|
-
readonly functionId: string
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function isViewDescriptor(view: NodeRefInput | ViewDescriptor): view is ViewDescriptor {
|
|
36
|
-
return typeof view === 'object' && view !== null && 'id' in view && 'path' in view
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** Last path segment or host, alnum-only — a stable-ish functionId from a url. */
|
|
40
|
-
function slugOfUrl(url: string): string {
|
|
41
|
-
const trimmed = url.replace(/[#?].*$/, '').replace(/\/+$/, '')
|
|
42
|
-
const tail = trimmed.split('/').filter(Boolean).pop() ?? 'view'
|
|
43
|
-
return tail.replace(/[^a-z0-9]/gi, '').slice(-32) || 'view'
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/** A ref addressable by the kernel read surface (`get`). `@<id>` for bare ids. */
|
|
47
|
-
function toPath(ref: NodeRefInput): string {
|
|
48
|
-
if (typeof ref === 'string') {
|
|
49
|
-
return ref.startsWith('/') || ref.startsWith('@') ? ref : `@${ref}`
|
|
50
|
-
}
|
|
51
|
-
const obj = ref as { id?: string; path?: { raw?: string } }
|
|
52
|
-
if (obj.path?.raw !== undefined) return obj.path.raw
|
|
53
|
-
if (obj.id !== undefined) return `@${obj.id}`
|
|
54
|
-
throw new Error('ViewHost: unresolvable view ref')
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async function resolveViewRef(
|
|
58
|
-
kernel: KernelClient,
|
|
59
|
-
ref: NodeRefInput,
|
|
60
|
-
handshakeHint?: string,
|
|
61
|
-
): Promise<ResolvedSource> {
|
|
62
|
-
const node = await kernel.get(toPath(ref))
|
|
63
|
-
if (node === null) throw new Error(`ViewHost: view not found (${toPath(ref)})`)
|
|
64
|
-
const props = (node as { id?: string; props?: Record<string, unknown> }).props ?? {}
|
|
65
|
-
const url = viewUrl(props)
|
|
66
|
-
if (typeof url !== 'string' || url.length === 0) {
|
|
67
|
-
throw new Error('ViewHost: resolved view has no url')
|
|
68
|
-
}
|
|
69
|
-
const handshake = normalizeHandshake(handshakeHint ?? props.handshake)
|
|
70
|
-
const id = (node as { id?: string }).id ?? slugOfUrl(url)
|
|
71
|
-
return { url, handshake, functionId: id }
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/** Resolve both the legacy flat url and the canonical Function binding. */
|
|
75
|
-
function viewUrl(props: Record<string, unknown>): string | undefined {
|
|
76
|
-
if (typeof props.url === 'string' && props.url.length > 0) return props.url
|
|
77
|
-
|
|
78
|
-
const direct = remoteUrlOf(props.binding)
|
|
79
|
-
if (direct !== undefined) return direct
|
|
80
|
-
|
|
81
|
-
// Raw graph props can be keyed by the property's canonical graph key rather
|
|
82
|
-
// than its local slug. The binding value remains self-describing.
|
|
83
|
-
for (const value of Object.values(props)) {
|
|
84
|
-
const remoteUrl = remoteUrlOf(value)
|
|
85
|
-
if (remoteUrl !== undefined) return remoteUrl
|
|
86
|
-
}
|
|
87
|
-
return undefined
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function remoteUrlOf(value: unknown): string | undefined {
|
|
91
|
-
let binding = value
|
|
92
|
-
if (typeof binding === 'string') {
|
|
93
|
-
try {
|
|
94
|
-
binding = JSON.parse(binding)
|
|
95
|
-
} catch {
|
|
96
|
-
return undefined
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (binding === null || typeof binding !== 'object') return undefined
|
|
100
|
-
const remoteUrl = (binding as { remoteUrl?: unknown }).remoteUrl
|
|
101
|
-
return typeof remoteUrl === 'string' && remoteUrl.length > 0 ? remoteUrl : undefined
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function normalizeHandshake(value: unknown): 'shell' | 'none' {
|
|
105
|
-
return value === 'none' ? 'none' : 'shell'
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/** Resolve a source; may hit the kernel for a bare/urless View ref (G5). */
|
|
109
|
-
export async function resolveSource(
|
|
110
|
-
kernel: KernelClient,
|
|
111
|
-
source: ViewSource,
|
|
112
|
-
): Promise<ResolvedSource> {
|
|
113
|
-
if ('url' in source) {
|
|
114
|
-
return { url: source.url, handshake: 'none', functionId: slugOfUrl(source.url) }
|
|
115
|
-
}
|
|
116
|
-
const view = source.view
|
|
117
|
-
if (isViewDescriptor(view)) {
|
|
118
|
-
if (view.url !== undefined && view.url.length > 0) {
|
|
119
|
-
return {
|
|
120
|
-
url: view.url,
|
|
121
|
-
handshake: normalizeHandshake(view.handshake),
|
|
122
|
-
functionId: view.id,
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
return resolveViewRef(kernel, view.id, view.handshake)
|
|
126
|
-
}
|
|
127
|
-
return resolveViewRef(kernel, view)
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/** A stable remount key: the same source identity must not remount. */
|
|
131
|
-
export function sourceKey(source: ViewSource): string {
|
|
132
|
-
if ('url' in source) return `url:${source.url}`
|
|
133
|
-
const view = source.view
|
|
134
|
-
if (isViewDescriptor(view)) return `view:${view.id}:${view.url ?? ''}:${view.handshake ?? ''}`
|
|
135
|
-
if (typeof view === 'string') return `ref:${view}`
|
|
136
|
-
const obj = view as { id?: string; path?: { raw?: string } }
|
|
137
|
-
return `ref:${obj.id ?? obj.path?.raw ?? '?'}`
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/** The bare node id delivered as `targetNodeId` at mount / retarget. */
|
|
141
|
-
export function refToId(ref: NodeRefInput | undefined): string | undefined {
|
|
142
|
-
if (ref === undefined) return undefined
|
|
143
|
-
if (typeof ref === 'string') return ref.startsWith('@') ? ref.slice(1) : ref
|
|
144
|
-
const obj = ref as { id?: string }
|
|
145
|
-
return obj.id
|
|
146
|
-
}
|
|
1
|
+
import type { ResolvedView } from '@astrale-os/shell'
|
|
147
2
|
|
|
148
3
|
/**
|
|
149
|
-
*
|
|
150
|
-
*
|
|
4
|
+
* Stable identity for one target-bound, provenance-complete View route.
|
|
5
|
+
* A change to any routing or semantic witness forces a fresh mount; an old
|
|
6
|
+
* iframe and credential can never be adopted under a different route.
|
|
151
7
|
*/
|
|
152
|
-
export function
|
|
153
|
-
const
|
|
154
|
-
return
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
})
|
|
8
|
+
export function viewMountKey(view: ResolvedView): string {
|
|
9
|
+
const { route, target } = view
|
|
10
|
+
return [
|
|
11
|
+
target,
|
|
12
|
+
route.key,
|
|
13
|
+
route.href,
|
|
14
|
+
route.handshake,
|
|
15
|
+
route.issuer,
|
|
16
|
+
route.etag,
|
|
17
|
+
route.revision,
|
|
18
|
+
].join('\u0000')
|
|
164
19
|
}
|
|
@@ -8,16 +8,12 @@
|
|
|
8
8
|
/**
|
|
9
9
|
* Lifecycle of a hosted view as the React face observes it (API §10).
|
|
10
10
|
*
|
|
11
|
-
* `ready.downgraded` marks a mount that fell back to a plain iframe after a
|
|
12
|
-
* fallbackable handshake error. It rides here (not on the shell `Window`) until
|
|
13
|
-
* the shell `Window` grows a first-class flag — flagged in the module report.
|
|
14
|
-
*
|
|
15
11
|
* `crashed.windowId` is OPTIONAL: a crash before a window exists (a session-open
|
|
16
12
|
* failure, a pre-mount source-resolution failure) has no id to report — the type
|
|
17
13
|
* says so rather than carrying a placeholder `''`.
|
|
18
14
|
*/
|
|
19
15
|
export type WindowState =
|
|
20
16
|
| { readonly phase: 'mounting' }
|
|
21
|
-
| { readonly phase: 'ready'; readonly windowId: string
|
|
17
|
+
| { readonly phase: 'ready'; readonly windowId: string }
|
|
22
18
|
| { readonly phase: 'crashed'; readonly windowId?: string; readonly error?: unknown }
|
|
23
19
|
| { readonly phase: 'closed'; readonly windowId: string; readonly refusal?: string }
|
package/src/window/stage.tsx
CHANGED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { RoleNode } from '@astrale-os/shell';
|
|
2
|
-
import type { ReadState } from '../graph/memory/read/envelope.js';
|
|
3
|
-
export interface RolesResult extends ReadState {
|
|
4
|
-
readonly roles: readonly RoleNode[];
|
|
5
|
-
}
|
|
6
|
-
export declare function useRoles(): RolesResult;
|
|
7
|
-
//# sourceMappingURL=roles.hook.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"roles.hook.d.ts","sourceRoot":"","sources":["../../src/application/roles.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAQjD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAA;AAQjE,MAAM,WAAW,WAAY,SAAQ,SAAS;IAC5C,QAAQ,CAAC,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAA;CACpC;AAED,wBAAgB,QAAQ,IAAI,WAAW,CAoBtC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* useRoles (API §12.2) — the roles self holds (`has_role` out-edges), over the
|
|
3
|
-
* async OS namespace (one-shot today, §12 flag).
|
|
4
|
-
*/
|
|
5
|
-
import { useMemo } from 'react';
|
|
6
|
-
import { useAsyncResource } from '../graph/async.js';
|
|
7
|
-
import { useShell } from '../session/shell.hook.js';
|
|
8
|
-
import { isOsPlaneAvailable } from './user/user.store.js';
|
|
9
|
-
const NO_ROLES = [];
|
|
10
|
-
export function useRoles() {
|
|
11
|
-
const shell = useShell();
|
|
12
|
-
// OS plane unavailable (§12.2) → idle: no roles read.
|
|
13
|
-
const available = isOsPlaneAvailable(shell);
|
|
14
|
-
const res = useAsyncResource(available ? () => shell.user.roles() : null, NO_ROLES, [shell, available]);
|
|
15
|
-
return useMemo(() => ({
|
|
16
|
-
roles: res.data,
|
|
17
|
-
pending: res.pending,
|
|
18
|
-
error: res.error,
|
|
19
|
-
live: false,
|
|
20
|
-
seq: 0,
|
|
21
|
-
refetch: res.refetch,
|
|
22
|
-
}), [res]);
|
|
23
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import type { GraphMemory, MemoryEvent } from '@astrale-os/kernel-client/store';
|
|
2
|
-
/**
|
|
3
|
-
* The base memory (API §5.4). One `GraphMemory` per live Shell — the partial
|
|
4
|
-
* client copy of the graph every graph/schema/nav hook reads through, so they all
|
|
5
|
-
* share one cache, one dedupe, one optimistic overlay. Derived from `shell.kernel`
|
|
6
|
-
* and memoized on the Shell object. Its `onError` fans out through a per-Shell
|
|
7
|
-
* sink the provider registers, so warm-refresh failures and rolled-back mutations
|
|
8
|
-
* reach the provider's `onError` channel (§2).
|
|
9
|
-
*/
|
|
10
|
-
import type { Shell } from '@astrale-os/shell';
|
|
11
|
-
/** Register (or clear) the provider's memory-event bridge for a Shell. */
|
|
12
|
-
export declare function setMemoryErrorSink(shell: Shell, sink: ((event: MemoryEvent) => void) | null): void;
|
|
13
|
-
/**
|
|
14
|
-
* The base (default-scope) memory for a Shell — the SAME instance every graph/
|
|
15
|
-
* schema/nav hook reads through `useMemory`, so the provider can seat it in
|
|
16
|
-
* `GraphContext` (selection's liveness source) without minting a rival copy.
|
|
17
|
-
* Its `onError` fans out through the per-Shell sink so warm-refresh failures and
|
|
18
|
-
* rolled-back mutations reach `ShellProvider`'s `onError` channel (§2).
|
|
19
|
-
*/
|
|
20
|
-
export declare function baseMemoryFor(shell: Shell): GraphMemory;
|
|
21
|
-
//# sourceMappingURL=base.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/graph/memory/base.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,iCAAiC,CAAA;AAC/E;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAc9C,0EAA0E;AAC1E,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,CAAC,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC,GAAG,IAAI,GAC1C,IAAI,CAGN;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,WAAW,CASvD"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createMemory } from '@astrale-os/kernel-client/store';
|
|
2
|
-
/** One memory per Shell reference — shared by every hook under that provider. */
|
|
3
|
-
const memoryByShell = new WeakMap();
|
|
4
|
-
/**
|
|
5
|
-
* Per-Shell error sink (API §2/§8). The provider registers a bridge here; the
|
|
6
|
-
* memory emits refresh/mutation/divergence events through it, read lazily at
|
|
7
|
-
* emit time so registration order doesn't matter. Cleared on provider unmount.
|
|
8
|
-
*/
|
|
9
|
-
const errorSinks = new WeakMap();
|
|
10
|
-
/** Register (or clear) the provider's memory-event bridge for a Shell. */
|
|
11
|
-
export function setMemoryErrorSink(shell, sink) {
|
|
12
|
-
if (sink === null)
|
|
13
|
-
errorSinks.delete(shell);
|
|
14
|
-
else
|
|
15
|
-
errorSinks.set(shell, sink);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* The base (default-scope) memory for a Shell — the SAME instance every graph/
|
|
19
|
-
* schema/nav hook reads through `useMemory`, so the provider can seat it in
|
|
20
|
-
* `GraphContext` (selection's liveness source) without minting a rival copy.
|
|
21
|
-
* Its `onError` fans out through the per-Shell sink so warm-refresh failures and
|
|
22
|
-
* rolled-back mutations reach `ShellProvider`'s `onError` channel (§2).
|
|
23
|
-
*/
|
|
24
|
-
export function baseMemoryFor(shell) {
|
|
25
|
-
let memory = memoryByShell.get(shell);
|
|
26
|
-
if (memory === undefined) {
|
|
27
|
-
memory = createMemory(shell.kernel, {
|
|
28
|
-
onError: (event) => errorSinks.get(shell)?.(event),
|
|
29
|
-
});
|
|
30
|
-
memoryByShell.set(shell, memory);
|
|
31
|
-
}
|
|
32
|
-
return memory;
|
|
33
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { ShapeInput } from '@astrale-os/kernel-client/store';
|
|
2
|
-
import type { CoreReadOptions, RawRead } from './envelope.js';
|
|
3
|
-
/**
|
|
4
|
-
* Subscribe to a memory shape and project it. `null`/`undefined` shape → idle.
|
|
5
|
-
* Cold + `suspend` (default) throws the cold-shape promise; `suspend:false`
|
|
6
|
-
* returns empty-pending; `keepPrevious` returns the last data while confirming.
|
|
7
|
-
*/
|
|
8
|
-
export declare function useRead(shape: ShapeInput | null | undefined, opts?: CoreReadOptions): RawRead;
|
|
9
|
-
//# sourceMappingURL=read.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../../src/graph/memory/read/read.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAGV,UAAU,EACX,MAAM,iCAAiC,CAAA;AAYxC,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAiC7D;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,eAAe,GAAG,OAAO,CAgD7F"}
|