@astrale-os/shell-react 0.2.6 → 0.2.7
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/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/package.json +2 -2
- package/src/intents/send-intent.hook.ts +18 -2
- package/src/window/hooks/views-for.hook.ts +8 -24
|
@@ -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
|
}
|
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.7",
|
|
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.5"
|
|
48
48
|
},
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"@astrale-os/shell": ">=0.2.0 <1.0.0",
|
|
@@ -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
|
|