cloudcruise 0.0.6 → 1.0.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/package.json +7 -7
- package/dist/CloudCruise.d.ts +0 -29
- package/dist/CloudCruise.js +0 -111
- package/dist/events/types.d.ts +0 -153
- package/dist/events/types.js +0 -22
- package/dist/index.d.ts +0 -18
- package/dist/index.js +0 -13
- package/dist/runs/RunsClient.d.ts +0 -42
- package/dist/runs/RunsClient.js +0 -200
- package/dist/runs/types.d.ts +0 -157
- package/dist/runs/types.js +0 -4
- package/dist/utils/asyncQueue.d.ts +0 -9
- package/dist/utils/asyncQueue.js +0 -43
- package/dist/utils/connectionManager.d.ts +0 -29
- package/dist/utils/connectionManager.js +0 -234
- package/dist/utils/env.d.ts +0 -2
- package/dist/utils/env.js +0 -9
- package/dist/utils/events.d.ts +0 -24
- package/dist/utils/events.js +0 -40
- package/dist/utils/sse.d.ts +0 -24
- package/dist/utils/sse.js +0 -122
- package/dist/vault/VaultClient.d.ts +0 -42
- package/dist/vault/VaultClient.js +0 -91
- package/dist/vault/types.d.ts +0 -50
- package/dist/vault/types.js +0 -4
- package/dist/vault/utils.d.ts +0 -33
- package/dist/vault/utils.js +0 -99
- package/dist/webhook/WebhookClient.d.ts +0 -15
- package/dist/webhook/WebhookClient.js +0 -18
- package/dist/webhook/types.d.ts +0 -7
- package/dist/webhook/types.js +0 -8
- package/dist/webhook/utils.d.ts +0 -3
- package/dist/webhook/utils.js +0 -49
- package/dist/workflows/WorkflowsClient.d.ts +0 -19
- package/dist/workflows/WorkflowsClient.js +0 -97
- package/dist/workflows/types.d.ts +0 -41
- package/dist/workflows/types.js +0 -15
package/dist/runs/types.d.ts
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CloudCruise Runs API Type Definitions
|
|
3
|
-
*/
|
|
4
|
-
import type { EventType, RunEventMessage, EventPayloadMap, ExecutionQueuedPayload, ExecutionStartPayload, ExecutionStepPayload, InteractionWaitingPayload, InteractionFinishedPayload, AgentErrorAnalysisPayload, ExecutionRequeuedPayload, EndRunPayload, EndRunError, ExecutionStoppedEarlyPayload, FileUploadedPayload, ScreenshotUploadedPayload } from '../events/types.js';
|
|
5
|
-
export type { EventType };
|
|
6
|
-
export type { ExecutionQueuedPayload, ExecutionStartPayload, ExecutionStepPayload, InteractionWaitingPayload, InteractionFinishedPayload, AgentErrorAnalysisPayload, ExecutionRequeuedPayload, EndRunPayload, EndRunError, ExecutionStoppedEarlyPayload, FileUploadedPayload, ScreenshotUploadedPayload, EventPayloadMap, };
|
|
7
|
-
export interface DryRun {
|
|
8
|
-
enabled: boolean;
|
|
9
|
-
add_to_output?: Record<string, any>;
|
|
10
|
-
}
|
|
11
|
-
export interface Metadata {
|
|
12
|
-
metadata: Record<string, any>;
|
|
13
|
-
}
|
|
14
|
-
export interface RunSpecificWebhook {
|
|
15
|
-
url: string;
|
|
16
|
-
event_types_subscribed: EventType[];
|
|
17
|
-
secret: string;
|
|
18
|
-
validity: number;
|
|
19
|
-
}
|
|
20
|
-
export type PayloadWebhook = Metadata | RunSpecificWebhook;
|
|
21
|
-
export interface StartRunRequest {
|
|
22
|
-
workflow_id: string;
|
|
23
|
-
run_input_variables: Record<string, any>;
|
|
24
|
-
dry_run?: DryRun;
|
|
25
|
-
webhook?: PayloadWebhook;
|
|
26
|
-
additional_context?: Record<string, any>;
|
|
27
|
-
client_id?: string;
|
|
28
|
-
}
|
|
29
|
-
export interface StartRunResponse {
|
|
30
|
-
session_id: string;
|
|
31
|
-
}
|
|
32
|
-
export type UserInteractionData = Record<string, any>;
|
|
33
|
-
export interface VideoUrl {
|
|
34
|
-
timestamp: string;
|
|
35
|
-
session_id: string;
|
|
36
|
-
signed_screen_recording_url: string;
|
|
37
|
-
signed_screen_recording_url_expires: string;
|
|
38
|
-
}
|
|
39
|
-
export interface RunError {
|
|
40
|
-
prompt?: string | null;
|
|
41
|
-
message?: string | null;
|
|
42
|
-
error_id?: string | null;
|
|
43
|
-
full_url?: string | null;
|
|
44
|
-
llm_model?: string | null;
|
|
45
|
-
created_at?: string | null;
|
|
46
|
-
error_code?: string | null;
|
|
47
|
-
action_type?: string | null;
|
|
48
|
-
action_display_name?: string | null;
|
|
49
|
-
}
|
|
50
|
-
export interface SignedFileUrl {
|
|
51
|
-
signed_file_url: string;
|
|
52
|
-
file_name: string;
|
|
53
|
-
timestamp: string;
|
|
54
|
-
signed_file_url_expires: string;
|
|
55
|
-
metadata: Record<string, any>;
|
|
56
|
-
}
|
|
57
|
-
export interface SignedScreenshotUrl {
|
|
58
|
-
signed_screenshot_url: string;
|
|
59
|
-
node_display_name: string;
|
|
60
|
-
timestamp: string;
|
|
61
|
-
signed_screenshot_url_expires: string;
|
|
62
|
-
error_screenshot: boolean;
|
|
63
|
-
full_length_screenshot?: boolean;
|
|
64
|
-
retry_index?: number;
|
|
65
|
-
}
|
|
66
|
-
export interface WorkflowError {
|
|
67
|
-
message: string;
|
|
68
|
-
error_id: string;
|
|
69
|
-
full_url?: string | null;
|
|
70
|
-
created_at?: string | null;
|
|
71
|
-
error_code?: string | null;
|
|
72
|
-
action_type?: string | null;
|
|
73
|
-
action_display_name?: string | null;
|
|
74
|
-
llm_error_category?: string | null;
|
|
75
|
-
original_error?: string | null;
|
|
76
|
-
}
|
|
77
|
-
export interface RunResult {
|
|
78
|
-
session_id: string;
|
|
79
|
-
status: EventType;
|
|
80
|
-
input_variables: Record<string, any>;
|
|
81
|
-
data: Record<string, any>;
|
|
82
|
-
video_urls: VideoUrl[];
|
|
83
|
-
file_urls: SignedFileUrl[];
|
|
84
|
-
screenshot_urls: SignedScreenshotUrl[];
|
|
85
|
-
errors: RunError[] | null;
|
|
86
|
-
}
|
|
87
|
-
export interface GetRunResult {
|
|
88
|
-
data: Record<string, any> | null;
|
|
89
|
-
session_id: string;
|
|
90
|
-
errors: WorkflowError[];
|
|
91
|
-
status: EventType;
|
|
92
|
-
input_variables: Record<string, any>;
|
|
93
|
-
workflow_id: string | null;
|
|
94
|
-
session_retries: number | null;
|
|
95
|
-
encrypted_variables: string[] | null;
|
|
96
|
-
video_urls: VideoUrl[] | null;
|
|
97
|
-
screenshot_urls?: SignedScreenshotUrl[] | null;
|
|
98
|
-
file_urls: SignedFileUrl[] | null;
|
|
99
|
-
}
|
|
100
|
-
export interface WebhookEvent {
|
|
101
|
-
success: boolean;
|
|
102
|
-
response: string;
|
|
103
|
-
error: string;
|
|
104
|
-
}
|
|
105
|
-
export interface WebhookReplayResponse {
|
|
106
|
-
status: string;
|
|
107
|
-
info: string;
|
|
108
|
-
nr_success: number;
|
|
109
|
-
nr_failed: number;
|
|
110
|
-
webhook_events: WebhookEvent[];
|
|
111
|
-
}
|
|
112
|
-
/**
|
|
113
|
-
* Streaming (SSE) types
|
|
114
|
-
*/
|
|
115
|
-
export type SseEventName = 'run.event' | 'ping';
|
|
116
|
-
export type RunEventEnvelope<E extends EventType = EventType> = RunEventMessage<E>;
|
|
117
|
-
export interface PingEnvelope {
|
|
118
|
-
event: 'ping';
|
|
119
|
-
data: {
|
|
120
|
-
ts: number;
|
|
121
|
-
} | Record<string, any>;
|
|
122
|
-
}
|
|
123
|
-
export type SseMessage<E extends EventType = EventType> = RunEventEnvelope<E> | PingEnvelope;
|
|
124
|
-
export interface RunStreamOptions {
|
|
125
|
-
signal?: AbortSignal;
|
|
126
|
-
withCredentials?: boolean;
|
|
127
|
-
headers?: Record<string, string>;
|
|
128
|
-
reconnect?: {
|
|
129
|
-
enabled?: boolean;
|
|
130
|
-
delays?: number[];
|
|
131
|
-
jitter?: number;
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
export type RunEventMap = {
|
|
135
|
-
[K in EventType]: RunEventEnvelope<K>;
|
|
136
|
-
};
|
|
137
|
-
export type RunHandleEventMap = {
|
|
138
|
-
'open': undefined;
|
|
139
|
-
'close': undefined;
|
|
140
|
-
'reconnect': {
|
|
141
|
-
attemptDelayMs: number;
|
|
142
|
-
};
|
|
143
|
-
'error': unknown;
|
|
144
|
-
'end': {
|
|
145
|
-
type: EventType;
|
|
146
|
-
};
|
|
147
|
-
'run.event': SseMessage;
|
|
148
|
-
'ping': PingEnvelope;
|
|
149
|
-
'message': SseMessage | PingEnvelope;
|
|
150
|
-
} & RunEventMap;
|
|
151
|
-
export interface RunHandle {
|
|
152
|
-
sessionId: string;
|
|
153
|
-
on<K extends keyof RunHandleEventMap>(event: K, handler: (e: RunHandleEventMap[K]) => void): () => void;
|
|
154
|
-
wait(): Promise<GetRunResult>;
|
|
155
|
-
close(): void;
|
|
156
|
-
[Symbol.asyncIterator](): AsyncIterator<SseMessage>;
|
|
157
|
-
}
|
package/dist/runs/types.js
DELETED
package/dist/utils/asyncQueue.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export class AsyncEventQueue {
|
|
2
|
-
items = [];
|
|
3
|
-
pending = null;
|
|
4
|
-
done = false;
|
|
5
|
-
push(item) {
|
|
6
|
-
if (this.done)
|
|
7
|
-
return;
|
|
8
|
-
if (this.pending) {
|
|
9
|
-
const resolve = this.pending;
|
|
10
|
-
this.pending = null;
|
|
11
|
-
resolve({ value: item, done: false });
|
|
12
|
-
}
|
|
13
|
-
else {
|
|
14
|
-
this.items.push(item);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
close() {
|
|
18
|
-
if (this.done)
|
|
19
|
-
return;
|
|
20
|
-
this.done = true;
|
|
21
|
-
if (this.pending) {
|
|
22
|
-
const resolve = this.pending;
|
|
23
|
-
this.pending = null;
|
|
24
|
-
resolve({ value: undefined, done: true });
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
async next() {
|
|
28
|
-
if (this.items.length) {
|
|
29
|
-
return { value: this.items.shift(), done: false };
|
|
30
|
-
}
|
|
31
|
-
if (this.done) {
|
|
32
|
-
return { value: undefined, done: true };
|
|
33
|
-
}
|
|
34
|
-
return await new Promise(resolve => {
|
|
35
|
-
this.pending = resolve;
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
[Symbol.asyncIterator]() {
|
|
39
|
-
return {
|
|
40
|
-
next: () => this.next(),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import type { SseMessage } from '../runs/types.js';
|
|
2
|
-
type Listener = (e: unknown) => void;
|
|
3
|
-
interface SubscribeOptions {
|
|
4
|
-
signal?: AbortSignal;
|
|
5
|
-
}
|
|
6
|
-
export interface SessionSubscription {
|
|
7
|
-
on(event: string, handler: Listener): () => void;
|
|
8
|
-
close(): void;
|
|
9
|
-
[Symbol.asyncIterator](): AsyncIterator<SseMessage>;
|
|
10
|
-
}
|
|
11
|
-
export declare class ConnectionManager {
|
|
12
|
-
private readonly baseUrl;
|
|
13
|
-
private readonly apiKey;
|
|
14
|
-
private clientId;
|
|
15
|
-
private conn;
|
|
16
|
-
private connecting;
|
|
17
|
-
private connected;
|
|
18
|
-
private reconnecting;
|
|
19
|
-
private readonly reconnectDelays;
|
|
20
|
-
private readonly sessions;
|
|
21
|
-
constructor(baseUrl: string, apiKey: string);
|
|
22
|
-
ensureClientId(): Promise<string>;
|
|
23
|
-
private generateClientId;
|
|
24
|
-
connectIfNeeded(): Promise<void>;
|
|
25
|
-
subscribe(sessionId: string, opts?: SubscribeOptions): SessionSubscription;
|
|
26
|
-
private openMuxConnection;
|
|
27
|
-
private scheduleReconnect;
|
|
28
|
-
}
|
|
29
|
-
export {};
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { openSSE } from './sse.js';
|
|
2
|
-
import { SimpleEventEmitter } from './events.js';
|
|
3
|
-
import { AsyncEventQueue } from './asyncQueue.js';
|
|
4
|
-
import { EventType } from '../events/types.js';
|
|
5
|
-
function isFinalEvent(eventType) {
|
|
6
|
-
return (eventType === EventType.ExecutionSuccess ||
|
|
7
|
-
eventType === EventType.ExecutionFailed ||
|
|
8
|
-
eventType === EventType.ExecutionStopped);
|
|
9
|
-
}
|
|
10
|
-
export class ConnectionManager {
|
|
11
|
-
baseUrl;
|
|
12
|
-
apiKey;
|
|
13
|
-
clientId;
|
|
14
|
-
conn = null;
|
|
15
|
-
connecting = false;
|
|
16
|
-
connected = false;
|
|
17
|
-
reconnecting = false;
|
|
18
|
-
reconnectDelays = [1000, 3000, 10000];
|
|
19
|
-
sessions = new Map();
|
|
20
|
-
constructor(baseUrl, apiKey) {
|
|
21
|
-
this.baseUrl = baseUrl.replace(/\/$/, '');
|
|
22
|
-
this.apiKey = apiKey;
|
|
23
|
-
}
|
|
24
|
-
async ensureClientId() {
|
|
25
|
-
if (this.clientId)
|
|
26
|
-
return this.clientId;
|
|
27
|
-
this.clientId = this.generateClientId();
|
|
28
|
-
return this.clientId;
|
|
29
|
-
}
|
|
30
|
-
/*
|
|
31
|
-
try to use crypto.randomUUID if the platform is supported. otherwise fallback to other methods: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523
|
|
32
|
-
*/
|
|
33
|
-
generateClientId() {
|
|
34
|
-
const cryptoObj = globalThis.crypto;
|
|
35
|
-
// Preferred: native CSPRNG-backed UUID
|
|
36
|
-
if (cryptoObj?.randomUUID) {
|
|
37
|
-
return cryptoObj.randomUUID();
|
|
38
|
-
}
|
|
39
|
-
// Fallback: RFC4122 v4 built from CSPRNG bytes
|
|
40
|
-
if (cryptoObj?.getRandomValues) {
|
|
41
|
-
const bytes = new Uint8Array(16);
|
|
42
|
-
cryptoObj.getRandomValues(bytes);
|
|
43
|
-
bytes[6] = (bytes[6] & 0x0f) | 0x40; // version 4
|
|
44
|
-
bytes[8] = (bytes[8] & 0x3f) | 0x80; // variant 10xx
|
|
45
|
-
const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, '0'));
|
|
46
|
-
return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10).join('')}`;
|
|
47
|
-
}
|
|
48
|
-
// Last resort: non-CSPRNG timestamp + Math.random
|
|
49
|
-
let d = Date.now();
|
|
50
|
-
let d2 = typeof performance !== 'undefined' && typeof performance.now === 'function'
|
|
51
|
-
? Math.floor(performance.now() * 1000)
|
|
52
|
-
: 0;
|
|
53
|
-
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
|
|
54
|
-
let r = Math.random() * 16;
|
|
55
|
-
if (d > 0) {
|
|
56
|
-
r = ((d + r) % 16) | 0;
|
|
57
|
-
d = Math.floor(d / 16);
|
|
58
|
-
}
|
|
59
|
-
else {
|
|
60
|
-
r = ((d2 + r) % 16) | 0;
|
|
61
|
-
d2 = Math.floor(d2 / 16);
|
|
62
|
-
}
|
|
63
|
-
const v = c === 'x' ? r : (r & 0x3) | 0x8;
|
|
64
|
-
return v.toString(16);
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
async connectIfNeeded() {
|
|
68
|
-
if (this.connected || this.connecting)
|
|
69
|
-
return;
|
|
70
|
-
if (!this.clientId)
|
|
71
|
-
await this.ensureClientId();
|
|
72
|
-
await this.openMuxConnection();
|
|
73
|
-
}
|
|
74
|
-
subscribe(sessionId, opts) {
|
|
75
|
-
// Kick off connection if not already connected
|
|
76
|
-
try {
|
|
77
|
-
void this.connectIfNeeded();
|
|
78
|
-
}
|
|
79
|
-
catch { }
|
|
80
|
-
// Ensure channel exists
|
|
81
|
-
let channel = this.sessions.get(sessionId);
|
|
82
|
-
if (!channel) {
|
|
83
|
-
channel = {
|
|
84
|
-
sessionId,
|
|
85
|
-
emitter: new SimpleEventEmitter(),
|
|
86
|
-
subscribers: new Set(),
|
|
87
|
-
ended: false
|
|
88
|
-
};
|
|
89
|
-
this.sessions.set(sessionId, channel);
|
|
90
|
-
}
|
|
91
|
-
// Create per-handle queue
|
|
92
|
-
const queue = new AsyncEventQueue();
|
|
93
|
-
channel.subscribers.add(queue);
|
|
94
|
-
// Propagate abort to handle close
|
|
95
|
-
if (opts?.signal) {
|
|
96
|
-
const onAbort = () => sub.close();
|
|
97
|
-
opts.signal.addEventListener('abort', onAbort, { once: true });
|
|
98
|
-
}
|
|
99
|
-
const sub = {
|
|
100
|
-
on: (event, handler) => channel.emitter.on(event, handler),
|
|
101
|
-
close: () => {
|
|
102
|
-
if (!channel)
|
|
103
|
-
return;
|
|
104
|
-
queue.close();
|
|
105
|
-
channel.subscribers.delete(queue);
|
|
106
|
-
// If no more subscribers and channel is ended, remove it
|
|
107
|
-
if (channel.subscribers.size === 0 && channel.ended) {
|
|
108
|
-
this.sessions.delete(sessionId);
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
[Symbol.asyncIterator]() {
|
|
112
|
-
return queue[Symbol.asyncIterator]();
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
return sub;
|
|
116
|
-
}
|
|
117
|
-
async openMuxConnection() {
|
|
118
|
-
if (this.connecting || this.connected)
|
|
119
|
-
return;
|
|
120
|
-
if (!this.clientId)
|
|
121
|
-
await this.ensureClientId();
|
|
122
|
-
this.connecting = true;
|
|
123
|
-
const headers = {
|
|
124
|
-
'cc-key': this.apiKey
|
|
125
|
-
};
|
|
126
|
-
const url = `${this.baseUrl}/run/clients/${this.clientId}/events`;
|
|
127
|
-
const emitAll = (event, payload) => {
|
|
128
|
-
for (const ch of this.sessions.values()) {
|
|
129
|
-
ch.emitter.emit(event, payload);
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
try {
|
|
133
|
-
this.conn = openSSE(url, {
|
|
134
|
-
onOpen: () => {
|
|
135
|
-
this.connected = true;
|
|
136
|
-
this.connecting = false;
|
|
137
|
-
emitAll('open');
|
|
138
|
-
},
|
|
139
|
-
onEvent: (evt) => {
|
|
140
|
-
if (evt.event === 'ping') {
|
|
141
|
-
emitAll('ping', evt);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
if (evt.event === 'run.event') {
|
|
145
|
-
const raw = evt;
|
|
146
|
-
const data = raw.data?.data;
|
|
147
|
-
if (!data) {
|
|
148
|
-
return;
|
|
149
|
-
}
|
|
150
|
-
// Extract session_id - it's always present in payload
|
|
151
|
-
const payload = data.payload;
|
|
152
|
-
const sessionId = payload?.session_id;
|
|
153
|
-
if (!sessionId) {
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
const channel = this.sessions.get(sessionId);
|
|
157
|
-
if (!channel) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
const msg = {
|
|
161
|
-
event: 'run.event',
|
|
162
|
-
data: data,
|
|
163
|
-
timestamp: raw.timestamp || new Date().toISOString(),
|
|
164
|
-
expires_at: raw.expires_at || new Date(Date.now() + 3600000).toISOString()
|
|
165
|
-
};
|
|
166
|
-
// fan-out to all subscribers
|
|
167
|
-
for (const q of channel.subscribers)
|
|
168
|
-
q.push(msg);
|
|
169
|
-
channel.emitter.emit('run.event', msg);
|
|
170
|
-
const eventType = data.event;
|
|
171
|
-
if (isFinalEvent(eventType)) {
|
|
172
|
-
channel.ended = true;
|
|
173
|
-
channel.emitter.emit('end', { type: eventType });
|
|
174
|
-
for (const q of channel.subscribers)
|
|
175
|
-
q.close();
|
|
176
|
-
channel.subscribers.clear();
|
|
177
|
-
// Remove the channel after notifying
|
|
178
|
-
this.sessions.delete(sessionId);
|
|
179
|
-
}
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
const u = evt;
|
|
183
|
-
},
|
|
184
|
-
onError: (err) => {
|
|
185
|
-
// Surface error to all channels and attempt reconnect
|
|
186
|
-
emitAll('error', err);
|
|
187
|
-
if (!this.reconnecting)
|
|
188
|
-
this.scheduleReconnect();
|
|
189
|
-
},
|
|
190
|
-
onClose: () => {
|
|
191
|
-
this.connected = false;
|
|
192
|
-
this.connecting = false;
|
|
193
|
-
emitAll('close');
|
|
194
|
-
if (!this.reconnecting)
|
|
195
|
-
this.scheduleReconnect();
|
|
196
|
-
}
|
|
197
|
-
}, {
|
|
198
|
-
headers,
|
|
199
|
-
withCredentials: false
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
catch (e) {
|
|
203
|
-
this.connected = false;
|
|
204
|
-
this.connecting = false;
|
|
205
|
-
if (!this.reconnecting)
|
|
206
|
-
this.scheduleReconnect();
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
scheduleReconnect() {
|
|
210
|
-
if (this.reconnecting)
|
|
211
|
-
return;
|
|
212
|
-
this.reconnecting = true;
|
|
213
|
-
(async () => {
|
|
214
|
-
for (const delay of this.reconnectDelays) {
|
|
215
|
-
// Notify listeners about reconnect attempt
|
|
216
|
-
for (const ch of this.sessions.values())
|
|
217
|
-
ch.emitter.emit('reconnect', { attemptDelayMs: delay });
|
|
218
|
-
await new Promise(r => setTimeout(r, delay));
|
|
219
|
-
try {
|
|
220
|
-
await this.openMuxConnection();
|
|
221
|
-
if (this.connected) {
|
|
222
|
-
this.reconnecting = false;
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
catch {
|
|
227
|
-
// continue to next delay
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
// Give up after exhausting delays; next event/subscribe will try again
|
|
231
|
-
this.reconnecting = false;
|
|
232
|
-
})();
|
|
233
|
-
}
|
|
234
|
-
}
|
package/dist/utils/env.d.ts
DELETED
package/dist/utils/env.js
DELETED
package/dist/utils/events.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export type EventHandler<T = unknown> = (event: T) => void;
|
|
2
|
-
/**
|
|
3
|
-
* Event emitter that supports both typed and untyped usage.
|
|
4
|
-
*
|
|
5
|
-
* - Use without type parameter for untyped events (backward compatible)
|
|
6
|
-
* - Use with EventMap type parameter for type-safe events
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* // Untyped usage
|
|
10
|
-
* const emitter = new SimpleEventEmitter();
|
|
11
|
-
* emitter.on('foo', (data) => console.log(data));
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* // Typed usage
|
|
15
|
-
* type Events = { foo: string; bar: number };
|
|
16
|
-
* const emitter = new SimpleEventEmitter<Events>();
|
|
17
|
-
* emitter.on('foo', (data) => console.log(data)); // data is string
|
|
18
|
-
*/
|
|
19
|
-
export declare class SimpleEventEmitter<EventMap extends Record<string, any> = Record<string, unknown>> {
|
|
20
|
-
private listeners;
|
|
21
|
-
on<K extends keyof EventMap>(event: K, handler: EventHandler<EventMap[K]>): () => void;
|
|
22
|
-
emit<K extends keyof EventMap>(event: K, payload: EventMap[K]): void;
|
|
23
|
-
clear(): void;
|
|
24
|
-
}
|
package/dist/utils/events.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Event emitter that supports both typed and untyped usage.
|
|
3
|
-
*
|
|
4
|
-
* - Use without type parameter for untyped events (backward compatible)
|
|
5
|
-
* - Use with EventMap type parameter for type-safe events
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* // Untyped usage
|
|
9
|
-
* const emitter = new SimpleEventEmitter();
|
|
10
|
-
* emitter.on('foo', (data) => console.log(data));
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* // Typed usage
|
|
14
|
-
* type Events = { foo: string; bar: number };
|
|
15
|
-
* const emitter = new SimpleEventEmitter<Events>();
|
|
16
|
-
* emitter.on('foo', (data) => console.log(data)); // data is string
|
|
17
|
-
*/
|
|
18
|
-
export class SimpleEventEmitter {
|
|
19
|
-
listeners = new Map();
|
|
20
|
-
on(event, handler) {
|
|
21
|
-
if (!this.listeners.has(event))
|
|
22
|
-
this.listeners.set(event, new Set());
|
|
23
|
-
this.listeners.get(event).add(handler);
|
|
24
|
-
return () => {
|
|
25
|
-
const set = this.listeners.get(event);
|
|
26
|
-
if (set)
|
|
27
|
-
set.delete(handler);
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
emit(event, payload) {
|
|
31
|
-
const set = this.listeners.get(event);
|
|
32
|
-
if (!set)
|
|
33
|
-
return;
|
|
34
|
-
for (const handler of set)
|
|
35
|
-
handler(payload);
|
|
36
|
-
}
|
|
37
|
-
clear() {
|
|
38
|
-
this.listeners.clear();
|
|
39
|
-
}
|
|
40
|
-
}
|
package/dist/utils/sse.d.ts
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
export interface SSEHandlers {
|
|
2
|
-
onOpen?: () => void;
|
|
3
|
-
onEvent?: (evt: {
|
|
4
|
-
event: string;
|
|
5
|
-
data?: unknown;
|
|
6
|
-
id?: string;
|
|
7
|
-
raw?: string;
|
|
8
|
-
}) => void;
|
|
9
|
-
onError?: (error: Error) => void;
|
|
10
|
-
onClose?: () => void;
|
|
11
|
-
}
|
|
12
|
-
export interface SSEOptions {
|
|
13
|
-
headers?: HeadersInit;
|
|
14
|
-
withCredentials?: boolean;
|
|
15
|
-
signal?: AbortSignal;
|
|
16
|
-
}
|
|
17
|
-
export interface SSEConnection {
|
|
18
|
-
close(): void;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Open an SSE connection using either native EventSource (browser, cookie auth)
|
|
22
|
-
* or fetch streaming (Node 18+ and modern browsers) when custom headers are needed.
|
|
23
|
-
*/
|
|
24
|
-
export declare function openSSE(url: string, handlers: SSEHandlers, opts?: SSEOptions): SSEConnection;
|