@aerostack/sdk-node 0.8.8 → 0.8.10
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 +10 -3
- package/FUNCTIONS.md +0 -95
- package/RUNTIMES.md +0 -48
- package/examples/aiAIChat.example.ts +0 -31
- package/examples/databaseDbQuery.example.ts +0 -34
- package/examples/e2e/__tests__/e2e.test.ts +0 -118
- package/examples/e2e/package.json +0 -15
- package/examples/e2e/vitest.config.ts +0 -8
- package/examples/express-integration.ts +0 -67
- package/examples/next-api-route.ts +0 -46
- package/examples/package.json +0 -18
- package/examples/standalone-auth.ts +0 -44
- package/jsr.json +0 -27
- package/src/__tests__/realtime.test.ts +0 -430
- package/src/__tests__/sdk.test.ts +0 -412
- package/src/_generated/apis/AIApi.ts +0 -477
- package/src/_generated/apis/AuthenticationApi.ts +0 -121
- package/src/_generated/apis/CacheApi.ts +0 -551
- package/src/_generated/apis/DatabaseApi.ts +0 -138
- package/src/_generated/apis/GatewayApi.ts +0 -204
- package/src/_generated/apis/QueueApi.ts +0 -218
- package/src/_generated/apis/ServicesApi.ts +0 -74
- package/src/_generated/apis/StorageApi.ts +0 -476
- package/src/_generated/apis/index.ts +0 -10
- package/src/_generated/index.ts +0 -5
- package/src/_generated/models/AuthResponse.ts +0 -88
- package/src/_generated/models/AuthSigninRequest.ts +0 -75
- package/src/_generated/models/AuthSignupRequest.ts +0 -91
- package/src/_generated/models/CacheDeleteMany200Response.ts +0 -81
- package/src/_generated/models/CacheDeleteManyRequest.ts +0 -66
- package/src/_generated/models/CacheExpireRequest.ts +0 -75
- package/src/_generated/models/CacheFlush200Response.ts +0 -73
- package/src/_generated/models/CacheFlushRequest.ts +0 -65
- package/src/_generated/models/CacheGet200Response.ts +0 -73
- package/src/_generated/models/CacheGetMany200Response.ts +0 -72
- package/src/_generated/models/CacheGetManyEntry.ts +0 -81
- package/src/_generated/models/CacheGetManyRequest.ts +0 -66
- package/src/_generated/models/CacheGetRequest.ts +0 -66
- package/src/_generated/models/CacheIncrement200Response.ts +0 -65
- package/src/_generated/models/CacheIncrementRequest.ts +0 -90
- package/src/_generated/models/CacheKeyEntry.ts +0 -73
- package/src/_generated/models/CacheKeys200Response.ts +0 -73
- package/src/_generated/models/CacheKeysRequest.ts +0 -65
- package/src/_generated/models/CacheListRequest.ts +0 -81
- package/src/_generated/models/CacheListResult.ts +0 -88
- package/src/_generated/models/CacheSet200Response.ts +0 -65
- package/src/_generated/models/CacheSetEntry.ts +0 -83
- package/src/_generated/models/CacheSetMany200Response.ts +0 -73
- package/src/_generated/models/CacheSetManyRequest.ts +0 -73
- package/src/_generated/models/CacheSetRequest.ts +0 -83
- package/src/_generated/models/ChatCompletionRequest.ts +0 -130
- package/src/_generated/models/ChatCompletionRequestStreamOptions.ts +0 -67
- package/src/_generated/models/ChatCompletionResponse.ts +0 -128
- package/src/_generated/models/ChatCompletionResponseChoicesInner.ts +0 -100
- package/src/_generated/models/ChatMessage.ts +0 -87
- package/src/_generated/models/ConfigureRequest.ts +0 -77
- package/src/_generated/models/DbBatchRequest.ts +0 -73
- package/src/_generated/models/DbBatchRequestQueriesInner.ts +0 -74
- package/src/_generated/models/DbBatchResult.ts +0 -80
- package/src/_generated/models/DbBatchResultResultsInner.ts +0 -81
- package/src/_generated/models/DbQueryRequest.ts +0 -74
- package/src/_generated/models/DbQueryResult.ts +0 -73
- package/src/_generated/models/DeleteByTypeRequest.ts +0 -66
- package/src/_generated/models/DeleteRequest.ts +0 -66
- package/src/_generated/models/ErrorResponse.ts +0 -99
- package/src/_generated/models/GatewayBillingLog200Response.ts +0 -73
- package/src/_generated/models/GatewayBillingLogRequest.ts +0 -92
- package/src/_generated/models/GatewayGetWallet200Response.ts +0 -72
- package/src/_generated/models/IngestRequest.ts +0 -91
- package/src/_generated/models/JobRecord.ts +0 -119
- package/src/_generated/models/ListTypes200Response.ts +0 -72
- package/src/_generated/models/Query200Response.ts +0 -72
- package/src/_generated/models/QueryRequest.ts +0 -90
- package/src/_generated/models/QueueCancelJob200Response.ts +0 -73
- package/src/_generated/models/QueueEnqueue201Response.ts +0 -73
- package/src/_generated/models/QueueEnqueueRequest.ts +0 -83
- package/src/_generated/models/QueueGetJob200Response.ts +0 -80
- package/src/_generated/models/QueueGetJobRequest.ts +0 -66
- package/src/_generated/models/QueueListJobs200Response.ts +0 -88
- package/src/_generated/models/QueueListJobsRequest.ts +0 -103
- package/src/_generated/models/SearchCount200Response.ts +0 -65
- package/src/_generated/models/SearchCountRequest.ts +0 -65
- package/src/_generated/models/SearchGet200Response.ts +0 -80
- package/src/_generated/models/SearchGetRequest.ts +0 -66
- package/src/_generated/models/SearchResult.ts +0 -97
- package/src/_generated/models/SearchUpdateRequest.ts +0 -91
- package/src/_generated/models/ServicesInvoke200Response.ts +0 -73
- package/src/_generated/models/ServicesInvokeRequest.ts +0 -75
- package/src/_generated/models/StorageCopy200Response.ts +0 -73
- package/src/_generated/models/StorageCopyRequest.ts +0 -75
- package/src/_generated/models/StorageExists200Response.ts +0 -65
- package/src/_generated/models/StorageGetRequest.ts +0 -66
- package/src/_generated/models/StorageListRequest.ts +0 -81
- package/src/_generated/models/StorageListResult.ts +0 -88
- package/src/_generated/models/StorageMetadata.ts +0 -97
- package/src/_generated/models/StorageMove200Response.ts +0 -73
- package/src/_generated/models/StorageMoveRequest.ts +0 -75
- package/src/_generated/models/StorageObject.ts +0 -97
- package/src/_generated/models/StorageUpload200Response.ts +0 -65
- package/src/_generated/models/TokenUsage.ts +0 -81
- package/src/_generated/models/TokenWallet.ts +0 -73
- package/src/_generated/models/TypeStats.ts +0 -73
- package/src/_generated/models/User.ts +0 -97
- package/src/_generated/models/index.ts +0 -80
- package/src/_generated/runtime.ts +0 -431
- package/src/index.ts +0 -3
- package/src/realtime.ts +0 -439
- package/src/sdk.ts +0 -317
- package/test_sdk.ts +0 -19
- package/tsconfig.json +0 -43
|
@@ -1,430 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
2
|
-
import { NodeRealtimeClient, RealtimeSubscription } from '../realtime.js';
|
|
3
|
-
|
|
4
|
-
// ─── Mock WebSocket ───────────────────────────────────────────
|
|
5
|
-
|
|
6
|
-
class MockWebSocket {
|
|
7
|
-
static OPEN = 1;
|
|
8
|
-
static CLOSED = 3;
|
|
9
|
-
|
|
10
|
-
url: string;
|
|
11
|
-
readyState = MockWebSocket.OPEN;
|
|
12
|
-
onopen: (() => void) | null = null;
|
|
13
|
-
onmessage: ((event: any) => void) | null = null;
|
|
14
|
-
onclose: (() => void) | null = null;
|
|
15
|
-
onerror: ((err: any) => void) | null = null;
|
|
16
|
-
sent: any[] = [];
|
|
17
|
-
|
|
18
|
-
constructor(url: string) {
|
|
19
|
-
this.url = url;
|
|
20
|
-
setTimeout(() => this.onopen?.(), 0);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
send(data: string) {
|
|
24
|
-
this.sent.push(JSON.parse(data));
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
close() {
|
|
28
|
-
this.readyState = MockWebSocket.CLOSED;
|
|
29
|
-
setTimeout(() => this.onclose?.(), 0);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
beforeEach(() => {
|
|
34
|
-
vi.stubGlobal('WebSocket', MockWebSocket);
|
|
35
|
-
vi.stubGlobal('fetch', vi.fn());
|
|
36
|
-
vi.useFakeTimers();
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
afterEach(() => {
|
|
40
|
-
vi.restoreAllMocks();
|
|
41
|
-
vi.useRealTimers();
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// ─── RealtimeSubscription ─────────────────────────────────────
|
|
45
|
-
|
|
46
|
-
describe('RealtimeSubscription', () => {
|
|
47
|
-
function createSub() {
|
|
48
|
-
const client = new NodeRealtimeClient({
|
|
49
|
-
serverUrl: 'https://api.test.com/v1',
|
|
50
|
-
projectId: 'proj-1',
|
|
51
|
-
});
|
|
52
|
-
const sub = client.channel('users');
|
|
53
|
-
return { client, sub };
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
it('should register and fire callbacks', () => {
|
|
57
|
-
const { sub } = createSub();
|
|
58
|
-
const cb = vi.fn();
|
|
59
|
-
sub.on('INSERT', cb);
|
|
60
|
-
|
|
61
|
-
sub._emit({
|
|
62
|
-
type: 'db_change',
|
|
63
|
-
topic: sub.topic,
|
|
64
|
-
operation: 'INSERT',
|
|
65
|
-
data: { id: 1 },
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
expect(cb).toHaveBeenCalledOnce();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should support wildcard listener', () => {
|
|
72
|
-
const { sub } = createSub();
|
|
73
|
-
const cb = vi.fn();
|
|
74
|
-
sub.on('*', cb);
|
|
75
|
-
|
|
76
|
-
sub._emit({
|
|
77
|
-
type: 'db_change',
|
|
78
|
-
topic: sub.topic,
|
|
79
|
-
operation: 'DELETE',
|
|
80
|
-
data: { id: 1 },
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
expect(cb).toHaveBeenCalledOnce();
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('should support custom event names', () => {
|
|
87
|
-
const { sub } = createSub();
|
|
88
|
-
const cb = vi.fn();
|
|
89
|
-
sub.on('player-moved', cb);
|
|
90
|
-
|
|
91
|
-
sub._emit({
|
|
92
|
-
type: 'event',
|
|
93
|
-
topic: sub.topic,
|
|
94
|
-
event: 'player-moved',
|
|
95
|
-
data: { x: 10 },
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
expect(cb).toHaveBeenCalledOnce();
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
it('should remove callbacks with off()', () => {
|
|
102
|
-
const { sub } = createSub();
|
|
103
|
-
const cb = vi.fn();
|
|
104
|
-
sub.on('INSERT', cb);
|
|
105
|
-
sub.off('INSERT', cb);
|
|
106
|
-
|
|
107
|
-
sub._emit({
|
|
108
|
-
type: 'db_change',
|
|
109
|
-
topic: sub.topic,
|
|
110
|
-
operation: 'INSERT',
|
|
111
|
-
data: {},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
expect(cb).not.toHaveBeenCalled();
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it('should be chainable', () => {
|
|
118
|
-
const { sub } = createSub();
|
|
119
|
-
const result = sub.on('INSERT', vi.fn()).on('UPDATE', vi.fn());
|
|
120
|
-
expect(result).toBe(sub);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should track isSubscribed state', () => {
|
|
124
|
-
const { sub } = createSub();
|
|
125
|
-
expect(sub.isSubscribed).toBe(false);
|
|
126
|
-
sub.subscribe();
|
|
127
|
-
expect(sub.isSubscribed).toBe(true);
|
|
128
|
-
sub.unsubscribe();
|
|
129
|
-
expect(sub.isSubscribed).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
it('should not send duplicate subscribe', () => {
|
|
133
|
-
const { sub } = createSub();
|
|
134
|
-
sub.subscribe();
|
|
135
|
-
sub.subscribe(); // Should be no-op
|
|
136
|
-
expect(sub.isSubscribed).toBe(true);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('should clear callbacks on unsubscribe', () => {
|
|
140
|
-
const { sub } = createSub();
|
|
141
|
-
const cb = vi.fn();
|
|
142
|
-
sub.on('INSERT', cb);
|
|
143
|
-
sub.subscribe();
|
|
144
|
-
sub.unsubscribe();
|
|
145
|
-
|
|
146
|
-
sub._emit({
|
|
147
|
-
type: 'db_change',
|
|
148
|
-
topic: sub.topic,
|
|
149
|
-
operation: 'INSERT',
|
|
150
|
-
data: {},
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
expect(cb).not.toHaveBeenCalled();
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should publish events', () => {
|
|
157
|
-
const { sub } = createSub();
|
|
158
|
-
sub.publish('custom-event', { key: 'value' }, { persist: true });
|
|
159
|
-
// Should not throw
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
it('should track presence', () => {
|
|
163
|
-
const { sub } = createSub();
|
|
164
|
-
sub.track({ online: true });
|
|
165
|
-
sub.untrack();
|
|
166
|
-
// Should not throw
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('should fetch history', async () => {
|
|
170
|
-
const mockFetch = vi.fn().mockResolvedValue({
|
|
171
|
-
json: async () => ({ messages: [{ id: '1' }] }),
|
|
172
|
-
});
|
|
173
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
174
|
-
|
|
175
|
-
const { sub } = createSub();
|
|
176
|
-
const history = await sub.getHistory(10);
|
|
177
|
-
expect(history).toEqual([{ id: '1' }]);
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
// ─── NodeRealtimeClient ───────────────────────────────────────
|
|
182
|
-
|
|
183
|
-
describe('NodeRealtimeClient', () => {
|
|
184
|
-
describe('constructor', () => {
|
|
185
|
-
it('should convert https to wss URL', () => {
|
|
186
|
-
const client = new NodeRealtimeClient({
|
|
187
|
-
serverUrl: 'https://api.test.com/v1',
|
|
188
|
-
projectId: 'proj-1',
|
|
189
|
-
});
|
|
190
|
-
expect(client.status).toBe('idle');
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('should start as idle', () => {
|
|
194
|
-
const client = new NodeRealtimeClient({
|
|
195
|
-
serverUrl: 'https://api.test.com/v1',
|
|
196
|
-
projectId: 'proj-1',
|
|
197
|
-
});
|
|
198
|
-
expect(client.status).toBe('idle');
|
|
199
|
-
expect(client.connected).toBe(false);
|
|
200
|
-
});
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
describe('connect', () => {
|
|
204
|
-
it('should connect and set status to connected', async () => {
|
|
205
|
-
const client = new NodeRealtimeClient({
|
|
206
|
-
serverUrl: 'https://api.test.com/v1',
|
|
207
|
-
projectId: 'proj-1',
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
const connectPromise = client.connect();
|
|
211
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
212
|
-
await connectPromise;
|
|
213
|
-
|
|
214
|
-
expect(client.status).toBe('connected');
|
|
215
|
-
expect(client.connected).toBe(true);
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('should pass apiKey in URL query params', async () => {
|
|
219
|
-
const client = new NodeRealtimeClient({
|
|
220
|
-
serverUrl: 'https://api.test.com/v1',
|
|
221
|
-
projectId: 'proj-1',
|
|
222
|
-
apiKey: 'my-key',
|
|
223
|
-
token: 'my-token',
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
const connectPromise = client.connect();
|
|
227
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
228
|
-
await connectPromise;
|
|
229
|
-
|
|
230
|
-
expect(client.status).toBe('connected');
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
it('should not create duplicate connections', async () => {
|
|
234
|
-
const client = new NodeRealtimeClient({
|
|
235
|
-
serverUrl: 'https://api.test.com/v1',
|
|
236
|
-
projectId: 'proj-1',
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
const p1 = client.connect();
|
|
240
|
-
const p2 = client.connect();
|
|
241
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
242
|
-
await Promise.all([p1, p2]);
|
|
243
|
-
|
|
244
|
-
expect(client.status).toBe('connected');
|
|
245
|
-
});
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
describe('disconnect', () => {
|
|
249
|
-
it('should disconnect and set status', async () => {
|
|
250
|
-
const client = new NodeRealtimeClient({
|
|
251
|
-
serverUrl: 'https://api.test.com/v1',
|
|
252
|
-
projectId: 'proj-1',
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
const connectPromise = client.connect();
|
|
256
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
257
|
-
await connectPromise;
|
|
258
|
-
|
|
259
|
-
client.disconnect();
|
|
260
|
-
expect(client.status).toBe('disconnected');
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
it('should be safe when not connected', () => {
|
|
264
|
-
const client = new NodeRealtimeClient({
|
|
265
|
-
serverUrl: 'https://api.test.com/v1',
|
|
266
|
-
projectId: 'proj-1',
|
|
267
|
-
});
|
|
268
|
-
client.disconnect();
|
|
269
|
-
expect(client.status).toBe('disconnected');
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
|
|
273
|
-
describe('channel', () => {
|
|
274
|
-
it('should qualify topic with projectId', () => {
|
|
275
|
-
const client = new NodeRealtimeClient({
|
|
276
|
-
serverUrl: 'https://api.test.com/v1',
|
|
277
|
-
projectId: 'proj-1',
|
|
278
|
-
});
|
|
279
|
-
const sub = client.channel('users');
|
|
280
|
-
expect(sub.topic).toBe('table/users/proj-1');
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
it('should append projectId to topic with path', () => {
|
|
284
|
-
const client = new NodeRealtimeClient({
|
|
285
|
-
serverUrl: 'https://api.test.com/v1',
|
|
286
|
-
projectId: 'proj-1',
|
|
287
|
-
});
|
|
288
|
-
const sub = client.channel('table/orders');
|
|
289
|
-
expect(sub.topic).toBe('table/orders/proj-1');
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should not double-qualify topics', () => {
|
|
293
|
-
const client = new NodeRealtimeClient({
|
|
294
|
-
serverUrl: 'https://api.test.com/v1',
|
|
295
|
-
projectId: 'proj-1',
|
|
296
|
-
});
|
|
297
|
-
const sub = client.channel('table/users/proj-1');
|
|
298
|
-
expect(sub.topic).toBe('table/users/proj-1');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should reuse subscriptions for same topic', () => {
|
|
302
|
-
const client = new NodeRealtimeClient({
|
|
303
|
-
serverUrl: 'https://api.test.com/v1',
|
|
304
|
-
projectId: 'proj-1',
|
|
305
|
-
});
|
|
306
|
-
const sub1 = client.channel('users');
|
|
307
|
-
const sub2 = client.channel('users');
|
|
308
|
-
expect(sub1).toBe(sub2);
|
|
309
|
-
});
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
describe('status listeners', () => {
|
|
313
|
-
it('should notify status change listeners', async () => {
|
|
314
|
-
const client = new NodeRealtimeClient({
|
|
315
|
-
serverUrl: 'https://api.test.com/v1',
|
|
316
|
-
projectId: 'proj-1',
|
|
317
|
-
});
|
|
318
|
-
const statuses: string[] = [];
|
|
319
|
-
client.onStatusChange((s: string) => statuses.push(s));
|
|
320
|
-
|
|
321
|
-
const connectPromise = client.connect();
|
|
322
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
323
|
-
await connectPromise;
|
|
324
|
-
|
|
325
|
-
expect(statuses).toContain('connecting');
|
|
326
|
-
expect(statuses).toContain('connected');
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
it('should allow unsubscribing', () => {
|
|
330
|
-
const client = new NodeRealtimeClient({
|
|
331
|
-
serverUrl: 'https://api.test.com/v1',
|
|
332
|
-
projectId: 'proj-1',
|
|
333
|
-
});
|
|
334
|
-
const cb = vi.fn();
|
|
335
|
-
const unsub = client.onStatusChange(cb);
|
|
336
|
-
unsub();
|
|
337
|
-
client.disconnect();
|
|
338
|
-
expect(cb).not.toHaveBeenCalled();
|
|
339
|
-
});
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
describe('setToken', () => {
|
|
343
|
-
it('should send auth message', async () => {
|
|
344
|
-
const client = new NodeRealtimeClient({
|
|
345
|
-
serverUrl: 'https://api.test.com/v1',
|
|
346
|
-
projectId: 'proj-1',
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
const connectPromise = client.connect();
|
|
350
|
-
await vi.advanceTimersByTimeAsync(10);
|
|
351
|
-
await connectPromise;
|
|
352
|
-
|
|
353
|
-
client.setToken('new-token');
|
|
354
|
-
});
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
describe('sendChat', () => {
|
|
358
|
-
it('should send chat message', () => {
|
|
359
|
-
const client = new NodeRealtimeClient({
|
|
360
|
-
serverUrl: 'https://api.test.com/v1',
|
|
361
|
-
projectId: 'proj-1',
|
|
362
|
-
});
|
|
363
|
-
client.sendChat('room-1', 'Hello!');
|
|
364
|
-
// Message queued since not connected
|
|
365
|
-
});
|
|
366
|
-
});
|
|
367
|
-
|
|
368
|
-
describe('_generateId', () => {
|
|
369
|
-
it('should return unique strings', () => {
|
|
370
|
-
const client = new NodeRealtimeClient({
|
|
371
|
-
serverUrl: 'https://api.test.com/v1',
|
|
372
|
-
projectId: 'proj-1',
|
|
373
|
-
});
|
|
374
|
-
const ids = new Set(Array.from({ length: 50 }, () => client._generateId()));
|
|
375
|
-
expect(ids.size).toBe(50);
|
|
376
|
-
});
|
|
377
|
-
});
|
|
378
|
-
|
|
379
|
-
describe('_fetchHistory', () => {
|
|
380
|
-
it('should fetch from REST API with auth headers', async () => {
|
|
381
|
-
const mockFetch = vi.fn().mockResolvedValue({
|
|
382
|
-
json: async () => ({ messages: [{ id: '1' }] }),
|
|
383
|
-
});
|
|
384
|
-
vi.stubGlobal('fetch', mockFetch);
|
|
385
|
-
|
|
386
|
-
const client = new NodeRealtimeClient({
|
|
387
|
-
serverUrl: 'https://api.test.com/v1',
|
|
388
|
-
projectId: 'proj-1',
|
|
389
|
-
apiKey: 'my-key',
|
|
390
|
-
token: 'my-token',
|
|
391
|
-
});
|
|
392
|
-
|
|
393
|
-
const result = await client._fetchHistory('room/test', 25, 9999);
|
|
394
|
-
expect(result).toEqual([{ id: '1' }]);
|
|
395
|
-
|
|
396
|
-
const url = new URL(mockFetch.mock.calls[0][0]);
|
|
397
|
-
expect(url.pathname).toBe('/api/v1/public/realtime/history');
|
|
398
|
-
expect(url.searchParams.get('room')).toBe('room/test');
|
|
399
|
-
expect(url.searchParams.get('limit')).toBe('25');
|
|
400
|
-
expect(url.searchParams.get('before')).toBe('9999');
|
|
401
|
-
|
|
402
|
-
const headers = mockFetch.mock.calls[0][1].headers;
|
|
403
|
-
expect(headers['X-Aerostack-Key']).toBe('my-key');
|
|
404
|
-
expect(headers['Authorization']).toBe('Bearer my-token');
|
|
405
|
-
});
|
|
406
|
-
});
|
|
407
|
-
|
|
408
|
-
describe('maxReconnectAttempts', () => {
|
|
409
|
-
it('should accept maxReconnectAttempts option', () => {
|
|
410
|
-
const client = new NodeRealtimeClient({
|
|
411
|
-
serverUrl: 'https://api.test.com/v1',
|
|
412
|
-
projectId: 'proj-1',
|
|
413
|
-
maxReconnectAttempts: 3,
|
|
414
|
-
});
|
|
415
|
-
expect(client.status).toBe('idle');
|
|
416
|
-
});
|
|
417
|
-
|
|
418
|
-
it('should allow onMaxRetriesExceeded listener', () => {
|
|
419
|
-
const client = new NodeRealtimeClient({
|
|
420
|
-
serverUrl: 'https://api.test.com/v1',
|
|
421
|
-
projectId: 'proj-1',
|
|
422
|
-
maxReconnectAttempts: 0,
|
|
423
|
-
});
|
|
424
|
-
const cb = vi.fn();
|
|
425
|
-
const unsub = client.onMaxRetriesExceeded(cb);
|
|
426
|
-
expect(typeof unsub).toBe('function');
|
|
427
|
-
unsub();
|
|
428
|
-
});
|
|
429
|
-
});
|
|
430
|
-
});
|