@portel/photon-core 2.1.2 → 2.3.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.
Files changed (76) hide show
  1. package/README.md +61 -0
  2. package/dist/base.d.ts +42 -2
  3. package/dist/base.d.ts.map +1 -1
  4. package/dist/base.js +75 -7
  5. package/dist/base.js.map +1 -1
  6. package/dist/channels/daemon-broker.d.ts +35 -0
  7. package/dist/channels/daemon-broker.d.ts.map +1 -0
  8. package/dist/channels/daemon-broker.js +229 -0
  9. package/dist/channels/daemon-broker.js.map +1 -0
  10. package/dist/channels/http-broker.d.ts +45 -0
  11. package/dist/channels/http-broker.d.ts.map +1 -0
  12. package/dist/channels/http-broker.js +182 -0
  13. package/dist/channels/http-broker.js.map +1 -0
  14. package/dist/channels/index.d.ts +53 -0
  15. package/dist/channels/index.d.ts.map +1 -0
  16. package/dist/channels/index.js +67 -0
  17. package/dist/channels/index.js.map +1 -0
  18. package/dist/channels/noop-broker.d.ts +21 -0
  19. package/dist/channels/noop-broker.d.ts.map +1 -0
  20. package/dist/channels/noop-broker.js +38 -0
  21. package/dist/channels/noop-broker.js.map +1 -0
  22. package/dist/channels/redis-broker.d.ts +45 -0
  23. package/dist/channels/redis-broker.d.ts.map +1 -0
  24. package/dist/channels/redis-broker.js +214 -0
  25. package/dist/channels/redis-broker.js.map +1 -0
  26. package/dist/channels/registry.d.ts +49 -0
  27. package/dist/channels/registry.d.ts.map +1 -0
  28. package/dist/channels/registry.js +150 -0
  29. package/dist/channels/registry.js.map +1 -0
  30. package/dist/channels/types.d.ts +85 -0
  31. package/dist/channels/types.d.ts.map +1 -0
  32. package/dist/channels/types.js +8 -0
  33. package/dist/channels/types.js.map +1 -0
  34. package/dist/config.d.ts +63 -0
  35. package/dist/config.d.ts.map +1 -0
  36. package/dist/config.js +117 -0
  37. package/dist/config.js.map +1 -0
  38. package/dist/decorators.d.ts +48 -0
  39. package/dist/decorators.d.ts.map +1 -0
  40. package/dist/decorators.js +64 -0
  41. package/dist/decorators.js.map +1 -0
  42. package/dist/design-system/tokens.d.ts +66 -0
  43. package/dist/design-system/tokens.d.ts.map +1 -1
  44. package/dist/design-system/tokens.js +324 -44
  45. package/dist/design-system/tokens.js.map +1 -1
  46. package/dist/index.d.ts +4 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +12 -0
  49. package/dist/index.js.map +1 -1
  50. package/dist/mcp-apps.d.ts +130 -0
  51. package/dist/mcp-apps.d.ts.map +1 -0
  52. package/dist/mcp-apps.js +87 -0
  53. package/dist/mcp-apps.js.map +1 -0
  54. package/dist/schema-extractor.d.ts +41 -3
  55. package/dist/schema-extractor.d.ts.map +1 -1
  56. package/dist/schema-extractor.js +166 -14
  57. package/dist/schema-extractor.js.map +1 -1
  58. package/dist/types.d.ts +91 -0
  59. package/dist/types.d.ts.map +1 -1
  60. package/dist/types.js.map +1 -1
  61. package/package.json +15 -3
  62. package/src/base.ts +82 -6
  63. package/src/channels/daemon-broker.ts +271 -0
  64. package/src/channels/http-broker.ts +221 -0
  65. package/src/channels/index.ts +96 -0
  66. package/src/channels/noop-broker.ts +47 -0
  67. package/src/channels/redis-broker.ts +252 -0
  68. package/src/channels/registry.ts +170 -0
  69. package/src/channels/types.ts +95 -0
  70. package/src/config.ts +134 -0
  71. package/src/decorators.ts +87 -0
  72. package/src/design-system/tokens.ts +381 -57
  73. package/src/index.ts +39 -0
  74. package/src/mcp-apps.ts +204 -0
  75. package/src/schema-extractor.ts +191 -15
  76. package/src/types.ts +103 -0
