@logdash/node 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.
Files changed (53) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.editorconfig +13 -0
  4. package/.github/workflows/build-and-publish.yml +39 -0
  5. package/.github/workflows/ci.yml +36 -0
  6. package/.prettierignore +12 -0
  7. package/.prettierrc +12 -0
  8. package/CHANGELOG.md +146 -0
  9. package/LICENSE.md +21 -0
  10. package/README.md +81 -0
  11. package/dist/Logdash.d.ts +36 -0
  12. package/dist/Logdash.d.ts.map +1 -0
  13. package/dist/Logdash.js +145 -0
  14. package/dist/Logdash.js.map +1 -0
  15. package/dist/__tests__/HttpTransport.test.d.ts +2 -0
  16. package/dist/__tests__/HttpTransport.test.d.ts.map +1 -0
  17. package/dist/__tests__/HttpTransport.test.js +148 -0
  18. package/dist/__tests__/HttpTransport.test.js.map +1 -0
  19. package/dist/__tests__/Logdash.test.d.ts +2 -0
  20. package/dist/__tests__/Logdash.test.d.ts.map +1 -0
  21. package/dist/__tests__/Logdash.test.js +131 -0
  22. package/dist/__tests__/Logdash.test.js.map +1 -0
  23. package/dist/__tests__/RequestQueue.test.d.ts +2 -0
  24. package/dist/__tests__/RequestQueue.test.d.ts.map +1 -0
  25. package/dist/__tests__/RequestQueue.test.js +129 -0
  26. package/dist/__tests__/RequestQueue.test.js.map +1 -0
  27. package/dist/index.d.ts +4 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +3 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/logger/internalLogger.d.ts +7 -0
  32. package/dist/logger/internalLogger.d.ts.map +1 -0
  33. package/dist/logger/internalLogger.js +17 -0
  34. package/dist/logger/internalLogger.js.map +1 -0
  35. package/dist/queue/RequestQueue.d.ts +24 -0
  36. package/dist/queue/RequestQueue.d.ts.map +1 -0
  37. package/dist/queue/RequestQueue.js +87 -0
  38. package/dist/queue/RequestQueue.js.map +1 -0
  39. package/dist/transport/HttpTransport.d.ts +28 -0
  40. package/dist/transport/HttpTransport.d.ts.map +1 -0
  41. package/dist/transport/HttpTransport.js +37 -0
  42. package/dist/transport/HttpTransport.js.map +1 -0
  43. package/dist/types/LogLevel.d.ts +10 -0
  44. package/dist/types/LogLevel.d.ts.map +1 -0
  45. package/dist/types/LogLevel.js +11 -0
  46. package/dist/types/LogLevel.js.map +1 -0
  47. package/docs/delta.png +0 -0
  48. package/docs/logs.png +0 -0
  49. package/package.json +49 -0
  50. package/test.ts +32 -0
  51. package/tsconfig.json +20 -0
  52. package/tsconfig.lib.json +29 -0
  53. package/vite.config.ts +8 -0
