@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.
@@ -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,CAiE1C"}
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;AAiBD,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,GAAG,IAAI,GAAG,SAAS,GAAG,cAAc,CAqBpF"}
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 { useKernelClient } from '../../session/kernel-client.hook.js';
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 kernel = useKernelClient();
12
+ const shell = useShell();
16
13
  const target = resolvePath(node);
17
- const res = useAsyncResource(target === null ? null : () => resolveViews(kernel, target), NO_VIEWS, [kernel, target]);
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(kernel, node) {
29
- const rows = (await kernel.call(VIEW_RESOLVE_METHOD, { node }));
30
- if (rows === null || rows === undefined || rows.length === 0)
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.6",
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.4"
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 { correlationId: string; result: unknown }
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 { useKernelClient } from '../../session/kernel-client.hook.js'
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 kernel = useKernelClient()
25
+ const shell = useShell()
39
26
  const target = resolvePath(node)
40
27
 
41
28
  const res = useAsyncResource<readonly ViewDescriptor[]>(
42
- target === null ? null : () => resolveViews(kernel, target),
29
+ target === null ? null : () => resolveViews(shell, target),
43
30
  NO_VIEWS,
44
- [kernel, target],
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
- kernel: { call(method: string, params: unknown): Promise<unknown> },
63
- node: string,
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