@sena-ai/platform-connector 0.1.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.
@@ -0,0 +1,22 @@
1
+ import type { Connector } from '@sena-ai/core';
2
+ export type TransportType = 'sse' | 'websocket' | 'auto';
3
+ export type PlatformConnectorOptions = {
4
+ /** Platform server URL (e.g. https://platform.example.com) */
5
+ platformUrl: string;
6
+ /** connect_key -- platform-issued authentication key */
7
+ connectKey: string;
8
+ /** Thinking message (optional) */
9
+ thinkingMessage?: string;
10
+ /** Transport type: 'sse' (default), 'websocket', or 'auto' */
11
+ transport?: TransportType;
12
+ };
13
+ /**
14
+ * Platform Connector: connects to the platform via SSE or WebSocket.
15
+ *
16
+ * - Receives Slack events from the platform relay
17
+ * - Calls Slack API via the platform's HTTP proxy
18
+ *
19
+ * No Slack tokens needed locally (zero token exposure principle).
20
+ */
21
+ export declare function platformConnector(options: PlatformConnectorOptions): Connector;
22
+ //# sourceMappingURL=connector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EAMV,MAAM,eAAe,CAAA;AAKtB,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,WAAW,GAAG,MAAM,CAAA;AAExD,MAAM,MAAM,wBAAwB,GAAG;IACrC,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAA;IACnB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAA;IAClB,kCAAkC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,aAAa,CAAA;CAC1B,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,SAAS,CA8K9E"}
@@ -0,0 +1,163 @@
1
+ import { createSSETransport } from './transports/sse.js';
2
+ import { createWebSocketTransport } from './transports/websocket.js';
3
+ /**
4
+ * Platform Connector: connects to the platform via SSE or WebSocket.
5
+ *
6
+ * - Receives Slack events from the platform relay
7
+ * - Calls Slack API via the platform's HTTP proxy
8
+ *
9
+ * No Slack tokens needed locally (zero token exposure principle).
10
+ */
11
+ export function platformConnector(options) {
12
+ const { platformUrl, connectKey, thinkingMessage } = options;
13
+ const transportType = options.transport ?? 'sse';
14
+ const baseUrl = platformUrl.replace(/\/$/, '');
15
+ let transport = null;
16
+ let engine = null;
17
+ /**
18
+ * Call Slack API via platform proxy.
19
+ */
20
+ async function callSlackApi(method, params) {
21
+ const res = await fetch(`${baseUrl}/relay/api`, {
22
+ method: 'POST',
23
+ headers: {
24
+ 'Content-Type': 'application/json',
25
+ 'x-connect-key': connectKey,
26
+ },
27
+ body: JSON.stringify({ method, params }),
28
+ });
29
+ return (await res.json());
30
+ }
31
+ /**
32
+ * Convert Slack event to InboundEvent.
33
+ * Ignores bot messages and messages with subtypes.
34
+ */
35
+ function toInboundEvent(slackEvent) {
36
+ const event = slackEvent.event;
37
+ if (!event)
38
+ return null;
39
+ const type = event.type;
40
+ const subtype = event.subtype;
41
+ const botId = event.bot_id;
42
+ // Ignore bot's own messages
43
+ if (botId)
44
+ return null;
45
+ // Ignore message subtypes (join, leave, etc.)
46
+ if (type === 'message' && subtype)
47
+ return null;
48
+ const channel = event.channel;
49
+ const threadTs = event.thread_ts || event.ts;
50
+ const text = event.text || '';
51
+ const user = event.user || 'unknown';
52
+ // Handle both app_mention and message
53
+ if (type !== 'app_mention' && type !== 'message')
54
+ return null;
55
+ return {
56
+ connector: 'platform',
57
+ conversationId: `${channel}:${threadTs}`,
58
+ userId: user,
59
+ userName: user,
60
+ text,
61
+ raw: slackEvent,
62
+ };
63
+ }
64
+ function createTransport() {
65
+ const streamUrl = `${baseUrl}/relay/stream?connect_key=${encodeURIComponent(connectKey)}`;
66
+ if (transportType === 'websocket') {
67
+ return createWebSocketTransport(streamUrl);
68
+ }
69
+ if (transportType === 'auto') {
70
+ // Auto-detect: try WebSocket first, fall back to SSE
71
+ // For now, default to SSE as it's more widely supported
72
+ return createSSETransport(streamUrl);
73
+ }
74
+ return createSSETransport(streamUrl);
75
+ }
76
+ return {
77
+ name: 'platform',
78
+ registerRoutes(_server, turnEngine) {
79
+ engine = turnEngine;
80
+ transport = createTransport();
81
+ transport.on('connected', (data) => {
82
+ const parsed = JSON.parse(data);
83
+ console.log(`[platform] connected to platform (botId: ${parsed.botId})`);
84
+ });
85
+ transport.on('slack_event', (data) => {
86
+ const slackEvent = JSON.parse(data);
87
+ const inbound = toInboundEvent(slackEvent);
88
+ if (inbound) {
89
+ engine?.submitTurn(inbound).catch((err) => {
90
+ console.error('[platform] submitTurn error:', err);
91
+ });
92
+ }
93
+ });
94
+ transport.on('ping', () => {
95
+ // Keepalive -- no action needed
96
+ });
97
+ transport.onError((err) => {
98
+ console.error('[platform] transport error, will auto-reconnect:', err);
99
+ });
100
+ transport.connect();
101
+ },
102
+ createOutput(context) {
103
+ const [channel, threadTs] = context.conversationId.split(':');
104
+ let thinkingTs = null;
105
+ return {
106
+ async showProgress(_text) {
107
+ if (thinkingMessage && !thinkingTs) {
108
+ const res = await callSlackApi('chat.postMessage', {
109
+ channel,
110
+ thread_ts: threadTs,
111
+ text: thinkingMessage,
112
+ });
113
+ thinkingTs = res.ts;
114
+ }
115
+ },
116
+ async sendResult(text) {
117
+ if (thinkingTs) {
118
+ await callSlackApi('chat.update', {
119
+ channel,
120
+ ts: thinkingTs,
121
+ text,
122
+ });
123
+ }
124
+ else {
125
+ await callSlackApi('chat.postMessage', {
126
+ channel,
127
+ thread_ts: threadTs,
128
+ text,
129
+ });
130
+ }
131
+ },
132
+ async sendError(message) {
133
+ const errorText = `\u26a0\ufe0f ${message}`;
134
+ if (thinkingTs) {
135
+ await callSlackApi('chat.update', {
136
+ channel,
137
+ ts: thinkingTs,
138
+ text: errorText,
139
+ });
140
+ }
141
+ else {
142
+ await callSlackApi('chat.postMessage', {
143
+ channel,
144
+ thread_ts: threadTs,
145
+ text: errorText,
146
+ });
147
+ }
148
+ },
149
+ async dispose() {
150
+ // Cleanup -- sendResult already handled thinking message update
151
+ },
152
+ };
153
+ },
154
+ async stop() {
155
+ if (transport) {
156
+ transport.close();
157
+ transport = null;
158
+ console.log('[platform] transport connection closed');
159
+ }
160
+ },
161
+ };
162
+ }
163
+ //# sourceMappingURL=connector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector.js","sourceRoot":"","sources":["../src/connector.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAA;AAepE;;;;;;;GAOG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAiC;IACjE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,EAAE,GAAG,OAAO,CAAA;IAC5D,MAAM,aAAa,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAA;IAChD,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAE9C,IAAI,SAAS,GAAqB,IAAI,CAAA;IACtC,IAAI,MAAM,GAAsB,IAAI,CAAA;IAEpC;;OAEG;IACH,KAAK,UAAU,YAAY,CACzB,MAAc,EACd,MAA+B;QAE/B,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,YAAY,EAAE;YAC9C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU;aAC5B;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;SACzC,CAAC,CAAA;QACF,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAA4B,CAAA;IACtD,CAAC;IAED;;;OAGG;IACH,SAAS,cAAc,CACrB,UAAmC;QAEnC,MAAM,KAAK,GAAG,UAAU,CAAC,KAA4C,CAAA;QACrE,IAAI,CAAC,KAAK;YAAE,OAAO,IAAI,CAAA;QAEvB,MAAM,IAAI,GAAG,KAAK,CAAC,IAAc,CAAA;QACjC,MAAM,OAAO,GAAG,KAAK,CAAC,OAA6B,CAAA;QACnD,MAAM,KAAK,GAAG,KAAK,CAAC,MAA4B,CAAA;QAEhD,4BAA4B;QAC5B,IAAI,KAAK;YAAE,OAAO,IAAI,CAAA;QACtB,8CAA8C;QAC9C,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO;YAAE,OAAO,IAAI,CAAA;QAE9C,MAAM,OAAO,GAAG,KAAK,CAAC,OAAiB,CAAA;QACvC,MAAM,QAAQ,GAAI,KAAK,CAAC,SAAoB,IAAK,KAAK,CAAC,EAAa,CAAA;QACpE,MAAM,IAAI,GAAI,KAAK,CAAC,IAAe,IAAI,EAAE,CAAA;QACzC,MAAM,IAAI,GAAI,KAAK,CAAC,IAAe,IAAI,SAAS,CAAA;QAEhD,sCAAsC;QACtC,IAAI,IAAI,KAAK,aAAa,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QAE7D,OAAO;YACL,SAAS,EAAE,UAAU;YACrB,cAAc,EAAE,GAAG,OAAO,IAAI,QAAQ,EAAE;YACxC,MAAM,EAAE,IAAI;YACZ,QAAQ,EAAE,IAAI;YACd,IAAI;YACJ,GAAG,EAAE,UAAU;SAChB,CAAA;IACH,CAAC;IAED,SAAS,eAAe;QACtB,MAAM,SAAS,GAAG,GAAG,OAAO,6BAA6B,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAA;QAEzF,IAAI,aAAa,KAAK,WAAW,EAAE,CAAC;YAClC,OAAO,wBAAwB,CAAC,SAAS,CAAC,CAAA;QAC5C,CAAC;QACD,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;YAC7B,qDAAqD;YACrD,wDAAwD;YACxD,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,kBAAkB,CAAC,SAAS,CAAC,CAAA;IACtC,CAAC;IAED,OAAO;QACL,IAAI,EAAE,UAAU;QAEhB,cAAc,CAAC,OAAmB,EAAE,UAAsB;YACxD,MAAM,GAAG,UAAU,CAAA;YAEnB,SAAS,GAAG,eAAe,EAAE,CAAA;YAE7B,SAAS,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,IAAY,EAAE,EAAE;gBACzC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAA;gBAC1D,OAAO,CAAC,GAAG,CAAC,4CAA4C,MAAM,CAAC,KAAK,GAAG,CAAC,CAAA;YAC1E,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,IAAY,EAAE,EAAE;gBAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAA;gBAC9D,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,CAAA;gBAC1C,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;wBACjD,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,GAAG,CAAC,CAAA;oBACpD,CAAC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;gBACxB,gCAAgC;YAClC,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;gBACxB,OAAO,CAAC,KAAK,CAAC,kDAAkD,EAAE,GAAG,CAAC,CAAA;YACxE,CAAC,CAAC,CAAA;YAEF,SAAS,CAAC,OAAO,EAAE,CAAA;QACrB,CAAC;QAED,YAAY,CAAC,OAA+B;YAC1C,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAC7D,IAAI,UAAU,GAAkB,IAAI,CAAA;YAEpC,OAAO;gBACL,KAAK,CAAC,YAAY,CAAC,KAAa;oBAC9B,IAAI,eAAe,IAAI,CAAC,UAAU,EAAE,CAAC;wBACnC,MAAM,GAAG,GAAG,MAAM,YAAY,CAAC,kBAAkB,EAAE;4BACjD,OAAO;4BACP,SAAS,EAAE,QAAQ;4BACnB,IAAI,EAAE,eAAe;yBACtB,CAAC,CAAA;wBACF,UAAU,GAAI,GAA+B,CAAC,EAAY,CAAA;oBAC5D,CAAC;gBACH,CAAC;gBAED,KAAK,CAAC,UAAU,CAAC,IAAY;oBAC3B,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,YAAY,CAAC,aAAa,EAAE;4BAChC,OAAO;4BACP,EAAE,EAAE,UAAU;4BACd,IAAI;yBACL,CAAC,CAAA;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,YAAY,CAAC,kBAAkB,EAAE;4BACrC,OAAO;4BACP,SAAS,EAAE,QAAQ;4BACnB,IAAI;yBACL,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;gBAED,KAAK,CAAC,SAAS,CAAC,OAAe;oBAC7B,MAAM,SAAS,GAAG,gBAAgB,OAAO,EAAE,CAAA;oBAC3C,IAAI,UAAU,EAAE,CAAC;wBACf,MAAM,YAAY,CAAC,aAAa,EAAE;4BAChC,OAAO;4BACP,EAAE,EAAE,UAAU;4BACd,IAAI,EAAE,SAAS;yBAChB,CAAC,CAAA;oBACJ,CAAC;yBAAM,CAAC;wBACN,MAAM,YAAY,CAAC,kBAAkB,EAAE;4BACrC,OAAO;4BACP,SAAS,EAAE,QAAQ;4BACnB,IAAI,EAAE,SAAS;yBAChB,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC;gBAED,KAAK,CAAC,OAAO;oBACX,gEAAgE;gBAClE,CAAC;aACF,CAAA;QACH,CAAC;QAED,KAAK,CAAC,IAAI;YACR,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,CAAC,KAAK,EAAE,CAAA;gBACjB,SAAS,GAAG,IAAI,CAAA;gBAChB,OAAO,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAA;YACvD,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { platformConnector } from './connector.js';
2
+ export type { PlatformConnectorOptions, TransportType } from './connector.js';
3
+ export type { Transport, TransportFactory } from './transports/types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAClD,YAAY,EAAE,wBAAwB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAC7E,YAAY,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { platformConnector } from './connector.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,6 @@
1
+ import type { Transport } from './types.js';
2
+ /**
3
+ * SSE transport using EventSource (for Node.js / SSE-based relay).
4
+ */
5
+ export declare function createSSETransport(url: string): Transport;
6
+ //# sourceMappingURL=sse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAoDzD"}
@@ -0,0 +1,52 @@
1
+ import { EventSource } from 'eventsource';
2
+ /**
3
+ * SSE transport using EventSource (for Node.js / SSE-based relay).
4
+ */
5
+ export function createSSETransport(url) {
6
+ let eventSource = null;
7
+ const listeners = new Map();
8
+ let errorHandler = null;
9
+ return {
10
+ connect() {
11
+ eventSource = new EventSource(url);
12
+ for (const [event, handlers] of listeners) {
13
+ for (const handler of handlers) {
14
+ eventSource.addEventListener(event, (e) => {
15
+ handler(e.data);
16
+ });
17
+ }
18
+ }
19
+ eventSource.onerror = (err) => {
20
+ if (errorHandler)
21
+ errorHandler(err);
22
+ };
23
+ },
24
+ on(event, handler) {
25
+ let handlers = listeners.get(event);
26
+ if (!handlers) {
27
+ handlers = [];
28
+ listeners.set(event, handlers);
29
+ }
30
+ handlers.push(handler);
31
+ // If already connected, add listener immediately
32
+ if (eventSource) {
33
+ eventSource.addEventListener(event, (e) => {
34
+ handler(e.data);
35
+ });
36
+ }
37
+ },
38
+ onError(handler) {
39
+ errorHandler = handler;
40
+ if (eventSource) {
41
+ eventSource.onerror = handler;
42
+ }
43
+ },
44
+ close() {
45
+ if (eventSource) {
46
+ eventSource.close();
47
+ eventSource = null;
48
+ }
49
+ },
50
+ };
51
+ }
52
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/transports/sse.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAGzC;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,WAAW,GAAuB,IAAI,CAAA;IAC1C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyC,CAAA;IAClE,IAAI,YAAY,GAAsC,IAAI,CAAA;IAE1D,OAAO;QACL,OAAO;YACL,WAAW,GAAG,IAAI,WAAW,CAAC,GAAG,CAAC,CAAA;YAElC,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC1C,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,WAAW,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAe,EAAE,EAAE;wBACtD,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;oBACjB,CAAC,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YAED,WAAW,CAAC,OAAO,GAAG,CAAC,GAAG,EAAE,EAAE;gBAC5B,IAAI,YAAY;oBAAE,YAAY,CAAC,GAAG,CAAC,CAAA;YACrC,CAAC,CAAA;QACH,CAAC;QAED,EAAE,CAAC,KAAa,EAAE,OAA+B;YAC/C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACnC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,EAAE,CAAA;gBACb,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YAChC,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAEtB,iDAAiD;YACjD,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAe,EAAE,EAAE;oBACtD,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;gBACjB,CAAC,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,OAAO,CAAC,OAAiC;YACvC,YAAY,GAAG,OAAO,CAAA;YACtB,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,OAAO,GAAG,OAAO,CAAA;YAC/B,CAAC;QACH,CAAC;QAED,KAAK;YACH,IAAI,WAAW,EAAE,CAAC;gBAChB,WAAW,CAAC,KAAK,EAAE,CAAA;gBACnB,WAAW,GAAG,IAAI,CAAA;YACpB,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Transport interface for platform connector.
3
+ * Abstracts SSE (Node.js) and WebSocket (CF Workers) connections.
4
+ */
5
+ export interface Transport {
6
+ /** Connect to the platform relay. */
7
+ connect(): void;
8
+ /** Register an event listener. */
9
+ on(event: string, handler: (data: string) => void): void;
10
+ /** Register an error handler. */
11
+ onError(handler: (error: unknown) => void): void;
12
+ /** Close the connection. */
13
+ close(): void;
14
+ }
15
+ export type TransportFactory = (url: string) => Transport;
16
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/transports/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,qCAAqC;IACrC,OAAO,IAAI,IAAI,CAAA;IACf,kCAAkC;IAClC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAA;IACxD,iCAAiC;IACjC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI,CAAA;IAChD,4BAA4B;IAC5B,KAAK,IAAI,IAAI,CAAA;CACd;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/transports/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,6 @@
1
+ import type { Transport } from './types.js';
2
+ /**
3
+ * WebSocket transport (for CF Workers / Durable Objects-based relay).
4
+ */
5
+ export declare function createWebSocketTransport(url: string): Transport;
6
+ //# sourceMappingURL=websocket.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.d.ts","sourceRoot":"","sources":["../../src/transports/websocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAE3C;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAyE/D"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * WebSocket transport (for CF Workers / Durable Objects-based relay).
3
+ */
4
+ export function createWebSocketTransport(url) {
5
+ let ws = null;
6
+ const listeners = new Map();
7
+ let errorHandler = null;
8
+ function dispatchMessage(raw) {
9
+ try {
10
+ const msg = JSON.parse(raw);
11
+ const handlers = listeners.get(msg.type);
12
+ if (handlers) {
13
+ const dataStr = typeof msg.data === 'string'
14
+ ? msg.data
15
+ : JSON.stringify(msg.data);
16
+ for (const handler of handlers) {
17
+ handler(dataStr);
18
+ }
19
+ }
20
+ }
21
+ catch {
22
+ // Ignore unparseable messages
23
+ }
24
+ }
25
+ return {
26
+ connect() {
27
+ // Convert http(s) to ws(s)
28
+ const wsUrl = url.replace(/^http/, 'ws');
29
+ ws = new WebSocket(wsUrl);
30
+ ws.onmessage = (event) => {
31
+ const data = typeof event.data === 'string'
32
+ ? event.data
33
+ : String(event.data);
34
+ dispatchMessage(data);
35
+ };
36
+ ws.onerror = (event) => {
37
+ if (errorHandler)
38
+ errorHandler(event);
39
+ };
40
+ ws.onclose = () => {
41
+ // Could implement auto-reconnect here
42
+ };
43
+ },
44
+ on(event, handler) {
45
+ let handlers = listeners.get(event);
46
+ if (!handlers) {
47
+ handlers = [];
48
+ listeners.set(event, handlers);
49
+ }
50
+ handlers.push(handler);
51
+ },
52
+ onError(handler) {
53
+ errorHandler = handler;
54
+ if (ws) {
55
+ ws.onerror = handler;
56
+ }
57
+ },
58
+ close() {
59
+ if (ws) {
60
+ ws.close();
61
+ ws = null;
62
+ }
63
+ },
64
+ };
65
+ }
66
+ //# sourceMappingURL=websocket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket.js","sourceRoot":"","sources":["../../src/transports/websocket.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAW;IAClD,IAAI,EAAE,GAAqB,IAAI,CAAA;IAC/B,MAAM,SAAS,GAAG,IAAI,GAAG,EAAyC,CAAA;IAClE,IAAI,YAAY,GAAsC,IAAI,CAAA;IAE1D,SAAS,eAAe,CAAC,GAAW;QAClC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAIzB,CAAA;YACD,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACxC,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,OAAO,GACX,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;oBAC1B,CAAC,CAAC,GAAG,CAAC,IAAI;oBACV,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;gBAC9B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;oBAC/B,OAAO,CAAC,OAAO,CAAC,CAAA;gBAClB,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8BAA8B;QAChC,CAAC;IACH,CAAC;IAED,OAAO;QACL,OAAO;YACL,2BAA2B;YAC3B,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;YACxC,EAAE,GAAG,IAAI,SAAS,CAAC,KAAK,CAAC,CAAA;YAEzB,EAAE,CAAC,SAAS,GAAG,CAAC,KAAmB,EAAE,EAAE;gBACrC,MAAM,IAAI,GACR,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;oBAC5B,CAAC,CAAC,KAAK,CAAC,IAAI;oBACZ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACxB,eAAe,CAAC,IAAI,CAAC,CAAA;YACvB,CAAC,CAAA;YAED,EAAE,CAAC,OAAO,GAAG,CAAC,KAAK,EAAE,EAAE;gBACrB,IAAI,YAAY;oBAAE,YAAY,CAAC,KAAK,CAAC,CAAA;YACvC,CAAC,CAAA;YAED,EAAE,CAAC,OAAO,GAAG,GAAG,EAAE;gBAChB,sCAAsC;YACxC,CAAC,CAAA;QACH,CAAC;QAED,EAAE,CAAC,KAAa,EAAE,OAA+B;YAC/C,IAAI,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;YACnC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,QAAQ,GAAG,EAAE,CAAA;gBACb,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;YAChC,CAAC;YACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;QAED,OAAO,CAAC,OAAiC;YACvC,YAAY,GAAG,OAAO,CAAA;YACtB,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,OAAO,GAAG,OAAO,CAAA;YACtB,CAAC;QACH,CAAC;QAED,KAAK;YACH,IAAI,EAAE,EAAE,CAAC;gBACP,EAAE,CAAC,KAAK,EAAE,CAAA;gBACV,EAAE,GAAG,IAAI,CAAA;YACX,CAAC;QACH,CAAC;KACF,CAAA;AACH,CAAC"}
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "@sena-ai/platform-connector",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.ts",
8
+ "import": "./dist/index.js",
9
+ "default": "./dist/index.js"
10
+ }
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "dependencies": {
16
+ "eventsource": "^3.0.0"
17
+ },
18
+ "peerDependencies": {
19
+ "@sena-ai/core": ">=1.0.0"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.8.0",
23
+ "@sena-ai/core": "1.0.23"
24
+ },
25
+ "scripts": {
26
+ "build": "tsc -b",
27
+ "typecheck": "tsc --noEmit"
28
+ }
29
+ }