package/README.md CHANGED
@@ -449,6 +449,67 @@ const resumed = await maybeStatefulExecute(
449
449
 
450
450
  ---
451
451
 
452
+ ### Channel-Based Pub/Sub
453
+
454
+ Photon Core provides a pluggable channel broker architecture for cross-process messaging. This enables real-time updates between MCP processes, Beam UI, and other services.
455
+
456
+ ```typescript
457
+ import { PhotonMCP } from '@portel/photon-core';
458
+
459
+ export default class KanbanBoard extends PhotonMCP {
460
+ async moveTask(params: { taskId: string; column: string }) {
461
+ const task = await this.updateTask(params);
462
+
463
+ // Emit to local output handler (current caller)
464
+ this.emit({ emit: 'board-update', board: 'default' });
465
+
466
+ // Also publish to channel for cross-process subscribers
467
+ this.emit({
468
+ channel: 'kanban:default', // Format: photonName:subChannel
469
+ event: 'task-moved',
470
+ data: { task }
471
+ });
472
+
473
+ return task;
474
+ }
475
+ }
476
+ ```
477
+
478
+ **Broker Types:**
479
+
480
+ | Broker | Use Case | Configuration |
481
+ |--------|----------|---------------|
482
+ | `daemon` | Local dev, single-server | Default (uses Unix sockets) |
483
+ | `redis` | Multi-server, production | `PHOTON_REDIS_URL` |
484
+ | `http` | Webhook integrations | `PHOTON_CHANNEL_HTTP_URL` |
485
+ | `noop` | Testing, disabled | `PHOTON_CHANNEL_BROKER=noop` |
486
+
487
+ **Subscribing to channels:**
488
+
489
+ ```typescript
490
+ import { getBroker } from '@portel/photon-core';
491
+
492
+ const broker = getBroker();
493
+
494
+ // Subscribe
495
+ const sub = await broker.subscribe('kanban:default', (message) => {
496
+ console.log('Received:', message.event, message.data);
497
+ });
498
+
499
+ // Later: unsubscribe
500
+ sub.unsubscribe();
501
+ ```
502
+
503
+ **Environment Variables:**
504
+ - `PHOTON_CHANNEL_BROKER` - Explicit broker type (`daemon`, `redis`, `http`, `noop`)
505
+ - `PHOTON_NAME` - Photon name for daemon socket path
506
+ - `PHOTON_REDIS_URL` - Redis connection URL (auto-enables redis broker)
507
+ - `PHOTON_CHANNEL_HTTP_URL` - HTTP webhook URL (auto-enables http broker)
508
+
509
+ See [CHANNELS.md](./CHANNELS.md) for full architecture documentation.
510
+
511
+ ---
512
+
452
513
  ## 🏗️ Building Custom Runtimes
453
514
 
454
515
  Photon Core is designed to be the foundation for custom runtimes. Here are examples:
package/dist/base.d.ts CHANGED
@@ -49,7 +49,24 @@ import { MCPClient, MCPClientFactory } from '@portel/mcp';
49
49
  export declare class PhotonMCP {
50
50
  /**
51
51
  * Emit an event/progress update
52
- * @param data Data to emit
52
+ *
53
+ * If data includes a `channel` property, the message is also published
54
+ * to the channel broker for cross-process notification.
55
+ *
56
+ * @param data Data to emit (can include channel, event, data properties for pub/sub)
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * // Simple emit (local only)
61
+ * this.emit({ status: 'processing', progress: 50 });
62
+ *
63
+ * // Emit with channel (broadcasts to subscribers)
64
+ * this.emit({
65
+ * channel: 'board:my-board',
66
+ * event: 'task-moved',
67
+ * data: { taskId: '123', newColumn: 'Done' }
68
+ * });
69
+ * ```
53
70
  */
54
71
  protected emit(data: any): void;
55
72
  /**
@@ -69,7 +86,7 @@ export declare class PhotonMCP {
69
86
  static getMCPName(): string;
70
87
  /**
71
88
  * Get all tool methods from this class
72
- * Returns all public async methods except lifecycle hooks
89
+ * Returns all public async methods except lifecycle hooks and configuration methods
73
90
  */
74
91
  static getToolMethods(): string[];
75
92
  /**
@@ -128,5 +145,28 @@ export declare class PhotonMCP {
128
145
  * Requires MCP factory to be set
129
146
  */
130
147
  listMCPServers(): Promise<string[]>;
148
+ /**
149
+ * Execute a function with a distributed lock
150
+ *
151
+ * Acquires the lock before executing, releases after (even on error).
152
+ * If the lock cannot be acquired, throws an error.
153
+ *
154
+ * @param lockName Name of the lock to acquire
155
+ * @param fn Function to execute while holding the lock
156
+ * @param timeout Optional lock timeout in ms (default 30000)
157
+ *
158
+ * @example
159
+ * ```typescript
160
+ * async moveTask(params: { taskId: string; column: string }) {
161
+ * return this.withLock('board:write', async () => {
162
+ * const task = await this.loadTask(params.taskId);
163
+ * task.column = params.column;
164
+ * await this.saveTask(task);
165
+ * return task;
166
+ * });
167
+ * }
168
+ * ```
169
+ */
170
+ protected withLock<T>(lockName: string, fn: () => Promise<T>, timeout?: number): Promise<T>;
131
171
  }
132
172
  //# sourceMappingURL=base.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAG1E;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB;;;OAGG;IACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IAM/B;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAEzC;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAsF;IAEzG;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAQ3B;;;OAGG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM,EAAE;IA0BjC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBrH;;OAEG;IACG,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAoBhF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAM9C;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;CAM1C"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAkB,MAAM,aAAa,CAAC;AAK1E;;;;;;GAMG;AACH,qBAAa,SAAS;IACpB;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,GAAG,IAAI;IA0B/B;;;OAGG;IACH,SAAS,CAAC,WAAW,CAAC,EAAE,gBAAgB,CAAC;IAEzC;;;OAGG;IACH,OAAO,CAAC,WAAW,CAAsF;IAEzG;;;OAGG;IACH,MAAM,CAAC,UAAU,IAAI,MAAM;IAQ3B;;;OAGG;IACH,MAAM,CAAC,cAAc,IAAI,MAAM,EAAE;IAiCjC;;OAEG;IACG,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,IAAI,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC;IAkBrH;;OAEG;IACG,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAC9B,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,GAAG,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,CAAC;IAoBhF;;;;;OAKG;IACH,aAAa,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI;IAM9C;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAOzC;;;;;;;;;;;;;;;;;;;;;OAqBG;cACa,QAAQ,CAAC,CAAC,EACxB,QAAQ,EAAE,MAAM,EAChB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC,CAAC,CAAC;CAGd"}
package/dist/base.js CHANGED
@@ -40,6 +40,8 @@
40
40
  */
41
41
  import { createMCPProxy } from '@portel/mcp';
42
42
  import { executionContext } from '@portel/cli';
43
+ import { getBroker } from './channels/index.js';
44
+ import { withLock as withLockHelper } from './decorators.js';
43
45
  /**
44
46
  * Simple base class for creating Photon MCPs
45
47
  *
@@ -50,13 +52,48 @@ import { executionContext } from '@portel/cli';
50
52
  export class PhotonMCP {
51
53
  /**
52
54
  * Emit an event/progress update
53
- * @param data Data to emit
55
+ *
56
+ * If data includes a `channel` property, the message is also published
57
+ * to the channel broker for cross-process notification.
58
+ *
59
+ * @param data Data to emit (can include channel, event, data properties for pub/sub)
60
+ *
61
+ * @example
62
+ * ```typescript
63
+ * // Simple emit (local only)
64
+ * this.emit({ status: 'processing', progress: 50 });
65
+ *
66
+ * // Emit with channel (broadcasts to subscribers)
67
+ * this.emit({
68
+ * channel: 'board:my-board',
69
+ * event: 'task-moved',
70
+ * data: { taskId: '123', newColumn: 'Done' }
71
+ * });
72
+ * ```
54
73
  */
55
74
  emit(data) {
56
75
  const store = executionContext.getStore();
76
+ // Send to local output handler (current caller)
57
77
  if (store?.outputHandler) {
58
78
  store.outputHandler(data);
59
79
  }
80
+ // If channel is specified, also publish to broker for cross-process notification
81
+ if (data && typeof data.channel === 'string') {
82
+ const broker = getBroker();
83
+ broker.publish({
84
+ channel: data.channel,
85
+ event: data.event || 'message',
86
+ data: data.data !== undefined ? data.data : data,
87
+ timestamp: Date.now(),
88
+ source: this.constructor.name,
89
+ }).catch((err) => {
90
+ // Silent fail - channel pub is best-effort
91
+ // Log only in debug mode
92
+ if (process.env.PHOTON_DEBUG) {
93
+ console.error('Channel publish error:', err);
94
+ }
95
+ });
96
+ }
60
97
  }
61
98
  /**
62
99
  * MCP client factory - injected by runtime
@@ -81,20 +118,26 @@ export class PhotonMCP {
81
118
  }
82
119
  /**
83
120
  * Get all tool methods from this class
84
- * Returns all public async methods except lifecycle hooks
121
+ * Returns all public async methods except lifecycle hooks and configuration methods
85
122
  */
86
123
  static getToolMethods() {
87
124
  const prototype = this.prototype;
88
125
  const methods = [];
126
+ // Methods that are conventions, not tools
127
+ const conventionMethods = new Set([
128
+ 'constructor',
129
+ 'onInitialize', // Lifecycle hook
130
+ 'onShutdown', // Lifecycle hook
131
+ 'configure', // Configuration convention
132
+ 'getConfig', // Configuration convention
133
+ ]);
89
134
  // Get all property names from prototype chain
90
135
  let current = prototype;
91
136
  while (current && current !== PhotonMCP.prototype) {
92
137
  Object.getOwnPropertyNames(current).forEach((name) => {
93
- // Skip constructor, private methods (starting with _), and lifecycle hooks
94
- if (name !== 'constructor' &&
95
- !name.startsWith('_') &&
96
- name !== 'onInitialize' &&
97
- name !== 'onShutdown' &&
138
+ // Skip private methods (starting with _) and convention methods
139
+ if (!name.startsWith('_') &&
140
+ !conventionMethods.has(name) &&
98
141
  typeof prototype[name] === 'function' &&
99
142
  !methods.includes(name)) {
100
143
  methods.push(name);
@@ -193,5 +236,30 @@ export class PhotonMCP {
193
236
  }
194
237
  return this._mcpFactory.listServers();
195
238
  }
239
+ /**
240
+ * Execute a function with a distributed lock
241
+ *
242
+ * Acquires the lock before executing, releases after (even on error).
243
+ * If the lock cannot be acquired, throws an error.
244
+ *
245
+ * @param lockName Name of the lock to acquire
246
+ * @param fn Function to execute while holding the lock
247
+ * @param timeout Optional lock timeout in ms (default 30000)
248
+ *
249
+ * @example
250
+ * ```typescript
251
+ * async moveTask(params: { taskId: string; column: string }) {
252
+ * return this.withLock('board:write', async () => {
253
+ * const task = await this.loadTask(params.taskId);
254
+ * task.column = params.column;
255
+ * await this.saveTask(task);
256
+ * return task;
257
+ * });
258
+ * }
259
+ * ```
260
+ */
261
+ async withLock(lockName, fn, timeout) {
262
+ return withLockHelper(lockName, fn, timeout);
263
+ }
196
264
  }
197
265
  //# sourceMappingURL=base.js.map
package/dist/base.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Daemon Channel Broker
3
+ *
4
+ * Uses Unix sockets (or named pipes on Windows) to communicate with
5
+ * the local photon daemon for pub/sub messaging.
6
+ *
7
+ * Best for:
8
+ * - Local development
9
+ * - Single-server deployments
10
+ * - Scenarios where BEAM and MCP share the same filesystem
11
+ */
12
+ import type { ChannelBroker, ChannelMessage, ChannelHandler, Subscription } from './types.js';
13
+ export interface DaemonBrokerOptions {
14
+ /** Photon name (for socket path) */
15
+ photonName?: string;
16
+ /** Custom socket directory */
17
+ socketDir?: string;
18
+ /** Connection timeout in ms */
19
+ timeout?: number;
20
+ }
21
+ export declare class DaemonBroker implements ChannelBroker {
22
+ readonly type = "daemon";
23
+ private photonName;
24
+ private socketDir?;
25
+ private timeout;
26
+ private subscriptions;
27
+ constructor(options?: DaemonBrokerOptions);
28
+ publish(message: ChannelMessage): Promise<void>;
29
+ subscribe(channel: string, handler: ChannelHandler): Promise<Subscription>;
30
+ isConnected(): boolean;
31
+ connect(): Promise<void>;
32
+ disconnect(): Promise<void>;
33
+ }
34
+ export default DaemonBroker;
35
+ //# sourceMappingURL=daemon-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-broker.d.ts","sourceRoot":"","sources":["../../src/channels/daemon-broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG9F,MAAM,WAAW,mBAAmB;IAClC,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAaD,qBAAa,YAAa,YAAW,aAAa;IAChD,QAAQ,CAAC,IAAI,YAAY;IAEzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAA4E;gBAErF,OAAO,GAAE,mBAAwB;IAMvC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAmE/C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IA+HhF,WAAW,IAAI,OAAO;IAKhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CASlC;AAKD,eAAe,YAAY,CAAC"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Daemon Channel Broker
3
+ *
4
+ * Uses Unix sockets (or named pipes on Windows) to communicate with
5
+ * the local photon daemon for pub/sub messaging.
6
+ *
7
+ * Best for:
8
+ * - Local development
9
+ * - Single-server deployments
10
+ * - Scenarios where BEAM and MCP share the same filesystem
11
+ */
12
+ import * as net from 'net';
13
+ import * as path from 'path';
14
+ import * as os from 'os';
15
+ import * as fs from 'fs';
16
+ import { registerBroker } from './registry.js';
17
+ /**
18
+ * Get the socket path for a photon daemon
19
+ */
20
+ function getSocketPath(photonName, socketDir) {
21
+ const dir = socketDir || path.join(os.homedir(), '.photon', 'daemons');
22
+ if (process.platform === 'win32') {
23
+ return `\\\\.\\pipe\\photon-${photonName}`;
24
+ }
25
+ return path.join(dir, `${photonName}.sock`);
26
+ }
27
+ export class DaemonBroker {
28
+ type = 'daemon';
29
+ photonName;
30
+ socketDir;
31
+ timeout;
32
+ subscriptions = new Map();
33
+ constructor(options = {}) {
34
+ this.photonName = options.photonName || process.env.PHOTON_NAME || 'unknown';
35
+ this.socketDir = options.socketDir;
36
+ this.timeout = options.timeout || 5000;
37
+ }
38
+ async publish(message) {
39
+ // Determine photon name: use configured name, or extract from channel format "photonName:subChannel"
40
+ let targetPhoton = this.photonName;
41
+ if (targetPhoton === 'unknown' && message.channel?.includes(':')) {
42
+ // Extract photon name from channel (e.g., "kanban:default" -> "kanban")
43
+ const colonIndex = message.channel.indexOf(':');
44
+ targetPhoton = message.channel.slice(0, colonIndex);
45
+ }
46
+ const socketPath = getSocketPath(targetPhoton, this.socketDir);
47
+ // Check if socket exists
48
+ if (process.platform !== 'win32' && !fs.existsSync(socketPath)) {
49
+ // Daemon not running, silently ignore
50
+ return;
51
+ }
52
+ return new Promise((resolve, reject) => {
53
+ const client = net.createConnection(socketPath);
54
+ const requestId = `pub_${Date.now()}_${Math.random().toString(36).slice(2)}`;
55
+ const timeout = setTimeout(() => {
56
+ client.destroy();
57
+ // Don't reject on timeout - publish is best-effort
58
+ resolve();
59
+ }, this.timeout);
60
+ client.on('connect', () => {
61
+ const request = {
62
+ type: 'publish',
63
+ id: requestId,
64
+ channel: message.channel,
65
+ message: {
66
+ ...message,
67
+ timestamp: message.timestamp || Date.now(),
68
+ source: message.source || this.photonName,
69
+ },
70
+ };
71
+ client.write(JSON.stringify(request) + '\n');
72
+ });
73
+ client.on('data', (chunk) => {
74
+ try {
75
+ const response = JSON.parse(chunk.toString().trim());
76
+ if (response.id === requestId) {
77
+ clearTimeout(timeout);
78
+ client.destroy();
79
+ resolve();
80
+ }
81
+ }
82
+ catch {
83
+ // Ignore parse errors
84
+ }
85
+ });
86
+ client.on('error', () => {
87
+ clearTimeout(timeout);
88
+ client.destroy();
89
+ // Don't reject - publish is best-effort
90
+ resolve();
91
+ });
92
+ client.on('end', () => {
93
+ clearTimeout(timeout);
94
+ });
95
+ });
96
+ }
97
+ async subscribe(channel, handler) {
98
+ const socketPath = getSocketPath(this.photonName, this.socketDir);
99
+ const subscribeId = `sub_${Date.now()}_${Math.random().toString(36).slice(2)}`;
100
+ return new Promise((resolve, reject) => {
101
+ const client = net.createConnection(socketPath);
102
+ let subscribed = false;
103
+ let buffer = '';
104
+ const timeout = setTimeout(() => {
105
+ if (!subscribed) {
106
+ client.destroy();
107
+ reject(new Error('Subscription timeout'));
108
+ }
109
+ }, this.timeout);
110
+ client.on('connect', () => {
111
+ const request = {
112
+ type: 'subscribe',
113
+ id: subscribeId,
114
+ channel,
115
+ clientType: 'photon',
116
+ };
117
+ client.write(JSON.stringify(request) + '\n');
118
+ });
119
+ client.on('data', (chunk) => {
120
+ buffer += chunk.toString();
121
+ // Process complete JSON messages (newline-delimited)
122
+ const lines = buffer.split('\n');
123
+ buffer = lines.pop() || '';
124
+ for (const line of lines) {
125
+ if (!line.trim())
126
+ continue;
127
+ try {
128
+ const response = JSON.parse(line);
129
+ // Handle subscription confirmation
130
+ if (response.id === subscribeId && response.type === 'result') {
131
+ clearTimeout(timeout);
132
+ subscribed = true;
133
+ // Track subscription
134
+ if (!this.subscriptions.has(channel)) {
135
+ this.subscriptions.set(channel, { socket: client, handlers: new Set() });
136
+ }
137
+ this.subscriptions.get(channel).handlers.add(handler);
138
+ // Return subscription handle
139
+ const subscription = {
140
+ channel,
141
+ active: true,
142
+ unsubscribe: () => {
143
+ subscription.active = false;
144
+ const sub = this.subscriptions.get(channel);
145
+ if (sub) {
146
+ sub.handlers.delete(handler);
147
+ if (sub.handlers.size === 0) {
148
+ // Send unsubscribe and close
149
+ const unsubRequest = {
150
+ type: 'unsubscribe',
151
+ id: `unsub_${Date.now()}`,
152
+ channel,
153
+ };
154
+ if (!client.destroyed) {
155
+ client.write(JSON.stringify(unsubRequest) + '\n');
156
+ client.end();
157
+ }
158
+ this.subscriptions.delete(channel);
159
+ }
160
+ }
161
+ },
162
+ };
163
+ resolve(subscription);
164
+ }
165
+ // Handle channel messages
166
+ if (response.type === 'channel_message' && response.channel === channel) {
167
+ const msg = {
168
+ channel: response.channel,
169
+ event: response.message?.event || 'message',
170
+ data: response.message?.data || response.message,
171
+ timestamp: response.message?.timestamp || Date.now(),
172
+ source: response.message?.source,
173
+ };
174
+ handler(msg);
175
+ }
176
+ // Handle errors
177
+ if (response.type === 'error' && response.id === subscribeId) {
178
+ clearTimeout(timeout);
179
+ reject(new Error(response.error || 'Subscription failed'));
180
+ }
181
+ }
182
+ catch {
183
+ // Ignore parse errors for partial messages
184
+ }
185
+ }
186
+ });
187
+ client.on('error', (error) => {
188
+ if (!subscribed) {
189
+ clearTimeout(timeout);
190
+ reject(new Error(`Connection error: ${error.message}`));
191
+ }
192
+ });
193
+ client.on('end', () => {
194
+ if (!subscribed) {
195
+ clearTimeout(timeout);
196
+ reject(new Error('Connection closed before subscription confirmed'));
197
+ }
198
+ });
199
+ client.on('close', () => {
200
+ // Mark all subscriptions on this socket as inactive
201
+ for (const [ch, sub] of this.subscriptions) {
202
+ if (sub.socket === client) {
203
+ this.subscriptions.delete(ch);
204
+ }
205
+ }
206
+ });
207
+ });
208
+ }
209
+ isConnected() {
210
+ // Check if any subscriptions are active
211
+ return this.subscriptions.size > 0;
212
+ }
213
+ async connect() {
214
+ // Connection happens lazily on first publish/subscribe
215
+ }
216
+ async disconnect() {
217
+ // Close all subscription sockets
218
+ for (const [, sub] of this.subscriptions) {
219
+ if (!sub.socket.destroyed) {
220
+ sub.socket.end();
221
+ }
222
+ }
223
+ this.subscriptions.clear();
224
+ }
225
+ }
226
+ // Register the broker
227
+ registerBroker('daemon', (options) => new DaemonBroker(options));
228
+ export default DaemonBroker;
229
+ //# sourceMappingURL=daemon-broker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-broker.js","sourceRoot":"","sources":["../../src/channels/daemon-broker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * HTTP Channel Broker
3
+ *
4
+ * Uses HTTP webhooks for publishing and Server-Sent Events (SSE) for subscribing.
5
+ * Works with any HTTP-based pub/sub system.
6
+ *
7
+ * Best for:
8
+ * - Serverless environments (AWS Lambda, Vercel, etc.)
9
+ * - Cloud functions that can't maintain long-lived connections
10
+ * - Integration with existing webhook infrastructure
11
+ *
12
+ * Publishing: POST to publishUrl with JSON body
13
+ * Subscribing: SSE connection to subscribeUrl
14
+ */
15
+ import type { ChannelBroker, ChannelMessage, ChannelHandler, Subscription } from './types.js';
16
+ export interface HttpBrokerOptions {
17
+ /** URL for publishing messages (POST requests) */
18
+ publishUrl?: string;
19
+ /** URL for SSE subscriptions */
20
+ subscribeUrl?: string;
21
+ /** Authentication token (sent as Bearer token) */
22
+ authToken?: string;
23
+ /** Custom headers for requests */
24
+ headers?: Record<string, string>;
25
+ /** Request timeout in ms */
26
+ timeout?: number;
27
+ }
28
+ export declare class HttpBroker implements ChannelBroker {
29
+ readonly type = "http";
30
+ private publishUrl?;
31
+ private subscribeUrl?;
32
+ private authToken?;
33
+ private headers;
34
+ private timeout;
35
+ private subscriptions;
36
+ constructor(options?: HttpBrokerOptions);
37
+ private getHeaders;
38
+ publish(message: ChannelMessage): Promise<void>;
39
+ subscribe(channel: string, handler: ChannelHandler): Promise<Subscription>;
40
+ isConnected(): boolean;
41
+ connect(): Promise<void>;
42
+ disconnect(): Promise<void>;
43
+ }
44
+ export default HttpBroker;
45
+ //# sourceMappingURL=http-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-broker.d.ts","sourceRoot":"","sources":["../../src/channels/http-broker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG9F,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,UAAW,YAAW,aAAa;IAC9C,QAAQ,CAAC,IAAI,UAAU;IAEvB,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,YAAY,CAAC,CAAS;IAC9B,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,aAAa,CAAqF;gBAE9F,OAAO,GAAE,iBAAsB;IAQ3C,OAAO,CAAC,UAAU;IAaZ,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA8B/C,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC;IA4GhF,WAAW,IAAI,OAAO;IAIhB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;CAOlC;AAKD,eAAe,UAAU,CAAC"}