@@ -0,0 +1,148 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { HttpTransport } from '../transport/HttpTransport.js';
3
+ describe('HttpTransport', () => {
4
+ let mockFetch;
5
+ beforeEach(() => {
6
+ mockFetch = vi.fn().mockResolvedValue({
7
+ ok: true,
8
+ status: 200,
9
+ statusText: 'OK',
10
+ });
11
+ vi.stubGlobal('fetch', mockFetch);
12
+ });
13
+ afterEach(() => {
14
+ vi.unstubAllGlobals();
15
+ vi.restoreAllMocks();
16
+ });
17
+ describe('constructor', () => {
18
+ it('creates instance with required options', () => {
19
+ const transport = new HttpTransport({
20
+ host: 'https://api.test.com',
21
+ apiKey: 'test-key',
22
+ });
23
+ expect(transport).toBeInstanceOf(HttpTransport);
24
+ });
25
+ });
26
+ describe('sendLogs', () => {
27
+ it('sends logs to /logs/batch endpoint', async () => {
28
+ const transport = new HttpTransport({
29
+ host: 'https://api.test.com',
30
+ apiKey: 'test-key',
31
+ });
32
+ await transport.sendLogs([
33
+ {
34
+ message: 'test',
35
+ level: 'info',
36
+ createdAt: '2024-01-01T00:00:00.000Z',
37
+ sequenceNumber: 0,
38
+ },
39
+ ]);
40
+ expect(mockFetch).toHaveBeenCalledWith('https://api.test.com/logs/batch', expect.objectContaining({
41
+ method: 'POST',
42
+ headers: {
43
+ 'Content-Type': 'application/json',
44
+ 'project-api-key': 'test-key',
45
+ },
46
+ }));
47
+ });
48
+ it('wraps logs in batch format', async () => {
49
+ const transport = new HttpTransport({
50
+ host: 'https://api.test.com',
51
+ apiKey: 'test-key',
52
+ });
53
+ await transport.sendLogs([
54
+ {
55
+ message: 'test message',
56
+ level: 'error',
57
+ createdAt: '2024-01-01T00:00:00.000Z',
58
+ sequenceNumber: 42,
59
+ namespace: 'auth',
60
+ },
61
+ ]);
62
+ expect(mockFetch).toHaveBeenCalledTimes(1);
63
+ const call = mockFetch.mock.calls[0];
64
+ const body = JSON.parse(call[1].body);
65
+ expect(body).toEqual({
66
+ logs: [
67
+ {
68
+ message: 'test message',
69
+ level: 'error',
70
+ createdAt: '2024-01-01T00:00:00.000Z',
71
+ sequenceNumber: 42,
72
+ namespace: 'auth',
73
+ },
74
+ ],
75
+ });
76
+ });
77
+ });
78
+ describe('sendMetrics', () => {
79
+ it('sends metrics to /metrics endpoint', async () => {
80
+ const transport = new HttpTransport({
81
+ host: 'https://api.test.com',
82
+ apiKey: 'test-key',
83
+ });
84
+ await transport.sendMetrics([
85
+ {
86
+ name: 'users',
87
+ value: 100,
88
+ operation: 'set',
89
+ },
90
+ ]);
91
+ expect(mockFetch).toHaveBeenCalledWith('https://api.test.com/metrics', expect.objectContaining({
92
+ method: 'PUT',
93
+ headers: {
94
+ 'Content-Type': 'application/json',
95
+ 'project-api-key': 'test-key',
96
+ },
97
+ }));
98
+ });
99
+ it('sends each metric individually', async () => {
100
+ const transport = new HttpTransport({
101
+ host: 'https://api.test.com',
102
+ apiKey: 'test-key',
103
+ });
104
+ await transport.sendMetrics([
105
+ { name: 'users', value: 100, operation: 'set' },
106
+ { name: 'requests', value: 1, operation: 'change' },
107
+ ]);
108
+ expect(mockFetch).toHaveBeenCalledTimes(2);
109
+ });
110
+ });
111
+ describe('error handling', () => {
112
+ it('throws on non-ok response', async () => {
113
+ mockFetch.mockResolvedValueOnce({
114
+ ok: false,
115
+ status: 500,
116
+ statusText: 'Internal Server Error',
117
+ });
118
+ const transport = new HttpTransport({
119
+ host: 'https://api.test.com',
120
+ apiKey: 'test-key',
121
+ });
122
+ await expect(transport.sendLogs([
123
+ {
124
+ message: 'test',
125
+ level: 'info',
126
+ createdAt: '2024-01-01T00:00:00.000Z',
127
+ sequenceNumber: 0,
128
+ },
129
+ ])).rejects.toThrow('HTTP 500: Internal Server Error');
130
+ });
131
+ it('throws on network error', async () => {
132
+ mockFetch.mockRejectedValueOnce(new Error('Network error'));
133
+ const transport = new HttpTransport({
134
+ host: 'https://api.test.com',
135
+ apiKey: 'test-key',
136
+ });
137
+ await expect(transport.sendLogs([
138
+ {
139
+ message: 'test',
140
+ level: 'info',
141
+ createdAt: '2024-01-01T00:00:00.000Z',
142
+ sequenceNumber: 0,
143
+ },
144
+ ])).rejects.toThrow('Network error');
145
+ });
146
+ });
147
+ });
148
+ //# sourceMappingURL=HttpTransport.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpTransport.test.js","sourceRoot":"","sources":["../../src/__tests__/HttpTransport.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=Logdash.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logdash.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/Logdash.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,131 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { Logdash } from '../Logdash.js';
3
+ describe('Logdash', () => {
4
+ beforeEach(() => {
5
+ vi.spyOn(console, 'log').mockImplementation(() => { });
6
+ });
7
+ afterEach(() => {
8
+ vi.restoreAllMocks();
9
+ });
10
+ describe('constructor', () => {
11
+ it('creates instance without options', () => {
12
+ const logdash = new Logdash();
13
+ expect(logdash).toBeInstanceOf(Logdash);
14
+ logdash.destroy();
15
+ });
16
+ it('creates instance with apiKey', () => {
17
+ const logdash = new Logdash('test-key');
18
+ expect(logdash).toBeInstanceOf(Logdash);
19
+ logdash.destroy();
20
+ });
21
+ it('creates instance with custom host', () => {
22
+ const logdash = new Logdash('test-key', {
23
+ host: 'https://custom.api.com',
24
+ });
25
+ expect(logdash).toBeInstanceOf(Logdash);
26
+ logdash.destroy();
27
+ });
28
+ });
29
+ describe('logging methods', () => {
30
+ let logdash;
31
+ beforeEach(() => {
32
+ logdash = new Logdash();
33
+ });
34
+ afterEach(() => {
35
+ logdash.destroy();
36
+ });
37
+ it('logs error messages', () => {
38
+ logdash.error('test error');
39
+ expect(console.log).toHaveBeenCalled();
40
+ });
41
+ it('logs warn messages', () => {
42
+ logdash.warn('test warning');
43
+ expect(console.log).toHaveBeenCalled();
44
+ });
45
+ it('logs info messages', () => {
46
+ logdash.info('test info');
47
+ expect(console.log).toHaveBeenCalled();
48
+ });
49
+ it('logs http messages', () => {
50
+ logdash.http('test http');
51
+ expect(console.log).toHaveBeenCalled();
52
+ });
53
+ it('logs verbose messages', () => {
54
+ logdash.verbose('test verbose');
55
+ expect(console.log).toHaveBeenCalled();
56
+ });
57
+ it('logs debug messages', () => {
58
+ logdash.debug('test debug');
59
+ expect(console.log).toHaveBeenCalled();
60
+ });
61
+ it('logs silly messages', () => {
62
+ logdash.silly('test silly');
63
+ expect(console.log).toHaveBeenCalled();
64
+ });
65
+ it('formats objects as JSON', () => {
66
+ logdash.info('data:', { key: 'value' });
67
+ expect(console.log).toHaveBeenCalledWith(expect.stringContaining('{"key":"value"}'));
68
+ });
69
+ it('handles multiple arguments', () => {
70
+ logdash.info('first', 'second', 123);
71
+ expect(console.log).toHaveBeenCalledWith(expect.stringContaining('first second 123'));
72
+ });
73
+ });
74
+ describe('withNamespace', () => {
75
+ let logdash;
76
+ beforeEach(() => {
77
+ logdash = new Logdash();
78
+ });
79
+ afterEach(() => {
80
+ logdash.destroy();
81
+ });
82
+ it('returns a new Logdash instance', () => {
83
+ const namespaced = logdash.withNamespace('auth');
84
+ expect(namespaced).toBeInstanceOf(Logdash);
85
+ });
86
+ it('includes namespace in log output', () => {
87
+ const namespaced = logdash.withNamespace('auth');
88
+ namespaced.info('test message');
89
+ expect(console.log).toHaveBeenCalledWith(expect.stringContaining('[auth]'));
90
+ });
91
+ it('allows creating multiple namespaces', () => {
92
+ const auth = logdash.withNamespace('auth');
93
+ const db = logdash.withNamespace('db');
94
+ auth.info('auth message');
95
+ db.info('db message');
96
+ expect(console.log).toHaveBeenCalledWith(expect.stringContaining('[auth]'));
97
+ expect(console.log).toHaveBeenCalledWith(expect.stringContaining('[db]'));
98
+ });
99
+ });
100
+ describe('metrics', () => {
101
+ let logdash;
102
+ beforeEach(() => {
103
+ logdash = new Logdash();
104
+ });
105
+ afterEach(() => {
106
+ logdash.destroy();
107
+ });
108
+ it('queues setMetric calls', () => {
109
+ // This shouldn't throw
110
+ expect(() => logdash.setMetric('users', 100)).not.toThrow();
111
+ });
112
+ it('queues mutateMetric calls', () => {
113
+ // This shouldn't throw
114
+ expect(() => logdash.mutateMetric('requests', 1)).not.toThrow();
115
+ });
116
+ });
117
+ describe('flush', () => {
118
+ it('resolves when queue is empty', async () => {
119
+ const logdash = new Logdash();
120
+ await expect(logdash.flush()).resolves.toBeUndefined();
121
+ logdash.destroy();
122
+ });
123
+ it('waits for pending items', async () => {
124
+ const logdash = new Logdash();
125
+ logdash.info('test message');
126
+ await expect(logdash.flush()).resolves.toBeUndefined();
127
+ logdash.destroy();
128
+ });
129
+ });
130
+ });
131
+ //# sourceMappingURL=Logdash.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Logdash.test.js","sourceRoot":"","sources":["../../src/__tests__/Logdash.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=RequestQueue.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestQueue.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/RequestQueue.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,129 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { RequestQueue } from '../queue/RequestQueue.js';
3
+ describe('RequestQueue', () => {
4
+ beforeEach(() => {
5
+ vi.spyOn(console, 'log').mockImplementation(() => { });
6
+ });
7
+ afterEach(() => {
8
+ vi.restoreAllMocks();
9
+ });
10
+ describe('add', () => {
11
+ it('adds items to the queue', () => {
12
+ const sendFn = vi.fn().mockResolvedValue(undefined);
13
+ const queue = new RequestQueue(sendFn);
14
+ queue.add({ id: 1 });
15
+ queue.add({ id: 2 });
16
+ queue.destroy();
17
+ expect(sendFn).not.toHaveBeenCalled(); // Not flushed yet
18
+ });
19
+ it('ignores items after destroy', () => {
20
+ const sendFn = vi.fn().mockResolvedValue(undefined);
21
+ const queue = new RequestQueue(sendFn);
22
+ queue.destroy();
23
+ queue.add({ id: 1 });
24
+ expect(sendFn).not.toHaveBeenCalled();
25
+ });
26
+ });
27
+ describe('batching', () => {
28
+ it('flushes when batch size is reached', async () => {
29
+ const sendFn = vi.fn().mockResolvedValue(undefined);
30
+ const queue = new RequestQueue(sendFn, { batchSize: 3 });
31
+ queue.add({ id: 1 });
32
+ queue.add({ id: 2 });
33
+ expect(sendFn).not.toHaveBeenCalled();
34
+ queue.add({ id: 3 }); // Triggers flush
35
+ // Wait for the async operation
36
+ await new Promise((resolve) => setTimeout(resolve, 10));
37
+ expect(sendFn).toHaveBeenCalledWith([
38
+ { id: 1 },
39
+ { id: 2 },
40
+ { id: 3 },
41
+ ]);
42
+ queue.destroy();
43
+ });
44
+ it('flushes on interval', async () => {
45
+ const sendFn = vi.fn().mockResolvedValue(undefined);
46
+ const queue = new RequestQueue(sendFn, {
47
+ batchSize: 100,
48
+ flushIntervalMs: 50,
49
+ });
50
+ queue.add({ id: 1 });
51
+ queue.add({ id: 2 });
52
+ // Wait for interval
53
+ await new Promise((resolve) => setTimeout(resolve, 100));
54
+ expect(sendFn).toHaveBeenCalledWith([{ id: 1 }, { id: 2 }]);
55
+ queue.destroy();
56
+ });
57
+ });
58
+ describe('retry', () => {
59
+ it('retries failed requests', async () => {
60
+ const sendFn = vi
61
+ .fn()
62
+ .mockRejectedValueOnce(new Error('Network error'))
63
+ .mockResolvedValueOnce(undefined);
64
+ const queue = new RequestQueue(sendFn, {
65
+ batchSize: 1,
66
+ maxRetries: 3,
67
+ baseRetryDelayMs: 10,
68
+ });
69
+ queue.add({ id: 1 });
70
+ // Wait for retries
71
+ await new Promise((resolve) => setTimeout(resolve, 100));
72
+ expect(sendFn).toHaveBeenCalledTimes(2);
73
+ queue.destroy();
74
+ });
75
+ it('stops after max retries', async () => {
76
+ const sendFn = vi
77
+ .fn()
78
+ .mockRejectedValue(new Error('Network error'));
79
+ const queue = new RequestQueue(sendFn, {
80
+ batchSize: 1,
81
+ maxRetries: 3,
82
+ baseRetryDelayMs: 10,
83
+ });
84
+ queue.add({ id: 1 });
85
+ // Wait for all retries (10 + 20 + 40 = 70ms base, add buffer)
86
+ await new Promise((resolve) => setTimeout(resolve, 200));
87
+ expect(sendFn).toHaveBeenCalledTimes(3);
88
+ queue.destroy();
89
+ });
90
+ });
91
+ describe('flush', () => {
92
+ it('sends remaining items immediately', async () => {
93
+ const sendFn = vi.fn().mockResolvedValue(undefined);
94
+ const queue = new RequestQueue(sendFn, { batchSize: 100 });
95
+ queue.add({ id: 1 });
96
+ queue.add({ id: 2 });
97
+ await queue.flush();
98
+ expect(sendFn).toHaveBeenCalledWith([{ id: 1 }, { id: 2 }]);
99
+ queue.destroy();
100
+ });
101
+ it('waits for in-flight requests', async () => {
102
+ let resolveRequest;
103
+ const sendFn = vi.fn().mockImplementation(() => new Promise((resolve) => {
104
+ resolveRequest = resolve;
105
+ }));
106
+ const queue = new RequestQueue(sendFn, { batchSize: 1 });
107
+ queue.add({ id: 1 });
108
+ // Start flush but don't await yet
109
+ const flushPromise = queue.flush();
110
+ // Resolve the pending request
111
+ await new Promise((resolve) => setTimeout(resolve, 10));
112
+ resolveRequest();
113
+ await flushPromise;
114
+ expect(sendFn).toHaveBeenCalled();
115
+ queue.destroy();
116
+ });
117
+ });
118
+ describe('destroy', () => {
119
+ it('stops the flush timer', async () => {
120
+ const sendFn = vi.fn().mockResolvedValue(undefined);
121
+ const queue = new RequestQueue(sendFn, { flushIntervalMs: 50 });
122
+ queue.add({ id: 1 });
123
+ queue.destroy();
124
+ await new Promise((resolve) => setTimeout(resolve, 100));
125
+ expect(sendFn).not.toHaveBeenCalled();
126
+ });
127
+ });
128
+ });
129
+ //# sourceMappingURL=RequestQueue.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestQueue.test.js","sourceRoot":"","sources":["../../src/__tests__/RequestQueue.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { Logdash } from './Logdash.js';
2
+ export type { LogdashOptions } from './Logdash.js';
3
+ export { LogLevel } from './types/LogLevel.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { Logdash } from './Logdash.js';
2
+ export { LogLevel } from './types/LogLevel.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,7 @@
1
+ export declare const internalLogger: {
2
+ error: (...args: unknown[]) => void;
3
+ warn: (...args: unknown[]) => void;
4
+ info: (...args: unknown[]) => void;
5
+ verbose: (...args: unknown[]) => void;
6
+ };
7
+ //# sourceMappingURL=internalLogger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internalLogger.d.ts","sourceRoot":"","sources":["../../src/logger/internalLogger.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,cAAc;qBACT,OAAO,EAAE;oBAGV,OAAO,EAAE;oBAGT,OAAO,EAAE;uBAGN,OAAO,EAAE;CAG5B,CAAC"}
@@ -0,0 +1,17 @@
1
+ import chalk from 'chalk';
2
+ const PREFIX = chalk.rgb(230, 0, 118)('[Logdash]');
3
+ export const internalLogger = {
4
+ error: (...args) => {
5
+ console.log(PREFIX, chalk.red('ERROR'), ...args);
6
+ },
7
+ warn: (...args) => {
8
+ console.log(PREFIX, chalk.yellow('WARN'), ...args);
9
+ },
10
+ info: (...args) => {
11
+ console.log(PREFIX, ...args);
12
+ },
13
+ verbose: (...args) => {
14
+ console.log(PREFIX, chalk.gray(...args));
15
+ },
16
+ };
17
+ //# sourceMappingURL=internalLogger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internalLogger.js","sourceRoot":"","sources":["../../src/logger/internalLogger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC;AAEnD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC7B,KAAK,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE;QAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;IAC1C,CAAC;CACD,CAAC"}
@@ -0,0 +1,24 @@
1
+ export type SendFunction<T> = (items: T[]) => Promise<void>;
2
+ export interface RequestQueueOptions {
3
+ batchSize?: number;
4
+ flushIntervalMs?: number;
5
+ maxRetries?: number;
6
+ baseRetryDelayMs?: number;
7
+ }
8
+ export declare class RequestQueue<T> {
9
+ private readonly sendFn;
10
+ private queue;
11
+ private inFlightPromises;
12
+ private flushTimer;
13
+ private destroyed;
14
+ private readonly options;
15
+ constructor(sendFn: SendFunction<T>, options?: RequestQueueOptions);
16
+ add(item: T): void;
17
+ flush(): Promise<void>;
18
+ destroy(): void;
19
+ private scheduleFlush;
20
+ private flushBatch;
21
+ private sendWithRetry;
22
+ private sleep;
23
+ }
24
+ //# sourceMappingURL=RequestQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestQueue.d.ts","sourceRoot":"","sources":["../../src/queue/RequestQueue.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE5D,MAAM,WAAW,mBAAmB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B;AASD,qBAAa,YAAY,CAAC,CAAC;IAQzB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPxB,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAgC;gBAGtC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACxC,OAAO,CAAC,EAAE,mBAAmB;IAM9B,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IAYZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAU5B,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,UAAU;YAcJ,aAAa;IA0B3B,OAAO,CAAC,KAAK;CAGb"}
@@ -0,0 +1,87 @@
1
+ import { internalLogger } from '../logger/internalLogger.js';
2
+ const DEFAULT_OPTIONS = {
3
+ batchSize: 25,
4
+ flushIntervalMs: 1000,
5
+ maxRetries: 3,
6
+ baseRetryDelayMs: 1000,
7
+ };
8
+ export class RequestQueue {
9
+ constructor(sendFn, options) {
10
+ this.sendFn = sendFn;
11
+ this.queue = [];
12
+ this.inFlightPromises = new Set();
13
+ this.flushTimer = null;
14
+ this.destroyed = false;
15
+ this.options = { ...DEFAULT_OPTIONS, ...options };
16
+ this.scheduleFlush();
17
+ }
18
+ add(item) {
19
+ if (this.destroyed) {
20
+ return;
21
+ }
22
+ this.queue.push(item);
23
+ if (this.queue.length >= this.options.batchSize) {
24
+ this.flushBatch();
25
+ }
26
+ }
27
+ async flush() {
28
+ // Flush any remaining items in the queue
29
+ if (this.queue.length > 0) {
30
+ this.flushBatch();
31
+ }
32
+ // Wait for all in-flight requests to complete
33
+ await Promise.all(Array.from(this.inFlightPromises));
34
+ }
35
+ destroy() {
36
+ this.destroyed = true;
37
+ if (this.flushTimer) {
38
+ clearTimeout(this.flushTimer);
39
+ this.flushTimer = null;
40
+ }
41
+ }
42
+ scheduleFlush() {
43
+ if (this.destroyed) {
44
+ return;
45
+ }
46
+ this.flushTimer = setTimeout(() => {
47
+ if (this.queue.length > 0) {
48
+ this.flushBatch();
49
+ }
50
+ this.scheduleFlush();
51
+ }, this.options.flushIntervalMs);
52
+ }
53
+ flushBatch() {
54
+ if (this.queue.length === 0) {
55
+ return;
56
+ }
57
+ const batch = this.queue.splice(0, this.options.batchSize);
58
+ const promise = this.sendWithRetry(batch);
59
+ this.inFlightPromises.add(promise);
60
+ promise.finally(() => {
61
+ this.inFlightPromises.delete(promise);
62
+ });
63
+ }
64
+ async sendWithRetry(items) {
65
+ let lastError = null;
66
+ for (let attempt = 0; attempt < this.options.maxRetries; attempt++) {
67
+ try {
68
+ await this.sendFn(items);
69
+ return;
70
+ }
71
+ catch (error) {
72
+ lastError =
73
+ error instanceof Error ? error : new Error(String(error));
74
+ if (attempt < this.options.maxRetries - 1) {
75
+ const delay = this.options.baseRetryDelayMs * Math.pow(2, attempt);
76
+ await this.sleep(delay);
77
+ }
78
+ }
79
+ }
80
+ // All retries exhausted - log error but don't throw to avoid breaking the app
81
+ internalLogger.error(`Failed to send batch after ${this.options.maxRetries} attempts:`, lastError?.message);
82
+ }
83
+ sleep(ms) {
84
+ return new Promise((resolve) => setTimeout(resolve, ms));
85
+ }
86
+ }
87
+ //# sourceMappingURL=RequestQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RequestQueue.js","sourceRoot":"","sources":["../../src/queue/RequestQueue.ts"],"names":[],"mappings":"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"}