@qping/plugin-bus 0.1.0 → 0.2.0
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/bootstrap.d.ts +34 -0
- package/dist/bootstrap.mjs +170 -16
- package/dist/framing.d.ts +36 -0
- package/dist/i18n.d.ts +19 -0
- package/dist/i18n.mjs +2343 -0
- package/dist/node.d.ts +65 -0
- package/dist/{server.mjs → node.mjs} +244 -60
- package/dist/protocol.d.ts +101 -0
- package/dist/protocol.mjs +73 -1
- package/dist/router.d.ts +41 -0
- package/dist/transport.d.ts +24 -0
- package/dist/webClient.d.ts +34 -0
- package/dist/webClient.mjs +2599 -0
- package/dist/webTypes.d.ts +50 -0
- package/package.json +22 -8
- package/src/bootstrap.ts +98 -9
- package/src/i18n.ts +120 -0
- package/src/node.ts +213 -0
- package/src/protocol.ts +82 -17
- package/src/router.ts +65 -18
- package/src/transport.ts +2 -1
- package/src/webClient.ts +285 -0
- package/src/webTypes.ts +52 -0
- package/dist/bootstrap.d.mts +0 -1
- package/dist/protocol.d.mts +0 -1
- package/dist/server.d.mts +0 -1
- package/src/server.ts +0 -156
package/src/server.ts
DELETED
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* v3 server-side tool SDK: a fluent `createTool()` API that mirrors the v2 @qping/plugin-common/server
|
|
3
|
-
* surface (initialize/search/action/handle/publish/hostCall/start) but runs over the v3 named-pipe
|
|
4
|
-
* message bus via bootstrap.ts. This lets existing plugin backends switch to v3 transport by
|
|
5
|
-
* changing only the import — no handler-logic rewrite.
|
|
6
|
-
*
|
|
7
|
-
* Legacy method names map to v3 routes:
|
|
8
|
-
* initialize -> plugin.call.initialize
|
|
9
|
-
* search -> plugin.call.search
|
|
10
|
-
* invokeAction -> plugin.call.invokeAction
|
|
11
|
-
* detailEvent -> plugin.call.detailEvent
|
|
12
|
-
* detailCall -> plugin.call.detailCall (+ named handlers via plugin.call.<action>)
|
|
13
|
-
* publish -> plugin.event.<subjectId>
|
|
14
|
-
* hostCall -> host.call.<method>
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import { runPlugin, type PluginRuntime } from "./bootstrap.ts";
|
|
18
|
-
|
|
19
|
-
type NodeToolContext = {
|
|
20
|
-
action: string;
|
|
21
|
-
itemId: string;
|
|
22
|
-
query: string;
|
|
23
|
-
locale: string;
|
|
24
|
-
fallbackLocale: string;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
type NodeToolHostHandler = (params: any) => unknown | Promise<unknown>;
|
|
28
|
-
type NodeToolHandler = (payload: any, context: NodeToolContext) => unknown | Promise<unknown>;
|
|
29
|
-
|
|
30
|
-
export class NodeTool {
|
|
31
|
-
#handlers = new Map<string, NodeToolHandler>();
|
|
32
|
-
#searchHandler: NodeToolHostHandler | null = null;
|
|
33
|
-
#actionHandler: NodeToolHostHandler | null = null;
|
|
34
|
-
#initializeHandler: NodeToolHostHandler | null = null;
|
|
35
|
-
#runtime: PluginRuntime | null = null;
|
|
36
|
-
|
|
37
|
-
initialize(handler: NodeToolHostHandler): this {
|
|
38
|
-
this.#initializeHandler = handler;
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
search(handler: NodeToolHostHandler): this {
|
|
43
|
-
this.#searchHandler = handler;
|
|
44
|
-
return this;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
action(handler: NodeToolHostHandler): this {
|
|
48
|
-
this.#actionHandler = handler;
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
handle(action: string, handler: NodeToolHandler): this {
|
|
53
|
-
if (!action || typeof action !== "string") {
|
|
54
|
-
throw new Error("tool.handle requires an action name.");
|
|
55
|
-
}
|
|
56
|
-
if (typeof handler !== "function") {
|
|
57
|
-
throw new Error("tool.handle requires a handler.");
|
|
58
|
-
}
|
|
59
|
-
this.#handlers.set(action, handler);
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Publishes a plugin.event.<subjectId> event to all webviews in the session. */
|
|
64
|
-
publish(subjectId: string, payload: unknown = {}): void {
|
|
65
|
-
if (!this.#runtime) throw new Error("tool not started");
|
|
66
|
-
// Strip the legacy prefix to form a clean route; the host EventReceived surfaces the route.
|
|
67
|
-
const route = subjectId.startsWith("plugin.event.") ? subjectId : `plugin.event.${subjectId}`;
|
|
68
|
-
this.#runtime.transport.send({
|
|
69
|
-
version: "3.0",
|
|
70
|
-
id: crypto.randomUUID().replace(/-/g, "").slice(0, 32),
|
|
71
|
-
traceId: crypto.randomUUID().replace(/-/g, "").slice(0, 32),
|
|
72
|
-
sessionId: "",
|
|
73
|
-
pluginId: "",
|
|
74
|
-
entryId: "",
|
|
75
|
-
endpointId: "node-main",
|
|
76
|
-
kind: "event",
|
|
77
|
-
route,
|
|
78
|
-
payload,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Calls a host.call.<method> capability and awaits the response. */
|
|
83
|
-
hostCall(method: string, params: Record<string, unknown> = {}): Promise<unknown> {
|
|
84
|
-
if (!this.#runtime) return Promise.reject(new Error("tool not started"));
|
|
85
|
-
return this.#runtime.router.callHost(`host.call.${method}`, params);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Connects to the host pipe and begins dispatching. Must be called last. */
|
|
89
|
-
async start(): Promise<void> {
|
|
90
|
-
const routes = this.buildRoutes();
|
|
91
|
-
this.#runtime = await runPlugin(routes);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Builds the v3 route map from the fluent registrations. Exposed for unit testing the mapping
|
|
96
|
-
* without connecting a pipe.
|
|
97
|
-
*/
|
|
98
|
-
buildRoutes(): Record<string, (payload: any) => unknown | Promise<unknown>> {
|
|
99
|
-
const routes: Record<string, (payload: any) => unknown | Promise<unknown>> = {};
|
|
100
|
-
|
|
101
|
-
if (this.#initializeHandler) {
|
|
102
|
-
routes["plugin.call.initialize"] = (p) => this.#initializeHandler!(p);
|
|
103
|
-
}
|
|
104
|
-
if (this.#searchHandler) {
|
|
105
|
-
routes["plugin.call.search"] = (p) => this.#searchHandler!(p);
|
|
106
|
-
}
|
|
107
|
-
if (this.#actionHandler) {
|
|
108
|
-
routes["plugin.call.invokeAction"] = (p) => {
|
|
109
|
-
return this.#actionHandler!({ ...p, itemId: p.itemId, query: p.query });
|
|
110
|
-
};
|
|
111
|
-
}
|
|
112
|
-
// Legacy detail calls: plugin.call.detailCall carries an `action` field selecting the handler.
|
|
113
|
-
routes["plugin.call.detailCall"] = async (p) => {
|
|
114
|
-
const action = p?.action ?? "";
|
|
115
|
-
const handler = this.#handlers.get(action);
|
|
116
|
-
if (!handler) {
|
|
117
|
-
throw new Error(`no handler registered for action '${action}'`);
|
|
118
|
-
}
|
|
119
|
-
const ctx = extractContext(p);
|
|
120
|
-
const result = await handler(p?.payload ?? {}, ctx);
|
|
121
|
-
return { result: result ?? {} };
|
|
122
|
-
};
|
|
123
|
-
routes["plugin.call.detailEvent"] = async (p) => {
|
|
124
|
-
return { state: p?.payload ?? {} };
|
|
125
|
-
};
|
|
126
|
-
for (const [action, handler] of this.#handlers) {
|
|
127
|
-
const route = `plugin.call.${action}`;
|
|
128
|
-
if (!routes[route]) {
|
|
129
|
-
routes[route] = async (p) => {
|
|
130
|
-
const ctx = extractContext(p);
|
|
131
|
-
return handler(p, ctx);
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
return routes;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
async stop(): Promise<void> {
|
|
139
|
-
if (this.#runtime) await this.#runtime.close();
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
function extractContext(p: any): NodeToolContext {
|
|
144
|
-
return {
|
|
145
|
-
action: p?.action ?? "",
|
|
146
|
-
itemId: p?.itemId ?? "",
|
|
147
|
-
query: p?.query ?? "",
|
|
148
|
-
locale: p?.locale ?? "en-US",
|
|
149
|
-
fallbackLocale: p?.fallbackLocale ?? "en-US",
|
|
150
|
-
};
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
/** Creates a v3 NodeTool. Drop-in replacement for @qping/plugin-common/server's createTool(). */
|
|
154
|
-
export function createTool(): NodeTool {
|
|
155
|
-
return new NodeTool();
|
|
156
|
-
}
|