@fungi.computer/agar 0.7.1 → 0.7.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/gills.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { type AppDeclaredGill, type AppGillDesktopSize, type AppGillParam, type AppGillWatch, type GillCall, type GillReply } from "@fungi.computer/gills";
2
2
  import type { WhistleJsonValue } from "@fungi.computer/whistle";
3
3
  import { type GillResponse } from "@fungi.computer/gills";
4
- /** Decode the App host's strict isolation refusal into its permanent Gill state. */
4
+ /** Decode the App host's isolation or disabled refusal into a typed Gill state. */
5
5
  export declare function decodeGillRefusal(raw: unknown, declaration: Readonly<{
6
6
  id: string;
7
7
  title: string;
package/dist/gills.js CHANGED
@@ -3,10 +3,12 @@ import * as Schema from "effect/Schema";
3
3
  import { appDeclaredGillSchema, decodeDeclaredGillResponse, decodeGillOptionsResponse, gillCallSchema, } from "@fungi.computer/gills";
4
4
  import { appBackendRefusalSchema } from "./backend-refusal.js";
5
5
  import { decodeGillResponse } from "@fungi.computer/gills";
6
- /** Decode the App host's strict isolation refusal into its permanent Gill state. */
6
+ /** Decode the App host's isolation or disabled refusal into a typed Gill state. */
7
7
  export function decodeGillRefusal(raw, declaration) {
8
8
  const refusal = appBackendRefusalSchema.safeParse(raw);
9
- if (!refusal.success || refusal.data.reason !== "exec_isolation_required")
9
+ if (!refusal.success ||
10
+ (refusal.data.reason !== "exec_isolation_required" &&
11
+ refusal.data.reason !== "disabled"))
10
12
  return undefined;
11
13
  return decodeGillResponse({
12
14
  viewId: declaration.id,
@@ -14,7 +16,9 @@ export function decodeGillRefusal(raw, declaration) {
14
16
  state: "error",
15
17
  rows: [],
16
18
  reason: refusal.data.reason,
17
- error: `${declaration.title} isn't available on this preview.`,
19
+ error: refusal.data.reason === "disabled"
20
+ ? `${declaration.title} is disabled.`
21
+ : `${declaration.title} isn't available on this preview.`,
18
22
  });
19
23
  }
20
24
  /** Define a compact view of one of this App's declared read methods. */
@@ -1,9 +1,10 @@
1
1
  import * as Predicate from "effect/Predicate";
2
2
  import { RpcTarget } from "@fungi.computer/capnweb";
3
+ import { correlationKey } from "@fungi.computer/cairn";
3
4
  import { WhistleActionError } from "@fungi.computer/whistle";
4
5
  import { parseFailure } from "@fungi.computer/whistle/wire";
5
6
  import { AppError } from "../errors.js";
6
- import { callRpc, rpcFailure, rpcSuccess } from "./result.js";
7
+ import { callRpc, rpcFailure, rpcSuccess, unwrapRpcResult, } from "./result.js";
7
8
  import { appInvocation, parseCommand, parseCommandId, parseCommandInvocation, parseCommandResult, parseRegisteredCommandResult, parseVoidResult, } from "./schemas.js";
8
9
  class CommandHandlerTarget extends RpcTarget {
9
10
  #active = true;
@@ -96,8 +97,8 @@ class CommandHandlerTarget extends RpcTarget {
96
97
  function localBindings(registrations) {
97
98
  const bindings = [];
98
99
  for (const registration of registrations.values()) {
99
- const { definition, handler } = registration;
100
- if (registration.commandId === undefined)
100
+ const { commandId, definition, target } = registration;
101
+ if (commandId === undefined)
101
102
  continue;
102
103
  // An unavailable command still owns its chord, so the browser default
103
104
  // (e.g. Save Page) does not run in its place.
@@ -111,10 +112,15 @@ function localBindings(registrations) {
111
112
  if (!available)
112
113
  return;
113
114
  void Promise.resolve()
114
- .then(() => handler({
115
- origin: "keyboard",
116
- signal: new AbortController().signal,
117
- }))
115
+ .then(async () => {
116
+ const outcome = unwrapRpcResult(await target.invoke({
117
+ commandId,
118
+ origin: "keyboard",
119
+ requestId: correlationKey(),
120
+ }));
121
+ if (outcome.status === "failed")
122
+ throw new WhistleActionError(outcome.error.code, outcome.error.message, outcome.error.details);
123
+ })
118
124
  .catch((cause) => {
119
125
  console.warn("App key command failed", cause);
120
126
  });
@@ -175,7 +181,7 @@ export function createAppCommands(remote, assertConnected, onFatal, bindings) {
175
181
  },
176
182
  };
177
183
  }
178
- function claimRegistration(registrations, definition, handler, target) {
184
+ function claimRegistration(registrations, definition, target) {
179
185
  const id = definition.id;
180
186
  if (registrations.size >= 128 || registrations.has(id)) {
181
187
  target.dispose();
@@ -187,7 +193,6 @@ function claimRegistration(registrations, definition, handler, target) {
187
193
  const registration = {
188
194
  commandId: undefined,
189
195
  definition,
190
- handler,
191
196
  target,
192
197
  };
193
198
  registrations.set(id, registration);
@@ -221,7 +226,7 @@ function createCommandApi(remote, assertConnected, registrations, isDisposed, un
221
226
  }
222
227
  const definition = parseCommand(command);
223
228
  const target = new CommandHandlerTarget(handler);
224
- const lease = claimRegistration(registrations, definition, handler, target);
229
+ const lease = claimRegistration(registrations, definition, target);
225
230
  try {
226
231
  const registration = await registerRemoteCommand(remote, definition, lease.target);
227
232
  if (isDisposed()) {
@@ -1,7 +1,7 @@
1
1
  import * as z from "zod";
2
2
  /** One canonical identity for a retryable Media operation. */
3
3
  export declare const mediaRequestIds: Readonly<{
4
- readonly request: import("@fungi.computer/cairn/id").IdCodec<"hub-media-request", "request", 1>;
4
+ readonly request: import("@fungi.computer/cairn").IdCodec<"hub-media-request", "request", 1>;
5
5
  }>;
6
6
  /** Public wire grammar for the canonical retry identity, visible in App JSON schemas. */
7
7
  export declare const mediaRequestIdSchema: z.ZodLazy<z.ZodString>;
package/docs/api/gills.md CHANGED
@@ -49,7 +49,7 @@ function decodeGillRefusal(
49
49
  title: string;
50
50
  state: "error";
51
51
  rows: readonly [];
52
- reason?: "exec_isolation_required" | "params_required";
52
+ reason?: "disabled" | "exec_isolation_required" | "params_required";
53
53
  error: string;
54
54
  recovery?:
55
55
  | {
@@ -70,7 +70,7 @@ function decodeGillRefusal(
70
70
  | undefined;
71
71
  ```
72
72
 
73
- Decode the App host's strict isolation refusal into its permanent Gill state.
73
+ Decode the App host's isolation or disabled refusal into a typed Gill state.
74
74
 
75
75
  #### Parameters
76
76
 
@@ -103,7 +103,7 @@ Decode the App host's strict isolation refusal into its permanent Gill state.
103
103
  title: string;
104
104
  state: "error";
105
105
  rows: readonly [];
106
- reason?: "exec_isolation_required" | "params_required";
106
+ reason?: "disabled" | "exec_isolation_required" | "params_required";
107
107
  error: string;
108
108
  recovery?: | {
109
109
  kind: "configure";
@@ -121,7 +121,7 @@ Decode the App host's strict isolation refusal into its permanent Gill state.
121
121
  | `title` | `string` | - |
122
122
  | `state` | `"error"` | - |
123
123
  | `rows` | readonly \[\] | - |
124
- | `reason?` | `"exec_isolation_required"` \| `"params_required"` | Host-owned permanent execution refusal; an ordinary error may still be refreshed. |
124
+ | `reason?` | `"disabled"` \| `"exec_isolation_required"` \| `"params_required"` | Host-owned permanent execution refusal; an ordinary error may still be refreshed. |
125
125
  | `error` | `string` | - |
126
126
  | `recovery?` | \| \{ `kind`: `"configure"`; `param`: `string`; \} \| \{ `kind`: `"open"`; \} | The host supplies the same-placement picker and this App's launch. |
127
127
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fungi.computer/agar",
3
- "version": "0.7.1",
3
+ "version": "0.7.2",
4
4
  "author": "Levi <levi@technomancy.dev>",
5
5
  "description": "App contract for fungi.computer: typed backend methods, host capabilities and the App frontend connection",
6
6
  "type": "module",
@@ -168,20 +168,20 @@
168
168
  }
169
169
  },
170
170
  "dependencies": {
171
- "@fungi.computer/puffball": "0.5.1",
171
+ "@fungi.computer/puffball": "0.5.2",
172
172
  "@fungi.computer/whistle": "0.3.0",
173
173
  "@opentui/keymap": "0.5.10",
174
- "@fungi.computer/capnweb": "0.12.0",
174
+ "@fungi.computer/capnweb": "0.12.0-fungi.0",
175
175
  "effect": "4.0.2",
176
176
  "zod": "4.4.3",
177
177
  "@fungi.computer/stipe": "0.1.0",
178
178
  "eventsource": "5.1.1",
179
179
  "isomorphic-git": "1.42.2",
180
180
  "buffer": "6.0.3",
181
- "@fungi.computer/gills": "0.2.1",
181
+ "@fungi.computer/gills": "0.2.2",
182
182
  "@fungi.computer/cairn": "0.1.0",
183
183
  "@fungi.computer/sprite": "0.2.0",
184
- "@fungi.computer/approvals": "0.2.0"
184
+ "@fungi.computer/approvals": "0.2.1"
185
185
  },
186
186
  "peerDependencies": {
187
187
  "react": "^18.3.1 || ^19.2.0",