@agentorg/cli 0.0.4 → 0.0.6
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/README.md +18 -102
- package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.d.ts +2 -7
- package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.js +4 -111
- package/dist/node_modules/@agentorg/hub/dist/src/index.d.ts +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/index.js +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/router.d.ts +6 -57
- package/dist/node_modules/@agentorg/hub/dist/src/router.js +38 -413
- package/dist/node_modules/@agentorg/hub/dist/src/state.d.ts +20 -298
- package/dist/node_modules/@agentorg/hub/dist/src/state.js +73 -456
- package/dist/node_modules/@agentorg/hub/dist/src/validate.d.ts +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/validate.js +3 -15
- package/dist/node_modules/@agentorg/hub/package.json +0 -3
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.d.ts +132 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.js +105 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.d.ts +42 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.js +53 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/chat.d.ts +15 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/chat.js +14 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/hub.d.ts +16 -267
- package/dist/node_modules/@agentorg/interfaces/dist/src/hub.js +17 -145
- package/dist/node_modules/@agentorg/interfaces/dist/src/index.d.ts +6 -8
- package/dist/node_modules/@agentorg/interfaces/dist/src/index.js +6 -8
- package/dist/node_modules/@agentorg/interfaces/dist/src/kv.d.ts +2 -2
- package/dist/node_modules/@agentorg/interfaces/dist/src/kv.js +2 -2
- package/dist/node_modules/@agentorg/interfaces/dist/src/manager.d.ts +272 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/manager.js +185 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/mcp-provider.d.ts +88 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/mcp-provider.js +78 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/tools.d.ts +39 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/tools.js +43 -0
- package/dist/node_modules/@agentorg/manager/dist/src/index.d.ts +1 -0
- package/dist/node_modules/@agentorg/manager/dist/src/index.js +1 -0
- package/dist/node_modules/@agentorg/manager/dist/src/manager.d.ts +21 -0
- package/dist/node_modules/@agentorg/manager/dist/src/manager.js +528 -0
- package/dist/node_modules/@agentorg/manager/dist/src/skills.d.ts +25 -0
- package/dist/node_modules/@agentorg/manager/dist/src/skills.js +145 -0
- package/dist/node_modules/@agentorg/manager/package.json +30 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/connection.d.ts +33 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/connection.js +290 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/index.d.ts +1 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/index.js +1 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/kinds.d.ts +50 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/kinds.js +69 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/provider.d.ts +22 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/provider.js +167 -0
- package/dist/node_modules/@agentorg/mcp/package.json +31 -0
- package/dist/node_modules/@agentorg/sdk/dist/src/cli.js +3 -23
- package/dist/node_modules/@agentorg/sdk/dist/src/client.d.ts +4 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/client.js +5 -55
- package/dist/node_modules/@agentorg/sdk/dist/src/errors.d.ts +1 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/errors.js +3 -3
- package/dist/node_modules/@agentorg/sdk/dist/src/index.d.ts +2 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/index.js +1 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/interface.d.ts +6 -34
- package/dist/node_modules/@agentorg/sdk/dist/src/interface.js +3 -24
- package/dist/node_modules/@agentorg/sdk/dist/src/module-host.d.ts +8 -17
- package/dist/node_modules/@agentorg/sdk/dist/src/module-host.js +15 -87
- package/dist/node_modules/@agentorg/sdk/dist/src/module.d.ts +10 -76
- package/dist/node_modules/@agentorg/sdk/dist/src/module.js +3 -23
- package/dist/node_modules/@agentorg/sdk/dist/src/person-commands.js +0 -5
- package/dist/node_modules/@agentorg/sdk/dist/src/runtime.d.ts +3 -27
- package/dist/node_modules/@agentorg/sdk/dist/src/runtime.js +5 -100
- package/dist/node_modules/@agentorg/sdk/dist/src/testing.d.ts +7 -8
- package/dist/node_modules/@agentorg/sdk/dist/src/testing.js +12 -24
- package/dist/node_modules/@agentorg/sdk/package.json +4 -37
- package/dist/node_modules/@agentorg/shell/dist/app.css +3435 -739
- package/dist/node_modules/@agentorg/shell/dist/app.js +204 -202
- package/dist/node_modules/@agentorg/shell/package.json +18 -10
- package/dist/node_modules/@agentorg/wire/dist/src/frames.d.ts +2 -3
- package/dist/node_modules/@agentorg/wire/dist/src/frames.js +2 -3
- package/dist/node_modules/@agentorg/wire/dist/src/ops.d.ts +5 -34
- package/dist/node_modules/@agentorg/wire/dist/src/ops.js +2 -17
- package/dist/node_modules/assistant/dist/src/agent.d.ts +62 -0
- package/dist/node_modules/assistant/dist/src/agent.js +226 -0
- package/dist/node_modules/assistant/dist/src/engine.d.ts +23 -0
- package/dist/node_modules/assistant/dist/src/engine.js +88 -0
- package/dist/node_modules/assistant/dist/src/history.d.ts +97 -0
- package/dist/node_modules/assistant/dist/src/history.js +235 -0
- package/dist/node_modules/assistant/dist/src/local-store.d.ts +3 -0
- package/dist/node_modules/assistant/dist/src/local-store.js +58 -0
- package/dist/node_modules/assistant/dist/src/provider.d.ts +21 -0
- package/dist/node_modules/assistant/dist/src/provider.js +231 -0
- package/dist/node_modules/assistant/dist/src/settings.d.ts +17 -0
- package/dist/node_modules/assistant/dist/src/settings.js +43 -0
- package/dist/node_modules/assistant/dist/src/tools.d.ts +74 -0
- package/dist/node_modules/assistant/dist/src/tools.js +123 -0
- package/dist/node_modules/assistant/package.json +29 -0
- package/dist/node_modules/chatgpt/dist/src/account.d.ts +52 -0
- package/dist/node_modules/chatgpt/dist/src/account.js +270 -0
- package/dist/node_modules/chatgpt/dist/src/encoding.d.ts +7 -0
- package/dist/node_modules/chatgpt/dist/src/encoding.js +20 -0
- package/dist/node_modules/chatgpt/dist/src/file-store.d.ts +9 -0
- package/dist/node_modules/chatgpt/dist/src/file-store.js +68 -0
- package/dist/node_modules/chatgpt/dist/src/index.d.ts +1 -0
- package/dist/node_modules/chatgpt/dist/src/index.js +1 -0
- package/dist/node_modules/chatgpt/dist/src/jwt.d.ts +15 -0
- package/dist/node_modules/chatgpt/dist/src/jwt.js +37 -0
- package/dist/node_modules/chatgpt/dist/src/oauth.d.ts +43 -0
- package/dist/node_modules/chatgpt/dist/src/oauth.js +104 -0
- package/dist/node_modules/chatgpt/dist/src/program.d.ts +23 -0
- package/dist/node_modules/chatgpt/dist/src/program.js +41 -0
- package/dist/node_modules/chatgpt/dist/src/responses.d.ts +54 -0
- package/dist/node_modules/chatgpt/dist/src/responses.js +300 -0
- package/dist/node_modules/chatgpt/dist/src/serve.d.ts +65 -0
- package/dist/node_modules/chatgpt/dist/src/serve.js +46 -0
- package/dist/node_modules/chatgpt/package.json +33 -0
- package/dist/src/api.d.ts +5 -34
- package/dist/src/api.js +6 -68
- package/dist/src/cli.js +3 -7
- package/dist/src/gateway.d.ts +6 -7
- package/dist/src/gateway.js +39 -285
- package/dist/src/index.d.ts +4 -5
- package/dist/src/index.js +3 -4
- package/dist/src/notes.d.ts +11 -0
- package/dist/src/notes.js +64 -0
- package/dist/src/oauth.d.ts +16 -0
- package/dist/src/oauth.js +46 -0
- package/dist/src/programs.d.ts +29 -0
- package/dist/src/programs.js +171 -0
- package/package.json +3 -11
- package/dist/bundled/index.json +0 -6
- package/dist/bundled/sha256-01d69bc3888c2a53963f4413d47de909d129ad27c78e9af6d830bb50c3478419.agentorg +0 -0
- package/dist/bundled/sha256-84165e3be5c904fc971d983dab31102e07cca725d8629a6fd7d118fa3a0a88b8.agentorg +0 -0
- package/dist/bundled/sha256-ade9132b3f34b4c39db92adeadc7e540dc745e4a81b5b54f5d45bf9ec92bca75.agentorg +0 -0
- package/dist/bundled/sha256-f4330f5987f37d8cf3aeb44d2f831b573641a87186daa2f811f0c35ba04804f0.agentorg +0 -0
- package/dist/node_modules/@agentorg/hub/dist/src/build.d.ts +0 -17
- package/dist/node_modules/@agentorg/hub/dist/src/build.js +0 -120
- package/dist/node_modules/@agentorg/hub/dist/src/logs.d.ts +0 -33
- package/dist/node_modules/@agentorg/hub/dist/src/logs.js +0 -162
- package/dist/node_modules/@agentorg/hub/dist/src/net.d.ts +0 -41
- package/dist/node_modules/@agentorg/hub/dist/src/net.js +0 -265
- package/dist/node_modules/@agentorg/hub/dist/src/processes.d.ts +0 -78
- package/dist/node_modules/@agentorg/hub/dist/src/processes.js +0 -485
- package/dist/node_modules/@agentorg/hub/dist/src/storage.d.ts +0 -38
- package/dist/node_modules/@agentorg/hub/dist/src/storage.js +0 -194
- package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.d.ts +0 -6
- package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.js +0 -7
- package/dist/node_modules/@agentorg/interfaces/dist/src/installer.d.ts +0 -191
- package/dist/node_modules/@agentorg/interfaces/dist/src/installer.js +0 -136
- package/dist/node_modules/@agentorg/interfaces/dist/src/layout.d.ts +0 -47
- package/dist/node_modules/@agentorg/interfaces/dist/src/layout.js +0 -52
- package/dist/node_modules/@agentorg/interfaces/dist/src/rules.d.ts +0 -35
- package/dist/node_modules/@agentorg/interfaces/dist/src/rules.js +0 -37
- package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.d.ts +0 -23
- package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.js +0 -31
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.d.ts +0 -14
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.js +0 -26
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.d.ts +0 -27
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.js +0 -26
- package/dist/node_modules/@agentorg/kit/dist/src/chat.d.ts +0 -37
- package/dist/node_modules/@agentorg/kit/dist/src/chat.js +0 -131
- package/dist/node_modules/@agentorg/kit/dist/src/components.d.ts +0 -94
- package/dist/node_modules/@agentorg/kit/dist/src/components.js +0 -66
- package/dist/node_modules/@agentorg/kit/dist/src/icons.d.ts +0 -17
- package/dist/node_modules/@agentorg/kit/dist/src/icons.js +0 -30
- package/dist/node_modules/@agentorg/kit/dist/src/index.d.ts +0 -6
- package/dist/node_modules/@agentorg/kit/dist/src/index.js +0 -10
- package/dist/node_modules/@agentorg/kit/dist/src/markdown.d.ts +0 -9
- package/dist/node_modules/@agentorg/kit/dist/src/markdown.js +0 -14
- package/dist/node_modules/@agentorg/kit/dist/src/resizable.d.ts +0 -5
- package/dist/node_modules/@agentorg/kit/dist/src/resizable.js +0 -8
- package/dist/node_modules/@agentorg/kit/dist/src/styles.d.ts +0 -11
- package/dist/node_modules/@agentorg/kit/dist/src/styles.js +0 -166
- package/dist/node_modules/@agentorg/kit/package.json +0 -44
- package/dist/node_modules/@agentorg/sdk/dist/frame/runtime.js +0 -753
- package/dist/node_modules/@agentorg/sdk/dist/host/runner.js +0 -21963
- package/dist/node_modules/@agentorg/sdk/dist/src/build.d.ts +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/build.js +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/client-http.d.ts +0 -24
- package/dist/node_modules/@agentorg/sdk/dist/src/client-http.js +0 -247
- package/dist/node_modules/@agentorg/sdk/dist/src/describe.d.ts +0 -13
- package/dist/node_modules/@agentorg/sdk/dist/src/describe.js +0 -16
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.d.ts +0 -8
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.js +0 -64
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.d.ts +0 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.js +0 -35
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.d.ts +0 -57
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.js +0 -293
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.d.ts +0 -124
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.js +0 -16
- package/dist/node_modules/@agentorg/sdk/dist/src/frame.d.ts +0 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/frame.js +0 -248
- package/dist/node_modules/@agentorg/sdk/dist/src/host-main.d.ts +0 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/host-main.js +0 -60
- package/dist/node_modules/@agentorg/sdk/dist/src/host.d.ts +0 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/host.js +0 -92
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.d.ts +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.js +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest.d.ts +0 -56
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest.js +0 -165
- package/dist/node_modules/@agentorg/sdk/dist/src/package.d.ts +0 -60
- package/dist/node_modules/@agentorg/sdk/dist/src/package.js +0 -538
- package/dist/node_modules/@agentorg/sdk/dist/src/tar.d.ts +0 -7
- package/dist/node_modules/@agentorg/sdk/dist/src/tar.js +0 -71
- package/dist/node_modules/@agentorg/shell/dist/agent-bindings.js +0 -59
- package/dist/node_modules/@agentorg/shell/src/agent-bindings.ts +0 -107
- package/dist/src/frames.d.ts +0 -23
- package/dist/src/frames.js +0 -78
- package/dist/src/layout.d.ts +0 -44
- package/dist/src/layout.js +0 -90
- package/dist/src/model.d.ts +0 -51
- package/dist/src/model.js +0 -230
- package/dist/src/rules.d.ts +0 -71
- package/dist/src/rules.js +0 -157
- package/dist/src/transfer.d.ts +0 -30
- package/dist/src/transfer.js +0 -110
|
@@ -1,36 +1,24 @@
|
|
|
1
|
-
import { NotConnected
|
|
2
|
-
import { describeInterface } from "./interface.js";
|
|
1
|
+
import { NotConnected } from "./errors.js";
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* process, where several share one channel. It binds slots as the Hub's notices say, subscribes
|
|
7
|
-
* `on` handlers while a slot is usable, serves the Hub's streams to its exports, and offers and
|
|
8
|
-
* withdraws run-time exports.
|
|
3
|
+
* A program's runtime, joined to its channel. It binds slots as the Hub's notices say, subscribes
|
|
4
|
+
* `on` handlers while a slot is usable, and serves the Hub's streams to its exports.
|
|
9
5
|
*/
|
|
10
6
|
export class ModuleHost {
|
|
11
|
-
#prefix;
|
|
12
7
|
#slots;
|
|
13
8
|
#log;
|
|
14
9
|
#runtime;
|
|
15
10
|
#channel;
|
|
16
11
|
/** The Hub's subscriptions to this module's exports, by export and event, each with its caller. */
|
|
17
12
|
#senders = new Map();
|
|
18
|
-
/** The same subscriptions by export, each ended when
|
|
13
|
+
/** The same subscriptions by export, each ended when the channel goes. */
|
|
19
14
|
#subscribers = new Map();
|
|
20
15
|
/** Slot events the module listens to, each with its live subscription, if any. */
|
|
21
16
|
#listened = new Map();
|
|
22
17
|
#bindings = new Map();
|
|
23
|
-
|
|
24
|
-
#added = new Map();
|
|
25
|
-
constructor(prefix, slots, log) {
|
|
26
|
-
this.#prefix = prefix;
|
|
18
|
+
constructor(slots, log) {
|
|
27
19
|
this.#slots = slots;
|
|
28
20
|
this.#log = log;
|
|
29
21
|
}
|
|
30
|
-
/** A local name as the Hub knows it. */
|
|
31
|
-
#wire(name) {
|
|
32
|
-
return `${this.#prefix}${name}`;
|
|
33
|
-
}
|
|
34
22
|
get runtime() {
|
|
35
23
|
if (!this.#runtime)
|
|
36
24
|
throw new Error("The module host has no runtime yet.");
|
|
@@ -60,31 +48,8 @@ export class ModuleHost {
|
|
|
60
48
|
}
|
|
61
49
|
},
|
|
62
50
|
onListen: (slot, event) => this.#subscribeSlot(slot, event),
|
|
63
|
-
onAdd: (name, iface, handle) => {
|
|
64
|
-
this.#added.set(name, { handle, iface });
|
|
65
|
-
// Added during start, before the channel opens: offered once it does.
|
|
66
|
-
if (this.#channel)
|
|
67
|
-
this.#offer(this.#channel, name, iface, handle);
|
|
68
|
-
},
|
|
69
|
-
onWithdraw: (name) => {
|
|
70
|
-
for (const end of [...(this.#subscribers.get(name) ?? [])])
|
|
71
|
-
end();
|
|
72
|
-
// Only exports offered at run time can be withdrawn at the Hub; static ones just stop here.
|
|
73
|
-
if (!this.#added.has(name))
|
|
74
|
-
return;
|
|
75
|
-
this.#added.delete(name);
|
|
76
|
-
void this.#channel?.withdraw(this.#wire(name)).catch(() => { });
|
|
77
|
-
},
|
|
78
51
|
};
|
|
79
52
|
}
|
|
80
|
-
/** Offer a run-time export; one the Hub refuses is withdrawn here too. */
|
|
81
|
-
#offer(channel, name, iface, handle) {
|
|
82
|
-
void channel.offer(this.#wire(name), describeInterface(iface)).catch((error) => {
|
|
83
|
-
this.#log.error("The Hub refused an export.", { export: name, error: String(error) });
|
|
84
|
-
if (this.#added.get(name)?.handle === handle)
|
|
85
|
-
handle.withdraw();
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
53
|
#subscribeSlot(slot, event) {
|
|
89
54
|
const events = this.#listened.get(slot) ?? new Map();
|
|
90
55
|
this.#listened.set(slot, events);
|
|
@@ -93,7 +58,7 @@ export class ModuleHost {
|
|
|
93
58
|
const binding = this.#bindings.get(slot);
|
|
94
59
|
if (!this.#channel || !binding || events.get(event))
|
|
95
60
|
return;
|
|
96
|
-
const stop = this.#channel.subscribe(
|
|
61
|
+
const stop = this.#channel.subscribe(slot, event, (payload) => {
|
|
97
62
|
try {
|
|
98
63
|
binding.emit(event, payload);
|
|
99
64
|
}
|
|
@@ -142,35 +107,14 @@ export class ModuleHost {
|
|
|
142
107
|
return;
|
|
143
108
|
}
|
|
144
109
|
const open = this.#channel;
|
|
145
|
-
const name =
|
|
110
|
+
const name = slot;
|
|
146
111
|
this.#bindings.set(slot, runtime.bind(slot, {
|
|
147
112
|
call: (method, value) => open.call(name, method, value),
|
|
148
|
-
open: (params) => open.open(name, params),
|
|
149
|
-
fetch: async (request) => {
|
|
150
|
-
// HTTP/1.1 is spoken with node:http, loaded when an http slot is first used (a bundle
|
|
151
|
-
// such as the runner has it inlined).
|
|
152
|
-
const { fetchOver } = await import("./client-http.js");
|
|
153
|
-
const stream = await open.http(name);
|
|
154
|
-
try {
|
|
155
|
-
return await fetchOver(stream, request, name);
|
|
156
|
-
}
|
|
157
|
-
catch (error) {
|
|
158
|
-
// An abort keeps its own reason, and the provider's own SDK error is that error; a
|
|
159
|
-
// stream lost mid-request may have reached the provider.
|
|
160
|
-
if (request.signal.aborted ||
|
|
161
|
-
error instanceof Refused ||
|
|
162
|
-
error instanceof NotConnected ||
|
|
163
|
-
error instanceof OutcomeUnknown)
|
|
164
|
-
throw error;
|
|
165
|
-
throw new OutcomeUnknown(`The http request on ${name} ended before its response: ${String(error)}`);
|
|
166
|
-
}
|
|
167
|
-
},
|
|
168
113
|
}));
|
|
169
114
|
this.#resubscribe(slot);
|
|
170
115
|
}
|
|
171
116
|
/**
|
|
172
|
-
* A notice for a slot made at run time: bound (or usable again) with its exposure, or gone.
|
|
173
|
-
* name is the Actor's, with no module prefix: every module of the Actor has it.
|
|
117
|
+
* A notice for a slot made at run time: bound (or usable again) with its exposure, or gone.
|
|
174
118
|
*/
|
|
175
119
|
onExposed(slot, exposure) {
|
|
176
120
|
if (!this.#channel)
|
|
@@ -191,8 +135,6 @@ export class ModuleHost {
|
|
|
191
135
|
serve = {
|
|
192
136
|
call: (serve, value) => this.runtime.call(serve.export, serve.method ?? "", value, serve.caller),
|
|
193
137
|
subscribe: (serve, sendTo, end) => {
|
|
194
|
-
if (this.runtime.withdrawn(serve.export))
|
|
195
|
-
throw new NotConnected(serve.export);
|
|
196
138
|
const key = `${serve.export}\0${serve.event ?? ""}`;
|
|
197
139
|
const set = this.#senders.get(key) ?? new Set();
|
|
198
140
|
this.#senders.set(key, set);
|
|
@@ -202,35 +144,25 @@ export class ModuleHost {
|
|
|
202
144
|
this.#subscribers.set(serve.export, ends);
|
|
203
145
|
const stop = () => {
|
|
204
146
|
set.delete(sender);
|
|
205
|
-
ends.delete(
|
|
147
|
+
ends.delete(ended);
|
|
206
148
|
};
|
|
207
|
-
const
|
|
149
|
+
const ended = () => {
|
|
208
150
|
stop();
|
|
209
151
|
end(new NotConnected(serve.export));
|
|
210
152
|
};
|
|
211
|
-
ends.add(
|
|
153
|
+
ends.add(ended);
|
|
212
154
|
return stop;
|
|
213
155
|
},
|
|
214
|
-
accept: (serve) => this.runtime.accepting(serve.export, serve.params),
|
|
215
|
-
serveHttp: (serve) => {
|
|
216
|
-
const handle = this.runtime.serving(serve.export);
|
|
217
|
-
return async (stream) => {
|
|
218
|
-
const { serveOver } = await import("./client-http.js");
|
|
219
|
-
await serveOver(stream, handle, this.#log);
|
|
220
|
-
};
|
|
221
|
-
},
|
|
222
156
|
};
|
|
223
157
|
/**
|
|
224
|
-
* Join the opened channel:
|
|
225
|
-
*
|
|
158
|
+
* Join the opened channel: bind the slots the Hub's hello said are bound, and leave nothing
|
|
159
|
+
* usable once the channel goes.
|
|
226
160
|
*/
|
|
227
161
|
attach(channel) {
|
|
228
162
|
this.#channel = channel;
|
|
229
|
-
for (const [name, { handle, iface }] of this.#added)
|
|
230
|
-
this.#offer(channel, name, iface, handle);
|
|
231
163
|
for (const name of channel.bound)
|
|
232
|
-
if (
|
|
233
|
-
this.onSlot(name
|
|
164
|
+
if (!channel.exposed.has(name))
|
|
165
|
+
this.onSlot(name, true);
|
|
234
166
|
for (const [name, exposure] of channel.exposed)
|
|
235
167
|
this.onExposed(name, exposure);
|
|
236
168
|
void channel.closed.then(() => {
|
|
@@ -244,7 +176,3 @@ export class ModuleHost {
|
|
|
244
176
|
});
|
|
245
177
|
}
|
|
246
178
|
}
|
|
247
|
-
/** A `serve` stream renamed to a module's local export name. */
|
|
248
|
-
export const localServe = (serve, local) => ({ ...serve, export: local });
|
|
249
|
-
/** A refusal for a name that names no module here. */
|
|
250
|
-
export const noModule = (name) => new Refused("unknown", `${name} names no host module of this Actor.`);
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import type { z } from "zod";
|
|
2
|
-
import type { DescribedInterface, Events, Interface, Methods, RpcInterface
|
|
3
|
-
/** Where a module runs: `host` in its own process, `view` in a sandboxed frame. */
|
|
4
|
-
export type Placement = "host" | "view";
|
|
5
|
-
/** A byte stream both ways, the same in a host process and in a view. */
|
|
6
|
-
export interface Duplex {
|
|
7
|
-
readonly readable: ReadableStream<Uint8Array>;
|
|
8
|
-
readonly writable: WritableStream<Uint8Array>;
|
|
9
|
-
}
|
|
2
|
+
import type { DescribedInterface, Events, Interface, Methods, RpcInterface } from "./interface.js";
|
|
10
3
|
interface SlotState {
|
|
11
4
|
/** Whether an export is bound to this slot now; a slot may be unbound at any time. */
|
|
12
5
|
readonly bound: boolean;
|
|
@@ -27,15 +20,7 @@ export interface RpcSlot<M extends Methods, E extends Events> extends SlotState
|
|
|
27
20
|
/** Live events from the bound export, at most once; returns a function that unsubscribes. */
|
|
28
21
|
on<K extends keyof E & string>(event: K, fn: (payload: z.output<E[K]["payload"]>) => void): () => void;
|
|
29
22
|
}
|
|
30
|
-
|
|
31
|
-
export interface StreamSlot<O extends z.ZodType> extends SlotState {
|
|
32
|
-
open(params: z.input<O>): Promise<Duplex>;
|
|
33
|
-
}
|
|
34
|
-
/** A slot of an `http` interface. */
|
|
35
|
-
export interface HttpSlot extends SlotState {
|
|
36
|
-
fetch(request: Request): Promise<Response>;
|
|
37
|
-
}
|
|
38
|
-
export type Slot<I extends Interface> = I extends RpcInterface<string, infer M, infer E> ? RpcSlot<M, E> : I extends StreamInterface<string, infer O> ? StreamSlot<O> : HttpSlot;
|
|
23
|
+
export type Slot<I extends Interface> = I extends RpcInterface<string, infer M, infer E> ? RpcSlot<M, E> : never;
|
|
39
24
|
/** Who made a call: the calling Actor, as the Hub names it. */
|
|
40
25
|
export interface CallInfo {
|
|
41
26
|
readonly caller: string;
|
|
@@ -54,47 +39,12 @@ export type Handlers<M extends Methods> = {
|
|
|
54
39
|
export interface EmitOptions {
|
|
55
40
|
readonly to?: string;
|
|
56
41
|
}
|
|
57
|
-
interface
|
|
58
|
-
/** Stop offering this export; bindings to it end. */
|
|
59
|
-
withdraw(): void;
|
|
60
|
-
}
|
|
61
|
-
export interface RpcExport<M extends Methods, E extends Events> extends Withdrawable {
|
|
42
|
+
export interface RpcExport<M extends Methods, E extends Events> {
|
|
62
43
|
implement(handlers: Handlers<M>): void;
|
|
63
44
|
emit<K extends keyof E & string>(event: K, payload: z.input<E[K]["payload"]>, options?: EmitOptions): void;
|
|
64
45
|
}
|
|
65
|
-
export
|
|
66
|
-
|
|
67
|
-
}
|
|
68
|
-
export interface HttpExport extends Withdrawable {
|
|
69
|
-
serve(handler: (request: Request) => Response | Promise<Response>): void;
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* The element a view renders into: the DOM's `Element` where the DOM library is in scope (a
|
|
73
|
-
* widget's code), and `object` elsewhere, so host-only code needs no DOM types.
|
|
74
|
-
*/
|
|
75
|
-
export type FrameRoot = typeof globalThis extends {
|
|
76
|
-
Element: {
|
|
77
|
-
prototype: infer E;
|
|
78
|
-
};
|
|
79
|
-
} ? E : object;
|
|
80
|
-
/**
|
|
81
|
-
* The export handle of `ui.view@1`, the one in-frame interface, and so the one interface whose
|
|
82
|
-
* handle isn't derived from its methods. A view renders into its own frame's DOM, which no wire
|
|
83
|
-
* message can carry: the view implements `mount(el, options)` against its frame's root element,
|
|
84
|
-
* and the frame runtime maps the wire methods `mount`, `resize` and `unmount` onto it. No other
|
|
85
|
-
* interface should take this shape; anything else crosses the wire as schemas.
|
|
86
|
-
*/
|
|
87
|
-
export interface ViewExport<MountOptions, Size> extends Withdrawable {
|
|
88
|
-
implement(view: {
|
|
89
|
-
/** Render into `el`; the function returned, if any, runs at unmount. */
|
|
90
|
-
mount(el: FrameRoot, options: MountOptions): (() => void) | void;
|
|
91
|
-
resize?(size: Size): void;
|
|
92
|
-
}): void;
|
|
93
|
-
}
|
|
94
|
-
export type Export<I extends Interface> = I extends RpcInterface<"ui.view", infer M, Events, 1> ? "mount" extends keyof M ? "resize" extends keyof M ? ViewExport<z.output<M["mount"]["input"]>, z.output<M["resize"]["input"]> extends {
|
|
95
|
-
size: infer Size;
|
|
96
|
-
} ? Size : never> : RpcExport<M, Events> : RpcExport<M, Events> : I extends RpcInterface<string, infer M, infer E> ? RpcExport<M, E> : I extends StreamInterface<string, infer O> ? StreamExport<O> : HttpExport;
|
|
97
|
-
/** Structured log lines, readable through the Hub by grant. */
|
|
46
|
+
export type Export<I extends Interface> = I extends RpcInterface<string, infer M, infer E> ? RpcExport<M, E> : never;
|
|
47
|
+
/** Structured log lines. */
|
|
98
48
|
export interface Log {
|
|
99
49
|
info(message: string, fields?: Record<string, unknown>): void;
|
|
100
50
|
warn(message: string, fields?: Record<string, unknown>): void;
|
|
@@ -102,15 +52,10 @@ export interface Log {
|
|
|
102
52
|
}
|
|
103
53
|
/** Slots or exports: names to interfaces. */
|
|
104
54
|
export type InterfaceMap = Record<string, Interface>;
|
|
105
|
-
|
|
106
|
-
export type ExportMap = InterfaceMap & {
|
|
107
|
-
add?: never;
|
|
108
|
-
};
|
|
109
|
-
/** Whether an interface is `ui.view@1`, the one in-frame interface, with its own export handle. */
|
|
110
|
-
export declare function isFrameInterface(iface: Interface): boolean;
|
|
55
|
+
export type ExportMap = InterfaceMap;
|
|
111
56
|
/**
|
|
112
57
|
* A slot made at run time: another Actor's export, exposed to this Actor with `hub.grants.expose`
|
|
113
|
-
* rather than declared by
|
|
58
|
+
* rather than declared by this Actor. It is here exactly while it is bound. Its values are JSON,
|
|
114
59
|
* checked against `described` by the Hub both ways, not here, so a misfit comes back as
|
|
115
60
|
* `Refused` (code `invalid`). A call on a slot that's gone, or whose provider isn't running, throws
|
|
116
61
|
* `NotConnected`, as a declared slot's does.
|
|
@@ -130,16 +75,13 @@ export interface ExposedSlot {
|
|
|
130
75
|
/** Live events from the export while the slot is here; returns a function that unsubscribes. */
|
|
131
76
|
on(event: string, fn: (payload: unknown) => void): () => void;
|
|
132
77
|
}
|
|
133
|
-
/** Everything a
|
|
78
|
+
/** Everything a program gets from the Hub. */
|
|
134
79
|
export interface Context<S extends InterfaceMap, X extends InterfaceMap> {
|
|
135
80
|
readonly slots: {
|
|
136
81
|
readonly [K in keyof S]: Slot<S[K]>;
|
|
137
82
|
};
|
|
138
83
|
readonly exports: {
|
|
139
84
|
readonly [K in keyof X]: Export<X[K]>;
|
|
140
|
-
} & {
|
|
141
|
-
/** Offer another export at run time; consumers still bind it explicitly. */
|
|
142
|
-
add<I extends Interface>(name: string, iface: I): Export<I>;
|
|
143
85
|
};
|
|
144
86
|
readonly self: {
|
|
145
87
|
readonly actorId: string;
|
|
@@ -147,18 +89,13 @@ export interface Context<S extends InterfaceMap, X extends InterfaceMap> {
|
|
|
147
89
|
};
|
|
148
90
|
readonly log: Log;
|
|
149
91
|
/**
|
|
150
|
-
* The slots made for this Actor at run time and bound now, in the order they came.
|
|
151
|
-
* module of the Actor sees them all; a view module sees none.
|
|
92
|
+
* The slots made for this Actor at run time and bound now, in the order they came.
|
|
152
93
|
*/
|
|
153
94
|
exposed(): readonly ExposedSlot[];
|
|
154
95
|
/** Runs after one is added or removed, so `exposed()` is read again; returns how to stop it. */
|
|
155
96
|
onExposed(fn: () => void): () => void;
|
|
156
97
|
}
|
|
157
|
-
/** The marker the build looks for on a module's default export. */
|
|
158
|
-
export declare const MODULE = "agentorg.module/1";
|
|
159
98
|
export interface ModuleDefinition<S extends InterfaceMap = InterfaceMap, X extends InterfaceMap = InterfaceMap> {
|
|
160
|
-
readonly agentorg: typeof MODULE;
|
|
161
|
-
readonly placement: Placement;
|
|
162
99
|
readonly slots: S;
|
|
163
100
|
readonly exports: X;
|
|
164
101
|
start(ctx: Context<S, X>): void | Promise<void>;
|
|
@@ -171,9 +108,6 @@ export interface ModuleSpec<S extends InterfaceMap, X extends InterfaceMap> {
|
|
|
171
108
|
exports?: X;
|
|
172
109
|
start(ctx: Context<S, X>): void | Promise<void>;
|
|
173
110
|
}
|
|
174
|
-
/** A
|
|
111
|
+
/** A program's handles, by name: what `connect` runs. */
|
|
175
112
|
export declare function defineActor<const S extends InterfaceMap = None, const X extends ExportMap = None>(spec: ModuleSpec<S, X>): ModuleDefinition<S, X>;
|
|
176
|
-
/** A view module: a widget, in a sandboxed frame. Same shape as an Actor's module. */
|
|
177
|
-
export declare function defineWidget<const S extends InterfaceMap = None, const X extends ExportMap = None>(spec: ModuleSpec<S, X>): ModuleDefinition<S, X>;
|
|
178
|
-
export declare function isModuleDefinition(value: unknown): value is ModuleDefinition;
|
|
179
113
|
export {};
|
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
/** Whether an interface is `ui.view@1`, the one in-frame interface, with its own export handle. */
|
|
2
|
-
export function isFrameInterface(iface) {
|
|
3
|
-
return iface.kind === "rpc" && iface.name === "ui.view" && iface.major === 1;
|
|
4
|
-
}
|
|
5
|
-
/** The marker the build looks for on a module's default export. */
|
|
6
|
-
export const MODULE = "agentorg.module/1";
|
|
7
1
|
const NAME = /^[a-z][A-Za-z0-9_]*$/;
|
|
8
|
-
|
|
2
|
+
/** A program's handles, by name: what `connect` runs. */
|
|
3
|
+
export function defineActor(spec) {
|
|
9
4
|
const slots = spec.slots ?? {};
|
|
10
5
|
const exports = spec.exports ?? {};
|
|
11
6
|
for (const [what, names] of [
|
|
@@ -15,20 +10,5 @@ function define(placement, spec) {
|
|
|
15
10
|
for (const name of names)
|
|
16
11
|
if (!NAME.test(name))
|
|
17
12
|
throw new TypeError(`${JSON.stringify(name)} isn't a valid ${what} name.`);
|
|
18
|
-
|
|
19
|
-
throw new TypeError(`"add" is reserved for exports.add; name the export differently.`);
|
|
20
|
-
return { agentorg: MODULE, placement, slots, exports, start: spec.start };
|
|
21
|
-
}
|
|
22
|
-
/** A host module: the Actor's logic, in its own process. */
|
|
23
|
-
export function defineActor(spec) {
|
|
24
|
-
return define("host", spec);
|
|
25
|
-
}
|
|
26
|
-
/** A view module: a widget, in a sandboxed frame. Same shape as an Actor's module. */
|
|
27
|
-
export function defineWidget(spec) {
|
|
28
|
-
return define("view", spec);
|
|
29
|
-
}
|
|
30
|
-
export function isModuleDefinition(value) {
|
|
31
|
-
return (typeof value === "object" &&
|
|
32
|
-
value !== null &&
|
|
33
|
-
value.agentorg === MODULE);
|
|
13
|
+
return { slots, exports, start: spec.start };
|
|
34
14
|
}
|
|
@@ -22,11 +22,6 @@ function usage(message) {
|
|
|
22
22
|
}
|
|
23
23
|
/** Each person command: the person's hub slot and method it calls, and its input from the args. */
|
|
24
24
|
const commands = {
|
|
25
|
-
add: {
|
|
26
|
-
slot: "packages",
|
|
27
|
-
method: "add",
|
|
28
|
-
input: ([file]) => (file ? { path: resolve(file) } : usage("add takes a .agentorg file.")),
|
|
29
|
-
},
|
|
30
25
|
actors: { slot: "actors", method: "list", input: () => ({}) },
|
|
31
26
|
bindings: { slot: "bindings", method: "list", input: () => ({}) },
|
|
32
27
|
exports: { slot: "exports", method: "list", input: () => ({}) },
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type { DescribedInterface
|
|
2
|
-
import {
|
|
1
|
+
import type { DescribedInterface } from "./interface.js";
|
|
2
|
+
import type { Context, InterfaceMap, Log, ModuleDefinition } from "./module.js";
|
|
3
3
|
/**
|
|
4
|
-
* What serves a bound slot, as the host side sees it
|
|
4
|
+
* What serves a bound slot, as the host side sees it. The runtime validates
|
|
5
5
|
* what goes in and comes out against the interface's schemas, as the Hub does.
|
|
6
6
|
*/
|
|
7
7
|
export interface SlotProvider {
|
|
8
8
|
call?(method: string, input: unknown): Promise<unknown>;
|
|
9
|
-
open?(params: unknown): Promise<Duplex>;
|
|
10
|
-
fetch?(request: Request): Promise<Response>;
|
|
11
9
|
}
|
|
12
10
|
/** A bound slot, seen from the host side: it delivers the provider's events to the module. */
|
|
13
11
|
export interface Binding {
|
|
@@ -27,11 +25,6 @@ export interface ExposedProvider {
|
|
|
27
25
|
/** Deliver an event's payloads until it ends (`onEnd`); returns how to stop. */
|
|
28
26
|
subscribe(event: string, onEvent: (payload: unknown) => void, onEnd: () => void): () => void;
|
|
29
27
|
}
|
|
30
|
-
/** A mounted view, seen from the frame runtime's side. */
|
|
31
|
-
export interface MountedView {
|
|
32
|
-
resize(size: unknown): void;
|
|
33
|
-
unmount(): void;
|
|
34
|
-
}
|
|
35
28
|
/**
|
|
36
29
|
* One module's context and the host side of it: bind providers to its slots and drive its
|
|
37
30
|
* exports. The test context and the real runtimes are both built on this, so a module behaves the
|
|
@@ -55,17 +48,6 @@ export interface ModuleRuntime<S extends InterfaceMap, X extends InterfaceMap> {
|
|
|
55
48
|
unexpose(slot: string): void;
|
|
56
49
|
/** Call an export's method for `caller`, the calling Actor as the Hub names it. */
|
|
57
50
|
call(exportName: string, method: string, input: unknown, caller: string): Promise<unknown>;
|
|
58
|
-
open(exportName: string, params: unknown, stream: Duplex): Promise<void>;
|
|
59
|
-
/**
|
|
60
|
-
* The two halves of `open`: checks that the export takes the stream (throwing a refusal at
|
|
61
|
-
* once), then returns what runs it. A remote host answers accept or refuse in between.
|
|
62
|
-
*/
|
|
63
|
-
accepting(exportName: string, params: unknown): (stream: Duplex) => Promise<void>;
|
|
64
|
-
fetch(exportName: string, request: Request): Promise<Response>;
|
|
65
|
-
/** The checking half of `fetch`: refuses at once, or returns what serves each request. */
|
|
66
|
-
serving(exportName: string): (request: Request) => Promise<Response>;
|
|
67
|
-
mount(exportName: string, el: FrameRoot, options: unknown): MountedView;
|
|
68
|
-
withdrawn(exportName: string): boolean;
|
|
69
51
|
}
|
|
70
52
|
export interface RuntimeOptions {
|
|
71
53
|
self: {
|
|
@@ -77,12 +59,6 @@ export interface RuntimeOptions {
|
|
|
77
59
|
onEmit(exportName: string, event: string, payload: unknown, to: string | undefined): void;
|
|
78
60
|
/** Called when the module listens to a slot's event, so a remote host can subscribe. */
|
|
79
61
|
onListen?(slot: string, event: string): void;
|
|
80
|
-
/** Called when the module offers an export at run time with `exports.add`, with its handle. */
|
|
81
|
-
onAdd?(name: string, iface: Interface, handle: {
|
|
82
|
-
withdraw(): void;
|
|
83
|
-
}): void;
|
|
84
|
-
/** Called when the module withdraws an export. */
|
|
85
|
-
onWithdraw?(name: string): void;
|
|
86
62
|
}
|
|
87
63
|
/**
|
|
88
64
|
* A value checked against a schema. A caller's misfit is `Refused` with code `invalid`, and nothing
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { NotConnected, Refused } from "./errors.js";
|
|
2
|
-
import { isFrameInterface, } from "./module.js";
|
|
3
2
|
/**
|
|
4
3
|
* A value checked against a schema. A caller's misfit is `Refused` with code `invalid`, and nothing
|
|
5
4
|
* ran. A provider's is code `bad_output`: the provider ran and its reply or event broke the
|
|
@@ -12,7 +11,6 @@ export function check(schema, value, where, code = "invalid") {
|
|
|
12
11
|
const issue = result.error.issues[0];
|
|
13
12
|
throw new Refused(code, `${where}: ${issue ? `${issue.path.map(String).join(".") || "value"} ${issue.message}` : "invalid"}`);
|
|
14
13
|
}
|
|
15
|
-
const NAME = /^[a-z][A-Za-z0-9_]*$/;
|
|
16
14
|
const own = (record, key) => Object.hasOwn(record, key) ? record[key] : undefined;
|
|
17
15
|
export function createRuntime(definition, options) {
|
|
18
16
|
const slots = new Map();
|
|
@@ -61,73 +59,34 @@ export function createRuntime(definition, options) {
|
|
|
61
59
|
return () => void set.delete(fn);
|
|
62
60
|
},
|
|
63
61
|
});
|
|
64
|
-
case "stream":
|
|
65
|
-
return Object.assign(base, {
|
|
66
|
-
async open(params) {
|
|
67
|
-
const target = provider();
|
|
68
|
-
const parsed = check(iface.open, params, `${name} open`);
|
|
69
|
-
if (!target.open)
|
|
70
|
-
throw new Refused("unimplemented", `${name} isn't served by a stream provider.`);
|
|
71
|
-
return target.open(parsed);
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
case "http":
|
|
75
|
-
return Object.assign(base, {
|
|
76
|
-
async fetch(request) {
|
|
77
|
-
const target = provider();
|
|
78
|
-
if (!target.fetch)
|
|
79
|
-
throw new Refused("unimplemented", `${name} isn't served by an http provider.`);
|
|
80
|
-
return target.fetch(request);
|
|
81
|
-
},
|
|
82
|
-
});
|
|
83
62
|
}
|
|
84
63
|
};
|
|
85
64
|
const exportHandle = (name, iface) => {
|
|
86
|
-
const state = { iface
|
|
65
|
+
const state = { iface };
|
|
87
66
|
exported.set(name, state);
|
|
88
|
-
const live = () => {
|
|
89
|
-
if (state.withdrawn)
|
|
90
|
-
throw new NotConnected(name);
|
|
91
|
-
};
|
|
92
|
-
const withdraw = () => {
|
|
93
|
-
if (state.withdrawn)
|
|
94
|
-
return;
|
|
95
|
-
state.withdrawn = true;
|
|
96
|
-
options.onWithdraw?.(name);
|
|
97
|
-
};
|
|
98
67
|
const store = (impl) => {
|
|
99
|
-
live();
|
|
100
68
|
state.impl = impl;
|
|
101
69
|
};
|
|
102
|
-
if (isFrameInterface(iface))
|
|
103
|
-
return { implement: store, withdraw };
|
|
104
70
|
switch (iface.kind) {
|
|
105
71
|
case "rpc":
|
|
106
72
|
return {
|
|
107
73
|
implement: store,
|
|
108
74
|
emit(event, payload, emitting) {
|
|
109
|
-
live();
|
|
110
75
|
const spec = own(iface.events, event);
|
|
111
76
|
if (!spec)
|
|
112
77
|
throw new TypeError(`${name} has no event ${event}.`);
|
|
113
78
|
options.onEmit(name, event, check(spec.payload, payload, `${name}.${event} payload`), emitting?.to);
|
|
114
79
|
},
|
|
115
|
-
withdraw,
|
|
116
80
|
};
|
|
117
|
-
case "stream":
|
|
118
|
-
return { accept: store, withdraw };
|
|
119
|
-
case "http":
|
|
120
|
-
return { serve: store, withdraw };
|
|
121
81
|
}
|
|
122
82
|
};
|
|
123
83
|
/** A connected export of the expected kind; implemented or not is checked after its input. */
|
|
124
84
|
const target = (name, kind) => {
|
|
125
85
|
const state = exported.get(name);
|
|
126
|
-
if (!state
|
|
86
|
+
if (!state)
|
|
127
87
|
throw new NotConnected(name);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
throw new TypeError(`${name} isn't ${kind === "frame" ? "a ui.view@1" : `an ${kind}`} export.`);
|
|
88
|
+
if (state.iface.kind !== kind)
|
|
89
|
+
throw new TypeError(`${name} isn't an ${kind} export.`);
|
|
131
90
|
return state;
|
|
132
91
|
};
|
|
133
92
|
const implemented = (state, name) => {
|
|
@@ -244,21 +203,7 @@ export function createRuntime(definition, options) {
|
|
|
244
203
|
};
|
|
245
204
|
const ctx = {
|
|
246
205
|
slots: Object.fromEntries(Object.entries(definition.slots).map(([name, iface]) => [name, slotHandle(name, iface)])),
|
|
247
|
-
exports: Object.
|
|
248
|
-
name,
|
|
249
|
-
exportHandle(name, iface),
|
|
250
|
-
])), {
|
|
251
|
-
add(name, iface) {
|
|
252
|
-
if (!NAME.test(name) || name === "add")
|
|
253
|
-
throw new TypeError(`${JSON.stringify(name)} isn't a valid export name.`);
|
|
254
|
-
const existing = exported.get(name);
|
|
255
|
-
if (existing && !existing.withdrawn)
|
|
256
|
-
throw new TypeError(`An export named ${name} is already offered.`);
|
|
257
|
-
const handle = exportHandle(name, iface);
|
|
258
|
-
options.onAdd?.(name, iface, handle);
|
|
259
|
-
return handle;
|
|
260
|
-
},
|
|
261
|
-
}),
|
|
206
|
+
exports: Object.fromEntries(Object.entries(definition.exports).map(([name, iface]) => [name, exportHandle(name, iface)])),
|
|
262
207
|
self: options.self,
|
|
263
208
|
log: options.log,
|
|
264
209
|
exposed: () => Object.freeze([...exposed.values()].map((state) => state.handle)),
|
|
@@ -267,19 +212,6 @@ export function createRuntime(definition, options) {
|
|
|
267
212
|
return () => void exposedWatchers.delete(fn);
|
|
268
213
|
},
|
|
269
214
|
};
|
|
270
|
-
const serving = (exportName) => {
|
|
271
|
-
const state = target(exportName, "http");
|
|
272
|
-
const handler = implemented(state, exportName);
|
|
273
|
-
return async (request) => handler(request);
|
|
274
|
-
};
|
|
275
|
-
const accepting = (exportName, params) => {
|
|
276
|
-
const state = target(exportName, "stream");
|
|
277
|
-
const parsed = check(state.iface.open, params, `${exportName} open`);
|
|
278
|
-
const handler = implemented(state, exportName);
|
|
279
|
-
return async (stream) => {
|
|
280
|
-
await handler(parsed, stream);
|
|
281
|
-
};
|
|
282
|
-
};
|
|
283
215
|
/** Run a slot's bind or unbind handlers; one that throws is logged and the rest still run. */
|
|
284
216
|
const notify = (slot, handlers) => {
|
|
285
217
|
const failed = (error) => options.log.error("A slot handler threw.", { slot, error: String(error) });
|
|
@@ -351,32 +283,5 @@ export function createRuntime(definition, options) {
|
|
|
351
283
|
throw new Refused("unimplemented", `${exportName}.${method} isn't implemented.`);
|
|
352
284
|
return check(spec.output, await handler(parsed, { caller }), `${exportName}.${method} output`, "bad_output");
|
|
353
285
|
},
|
|
354
|
-
accepting,
|
|
355
|
-
async open(exportName, params, stream) {
|
|
356
|
-
await accepting(exportName, params)(stream);
|
|
357
|
-
},
|
|
358
|
-
serving,
|
|
359
|
-
async fetch(exportName, request) {
|
|
360
|
-
return serving(exportName)(request);
|
|
361
|
-
},
|
|
362
|
-
mount(exportName, el, options) {
|
|
363
|
-
const state = target(exportName, "frame");
|
|
364
|
-
const methods = state.iface.methods;
|
|
365
|
-
const parsed = check(methods.mount?.input, options, `${exportName} mount`);
|
|
366
|
-
const view = implemented(state, exportName);
|
|
367
|
-
const cleanup = view.mount(el, parsed);
|
|
368
|
-
return {
|
|
369
|
-
resize(size) {
|
|
370
|
-
const { size: checked } = check(methods.resize?.input, { size }, `${exportName} resize`);
|
|
371
|
-
view.resize?.(checked);
|
|
372
|
-
},
|
|
373
|
-
unmount() {
|
|
374
|
-
cleanup?.();
|
|
375
|
-
},
|
|
376
|
-
};
|
|
377
|
-
},
|
|
378
|
-
withdrawn(exportName) {
|
|
379
|
-
return exported.get(exportName)?.withdrawn ?? false;
|
|
380
|
-
},
|
|
381
286
|
};
|
|
382
287
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import {
|
|
3
|
-
import type { Duplex, Handlers, InterfaceMap, ModuleDefinition } from "./module.js";
|
|
1
|
+
import { type Interface, type RpcInterface } from "./interface.js";
|
|
2
|
+
import type { Handlers, InterfaceMap, ModuleDefinition } from "./module.js";
|
|
4
3
|
import { type Binding, type ModuleRuntime } from "./runtime.js";
|
|
5
|
-
/** A fake bound to a slot in a test: handlers
|
|
6
|
-
export type Provider<I extends Interface> = I extends RpcInterface<string, infer M> ? Partial<Handlers<M>> :
|
|
4
|
+
/** A fake bound to a slot in a test: its handlers. */
|
|
5
|
+
export type Provider<I extends Interface> = I extends RpcInterface<string, infer M> ? Partial<Handlers<M>> : never;
|
|
7
6
|
export interface Emitted {
|
|
8
7
|
export: string;
|
|
9
8
|
event: string;
|
|
@@ -19,8 +18,8 @@ export interface LogLine {
|
|
|
19
18
|
/**
|
|
20
19
|
* A module run without a Hub, for tests: bind fakes to its slots, drive its exports, and read what
|
|
21
20
|
* it emitted and logged. It runs on the same runtime as a real module, so every call is validated
|
|
22
|
-
* as the Hub validates it: bad input is `Refused` with code `invalid`, and an unbound slot
|
|
23
|
-
*
|
|
21
|
+
* as the Hub validates it: bad input is `Refused` with code `invalid`, and an unbound slot throws
|
|
22
|
+
* `NotConnected`.
|
|
24
23
|
*/
|
|
25
24
|
export interface TestContext<S extends InterfaceMap, X extends InterfaceMap> extends Omit<ModuleRuntime<S, X>, "bind" | "call" | "expose"> {
|
|
26
25
|
bind<K extends keyof S & string>(slot: K, provider: Provider<S[K]>): Binding;
|
|
@@ -45,4 +44,4 @@ export declare function createTestContext<S extends InterfaceMap, X extends Inte
|
|
|
45
44
|
actorId?: string;
|
|
46
45
|
module?: string;
|
|
47
46
|
}): TestContext<S, X>;
|
|
48
|
-
export type { Binding
|
|
47
|
+
export type { Binding } from "./runtime.js";
|