@mochabug/adapt-core 1.0.0-rc21

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 ADDED
@@ -0,0 +1,76 @@
1
+ # @mochabug/adapt-core
2
+
3
+ Low-level client for Adapt. REST API + WebSocket subscriptions.
4
+
5
+ ```bash
6
+ npm install @mochabug/adapt-core
7
+ ```
8
+
9
+ ## Start a session
10
+
11
+ ```typescript
12
+ import { startSession, stopSession } from '@mochabug/adapt-core';
13
+
14
+ const { token } = await startSession({ id: 'auto-123' }, authToken);
15
+
16
+ // later
17
+ await stopSession('auto-123', token);
18
+ ```
19
+
20
+ ## Inherit existing session
21
+
22
+ ```typescript
23
+ import { inheritSession } from '@mochabug/adapt-core';
24
+
25
+ const { token } = await inheritSession('auto-123', inheritToken);
26
+ ```
27
+
28
+ ## Real-time updates
29
+
30
+ ```typescript
31
+ import { PubsubClient } from '@mochabug/adapt-core';
32
+
33
+ const pubsub = new PubsubClient();
34
+
35
+ await pubsub.subscribe({
36
+ id: 'auto-123',
37
+ sessionToken: token,
38
+ onUrl: (url) => console.log('url:', url),
39
+ onSession: (session) => console.log('status:', session.status),
40
+ onOutput: (output) => console.log('output:', output)
41
+ });
42
+
43
+ await pubsub.unsubscribe();
44
+ ```
45
+
46
+ ## Other API calls
47
+
48
+ ```typescript
49
+ import { getSession, readOutput, readUrls } from '@mochabug/adapt-core';
50
+
51
+ const session = await getSession('auto-123', token);
52
+ const output = await readOutput('auto-123', token, { pageSize: 100 });
53
+ const urls = await readUrls('auto-123', token);
54
+ ```
55
+
56
+ ## Error handling
57
+
58
+ ```typescript
59
+ import { RestClientError } from '@mochabug/adapt-core';
60
+
61
+ try {
62
+ await startSession({ id: 'auto-123' });
63
+ } catch (e) {
64
+ if (e instanceof RestClientError) {
65
+ console.error(e.status, e.statusText);
66
+ }
67
+ }
68
+ ```
69
+
70
+ ## Retry behavior
71
+
72
+ All REST calls retry automatically on 429, 502, 503, 504. Max 5 attempts, exponential backoff.
73
+
74
+ ## License
75
+
76
+ ISC © mochabug AB
@@ -0,0 +1,164 @@
1
+ // Re-export from the new PubsubClient module
2
+ export * from "./pubsub-client.js";
3
+ // Default configuration
4
+ const defaultConfig = {
5
+ baseUrl: "https://adapt-dev.mochabugapis.com/v1/automations",
6
+ wsBaseUrl: "wss://adapt-dev.mochabugapis.com/v1/automations",
7
+ };
8
+ // Global configuration
9
+ let globalConfig = { ...defaultConfig };
10
+ // Configure the Adapt client
11
+ export function configure(config) {
12
+ globalConfig = { ...globalConfig, ...config };
13
+ }
14
+ // Get current configuration
15
+ export function getConfig() {
16
+ return { ...globalConfig };
17
+ }
18
+ // Reset to default configuration
19
+ export function resetConfig() {
20
+ globalConfig = { ...defaultConfig };
21
+ }
22
+ // Retry configuration
23
+ const RETRY_CONFIG = {
24
+ maxAttempts: 5,
25
+ initialDelay: 50, // 50ms
26
+ maxDelay: 5000, // 5 seconds
27
+ retryableStatusCodes: [429, 502, 503, 504], // Too Many Requests, Bad Gateway, Service Unavailable, Gateway Timeout
28
+ };
29
+ // Sleep helper
30
+ function sleep(ms) {
31
+ return new Promise((resolve) => setTimeout(resolve, ms));
32
+ }
33
+ // Retry wrapper with exponential backoff
34
+ async function fetchWithRetry(url, options) {
35
+ let lastError;
36
+ for (let attempt = 1; attempt <= RETRY_CONFIG.maxAttempts; attempt++) {
37
+ try {
38
+ const response = await fetch(url, options);
39
+ if (response.ok) {
40
+ return response;
41
+ }
42
+ if (RETRY_CONFIG.retryableStatusCodes.includes(response.status)) {
43
+ lastError = new RestClientError(response);
44
+ if (attempt < RETRY_CONFIG.maxAttempts) {
45
+ const delay = Math.min(RETRY_CONFIG.initialDelay * Math.pow(2, attempt - 1), RETRY_CONFIG.maxDelay);
46
+ console.warn(`Request failed with ${response.status}, retrying in ${delay}ms (attempt ${attempt}/${RETRY_CONFIG.maxAttempts})`);
47
+ await sleep(delay);
48
+ continue;
49
+ }
50
+ }
51
+ throw new RestClientError(response);
52
+ }
53
+ catch (error) {
54
+ if (error instanceof RestClientError) {
55
+ throw error;
56
+ }
57
+ if (attempt < RETRY_CONFIG.maxAttempts) {
58
+ const delay = Math.min(RETRY_CONFIG.initialDelay * Math.pow(2, attempt - 1), RETRY_CONFIG.maxDelay);
59
+ console.warn(`Network error, retrying in ${delay}ms (attempt ${attempt}/${RETRY_CONFIG.maxAttempts})`, error);
60
+ await sleep(delay);
61
+ continue;
62
+ }
63
+ throw error;
64
+ }
65
+ }
66
+ throw lastError || new Error("All retry attempts failed");
67
+ }
68
+ // REST API functions
69
+ export async function startSession(req, token) {
70
+ const headers = new Headers({
71
+ "Content-Type": "application/json",
72
+ "Response-Type": "application/json",
73
+ });
74
+ if (token) {
75
+ headers.set("Authorization", `Bearer ${token}`);
76
+ }
77
+ const response = await fetchWithRetry(`${globalConfig.baseUrl}/${req.id}/session/start`, {
78
+ method: "POST",
79
+ body: JSON.stringify(req),
80
+ headers,
81
+ });
82
+ return await response.json();
83
+ }
84
+ export async function inheritSession(id, sessionToken) {
85
+ const response = await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session/inherit`, {
86
+ method: "POST",
87
+ body: JSON.stringify({ id }),
88
+ headers: {
89
+ "Content-Type": "application/json",
90
+ "Response-Type": "application/json",
91
+ Authorization: `Bearer ${sessionToken}`,
92
+ },
93
+ });
94
+ return await response.json();
95
+ }
96
+ export async function getSession(id, sessionToken) {
97
+ const response = await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session`, {
98
+ method: "GET",
99
+ headers: {
100
+ "Response-Type": "application/json",
101
+ Authorization: `Bearer ${sessionToken}`,
102
+ },
103
+ });
104
+ return await response.json();
105
+ }
106
+ export async function readOutput(id, sessionToken, options) {
107
+ const params = new URLSearchParams();
108
+ if (options?.pageSize !== undefined) {
109
+ params.set("page_size", options.pageSize.toString());
110
+ }
111
+ if (options?.vertex) {
112
+ params.set("vertex", options.vertex);
113
+ }
114
+ if (options?.newerThan) {
115
+ params.set("newer_than", options.newerThan);
116
+ }
117
+ const queryString = params.toString();
118
+ const url = `${globalConfig.baseUrl}/${id}/session/output${queryString ? `?${queryString}` : ""}`;
119
+ const response = await fetchWithRetry(url, {
120
+ method: "GET",
121
+ headers: {
122
+ "Response-Type": "application/json",
123
+ Authorization: `Bearer ${sessionToken}`,
124
+ },
125
+ });
126
+ return await response.json();
127
+ }
128
+ export async function readUrls(id, sessionToken, options) {
129
+ const params = new URLSearchParams();
130
+ if (options?.pageSize !== undefined) {
131
+ params.set("page_size", options.pageSize.toString());
132
+ }
133
+ if (options?.newerThan) {
134
+ params.set("newer_than", options.newerThan);
135
+ }
136
+ const queryString = params.toString();
137
+ const url = `${globalConfig.baseUrl}/${id}/session/urls${queryString ? `?${queryString}` : ""}`;
138
+ const response = await fetchWithRetry(url, {
139
+ method: "GET",
140
+ headers: {
141
+ "Response-Type": "application/json",
142
+ Authorization: `Bearer ${sessionToken}`,
143
+ },
144
+ });
145
+ return await response.json();
146
+ }
147
+ export async function stopSession(id, sessionToken) {
148
+ await fetchWithRetry(`${globalConfig.baseUrl}/${id}/session`, {
149
+ method: "DELETE",
150
+ headers: {
151
+ Authorization: `Bearer ${sessionToken}`,
152
+ },
153
+ });
154
+ }
155
+ export class RestClientError extends Error {
156
+ constructor(response) {
157
+ super(`HTTP Error: ${response.status} ${response.statusText}`);
158
+ this.name = "RestClientError";
159
+ this.status = response.status;
160
+ this.statusText = response.statusText;
161
+ this.response = response;
162
+ }
163
+ }
164
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,559 @@
1
+ import { fromBinary, toJson } from "@bufbuild/protobuf";
2
+ import { timestampDate } from "@bufbuild/protobuf/wkt";
3
+ import WebSocket from "isomorphic-ws";
4
+ import { parse as parseUuid } from "uuid";
5
+ import { SessionSchema, Status, UrlSchema, WebsocketMessageSchema, } from "@mochabug/genproto/mochabugapis/adapt/automations/v1/automations_pb.js";
6
+ import { getConfig } from "./index.js";
7
+ // Connection states
8
+ export var ConnectionState;
9
+ (function (ConnectionState) {
10
+ ConnectionState["DISCONNECTED"] = "disconnected";
11
+ ConnectionState["CONNECTING"] = "connecting";
12
+ ConnectionState["CONNECTED"] = "connected";
13
+ ConnectionState["CLOSING"] = "closing";
14
+ })(ConnectionState || (ConnectionState = {}));
15
+ // WebSocket close codes (following RFC 6455)
16
+ var CloseCode;
17
+ (function (CloseCode) {
18
+ CloseCode[CloseCode["NORMAL"] = 1000] = "NORMAL";
19
+ CloseCode[CloseCode["GOING_AWAY"] = 1001] = "GOING_AWAY";
20
+ CloseCode[CloseCode["PROTOCOL_ERROR"] = 1002] = "PROTOCOL_ERROR";
21
+ CloseCode[CloseCode["UNSUPPORTED_DATA"] = 1003] = "UNSUPPORTED_DATA";
22
+ CloseCode[CloseCode["ABNORMAL"] = 1006] = "ABNORMAL";
23
+ CloseCode[CloseCode["POLICY_VIOLATION"] = 1008] = "POLICY_VIOLATION";
24
+ CloseCode[CloseCode["SERVER_RESTART"] = 1012] = "SERVER_RESTART";
25
+ CloseCode[CloseCode["TRY_AGAIN_LATER"] = 1013] = "TRY_AGAIN_LATER";
26
+ CloseCode[CloseCode["BAD_GATEWAY"] = 1014] = "BAD_GATEWAY";
27
+ CloseCode[CloseCode["TLS_HANDSHAKE"] = 1015] = "TLS_HANDSHAKE";
28
+ })(CloseCode || (CloseCode = {}));
29
+ // Logger class for consistent logging
30
+ class Logger {
31
+ constructor(debug) {
32
+ this.debug = debug;
33
+ }
34
+ log(level, message, data) {
35
+ if (!this.debug && level === "debug")
36
+ return;
37
+ const timestamp = new Date().toISOString();
38
+ const prefix = `[PubSub ${timestamp}]`;
39
+ const fullMessage = `${prefix} ${message}`;
40
+ if (data !== undefined) {
41
+ console[level](fullMessage, data);
42
+ }
43
+ else {
44
+ console[level](fullMessage);
45
+ }
46
+ }
47
+ }
48
+ // ACK tracker to prevent duplicate message processing
49
+ class AckTracker {
50
+ constructor(logger) {
51
+ this.logger = logger;
52
+ this.ackedMessages = new Map();
53
+ this.MESSAGE_TTL = 60000; // 60 seconds
54
+ this.cleanupTimer = null;
55
+ }
56
+ start() {
57
+ // Cleanup old messages every 30 seconds
58
+ this.cleanupTimer = setInterval(() => this.cleanup(), 30000);
59
+ }
60
+ stop() {
61
+ if (this.cleanupTimer) {
62
+ clearInterval(this.cleanupTimer);
63
+ this.cleanupTimer = null;
64
+ }
65
+ this.ackedMessages.clear();
66
+ }
67
+ isProcessed(messageId) {
68
+ return this.ackedMessages.has(messageId);
69
+ }
70
+ markProcessed(messageId) {
71
+ this.ackedMessages.set(messageId, Date.now());
72
+ }
73
+ cleanup() {
74
+ const now = Date.now();
75
+ const deadline = now - this.MESSAGE_TTL;
76
+ let removed = 0;
77
+ for (const [messageId, timestamp] of this.ackedMessages.entries()) {
78
+ if (timestamp < deadline) {
79
+ this.ackedMessages.delete(messageId);
80
+ removed++;
81
+ }
82
+ }
83
+ if (removed > 0) {
84
+ this.logger.log("debug", `Cleaned up ${removed} old ACKed messages`);
85
+ }
86
+ }
87
+ }
88
+ // Reconnection manager with exponential backoff
89
+ class ReconnectionManager {
90
+ constructor(logger) {
91
+ this.logger = logger;
92
+ this.attempts = 0;
93
+ this.timer = null;
94
+ this.FAST_INITIAL_DELAY = 50; // 50ms for first 10 attempts
95
+ this.FAST_ATTEMPTS_THRESHOLD = 10; // First 10 attempts are fast
96
+ this.SLOW_INITIAL_DELAY = 1000; // 1 second after fast attempts
97
+ this.MAX_DELAY = 30000; // 30 seconds
98
+ this.MAX_ATTEMPTS = -1; // -1 = infinite
99
+ }
100
+ reset() {
101
+ this.attempts = 0;
102
+ this.cancel();
103
+ }
104
+ cancel() {
105
+ if (this.timer) {
106
+ clearTimeout(this.timer);
107
+ this.timer = null;
108
+ }
109
+ }
110
+ scheduleReconnect(callback, immediate = false) {
111
+ if (this.MAX_ATTEMPTS !== -1 && this.attempts >= this.MAX_ATTEMPTS) {
112
+ this.logger.log("error", "Max reconnection attempts reached");
113
+ return false;
114
+ }
115
+ this.attempts++;
116
+ // Calculate delay with fast exponential backoff for first 10 attempts
117
+ let delay;
118
+ if (immediate) {
119
+ // Immediate reconnection for server restart
120
+ delay = 0;
121
+ this.logger.log("info", "Scheduling immediate reconnect (server restart)");
122
+ }
123
+ else if (this.attempts <= this.FAST_ATTEMPTS_THRESHOLD) {
124
+ // Fast reconnection: 50 => 100 => 200 => 400 => 800 => 1600 => 3200 => 6400 => 12800 => 25600
125
+ delay = this.FAST_INITIAL_DELAY * Math.pow(2, this.attempts - 1);
126
+ }
127
+ else {
128
+ // After fast attempts, use slower backoff starting from SLOW_INITIAL_DELAY
129
+ const slowAttempt = this.attempts - this.FAST_ATTEMPTS_THRESHOLD;
130
+ delay = this.SLOW_INITIAL_DELAY * Math.pow(2, slowAttempt - 1);
131
+ }
132
+ // Cap at MAX_DELAY (except for immediate reconnects)
133
+ if (!immediate) {
134
+ delay = Math.min(delay, this.MAX_DELAY);
135
+ }
136
+ if (!immediate) {
137
+ this.logger.log("info", `Scheduling reconnect attempt ${this.attempts} in ${delay}ms`);
138
+ }
139
+ this.timer = setTimeout(() => {
140
+ this.timer = null;
141
+ callback();
142
+ }, delay);
143
+ return true;
144
+ }
145
+ }
146
+ // WebSocket connection manager
147
+ class WebSocketManager {
148
+ constructor(logger) {
149
+ this.logger = logger;
150
+ this.ws = null;
151
+ this.closePromise = null;
152
+ this.closeResolve = null;
153
+ }
154
+ connect(url, onOpen, onMessage, onClose, onError) {
155
+ if (this.ws) {
156
+ throw new Error("WebSocket already exists");
157
+ }
158
+ this.logger.log("info", `Connecting to: ${url}`);
159
+ // Create a promise that resolves when the WebSocket closes
160
+ this.closePromise = new Promise((resolve) => {
161
+ this.closeResolve = resolve;
162
+ });
163
+ this.ws = new WebSocket(url);
164
+ this.ws.binaryType = "arraybuffer";
165
+ this.ws.onopen = () => {
166
+ this.logger.log("info", "✓ WebSocket connected");
167
+ onOpen();
168
+ };
169
+ this.ws.onmessage = (event) => {
170
+ if (event.data instanceof ArrayBuffer) {
171
+ onMessage(event.data);
172
+ }
173
+ else if (event.data instanceof Blob) {
174
+ // Handle Blob data (some browsers may return Blob instead of ArrayBuffer)
175
+ event.data
176
+ .arrayBuffer()
177
+ .then(onMessage)
178
+ .catch((error) => {
179
+ this.logger.log("error", "Failed to convert Blob to ArrayBuffer:", error);
180
+ });
181
+ }
182
+ else {
183
+ this.logger.log("warn", "Received non-binary message, ignoring");
184
+ }
185
+ };
186
+ this.ws.onerror = (error) => {
187
+ this.logger.log("error", "WebSocket error:", error);
188
+ onError(error);
189
+ };
190
+ this.ws.onclose = (event) => {
191
+ this.logger.log("info", `WebSocket closed: ${event.code} - ${event.reason}`);
192
+ onClose(event.code, event.reason);
193
+ this.ws = null;
194
+ // Resolve the close promise
195
+ this.closeResolve();
196
+ this.closeResolve = null;
197
+ this.closePromise = null;
198
+ };
199
+ }
200
+ sendAck(messageId) {
201
+ if (!this.isConnected()) {
202
+ this.logger.log("warn", `Cannot send ACK (not connected): ${messageId}`);
203
+ return false;
204
+ }
205
+ try {
206
+ // Parse UUID string to bytes (16 bytes)
207
+ const uuid = new Uint8Array(parseUuid(messageId));
208
+ this.ws.send(uuid);
209
+ this.logger.log("debug", `Sent ACK: ${messageId}`);
210
+ return true;
211
+ }
212
+ catch (error) {
213
+ this.logger.log("error", `Failed to send ACK for ${messageId}:`, error);
214
+ return false;
215
+ }
216
+ }
217
+ async close(code = CloseCode.NORMAL, reason = "Client disconnecting") {
218
+ if (!this.ws) {
219
+ return;
220
+ }
221
+ if (this.ws.readyState === WebSocket.OPEN ||
222
+ this.ws.readyState === WebSocket.CONNECTING) {
223
+ this.ws.close(code, reason);
224
+ }
225
+ await this.closePromise;
226
+ }
227
+ isConnected() {
228
+ return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
229
+ }
230
+ }
231
+ // Message processor for handling incoming WebSocket messages
232
+ class MessageProcessor {
233
+ constructor(logger, handlers) {
234
+ this.logger = logger;
235
+ this.handlers = handlers;
236
+ this.sessionEnded = false;
237
+ }
238
+ process(data) {
239
+ try {
240
+ const message = fromBinary(WebsocketMessageSchema, new Uint8Array(data));
241
+ this.logger.log("debug", `Processing message: ${message.id}`);
242
+ // Process based on message type
243
+ switch (message.message.case) {
244
+ case "output":
245
+ this.processOutput(message.message.value);
246
+ break;
247
+ case "session":
248
+ this.processSession(message.message.value);
249
+ break;
250
+ case "url":
251
+ this.processUrl(message.message.value);
252
+ break;
253
+ default:
254
+ this.logger.log("warn", `Unknown message type: ${message.message.case}`);
255
+ }
256
+ return { messageId: message.id, sessionEnded: this.sessionEnded };
257
+ }
258
+ catch (error) {
259
+ this.logger.log("error", "Failed to process message:", error);
260
+ return { messageId: null, sessionEnded: this.sessionEnded };
261
+ }
262
+ }
263
+ hasSessionEnded() {
264
+ return this.sessionEnded;
265
+ }
266
+ processOutput(output) {
267
+ if (!this.handlers.onOutput)
268
+ return;
269
+ try {
270
+ const result = {
271
+ vertex: output.vertex,
272
+ fork: output.fork,
273
+ data: output.data,
274
+ };
275
+ if (output.created) {
276
+ result.created = timestampDate(output.created);
277
+ }
278
+ this.handlers.onOutput(result);
279
+ }
280
+ catch (error) {
281
+ this.logger.log("error", "Error in output handler:", error);
282
+ }
283
+ }
284
+ processSession(session) {
285
+ // Check for terminal status
286
+ switch (session.status) {
287
+ case Status.STOPPED:
288
+ case Status.COMPLETED:
289
+ case Status.ERRORED:
290
+ case Status.EXPIRED:
291
+ this.sessionEnded = true;
292
+ this.logger.log("info", `Session ended with status: ${Status[session.status]}`);
293
+ break;
294
+ }
295
+ if (!this.handlers.onSession)
296
+ return;
297
+ try {
298
+ this.handlers.onSession(toJson(SessionSchema, session));
299
+ }
300
+ catch (error) {
301
+ this.logger.log("error", "Error in session handler:", error);
302
+ }
303
+ }
304
+ processUrl(url) {
305
+ if (!this.handlers.onUrl)
306
+ return;
307
+ try {
308
+ this.handlers.onUrl(toJson(UrlSchema, url));
309
+ }
310
+ catch (error) {
311
+ this.logger.log("error", "Error in URL handler:", error);
312
+ }
313
+ }
314
+ }
315
+ // Main PubsubClient class
316
+ export class PubsubClient {
317
+ constructor(debug = false) {
318
+ this.state = ConnectionState.DISCONNECTED;
319
+ this.sessionInfo = null;
320
+ this.messageProcessor = null;
321
+ this.shouldReconnect = true;
322
+ this.sessionComplete = false;
323
+ this.logger = new Logger(debug);
324
+ this.ackTracker = new AckTracker(this.logger);
325
+ this.reconnectManager = new ReconnectionManager(this.logger);
326
+ this.wsManager = new WebSocketManager(this.logger);
327
+ }
328
+ async subscribe(opts) {
329
+ this.logger.log("debug", "Subscribe called", {
330
+ automation: opts.id,
331
+ hasToken: !!opts.sessionToken,
332
+ });
333
+ // Validate input
334
+ if (!opts.sessionToken || !opts.id) {
335
+ throw new Error("Session token and automation are required");
336
+ }
337
+ // Check if already connected to same session
338
+ if (this.isSameSession(opts)) {
339
+ this.logger.log("debug", "Already connected to same session, updating handlers");
340
+ this.updateHandlers(opts);
341
+ return;
342
+ }
343
+ // Check state
344
+ if (this.state === ConnectionState.CONNECTING) {
345
+ throw new Error("Already connecting, please wait");
346
+ }
347
+ // Disconnect if connected to different session
348
+ if (this.state === ConnectionState.CONNECTED) {
349
+ await this.unsubscribe();
350
+ }
351
+ // Store configuration
352
+ this.sessionInfo = {
353
+ token: opts.sessionToken,
354
+ id: opts.id,
355
+ };
356
+ // Create message processor with handlers
357
+ const handlers = {};
358
+ if (opts.onOutput)
359
+ handlers.onOutput = opts.onOutput;
360
+ if (opts.onSession)
361
+ handlers.onSession = opts.onSession;
362
+ if (opts.onUrl)
363
+ handlers.onUrl = opts.onUrl;
364
+ this.messageProcessor = new MessageProcessor(this.logger, handlers);
365
+ // Reset state
366
+ this.shouldReconnect = true;
367
+ this.sessionComplete = false;
368
+ this.reconnectManager.reset();
369
+ // Start ACK tracker
370
+ this.ackTracker.start();
371
+ // Connect
372
+ await this.connect();
373
+ }
374
+ async unsubscribe() {
375
+ if (this.state === ConnectionState.DISCONNECTED ||
376
+ this.state === ConnectionState.CLOSING) {
377
+ return;
378
+ }
379
+ this.logger.log("info", "Unsubscribing...");
380
+ // Update state
381
+ this.state = ConnectionState.CLOSING;
382
+ this.shouldReconnect = false;
383
+ // Cancel any pending reconnects
384
+ this.reconnectManager.cancel();
385
+ // Close WebSocket and wait for it to fully close
386
+ await this.wsManager.close();
387
+ // Stop ACK tracker
388
+ this.ackTracker.stop();
389
+ // Clear state
390
+ this.sessionInfo = null;
391
+ this.messageProcessor = null;
392
+ this.state = ConnectionState.DISCONNECTED;
393
+ this.logger.log("info", "Unsubscribed successfully");
394
+ }
395
+ isConnected() {
396
+ return this.state === ConnectionState.CONNECTED;
397
+ }
398
+ getConnectionState() {
399
+ return this.state;
400
+ }
401
+ getSessionInfo() {
402
+ if (!this.sessionInfo) {
403
+ throw new Error("No active session");
404
+ }
405
+ return this.sessionInfo;
406
+ }
407
+ async connect() {
408
+ if (!this.sessionInfo) {
409
+ throw new Error("No session configuration");
410
+ }
411
+ this.state = ConnectionState.CONNECTING;
412
+ const config = getConfig();
413
+ const wsUrl = `${config.wsBaseUrl}/${this.sessionInfo.id}/ws?token=${encodeURIComponent(this.sessionInfo.token)}`;
414
+ try {
415
+ this.wsManager.connect(wsUrl, () => this.handleOpen(), (data) => this.handleMessage(data), (code, reason) => this.handleClose(code, reason), (error) => this.handleError(error));
416
+ }
417
+ catch (error) {
418
+ this.state = ConnectionState.DISCONNECTED;
419
+ throw error;
420
+ }
421
+ }
422
+ handleOpen() {
423
+ this.state = ConnectionState.CONNECTED;
424
+ this.reconnectManager.reset();
425
+ }
426
+ handleMessage(data) {
427
+ if (!this.messageProcessor) {
428
+ this.logger.log("error", "No message processor configured");
429
+ return;
430
+ }
431
+ // Process the message
432
+ const result = this.messageProcessor.process(data);
433
+ if (!result.messageId) {
434
+ return; // Failed to parse
435
+ }
436
+ // Update session complete flag if session ended
437
+ if (result.sessionEnded && !this.sessionComplete) {
438
+ this.logger.log("info", "Session has ended (detected from message)");
439
+ this.sessionComplete = true;
440
+ }
441
+ // Check for duplicate
442
+ if (this.ackTracker.isProcessed(result.messageId)) {
443
+ this.logger.log("debug", `Duplicate message: ${result.messageId}`);
444
+ }
445
+ else {
446
+ this.ackTracker.markProcessed(result.messageId);
447
+ }
448
+ // ACK the message (skip for session-ending messages as connection will close)
449
+ if (!result.sessionEnded) {
450
+ this.wsManager.sendAck(result.messageId);
451
+ }
452
+ }
453
+ handleClose(code, reason) {
454
+ this.state = ConnectionState.DISCONNECTED;
455
+ // Analyze close code
456
+ const reconnectStrategy = this.analyzeCloseCode(code, reason);
457
+ // Schedule reconnect if appropriate
458
+ if (reconnectStrategy.shouldReconnect &&
459
+ this.shouldReconnect &&
460
+ !this.sessionComplete) {
461
+ this.scheduleReconnect(reconnectStrategy.immediate);
462
+ }
463
+ else {
464
+ // Clean shutdown (fire and forget - cleanup is async but we don't need to wait)
465
+ this.cleanup().catch((error) => {
466
+ this.logger.log("error", "Error during cleanup:", error);
467
+ });
468
+ }
469
+ }
470
+ handleError(error) {
471
+ this.logger.log("error", "WebSocket error:", error);
472
+ }
473
+ analyzeCloseCode(code, reason) {
474
+ switch (code) {
475
+ case CloseCode.NORMAL:
476
+ // Normal closure - session complete or client requested
477
+ this.logger.log("info", "Normal closure");
478
+ this.sessionComplete = true;
479
+ return { shouldReconnect: false, immediate: false };
480
+ case CloseCode.GOING_AWAY:
481
+ // Server shutting down
482
+ this.logger.log("warn", "Server going away");
483
+ return { shouldReconnect: true, immediate: false };
484
+ case CloseCode.SERVER_RESTART:
485
+ // Server restart - reconnect immediately (no backoff)
486
+ this.logger.log("warn", "Server restarting - will reconnect immediately");
487
+ return { shouldReconnect: true, immediate: true };
488
+ case CloseCode.TRY_AGAIN_LATER:
489
+ // Service temporarily unavailable - reconnect with backoff
490
+ this.logger.log("warn", "Service temporarily unavailable, will retry");
491
+ return { shouldReconnect: true, immediate: false };
492
+ case CloseCode.PROTOCOL_ERROR:
493
+ case CloseCode.UNSUPPORTED_DATA:
494
+ case CloseCode.POLICY_VIOLATION:
495
+ // Critical errors - don't reconnect
496
+ this.logger.log("error", `Critical error (${code}): ${reason}`);
497
+ return { shouldReconnect: false, immediate: false };
498
+ case CloseCode.ABNORMAL:
499
+ // Connection lost - try to reconnect
500
+ this.logger.log("warn", "Connection lost (abnormal closure)");
501
+ return { shouldReconnect: true, immediate: false };
502
+ default:
503
+ // Unknown code - try to reconnect
504
+ this.logger.log("warn", `Unknown close code ${code}: ${reason}`);
505
+ return { shouldReconnect: true, immediate: false };
506
+ }
507
+ }
508
+ scheduleReconnect(immediate = false) {
509
+ const scheduled = this.reconnectManager.scheduleReconnect(() => {
510
+ // Double-check state to avoid race conditions
511
+ if (this.shouldReconnect &&
512
+ this.state === ConnectionState.DISCONNECTED &&
513
+ !this.sessionComplete) {
514
+ this.connect().catch((error) => {
515
+ this.logger.log("error", "Reconnection failed:", error);
516
+ // Try again with normal backoff (not immediate)
517
+ this.scheduleReconnect(false);
518
+ });
519
+ }
520
+ }, immediate);
521
+ if (!scheduled) {
522
+ // Max attempts reached (fire and forget cleanup)
523
+ this.cleanup().catch((error) => {
524
+ this.logger.log("error", "Error during cleanup:", error);
525
+ });
526
+ }
527
+ }
528
+ async cleanup() {
529
+ this.shouldReconnect = false;
530
+ this.reconnectManager.cancel();
531
+ this.ackTracker.stop();
532
+ await this.wsManager.close();
533
+ this.sessionInfo = null;
534
+ this.messageProcessor = null;
535
+ this.state = ConnectionState.DISCONNECTED;
536
+ }
537
+ isSameSession(opts) {
538
+ if (!this.sessionInfo || this.state !== ConnectionState.CONNECTED) {
539
+ return false;
540
+ }
541
+ return (this.sessionInfo.token === opts.sessionToken &&
542
+ this.sessionInfo.id === opts.id);
543
+ }
544
+ updateHandlers(opts) {
545
+ if (!this.messageProcessor) {
546
+ return;
547
+ }
548
+ // Update handlers in message processor
549
+ const handlers = {};
550
+ if (opts.onOutput)
551
+ handlers.onOutput = opts.onOutput;
552
+ if (opts.onSession)
553
+ handlers.onSession = opts.onSession;
554
+ if (opts.onUrl)
555
+ handlers.onUrl = opts.onUrl;
556
+ this.messageProcessor = new MessageProcessor(this.logger, handlers);
557
+ }
558
+ }
559
+ //# sourceMappingURL=pubsub-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pubsub-client.js","sourceRoot":"","sources":["../../src/pubsub-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { GetSessionResponseJson, InheritSessionResponseJson, ReadOutputResponseJson, ReadUrlsResponseJson, StartSessionRequestJson, StartSessionResponseJson } from "@mochabug/genproto/mochabugapis/adapt/automations/v1/automations_pb.js";
2
+ export * from "./pubsub-client.js";
3
+ export interface AdaptConfig {
4
+ baseUrl: string;
5
+ wsBaseUrl: string;
6
+ }
7
+ export declare function configure(config: Partial<AdaptConfig>): void;
8
+ export declare function getConfig(): AdaptConfig;
9
+ export declare function resetConfig(): void;
10
+ export declare function startSession(req: StartSessionRequestJson, token?: string): Promise<StartSessionResponseJson>;
11
+ export declare function inheritSession(id: string, sessionToken: string): Promise<InheritSessionResponseJson>;
12
+ export declare function getSession(id: string, sessionToken: string): Promise<GetSessionResponseJson>;
13
+ export declare function readOutput(id: string, sessionToken: string, options?: {
14
+ pageSize?: number;
15
+ vertex?: string;
16
+ newerThan?: string;
17
+ }): Promise<ReadOutputResponseJson>;
18
+ export declare function readUrls(id: string, sessionToken: string, options?: {
19
+ pageSize?: number;
20
+ newerThan?: string;
21
+ }): Promise<ReadUrlsResponseJson>;
22
+ export declare function stopSession(id: string, sessionToken: string): Promise<void>;
23
+ export declare class RestClientError extends Error {
24
+ status: number;
25
+ statusText: string;
26
+ response: Response;
27
+ constructor(response: Response);
28
+ }
@@ -0,0 +1,59 @@
1
+ import type { Output as OutputMessage, Session, SessionJson, Session as SessionMessage, StatusJson, Url, UrlJson, Url as UrlMessage } from "@mochabug/genproto/mochabugapis/adapt/automations/v1/automations_pb.js";
2
+ import { Status } from "@mochabug/genproto/mochabugapis/adapt/automations/v1/automations_pb.js";
3
+ import type { SignalData } from "@mochabug/genproto/mochabugapis/adapt/graph/signal_data_pb.js";
4
+ export type { OutputMessage, Session, SessionJson, SessionMessage, SignalData, Status, StatusJson, Url, UrlJson, UrlMessage, };
5
+ export interface Output {
6
+ vertex: string;
7
+ fork: string;
8
+ data: {
9
+ [key: string]: SignalData;
10
+ };
11
+ created?: Date;
12
+ }
13
+ export interface MessageHandlers {
14
+ onOutput?: (output: Output) => void;
15
+ onSession?: (session: SessionJson) => void;
16
+ onUrl?: (url: UrlJson) => void;
17
+ }
18
+ export interface SubscriptionOptions extends MessageHandlers {
19
+ sessionToken: string;
20
+ id: string;
21
+ debug?: boolean;
22
+ }
23
+ export declare enum ConnectionState {
24
+ DISCONNECTED = "disconnected",
25
+ CONNECTING = "connecting",
26
+ CONNECTED = "connected",
27
+ CLOSING = "closing"
28
+ }
29
+ export interface SessionInfo {
30
+ id: string;
31
+ token: string;
32
+ }
33
+ export declare class PubsubClient {
34
+ private state;
35
+ private sessionInfo;
36
+ private readonly logger;
37
+ private readonly ackTracker;
38
+ private readonly reconnectManager;
39
+ private readonly wsManager;
40
+ private messageProcessor;
41
+ private shouldReconnect;
42
+ private sessionComplete;
43
+ constructor(debug?: boolean);
44
+ subscribe(opts: SubscriptionOptions): Promise<void>;
45
+ unsubscribe(): Promise<void>;
46
+ isConnected(): boolean;
47
+ getConnectionState(): ConnectionState;
48
+ getSessionInfo(): SessionInfo;
49
+ private connect;
50
+ private handleOpen;
51
+ private handleMessage;
52
+ private handleClose;
53
+ private handleError;
54
+ private analyzeCloseCode;
55
+ private scheduleReconnect;
56
+ private cleanup;
57
+ private isSameSession;
58
+ private updateHandlers;
59
+ }
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@mochabug/adapt-core",
3
+ "version": "1.0.0-rc21",
4
+ "description": "Cross-platform core client library for Adapt automation platform",
5
+ "type": "module",
6
+ "main": "./dist/esm/index.js",
7
+ "types": "./dist/types/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/types/index.d.ts",
11
+ "import": "./dist/esm/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "scripts": {
18
+ "build:esm": "tsc --project tsconfig.esm.json",
19
+ "build:types": "tsc --project tsconfig.types.json",
20
+ "build": "rm -rf dist && npm run build:esm && npm run build:types",
21
+ "test": "vitest run",
22
+ "test:ui": "vitest --ui"
23
+ },
24
+ "keywords": [
25
+ "adapt",
26
+ "automations",
27
+ "mochabug"
28
+ ],
29
+ "author": "mochabug AB",
30
+ "license": "ISC",
31
+ "devDependencies": {
32
+ "@types/ws": "^8.18.1",
33
+ "@vitest/ui": "^4.0.12",
34
+ "typescript": "^5.9.3",
35
+ "vitest": "^4.0.12",
36
+ "ws": "^8.18.3"
37
+ },
38
+ "dependencies": {
39
+ "@bufbuild/protobuf": "^2.10.1",
40
+ "@types/uuid": "^11.0.0",
41
+ "isomorphic-ws": "^5.0.0",
42
+ "uuid": "^13.0.0"
43
+ }
44
+ }