@inferencesh/sdk 0.1.0 → 0.1.3

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,168 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const stream_1 = require("./stream");
4
+ describe('StreamManager', () => {
5
+ let mockEventSource;
6
+ beforeEach(() => {
7
+ mockEventSource = {
8
+ onmessage: null,
9
+ onerror: null,
10
+ close: jest.fn(),
11
+ };
12
+ });
13
+ describe('constructor', () => {
14
+ it('should create instance with default options', () => {
15
+ const manager = new stream_1.StreamManager({
16
+ createEventSource: async () => mockEventSource,
17
+ });
18
+ expect(manager).toBeDefined();
19
+ });
20
+ });
21
+ describe('connect', () => {
22
+ it('should call createEventSource', async () => {
23
+ const createEventSource = jest
24
+ .fn()
25
+ .mockResolvedValue(mockEventSource);
26
+ const manager = new stream_1.StreamManager({ createEventSource });
27
+ await manager.connect();
28
+ expect(createEventSource).toHaveBeenCalled();
29
+ });
30
+ it('should call onStart when connected', async () => {
31
+ const onStart = jest.fn();
32
+ const manager = new stream_1.StreamManager({
33
+ createEventSource: async () => mockEventSource,
34
+ onStart,
35
+ });
36
+ await manager.connect();
37
+ expect(onStart).toHaveBeenCalled();
38
+ });
39
+ it('should parse JSON messages and call onData', async () => {
40
+ const onData = jest.fn();
41
+ const manager = new stream_1.StreamManager({
42
+ createEventSource: async () => mockEventSource,
43
+ onData,
44
+ });
45
+ await manager.connect();
46
+ // Simulate receiving a message
47
+ const testData = { status: 'running', id: 'task-123' };
48
+ mockEventSource.onmessage?.({ data: JSON.stringify(testData) });
49
+ expect(onData).toHaveBeenCalledWith(testData);
50
+ });
51
+ it('should extract data from partial data wrapper and call onData', async () => {
52
+ const onData = jest.fn();
53
+ const manager = new stream_1.StreamManager({
54
+ createEventSource: async () => mockEventSource,
55
+ onData,
56
+ });
57
+ await manager.connect();
58
+ // Simulate receiving a partial data wrapper from server
59
+ const innerData = { status: 7, id: 'task-123', logs: ['log1'] };
60
+ const partialWrapper = { data: innerData, fields: ['status', 'logs'] };
61
+ mockEventSource.onmessage?.({ data: JSON.stringify(partialWrapper) });
62
+ // onData should receive the extracted inner data, not the wrapper
63
+ expect(onData).toHaveBeenCalledWith(innerData);
64
+ });
65
+ it('should call onPartialData with data and fields for partial updates', async () => {
66
+ const onData = jest.fn();
67
+ const onPartialData = jest.fn();
68
+ const manager = new stream_1.StreamManager({
69
+ createEventSource: async () => mockEventSource,
70
+ onData,
71
+ onPartialData,
72
+ });
73
+ await manager.connect();
74
+ // Simulate receiving a partial data wrapper
75
+ const innerData = { status: 7, id: 'task-123' };
76
+ const fields = ['status'];
77
+ const partialWrapper = { data: innerData, fields };
78
+ mockEventSource.onmessage?.({ data: JSON.stringify(partialWrapper) });
79
+ expect(onPartialData).toHaveBeenCalledWith(innerData, fields);
80
+ expect(onData).toHaveBeenCalledWith(innerData);
81
+ });
82
+ it('should not call onPartialData for non-partial data', async () => {
83
+ const onData = jest.fn();
84
+ const onPartialData = jest.fn();
85
+ const manager = new stream_1.StreamManager({
86
+ createEventSource: async () => mockEventSource,
87
+ onData,
88
+ onPartialData,
89
+ });
90
+ await manager.connect();
91
+ // Regular data without partial wrapper
92
+ const regularData = { status: 9, id: 'task-123' };
93
+ mockEventSource.onmessage?.({ data: JSON.stringify(regularData) });
94
+ expect(onPartialData).not.toHaveBeenCalled();
95
+ expect(onData).toHaveBeenCalledWith(regularData);
96
+ });
97
+ it('should call onError for invalid JSON', async () => {
98
+ const onError = jest.fn();
99
+ const manager = new stream_1.StreamManager({
100
+ createEventSource: async () => mockEventSource,
101
+ onError,
102
+ });
103
+ await manager.connect();
104
+ mockEventSource.onmessage?.({ data: 'invalid json' });
105
+ expect(onError).toHaveBeenCalled();
106
+ });
107
+ });
108
+ describe('stop', () => {
109
+ it('should close the event source', async () => {
110
+ const onStop = jest.fn();
111
+ const manager = new stream_1.StreamManager({
112
+ createEventSource: async () => mockEventSource,
113
+ onStop,
114
+ });
115
+ await manager.connect();
116
+ manager.stop();
117
+ expect(mockEventSource.close).toHaveBeenCalled();
118
+ expect(onStop).toHaveBeenCalled();
119
+ });
120
+ it('should not process messages after stop', async () => {
121
+ const onData = jest.fn();
122
+ const manager = new stream_1.StreamManager({
123
+ createEventSource: async () => mockEventSource,
124
+ onData,
125
+ });
126
+ await manager.connect();
127
+ manager.stop();
128
+ mockEventSource.onmessage?.({ data: '{"status":"running"}' });
129
+ expect(onData).not.toHaveBeenCalled();
130
+ });
131
+ });
132
+ describe('reconnection', () => {
133
+ it('should attempt reconnection on error when autoReconnect is true', async () => {
134
+ jest.useFakeTimers();
135
+ const createEventSource = jest
136
+ .fn()
137
+ .mockResolvedValue(mockEventSource);
138
+ const manager = new stream_1.StreamManager({
139
+ createEventSource,
140
+ autoReconnect: true,
141
+ reconnectDelayMs: 100,
142
+ });
143
+ await manager.connect();
144
+ expect(createEventSource).toHaveBeenCalledTimes(1);
145
+ // Simulate error
146
+ mockEventSource.onerror?.({});
147
+ // Fast-forward past reconnect delay
148
+ jest.advanceTimersByTime(100);
149
+ await Promise.resolve(); // Flush promises
150
+ expect(createEventSource).toHaveBeenCalledTimes(2);
151
+ jest.useRealTimers();
152
+ });
153
+ it('should not reconnect when autoReconnect is false', async () => {
154
+ const createEventSource = jest
155
+ .fn()
156
+ .mockResolvedValue(mockEventSource);
157
+ const manager = new stream_1.StreamManager({
158
+ createEventSource,
159
+ autoReconnect: false,
160
+ });
161
+ await manager.connect();
162
+ mockEventSource.onerror?.({});
163
+ // Wait a bit
164
+ await new Promise((r) => setTimeout(r, 50));
165
+ expect(createEventSource).toHaveBeenCalledTimes(1);
166
+ });
167
+ });
168
+ });