@astrale-os/shell-react 0.2.6 → 0.2.8
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/domains.hook.d.ts +7 -0
- package/dist/application/apps/domains.hook.d.ts.map +1 -0
- package/dist/application/apps/domains.hook.js +18 -0
- package/dist/application/index.d.ts +3 -1
- package/dist/application/index.d.ts.map +1 -1
- package/dist/application/index.js +3 -1
- package/dist/application/user/user.store.d.ts.map +1 -1
- package/dist/application/user/user.store.js +2 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/intents/send-intent.hook.d.ts.map +1 -1
- package/dist/intents/send-intent.hook.js +14 -1
- package/dist/window/hooks/views-for.hook.d.ts.map +1 -1
- package/dist/window/hooks/views-for.hook.js +6 -9
- package/dist/window/lifecycle/mount.d.ts.map +1 -1
- package/dist/window/lifecycle/mount.js +32 -1
- package/package.json +2 -2
- package/src/application/apps/domains.hook.ts +37 -0
- package/src/application/index.ts +12 -2
- package/src/application/user/user.store.ts +2 -1
- package/src/index.ts +10 -1
- package/src/intents/send-intent.hook.ts +18 -2
- package/src/window/hooks/views-for.hook.ts +8 -24
- package/src/window/lifecycle/mount.ts +31 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DomainSearchResult } from '@astrale-os/shell';
|
|
2
|
+
import type { ReadState } from '../../graph/memory/read/envelope.js';
|
|
3
|
+
export interface DomainsResult extends ReadState {
|
|
4
|
+
readonly domains: readonly DomainSearchResult[];
|
|
5
|
+
}
|
|
6
|
+
export declare function useDomains(): DomainsResult;
|
|
7
|
+
//# sourceMappingURL=domains.hook.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domains.hook.d.ts","sourceRoot":"","sources":["../../../src/application/apps/domains.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AAI3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAQpE,MAAM,WAAW,aAAc,SAAQ,SAAS;IAC9C,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAA;CAChD;AAED,wBAAgB,UAAU,IAAI,aAAa,CAoB1C"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import { useAsyncResource } from '../../graph/async.js';
|
|
3
|
+
import { useShell } from '../../session/shell.hook.js';
|
|
4
|
+
import { isOsPlaneAvailable } from '../user/user.store.js';
|
|
5
|
+
const NO_DOMAINS = [];
|
|
6
|
+
export function useDomains() {
|
|
7
|
+
const shell = useShell();
|
|
8
|
+
const available = isOsPlaneAvailable(shell);
|
|
9
|
+
const result = useAsyncResource(available ? () => shell.apps.searchDomains() : null, NO_DOMAINS, [shell, available]);
|
|
10
|
+
return useMemo(() => ({
|
|
11
|
+
domains: result.data,
|
|
12
|
+
pending: result.pending,
|
|
13
|
+
error: result.error,
|
|
14
|
+
live: false,
|
|
15
|
+
seq: 0,
|
|
16
|
+
refetch: result.refetch,
|
|
17
|
+
}), [result]);
|
|
18
|
+
}
|
|
@@ -7,6 +7,8 @@ export { useSpace } from './spaces/space.hook.js';
|
|
|
7
7
|
export type { SpaceResult } from './spaces/space.hook.js';
|
|
8
8
|
export { useApps } from './apps/apps.hook.js';
|
|
9
9
|
export type { AppsResult } from './apps/apps.hook.js';
|
|
10
|
+
export { useDomains } from './apps/domains.hook.js';
|
|
11
|
+
export type { DomainsResult } from './apps/domains.hook.js';
|
|
10
12
|
export { useOpenApp } from './apps/open-app.hook.js';
|
|
11
13
|
export { AppHost } from './apps/app-host.js';
|
|
12
14
|
export type { AppHostFallbackState, AppHostProps } from './apps/app-host.js';
|
|
@@ -14,5 +16,5 @@ export { AppLogo } from './apps/app-logo.js';
|
|
|
14
16
|
export type { AppLogoProps } from './apps/app-logo.js';
|
|
15
17
|
export { useRoles } from './roles.hook.js';
|
|
16
18
|
export type { RolesResult } from './roles.hook.js';
|
|
17
|
-
export type { ApplicationNode, AppSession, RoleNode, SpaceNode, UserNode } from '@astrale-os/shell';
|
|
19
|
+
export type { ApplicationNode, AppSession, DomainSearchResult, RoleNode, SpaceNode, UserNode, } from '@astrale-os/shell';
|
|
18
20
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/application/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACnD,YAAY,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAA;AAChE,YAAY,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,YAAY,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AACnD,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAA;AAC5C,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAC1C,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAGlD,YAAY,EACV,eAAe,EACf,UAAU,EACV,kBAAkB,EAClB,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,MAAM,mBAAmB,CAAA"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
// application — API §12.2. The OS-plane hooks over the shell package's
|
|
2
2
|
// `shell.user/spaces/apps` namespaces + the window module: useUser, useSpaces,
|
|
3
|
-
// useCurrentSpace, useSpace, useApps, useRoles, useOpenApp,
|
|
3
|
+
// useCurrentSpace, useSpace, useApps, useDomains, useRoles, useOpenApp,
|
|
4
|
+
// AppHost, AppLogo.
|
|
4
5
|
export { useUser } from './user/user.hook.js';
|
|
5
6
|
export { useSpaces } from './spaces/spaces.hook.js';
|
|
6
7
|
export { useCurrentSpace } from './spaces/current-space.hook.js';
|
|
7
8
|
export { useSpace } from './spaces/space.hook.js';
|
|
8
9
|
export { useApps } from './apps/apps.hook.js';
|
|
10
|
+
export { useDomains } from './apps/domains.hook.js';
|
|
9
11
|
export { useOpenApp } from './apps/open-app.hook.js';
|
|
10
12
|
export { AppHost } from './apps/app-host.js';
|
|
11
13
|
export { AppLogo } from './apps/app-logo.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user.store.d.ts","sourceRoot":"","sources":["../../../src/application/user/user.store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAExD,MAAM,MAAM,SAAS,GACjB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACxC,qFAAqF;GACnF;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAE7C,eAAO,MAAM,SAAS,2BAAkC,CAAA;AAKxD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAExD;
|
|
1
|
+
{"version":3,"file":"user.store.d.ts","sourceRoot":"","sources":["../../../src/application/user/user.store.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAA;AAExD,MAAM,MAAM,SAAS,GACjB;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAC7C;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAA;CAAE,GACvC;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE;AACxC,qFAAqF;GACnF;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAAA;AAE7C,eAAO,MAAM,SAAS,2BAAkC,CAAA;AAKxD,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAExD;AAeD;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB3D;AAED,wFAAwF;AACxF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAoBhD"}
|
|
@@ -7,7 +7,8 @@ export function isOsPlaneAvailable(shell) {
|
|
|
7
7
|
}
|
|
8
8
|
function osPlaneError(cause) {
|
|
9
9
|
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
10
|
-
return new Error(`The OS plane is unavailable (useUser/useSpaces/useApps):
|
|
10
|
+
return new Error(`The OS plane is unavailable (useUser/useSpaces/useApps/useDomains): ` +
|
|
11
|
+
`shell.user.me() could not resolve ` +
|
|
11
12
|
`— the workspace/shell domain may not be installed for this identity. (${detail})`);
|
|
12
13
|
}
|
|
13
14
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -28,9 +28,9 @@ export { useCloseGuard, useTargetNode, useViewsFor, useWindow, useWindowList, us
|
|
|
28
28
|
export type { CloseGuard, CloseVerdict, ViewDescriptor, ViewHostProps, ViewSource, ViewHostHandle, ViewsForResult, WindowListEntry, WindowState, WindowView, } from './window/index.js';
|
|
29
29
|
export { useEmitIntent, useIntent, useSendIntent } from './intents/index.js';
|
|
30
30
|
export type { EmitIntent, IntentCtx, IntentPayload, IntentReply, SendIntent, } from './intents/index.js';
|
|
31
|
-
export { AppHost, AppLogo, useApps, useCurrentSpace, useOpenApp, useRoles, useSpace, useSpaces, useUser, } from './application/index.js';
|
|
32
|
-
export type { AppHostFallbackState, AppHostProps, AppLogoProps, AppsResult, CurrentSpaceResult, RolesResult, SpaceResult, SpacesResult, } from './application/index.js';
|
|
33
|
-
export type { ApplicationNode, AppSession, RoleNode, SpaceNode, UserNode } from '@astrale-os/shell';
|
|
31
|
+
export { AppHost, AppLogo, useApps, useCurrentSpace, useOpenApp, useRoles, useDomains, useSpace, useSpaces, useUser, } from './application/index.js';
|
|
32
|
+
export type { AppHostFallbackState, AppHostProps, AppLogoProps, AppsResult, CurrentSpaceResult, RolesResult, DomainsResult, SpaceResult, SpacesResult, } from './application/index.js';
|
|
33
|
+
export type { ApplicationNode, AppSession, DomainSearchResult, RoleNode, SpaceNode, UserNode, } from '@astrale-os/shell';
|
|
34
34
|
export type { Action, ReadState, ReadOptions, Windowed } from './graph/index.js';
|
|
35
35
|
export * from './graph/guards.error.js';
|
|
36
36
|
export { DESCRIPTION_KEY, NAME_KEY, STATUS_KEY, descriptionOf, nameOf, normalizeRef, statusOf, } from '@astrale-os/kernel-client';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ export { useCloseGuard, useTargetNode, useViewsFor, useWindow, useWindowList, us
|
|
|
27
27
|
// ─── intents (§11) ───────────────────────────────────────────────────────────
|
|
28
28
|
export { useEmitIntent, useIntent, useSendIntent } from './intents/index.js';
|
|
29
29
|
// ─── application — the OS plane (§12) ────────────────────────────────────────
|
|
30
|
-
export { AppHost, AppLogo, useApps, useCurrentSpace, useOpenApp, useRoles, useSpace, useSpaces, useUser, } from './application/index.js';
|
|
30
|
+
export { AppHost, AppLogo, useApps, useCurrentSpace, useOpenApp, useRoles, useDomains, useSpace, useSpaces, useUser, } from './application/index.js';
|
|
31
31
|
// ─── error taxonomy (§1.4) — guards + classes, re-exported from kernel-client ─
|
|
32
32
|
export * from './graph/guards.error.js';
|
|
33
33
|
// ─── re-exported kernel-client types (one import surface, §0 preamble) ───────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"send-intent.hook.d.ts","sourceRoot":"","sources":["../../src/intents/send-intent.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAWtE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAM/D,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IACzB,CAAC,CAAC,SAAS,MAAM,cAAc,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IACzB,oFAAoF;IACpF,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAE,GAChC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;CAClC;AAED,wBAAgB,aAAa,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"send-intent.hook.d.ts","sourceRoot":"","sources":["../../src/intents/send-intent.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAWtE,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAM/D,0DAA0D;AAC1D,MAAM,WAAW,UAAU;IACzB,CAAC,CAAC,SAAS,MAAM,cAAc,EAC7B,IAAI,EAAE,CAAC,EACP,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;IACzB,oFAAoF;IACpF,IAAI,CAAC,EAAE;QAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAAA;KAAE,GAChC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAA;CAClC;AAED,wBAAgB,aAAa,IAAI,UAAU,CAiF1C"}
|
|
@@ -29,7 +29,7 @@ export function useSendIntent() {
|
|
|
29
29
|
const correlationId = crypto.randomUUID();
|
|
30
30
|
const message = intentMessage(name, payload, correlationId);
|
|
31
31
|
const pending = pendingRef.current;
|
|
32
|
-
return new Promise((resolve) => {
|
|
32
|
+
return new Promise((resolve, reject) => {
|
|
33
33
|
let done = false;
|
|
34
34
|
let offReply = NOOP;
|
|
35
35
|
let offClose = NOOP;
|
|
@@ -43,12 +43,25 @@ export function useSendIntent() {
|
|
|
43
43
|
pending.delete(onUnmount);
|
|
44
44
|
resolve(value);
|
|
45
45
|
}
|
|
46
|
+
function fail(error) {
|
|
47
|
+
if (done)
|
|
48
|
+
return;
|
|
49
|
+
done = true;
|
|
50
|
+
offReply();
|
|
51
|
+
offClose();
|
|
52
|
+
pending.delete(onUnmount);
|
|
53
|
+
reject(error);
|
|
54
|
+
}
|
|
46
55
|
const onReply = (m) => {
|
|
47
56
|
if (m.envelope.name !== INTENT_REPLY)
|
|
48
57
|
return;
|
|
49
58
|
const reply = m.envelope.payload;
|
|
50
59
|
if (reply.correlationId !== correlationId)
|
|
51
60
|
return;
|
|
61
|
+
if (reply.error) {
|
|
62
|
+
fail(new Error(reply.error.message));
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
52
65
|
settle(reply.result);
|
|
53
66
|
};
|
|
54
67
|
pending.add(onUnmount);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"views-for.hook.d.ts","sourceRoot":"","sources":["../../../src/window/hooks/views-for.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAW/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAKjE,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;CAC1C;
|
|
1
|
+
{"version":3,"file":"views-for.hook.d.ts","sourceRoot":"","sources":["../../../src/window/hooks/views-for.hook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAA;AAW/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAKjE,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C,QAAQ,CAAC,KAAK,EAAE,SAAS,cAAc,EAAE,CAAA;CAC1C;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,CAqBpF"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { K } from '@astrale-os/kernel-core';
|
|
2
1
|
/**
|
|
3
2
|
* useViewsFor (API §10) — "what Views can render this node", as mountable
|
|
4
3
|
* `ViewDescriptor`s for the open-with menu. Backed one-shot (`live:false`) by the
|
|
@@ -7,14 +6,12 @@ import { K } from '@astrale-os/kernel-core';
|
|
|
7
6
|
*/
|
|
8
7
|
import { useMemo } from 'react';
|
|
9
8
|
import { useAsyncResource } from '../../graph/async.js';
|
|
10
|
-
import {
|
|
11
|
-
/** The `View.resolve` wire address — the qualified static-method slug from the schema. */
|
|
12
|
-
const VIEW_RESOLVE_METHOD = K.View.resolve.path.method.raw;
|
|
9
|
+
import { useShell } from '../../session/shell.hook.js';
|
|
13
10
|
const NO_VIEWS = Object.freeze([]);
|
|
14
11
|
export function useViewsFor(node) {
|
|
15
|
-
const
|
|
12
|
+
const shell = useShell();
|
|
16
13
|
const target = resolvePath(node);
|
|
17
|
-
const res = useAsyncResource(target === null ? null : () => resolveViews(
|
|
14
|
+
const res = useAsyncResource(target === null ? null : () => resolveViews(shell, target), NO_VIEWS, [shell, target]);
|
|
18
15
|
return useMemo(() => ({
|
|
19
16
|
views: res.data,
|
|
20
17
|
pending: res.pending,
|
|
@@ -25,9 +22,9 @@ export function useViewsFor(node) {
|
|
|
25
22
|
}), [res.data, res.pending, res.error, res.refetch]);
|
|
26
23
|
}
|
|
27
24
|
/** Dispatch `View.resolve` and project its rows to mountable `ViewDescriptor`s. */
|
|
28
|
-
async function resolveViews(
|
|
29
|
-
const rows =
|
|
30
|
-
if (rows
|
|
25
|
+
async function resolveViews(shell, node) {
|
|
26
|
+
const rows = await shell.views.resolve(node);
|
|
27
|
+
if (rows.length === 0)
|
|
31
28
|
return NO_VIEWS;
|
|
32
29
|
return rows.map((r) => ({ id: r.id, path: r.path, url: r.url, handshake: r.handshake }));
|
|
33
30
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/window/lifecycle/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE5D,+EAA+E;AAC/E,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAExE,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;
|
|
1
|
+
{"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/window/lifecycle/mount.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAA;AAC7D;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAE5D,+EAA+E;AAC/E,MAAM,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;AAExE,kFAAkF;AAClF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAC5B;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,cAAc,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpG,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAA;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AA2ED,4EAA4E;AAC5E,wBAAsB,aAAa,CACjC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,cAAc,CAAC,CAgBzB;AAED,uEAAuE;AACvE,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAOpD;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,GAAG,EAAE,YAAY,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKzE;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAGlE;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAMlF"}
|
|
@@ -24,7 +24,7 @@ async function resolveViewRef(kernel, ref, handshakeHint) {
|
|
|
24
24
|
if (node === null)
|
|
25
25
|
throw new Error(`ViewHost: view not found (${toPath(ref)})`);
|
|
26
26
|
const props = node.props ?? {};
|
|
27
|
-
const url = props
|
|
27
|
+
const url = viewUrl(props);
|
|
28
28
|
if (typeof url !== 'string' || url.length === 0) {
|
|
29
29
|
throw new Error('ViewHost: resolved view has no url');
|
|
30
30
|
}
|
|
@@ -32,6 +32,37 @@ async function resolveViewRef(kernel, ref, handshakeHint) {
|
|
|
32
32
|
const id = node.id ?? slugOfUrl(url);
|
|
33
33
|
return { url, handshake, functionId: id };
|
|
34
34
|
}
|
|
35
|
+
/** Resolve both the legacy flat url and the canonical Function binding. */
|
|
36
|
+
function viewUrl(props) {
|
|
37
|
+
if (typeof props.url === 'string' && props.url.length > 0)
|
|
38
|
+
return props.url;
|
|
39
|
+
const direct = remoteUrlOf(props.binding);
|
|
40
|
+
if (direct !== undefined)
|
|
41
|
+
return direct;
|
|
42
|
+
// Raw graph props can be keyed by the property's canonical graph key rather
|
|
43
|
+
// than its local slug. The binding value remains self-describing.
|
|
44
|
+
for (const value of Object.values(props)) {
|
|
45
|
+
const remoteUrl = remoteUrlOf(value);
|
|
46
|
+
if (remoteUrl !== undefined)
|
|
47
|
+
return remoteUrl;
|
|
48
|
+
}
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
function remoteUrlOf(value) {
|
|
52
|
+
let binding = value;
|
|
53
|
+
if (typeof binding === 'string') {
|
|
54
|
+
try {
|
|
55
|
+
binding = JSON.parse(binding);
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
if (binding === null || typeof binding !== 'object')
|
|
62
|
+
return undefined;
|
|
63
|
+
const remoteUrl = binding.remoteUrl;
|
|
64
|
+
return typeof remoteUrl === 'string' && remoteUrl.length > 0 ? remoteUrl : undefined;
|
|
65
|
+
}
|
|
35
66
|
function normalizeHandshake(value) {
|
|
36
67
|
return value === 'none' ? 'none' : 'shell';
|
|
37
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrale-os/shell-react",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.8",
|
|
4
4
|
"description": "Astrale shell-react — the React face of the shell (provider, hooks, view components)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"react-dom": "^19.2.0",
|
|
45
45
|
"typescript": "~6.0.1-rc",
|
|
46
46
|
"vitest": "^3.2.4",
|
|
47
|
-
"@astrale-os/shell": "0.3.
|
|
47
|
+
"@astrale-os/shell": "0.3.6"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@astrale-os/shell": ">=0.2.0 <1.0.0",
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { DomainSearchResult } from '@astrale-os/shell'
|
|
2
|
+
|
|
3
|
+
import { useMemo } from 'react'
|
|
4
|
+
|
|
5
|
+
import type { ReadState } from '../../graph/memory/read/envelope.js'
|
|
6
|
+
|
|
7
|
+
import { useAsyncResource } from '../../graph/async.js'
|
|
8
|
+
import { useShell } from '../../session/shell.hook.js'
|
|
9
|
+
import { isOsPlaneAvailable } from '../user/user.store.js'
|
|
10
|
+
|
|
11
|
+
const NO_DOMAINS: readonly DomainSearchResult[] = []
|
|
12
|
+
|
|
13
|
+
export interface DomainsResult extends ReadState {
|
|
14
|
+
readonly domains: readonly DomainSearchResult[]
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export function useDomains(): DomainsResult {
|
|
18
|
+
const shell = useShell()
|
|
19
|
+
const available = isOsPlaneAvailable(shell)
|
|
20
|
+
const result = useAsyncResource<readonly DomainSearchResult[]>(
|
|
21
|
+
available ? () => shell.apps.searchDomains() : null,
|
|
22
|
+
NO_DOMAINS,
|
|
23
|
+
[shell, available],
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
return useMemo(
|
|
27
|
+
() => ({
|
|
28
|
+
domains: result.data,
|
|
29
|
+
pending: result.pending,
|
|
30
|
+
error: result.error,
|
|
31
|
+
live: false,
|
|
32
|
+
seq: 0,
|
|
33
|
+
refetch: result.refetch,
|
|
34
|
+
}),
|
|
35
|
+
[result],
|
|
36
|
+
)
|
|
37
|
+
}
|
package/src/application/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// application — API §12.2. The OS-plane hooks over the shell package's
|
|
2
2
|
// `shell.user/spaces/apps` namespaces + the window module: useUser, useSpaces,
|
|
3
|
-
// useCurrentSpace, useSpace, useApps, useRoles, useOpenApp,
|
|
3
|
+
// useCurrentSpace, useSpace, useApps, useDomains, useRoles, useOpenApp,
|
|
4
|
+
// AppHost, AppLogo.
|
|
4
5
|
export { useUser } from './user/user.hook.js'
|
|
5
6
|
export { useSpaces } from './spaces/spaces.hook.js'
|
|
6
7
|
export type { SpacesResult } from './spaces/spaces.hook.js'
|
|
@@ -10,6 +11,8 @@ export { useSpace } from './spaces/space.hook.js'
|
|
|
10
11
|
export type { SpaceResult } from './spaces/space.hook.js'
|
|
11
12
|
export { useApps } from './apps/apps.hook.js'
|
|
12
13
|
export type { AppsResult } from './apps/apps.hook.js'
|
|
14
|
+
export { useDomains } from './apps/domains.hook.js'
|
|
15
|
+
export type { DomainsResult } from './apps/domains.hook.js'
|
|
13
16
|
export { useOpenApp } from './apps/open-app.hook.js'
|
|
14
17
|
export { AppHost } from './apps/app-host.js'
|
|
15
18
|
export type { AppHostFallbackState, AppHostProps } from './apps/app-host.js'
|
|
@@ -19,4 +22,11 @@ export { useRoles } from './roles.hook.js'
|
|
|
19
22
|
export type { RolesResult } from './roles.hook.js'
|
|
20
23
|
|
|
21
24
|
// The OS node/session types (from the shell package, single import surface).
|
|
22
|
-
export type {
|
|
25
|
+
export type {
|
|
26
|
+
ApplicationNode,
|
|
27
|
+
AppSession,
|
|
28
|
+
DomainSearchResult,
|
|
29
|
+
RoleNode,
|
|
30
|
+
SpaceNode,
|
|
31
|
+
UserNode,
|
|
32
|
+
} from '@astrale-os/shell'
|
|
@@ -31,7 +31,8 @@ interface UserSurface {
|
|
|
31
31
|
function osPlaneError(cause: unknown): Error {
|
|
32
32
|
const detail = cause instanceof Error ? cause.message : String(cause)
|
|
33
33
|
return new Error(
|
|
34
|
-
`The OS plane is unavailable (useUser/useSpaces/useApps):
|
|
34
|
+
`The OS plane is unavailable (useUser/useSpaces/useApps/useDomains): ` +
|
|
35
|
+
`shell.user.me() could not resolve ` +
|
|
35
36
|
`— the workspace/shell domain may not be installed for this identity. (${detail})`,
|
|
36
37
|
)
|
|
37
38
|
}
|
package/src/index.ts
CHANGED
|
@@ -134,6 +134,7 @@ export {
|
|
|
134
134
|
useCurrentSpace,
|
|
135
135
|
useOpenApp,
|
|
136
136
|
useRoles,
|
|
137
|
+
useDomains,
|
|
137
138
|
useSpace,
|
|
138
139
|
useSpaces,
|
|
139
140
|
useUser,
|
|
@@ -145,11 +146,19 @@ export type {
|
|
|
145
146
|
AppsResult,
|
|
146
147
|
CurrentSpaceResult,
|
|
147
148
|
RolesResult,
|
|
149
|
+
DomainsResult,
|
|
148
150
|
SpaceResult,
|
|
149
151
|
SpacesResult,
|
|
150
152
|
} from './application/index.js'
|
|
151
153
|
// OS node/session types (from the shell package, single import surface).
|
|
152
|
-
export type {
|
|
154
|
+
export type {
|
|
155
|
+
ApplicationNode,
|
|
156
|
+
AppSession,
|
|
157
|
+
DomainSearchResult,
|
|
158
|
+
RoleNode,
|
|
159
|
+
SpaceNode,
|
|
160
|
+
UserNode,
|
|
161
|
+
} from '@astrale-os/shell'
|
|
153
162
|
|
|
154
163
|
// ─── shared envelopes (§1) ───────────────────────────────────────────────────
|
|
155
164
|
export type { Action, ReadState, ReadOptions, Windowed } from './graph/index.js'
|
|
@@ -51,7 +51,7 @@ export function useSendIntent(): SendIntent {
|
|
|
51
51
|
const message = intentMessage(name, payload, correlationId)
|
|
52
52
|
const pending = pendingRef.current
|
|
53
53
|
|
|
54
|
-
return new Promise<IntentReply<K> | void>((resolve) => {
|
|
54
|
+
return new Promise<IntentReply<K> | void>((resolve, reject) => {
|
|
55
55
|
let done = false
|
|
56
56
|
let offReply = NOOP
|
|
57
57
|
let offClose = NOOP
|
|
@@ -64,10 +64,26 @@ export function useSendIntent(): SendIntent {
|
|
|
64
64
|
pending.delete(onUnmount)
|
|
65
65
|
resolve(value)
|
|
66
66
|
}
|
|
67
|
+
function fail(error: Error): void {
|
|
68
|
+
if (done) return
|
|
69
|
+
done = true
|
|
70
|
+
offReply()
|
|
71
|
+
offClose()
|
|
72
|
+
pending.delete(onUnmount)
|
|
73
|
+
reject(error)
|
|
74
|
+
}
|
|
67
75
|
const onReply = (m: IntentMessage): void => {
|
|
68
76
|
if (m.envelope.name !== INTENT_REPLY) return
|
|
69
|
-
const reply = m.envelope.payload as {
|
|
77
|
+
const reply = m.envelope.payload as {
|
|
78
|
+
correlationId: string
|
|
79
|
+
result?: unknown
|
|
80
|
+
error?: { message: string }
|
|
81
|
+
}
|
|
70
82
|
if (reply.correlationId !== correlationId) return
|
|
83
|
+
if (reply.error) {
|
|
84
|
+
fail(new Error(reply.error.message))
|
|
85
|
+
return
|
|
86
|
+
}
|
|
71
87
|
settle(reply.result as IntentReply<K>)
|
|
72
88
|
}
|
|
73
89
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { PathLike } from '@astrale-os/kernel-client/graph'
|
|
2
|
+
import type { Shell } from '@astrale-os/shell'
|
|
2
3
|
|
|
3
|
-
import { K } from '@astrale-os/kernel-core'
|
|
4
4
|
/**
|
|
5
5
|
* useViewsFor (API §10) — "what Views can render this node", as mountable
|
|
6
6
|
* `ViewDescriptor`s for the open-with menu. Backed one-shot (`live:false`) by the
|
|
@@ -13,35 +13,22 @@ import type { ReadState } from '../../graph/memory/read/envelope.js'
|
|
|
13
13
|
import type { Node, ViewDescriptor } from '../lifecycle/mount.js'
|
|
14
14
|
|
|
15
15
|
import { useAsyncResource } from '../../graph/async.js'
|
|
16
|
-
import {
|
|
16
|
+
import { useShell } from '../../session/shell.hook.js'
|
|
17
17
|
|
|
18
18
|
export interface ViewsForResult extends ReadState {
|
|
19
19
|
readonly views: readonly ViewDescriptor[]
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
/** The `View.resolve` wire address — the qualified static-method slug from the schema. */
|
|
23
|
-
const VIEW_RESOLVE_METHOD = K.View.resolve.path.method.raw
|
|
24
|
-
|
|
25
|
-
/** The kernel `View.resolve` row shape (id/path/url/name?/handshake?/origin). */
|
|
26
|
-
interface ViewOut {
|
|
27
|
-
readonly id: string
|
|
28
|
-
readonly path: string
|
|
29
|
-
readonly url: string
|
|
30
|
-
readonly name?: string
|
|
31
|
-
readonly handshake?: 'shell' | 'none'
|
|
32
|
-
readonly origin: 'self' | 'class'
|
|
33
|
-
}
|
|
34
|
-
|
|
35
22
|
const NO_VIEWS: readonly ViewDescriptor[] = Object.freeze([])
|
|
36
23
|
|
|
37
24
|
export function useViewsFor(node: Node | PathLike | null | undefined): ViewsForResult {
|
|
38
|
-
const
|
|
25
|
+
const shell = useShell()
|
|
39
26
|
const target = resolvePath(node)
|
|
40
27
|
|
|
41
28
|
const res = useAsyncResource<readonly ViewDescriptor[]>(
|
|
42
|
-
target === null ? null : () => resolveViews(
|
|
29
|
+
target === null ? null : () => resolveViews(shell, target),
|
|
43
30
|
NO_VIEWS,
|
|
44
|
-
[
|
|
31
|
+
[shell, target],
|
|
45
32
|
)
|
|
46
33
|
|
|
47
34
|
return useMemo<ViewsForResult>(
|
|
@@ -58,12 +45,9 @@ export function useViewsFor(node: Node | PathLike | null | undefined): ViewsForR
|
|
|
58
45
|
}
|
|
59
46
|
|
|
60
47
|
/** Dispatch `View.resolve` and project its rows to mountable `ViewDescriptor`s. */
|
|
61
|
-
async function resolveViews(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
): Promise<readonly ViewDescriptor[]> {
|
|
65
|
-
const rows = (await kernel.call(VIEW_RESOLVE_METHOD, { node })) as ViewOut[] | null | undefined
|
|
66
|
-
if (rows === null || rows === undefined || rows.length === 0) return NO_VIEWS
|
|
48
|
+
async function resolveViews(shell: Shell, node: string): Promise<readonly ViewDescriptor[]> {
|
|
49
|
+
const rows = await shell.views.resolve(node)
|
|
50
|
+
if (rows.length === 0) return NO_VIEWS
|
|
67
51
|
return rows.map((r) => ({ id: r.id, path: r.path, url: r.url, handshake: r.handshake }))
|
|
68
52
|
}
|
|
69
53
|
|
|
@@ -62,7 +62,7 @@ async function resolveViewRef(
|
|
|
62
62
|
const node = await kernel.get(toPath(ref))
|
|
63
63
|
if (node === null) throw new Error(`ViewHost: view not found (${toPath(ref)})`)
|
|
64
64
|
const props = (node as { id?: string; props?: Record<string, unknown> }).props ?? {}
|
|
65
|
-
const url = props
|
|
65
|
+
const url = viewUrl(props)
|
|
66
66
|
if (typeof url !== 'string' || url.length === 0) {
|
|
67
67
|
throw new Error('ViewHost: resolved view has no url')
|
|
68
68
|
}
|
|
@@ -71,6 +71,36 @@ async function resolveViewRef(
|
|
|
71
71
|
return { url, handshake, functionId: id }
|
|
72
72
|
}
|
|
73
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
|
+
|
|
74
104
|
function normalizeHandshake(value: unknown): 'shell' | 'none' {
|
|
75
105
|
return value === 'none' ? 'none' : 'shell'
|
|
76
106
|
}
|