@qping/plugin-bus 0.3.0 → 0.5.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/actions.d.ts CHANGED
@@ -151,27 +151,47 @@ export type DetailRequest = {
151
151
  page?: string;
152
152
  title?: string;
153
153
  initialState?: unknown;
154
+ /** Restricts the action bar for this detail page. Omit to expose every registered action. */
155
+ actions?: string[];
154
156
  };
155
- /**
156
- * The result of running an action. Every field is optional and they combine: opening an IDE and
157
- * closing the search window is `{ host: {...}, close: true }`.
158
- */
159
- export type ActionOutcome = {
160
- /** Run a host-side action (clipboard, process launch, browser, ...). */
161
- host?: HostActionRequest;
162
- /** Hand off to the detail page; arrives as `host.event.detailAction` with this payload. */
163
- web?: {
164
- payload?: unknown;
165
- };
166
- /** Open a web detail page. */
167
- detail?: DetailRequest;
157
+ export type ActionTarget =
158
+ /** Run one privileged host-side action (clipboard, process launch, browser, ...). */
159
+ {
160
+ kind: "host";
161
+ action: HostActionRequest;
162
+ }
163
+ /** Hand off to the currently active detail page as host.event.detailAction. */
164
+ | {
165
+ kind: "web";
166
+ payload?: unknown;
167
+ }
168
+ /** Open a new web detail page. */
169
+ | ({
170
+ kind: "detail";
171
+ } & DetailRequest);
172
+ export type ActionAfter = "keep" | "close" | "refresh";
173
+ type ActionOutcomeBase = {
168
174
  /** Status bar text. */
169
175
  message?: LocalizedText;
170
- /** Close the search window afterwards. Defaults to false. */
171
- close?: boolean;
172
- /** Refresh the current search results afterwards. Defaults to false. */
173
- refresh?: boolean;
174
176
  };
177
+ /**
178
+ * The result of running an action. An action selects at most one execution target. Host targets
179
+ * may choose a follow-up lifecycle action; web and detail targets keep their current surface alive.
180
+ */
181
+ export type ActionOutcome = ActionOutcomeBase & ({
182
+ target?: undefined;
183
+ after?: ActionAfter;
184
+ } | {
185
+ target: Extract<ActionTarget, {
186
+ kind: "host";
187
+ }>;
188
+ after?: ActionAfter;
189
+ } | {
190
+ target: Exclude<ActionTarget, {
191
+ kind: "host";
192
+ }>;
193
+ after?: "keep";
194
+ });
175
195
  /**
176
196
  * What an action sees when it runs. `item` is the original object returned by `search()`,
177
197
  * including fields the host never saw — the SDK keeps it so actions do not have to re-derive
@@ -202,3 +222,4 @@ export type ActionManifestEntry = {
202
222
  hotkey?: Hotkey;
203
223
  };
204
224
  export declare function toActionManifest(definition: ActionDefinition): ActionManifestEntry;
225
+ export {};
@@ -26,11 +26,10 @@ export interface PluginRuntime {
26
26
  export declare function runPlugin(handlers: PluginHandlers): Promise<PluginRuntime>;
27
27
  /**
28
28
  * Sends bus.handshake with the bootstrap token and waits for the host response that binds
29
- * plugin/entry/session/endpoint identity. Rejects on HandshakeFailed / ProtocolMismatch / timeout.
29
+ * plugin/session/endpoint identity. Rejects on HandshakeFailed / ProtocolMismatch / timeout.
30
30
  */
31
31
  export declare function completeHandshake(transport: NodeTransport, token: string, timeoutMs?: number): Promise<{
32
32
  pluginId: string;
33
- entryId: string;
34
33
  sessionId: string;
35
34
  endpointId: string;
36
35
  }>;
@@ -295,7 +295,6 @@ var HandlerRouter = class {
295
295
  handlers = /* @__PURE__ */ new Map();
296
296
  pendingHostCalls = /* @__PURE__ */ new Map();
297
297
  pluginId = "p";
298
- entryId = "e";
299
298
  sessionId = "s";
300
299
  endpointId = EndpointIds.NodeMain;
301
300
  /** Injected transport send fn; tests can override `router.send` directly. */
@@ -306,7 +305,6 @@ var HandlerRouter = class {
306
305
  /** Sets the bound identity stamped on outbound messages (after handshake). */
307
306
  setIdentity(ids) {
308
307
  this.pluginId = ids.pluginId;
309
- this.entryId = ids.entryId;
310
308
  this.sessionId = ids.sessionId;
311
309
  this.endpointId = ids.endpointId;
312
310
  }
@@ -355,7 +353,6 @@ var HandlerRouter = class {
355
353
  traceId: id,
356
354
  sessionId: this.sessionId,
357
355
  pluginId: this.pluginId,
358
- entryId: this.entryId,
359
356
  endpointId: this.endpointId,
360
357
  kind: MessageKind.Request,
361
358
  route,
@@ -402,7 +399,6 @@ var HandlerRouter = class {
402
399
  traceId: req.traceId,
403
400
  sessionId: req.sessionId,
404
401
  pluginId: req.pluginId,
405
- entryId: req.entryId,
406
402
  endpointId: this.endpointId,
407
403
  kind: MessageKind.Response,
408
404
  route: req.route,
@@ -483,7 +479,6 @@ async function completeHandshake(transport, token, timeoutMs = 1e4) {
483
479
  traceId: id,
484
480
  sessionId: "",
485
481
  pluginId: "",
486
- entryId: "",
487
482
  endpointId: EndpointIds.NodeMain,
488
483
  kind: MessageKind.Request,
489
484
  route: Routes.Bus.Handshake,
@@ -509,14 +504,13 @@ async function completeHandshake(transport, token, timeoutMs = 1e4) {
509
504
  }
510
505
  const p = env.payload ?? {};
511
506
  const pluginId = String(p.pluginId ?? "");
512
- const entryId = String(p.entryId ?? "");
513
507
  const sessionId = String(p.sessionId ?? "");
514
508
  const endpointId = String(p.endpointId ?? EndpointIds.NodeMain);
515
- if (!pluginId || !entryId || !sessionId) {
509
+ if (!pluginId || !sessionId) {
516
510
  reject(new Error("bus.handshake success response missing bound identity"));
517
511
  return;
518
512
  }
519
- resolve({ pluginId, entryId, sessionId, endpointId });
513
+ resolve({ pluginId, sessionId, endpointId });
520
514
  });
521
515
  transport.send(req);
522
516
  });
package/dist/node.mjs CHANGED
@@ -304,7 +304,6 @@ var HandlerRouter = class {
304
304
  handlers = /* @__PURE__ */ new Map();
305
305
  pendingHostCalls = /* @__PURE__ */ new Map();
306
306
  pluginId = "p";
307
- entryId = "e";
308
307
  sessionId = "s";
309
308
  endpointId = EndpointIds.NodeMain;
310
309
  /** Injected transport send fn; tests can override `router.send` directly. */
@@ -315,7 +314,6 @@ var HandlerRouter = class {
315
314
  /** Sets the bound identity stamped on outbound messages (after handshake). */
316
315
  setIdentity(ids) {
317
316
  this.pluginId = ids.pluginId;
318
- this.entryId = ids.entryId;
319
317
  this.sessionId = ids.sessionId;
320
318
  this.endpointId = ids.endpointId;
321
319
  }
@@ -364,7 +362,6 @@ var HandlerRouter = class {
364
362
  traceId: id,
365
363
  sessionId: this.sessionId,
366
364
  pluginId: this.pluginId,
367
- entryId: this.entryId,
368
365
  endpointId: this.endpointId,
369
366
  kind: MessageKind.Request,
370
367
  route,
@@ -411,7 +408,6 @@ var HandlerRouter = class {
411
408
  traceId: req.traceId,
412
409
  sessionId: req.sessionId,
413
410
  pluginId: req.pluginId,
414
- entryId: req.entryId,
415
411
  endpointId: this.endpointId,
416
412
  kind: MessageKind.Response,
417
413
  route: req.route,
@@ -492,7 +488,6 @@ async function completeHandshake(transport, token, timeoutMs = 1e4) {
492
488
  traceId: id,
493
489
  sessionId: "",
494
490
  pluginId: "",
495
- entryId: "",
496
491
  endpointId: EndpointIds.NodeMain,
497
492
  kind: MessageKind.Request,
498
493
  route: Routes.Bus.Handshake,
@@ -518,14 +513,13 @@ async function completeHandshake(transport, token, timeoutMs = 1e4) {
518
513
  }
519
514
  const p = env.payload ?? {};
520
515
  const pluginId = String(p.pluginId ?? "");
521
- const entryId = String(p.entryId ?? "");
522
516
  const sessionId = String(p.sessionId ?? "");
523
517
  const endpointId = String(p.endpointId ?? EndpointIds.NodeMain);
524
- if (!pluginId || !entryId || !sessionId) {
518
+ if (!pluginId || !sessionId) {
525
519
  reject(new Error("bus.handshake success response missing bound identity"));
526
520
  return;
527
521
  }
528
- resolve({ pluginId, entryId, sessionId, endpointId });
522
+ resolve({ pluginId, sessionId, endpointId });
529
523
  });
530
524
  transport.send(req);
531
525
  });
@@ -696,7 +690,6 @@ var Plugin = class {
696
690
  traceId: crypto.randomUUID().replace(/-/g, "").slice(0, 32),
697
691
  sessionId: "",
698
692
  pluginId: "",
699
- entryId: "",
700
693
  endpointId: EndpointIds.NodeMain,
701
694
  kind: MessageKind.Event,
702
695
  route,
@@ -88,7 +88,6 @@ export interface Envelope {
88
88
  traceId: string;
89
89
  sessionId: string;
90
90
  pluginId: string;
91
- entryId: string;
92
91
  endpointId: string;
93
92
  kind: MessageKind;
94
93
  route: string;
package/dist/router.d.ts CHANGED
@@ -16,7 +16,6 @@ export declare class HandlerRouter {
16
16
  private handlers;
17
17
  private pendingHostCalls;
18
18
  private pluginId;
19
- private entryId;
20
19
  private sessionId;
21
20
  private endpointId;
22
21
  /** Injected transport send fn; tests can override `router.send` directly. */
@@ -27,7 +26,6 @@ export declare class HandlerRouter {
27
26
  /** Sets the bound identity stamped on outbound messages (after handshake). */
28
27
  setIdentity(ids: {
29
28
  pluginId: string;
30
- entryId: string;
31
29
  sessionId: string;
32
30
  endpointId: string;
33
31
  }): void;
@@ -2545,7 +2545,6 @@ function createWebBusClient(options) {
2545
2545
  traceId: id,
2546
2546
  sessionId: "",
2547
2547
  pluginId: "",
2548
- entryId: "",
2549
2548
  endpointId: "",
2550
2549
  kind: MessageKind.Request,
2551
2550
  route,
@@ -2607,7 +2606,6 @@ function handshake(timeoutMs) {
2607
2606
  traceId: id,
2608
2607
  sessionId: "",
2609
2608
  pluginId: "",
2610
- entryId: "",
2611
2609
  endpointId: "web",
2612
2610
  kind: MessageKind.Request,
2613
2611
  route: Routes.Bus.Handshake,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qping/plugin-bus",
3
- "version": "0.3.0",
3
+ "version": "0.5.0",
4
4
  "description": "v3 message-bus runtime for MyTools plugins (named-pipe transport).",
5
5
  "type": "module",
6
6
  "files": [
@@ -28,17 +28,17 @@
28
28
  "import": "./dist/webClient.mjs",
29
29
  "default": "./dist/webClient.mjs"
30
30
  },
31
- "./i18n": {
32
- "types": "./dist/i18n.d.ts",
33
- "import": "./dist/i18n.mjs",
34
- "default": "./dist/i18n.mjs"
35
- },
36
- "./search": {
37
- "types": "./dist/search.d.ts",
38
- "import": "./dist/search.mjs",
39
- "default": "./dist/search.mjs"
40
- },
41
- "./dev": {
31
+ "./i18n": {
32
+ "types": "./dist/i18n.d.ts",
33
+ "import": "./dist/i18n.mjs",
34
+ "default": "./dist/i18n.mjs"
35
+ },
36
+ "./search": {
37
+ "types": "./dist/search.d.ts",
38
+ "import": "./dist/search.mjs",
39
+ "default": "./dist/search.mjs"
40
+ },
41
+ "./dev": {
42
42
  "types": "./dist/dev.d.ts",
43
43
  "import": "./dist/dev.mjs",
44
44
  "default": "./dist/dev.mjs"
package/src/actions.ts CHANGED
@@ -94,26 +94,34 @@ export type DetailRequest = {
94
94
  page?: string;
95
95
  title?: string;
96
96
  initialState?: unknown;
97
+ /** Restricts the action bar for this detail page. Omit to expose every registered action. */
98
+ actions?: string[];
97
99
  };
98
100
 
99
- /**
100
- * The result of running an action. Every field is optional and they combine: opening an IDE and
101
- * closing the search window is `{ host: {...}, close: true }`.
102
- */
103
- export type ActionOutcome = {
104
- /** Run a host-side action (clipboard, process launch, browser, ...). */
105
- host?: HostActionRequest;
106
- /** Hand off to the detail page; arrives as `host.event.detailAction` with this payload. */
107
- web?: { payload?: unknown };
108
- /** Open a web detail page. */
109
- detail?: DetailRequest;
101
+ export type ActionTarget =
102
+ /** Run one privileged host-side action (clipboard, process launch, browser, ...). */
103
+ | { kind: "host"; action: HostActionRequest }
104
+ /** Hand off to the currently active detail page as host.event.detailAction. */
105
+ | { kind: "web"; payload?: unknown }
106
+ /** Open a new web detail page. */
107
+ | ({ kind: "detail" } & DetailRequest);
108
+
109
+ export type ActionAfter = "keep" | "close" | "refresh";
110
+
111
+ type ActionOutcomeBase = {
110
112
  /** Status bar text. */
111
113
  message?: LocalizedText;
112
- /** Close the search window afterwards. Defaults to false. */
113
- close?: boolean;
114
- /** Refresh the current search results afterwards. Defaults to false. */
115
- refresh?: boolean;
116
- };
114
+ };
115
+
116
+ /**
117
+ * The result of running an action. An action selects at most one execution target. Host targets
118
+ * may choose a follow-up lifecycle action; web and detail targets keep their current surface alive.
119
+ */
120
+ export type ActionOutcome = ActionOutcomeBase & (
121
+ | { target?: undefined; after?: ActionAfter }
122
+ | { target: Extract<ActionTarget, { kind: "host" }>; after?: ActionAfter }
123
+ | { target: Exclude<ActionTarget, { kind: "host" }>; after?: "keep" }
124
+ );
117
125
 
118
126
  /**
119
127
  * What an action sees when it runs. `item` is the original object returned by `search()`,
package/src/bootstrap.ts CHANGED
@@ -102,13 +102,13 @@ async function readBootstrapLine(): Promise<{ pipePath: string; token: string }>
102
102
 
103
103
  /**
104
104
  * Sends bus.handshake with the bootstrap token and waits for the host response that binds
105
- * plugin/entry/session/endpoint identity. Rejects on HandshakeFailed / ProtocolMismatch / timeout.
105
+ * plugin/session/endpoint identity. Rejects on HandshakeFailed / ProtocolMismatch / timeout.
106
106
  */
107
107
  export async function completeHandshake(
108
108
  transport: NodeTransport,
109
109
  token: string,
110
110
  timeoutMs = 10000,
111
- ): Promise<{ pluginId: string; entryId: string; sessionId: string; endpointId: string }> {
111
+ ): Promise<{ pluginId: string; sessionId: string; endpointId: string }> {
112
112
  const id = randomBytes(16).toString("hex");
113
113
  const req: Envelope = {
114
114
  version: ProtocolVersion,
@@ -116,7 +116,6 @@ export async function completeHandshake(
116
116
  traceId: id,
117
117
  sessionId: "",
118
118
  pluginId: "",
119
- entryId: "",
120
119
  endpointId: EndpointIds.NodeMain,
121
120
  kind: MessageKind.Request,
122
121
  route: Routes.Bus.Handshake,
@@ -144,14 +143,13 @@ export async function completeHandshake(
144
143
  }
145
144
  const p = (env.payload ?? {}) as Record<string, unknown>;
146
145
  const pluginId = String(p.pluginId ?? "");
147
- const entryId = String(p.entryId ?? "");
148
146
  const sessionId = String(p.sessionId ?? "");
149
147
  const endpointId = String(p.endpointId ?? EndpointIds.NodeMain);
150
- if (!pluginId || !entryId || !sessionId) {
148
+ if (!pluginId || !sessionId) {
151
149
  reject(new Error("bus.handshake success response missing bound identity"));
152
150
  return;
153
151
  }
154
- resolve({ pluginId, entryId, sessionId, endpointId });
152
+ resolve({ pluginId, sessionId, endpointId });
155
153
  });
156
154
 
157
155
  transport.send(req);
package/src/node.ts CHANGED
@@ -153,7 +153,6 @@ export class Plugin {
153
153
  traceId: crypto.randomUUID().replace(/-/g, "").slice(0, 32),
154
154
  sessionId: "",
155
155
  pluginId: "",
156
- entryId: "",
157
156
  endpointId: EndpointIds.NodeMain,
158
157
  kind: MessageKind.Event,
159
158
  route,
package/src/protocol.ts CHANGED
@@ -110,7 +110,6 @@ export interface Envelope {
110
110
  traceId: string;
111
111
  sessionId: string;
112
112
  pluginId: string;
113
- entryId: string;
114
113
  endpointId: string;
115
114
  kind: MessageKind;
116
115
  route: string;
package/src/router.ts CHANGED
@@ -62,7 +62,6 @@ export class HandlerRouter {
62
62
  private handlers = new Map<string, Handler>();
63
63
  private pendingHostCalls = new Map<string, PendingHostCall>();
64
64
  private pluginId = "p";
65
- private entryId = "e";
66
65
  private sessionId = "s";
67
66
  private endpointId: string = EndpointIds.NodeMain;
68
67
 
@@ -74,9 +73,8 @@ export class HandlerRouter {
74
73
  }
75
74
 
76
75
  /** Sets the bound identity stamped on outbound messages (after handshake). */
77
- setIdentity(ids: { pluginId: string; entryId: string; sessionId: string; endpointId: string }): void {
76
+ setIdentity(ids: { pluginId: string; sessionId: string; endpointId: string }): void {
78
77
  this.pluginId = ids.pluginId;
79
- this.entryId = ids.entryId;
80
78
  this.sessionId = ids.sessionId;
81
79
  this.endpointId = ids.endpointId;
82
80
  }
@@ -133,7 +131,6 @@ export class HandlerRouter {
133
131
  traceId: id,
134
132
  sessionId: this.sessionId,
135
133
  pluginId: this.pluginId,
136
- entryId: this.entryId,
137
134
  endpointId: this.endpointId,
138
135
  kind: MessageKind.Request,
139
136
  route,
@@ -176,7 +173,6 @@ export class HandlerRouter {
176
173
  traceId: req.traceId,
177
174
  sessionId: req.sessionId,
178
175
  pluginId: req.pluginId,
179
- entryId: req.entryId,
180
176
  endpointId: this.endpointId,
181
177
  kind: MessageKind.Response,
182
178
  route: req.route,
package/src/webClient.ts CHANGED
@@ -208,7 +208,6 @@ export function createWebBusClient(options?: {
208
208
  traceId: id,
209
209
  sessionId: "",
210
210
  pluginId: "",
211
- entryId: "",
212
211
  endpointId: "",
213
212
  kind: MessageKind.Request,
214
213
  route,
@@ -277,7 +276,6 @@ function handshake(timeoutMs: number): Promise<string> {
277
276
  traceId: id,
278
277
  sessionId: "",
279
278
  pluginId: "",
280
- entryId: "",
281
279
  endpointId: "web",
282
280
  kind: MessageKind.Request,
283
281
  route: Routes.Bus.Handshake,