@inferencesh/sdk 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.
package/dist/stream.js ADDED
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamManager = void 0;
4
+ class StreamManager {
5
+ constructor(options) {
6
+ this.eventSource = null;
7
+ this.reconnectTimeout = null;
8
+ this.stopTimeout = null;
9
+ this.initialConnectionAttempts = 0;
10
+ this.isConnected = false;
11
+ this.isStopped = false;
12
+ this.options = {
13
+ autoReconnect: true,
14
+ maxReconnects: 5,
15
+ reconnectDelayMs: 1000,
16
+ ...options,
17
+ };
18
+ }
19
+ clearTimeouts() {
20
+ if (this.reconnectTimeout) {
21
+ clearTimeout(this.reconnectTimeout);
22
+ this.reconnectTimeout = null;
23
+ }
24
+ if (this.stopTimeout) {
25
+ clearTimeout(this.stopTimeout);
26
+ this.stopTimeout = null;
27
+ }
28
+ }
29
+ closeEventSource() {
30
+ if (this.eventSource) {
31
+ this.eventSource.close();
32
+ this.eventSource = null;
33
+ }
34
+ }
35
+ cleanup() {
36
+ this.clearTimeouts();
37
+ this.closeEventSource();
38
+ this.isConnected = false;
39
+ this.options.onStop?.();
40
+ }
41
+ stopAfter(delayMs) {
42
+ this.clearTimeouts();
43
+ this.stopTimeout = setTimeout(() => this.stop(), delayMs);
44
+ }
45
+ clearStopTimeout() {
46
+ if (this.stopTimeout) {
47
+ clearTimeout(this.stopTimeout);
48
+ this.stopTimeout = null;
49
+ }
50
+ }
51
+ stop() {
52
+ this.isStopped = true;
53
+ this.cleanup();
54
+ }
55
+ scheduleReconnect() {
56
+ if (!this.options.autoReconnect || this.isStopped)
57
+ return false;
58
+ // If we had a successful connection before, always reconnect
59
+ // Otherwise, check if we've exceeded initial connection attempts
60
+ if (!this.isConnected && this.initialConnectionAttempts >= (this.options.maxReconnects ?? 5)) {
61
+ return false;
62
+ }
63
+ this.reconnectTimeout = setTimeout(() => {
64
+ if (!this.isStopped) {
65
+ if (!this.isConnected) {
66
+ this.initialConnectionAttempts++;
67
+ }
68
+ this.connect();
69
+ }
70
+ }, this.options.reconnectDelayMs);
71
+ return true;
72
+ }
73
+ async connect() {
74
+ if (this.isStopped)
75
+ return;
76
+ this.cleanup();
77
+ this.isStopped = false;
78
+ try {
79
+ const source = await this.options.createEventSource();
80
+ if (!source || this.isStopped)
81
+ return;
82
+ this.eventSource = source;
83
+ this.isConnected = true;
84
+ this.options.onStart?.();
85
+ source.onmessage = (e) => {
86
+ if (this.isStopped)
87
+ return;
88
+ try {
89
+ const parsed = JSON.parse(e.data);
90
+ this.options.onData?.(parsed);
91
+ this.options.onYield?.(parsed);
92
+ }
93
+ catch (err) {
94
+ const error = err instanceof Error ? err : new Error("Invalid JSON");
95
+ this.options.onError?.(error);
96
+ }
97
+ };
98
+ source.onerror = (evt) => {
99
+ if (this.isStopped)
100
+ return;
101
+ const error = new Error("Event stream error: " + evt);
102
+ this.options.onError?.(error);
103
+ this.cleanup();
104
+ if (!this.scheduleReconnect()) {
105
+ this.stop();
106
+ }
107
+ };
108
+ }
109
+ catch (err) {
110
+ if (this.isStopped)
111
+ return;
112
+ const error = err instanceof Error ? err : new Error("createEventSource failed");
113
+ this.options.onError?.(error);
114
+ if (!this.scheduleReconnect()) {
115
+ this.stop();
116
+ }
117
+ }
118
+ }
119
+ }
120
+ exports.StreamManager = StreamManager;