@mongrov/core 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +211 -0
  3. package/dist/context/logging-provider.d.ts +11 -0
  4. package/dist/context/logging-provider.d.ts.map +1 -0
  5. package/dist/context/logging-provider.js +43 -0
  6. package/dist/context/logging-provider.js.map +1 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +13 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/logger.d.ts +17 -0
  12. package/dist/logger.d.ts.map +1 -0
  13. package/dist/logger.js +159 -0
  14. package/dist/logger.js.map +1 -0
  15. package/dist/network-state.d.ts +13 -0
  16. package/dist/network-state.d.ts.map +1 -0
  17. package/dist/network-state.js +85 -0
  18. package/dist/network-state.js.map +1 -0
  19. package/dist/offline-queue.d.ts +30 -0
  20. package/dist/offline-queue.d.ts.map +1 -0
  21. package/dist/offline-queue.js +121 -0
  22. package/dist/offline-queue.js.map +1 -0
  23. package/dist/transports/file.d.ts +19 -0
  24. package/dist/transports/file.d.ts.map +1 -0
  25. package/dist/transports/file.js +136 -0
  26. package/dist/transports/file.js.map +1 -0
  27. package/dist/transports/index.d.ts +4 -0
  28. package/dist/transports/index.d.ts.map +1 -0
  29. package/dist/transports/index.js +4 -0
  30. package/dist/transports/index.js.map +1 -0
  31. package/dist/transports/ring-buffer.d.ts +15 -0
  32. package/dist/transports/ring-buffer.d.ts.map +1 -0
  33. package/dist/transports/ring-buffer.js +66 -0
  34. package/dist/transports/ring-buffer.js.map +1 -0
  35. package/dist/transports/webhook.d.ts +18 -0
  36. package/dist/transports/webhook.d.ts.map +1 -0
  37. package/dist/transports/webhook.js +88 -0
  38. package/dist/transports/webhook.js.map +1 -0
  39. package/dist/types.d.ts +59 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +2 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +73 -0
@@ -0,0 +1,121 @@
1
+ import { addNetworkStateListener, getNetworkState } from './network-state';
2
+ const QUEUE_KEY = '@mongrov/log-queue';
3
+ const DEFAULT_MAX_SIZE = 500;
4
+ const DEFAULT_MAX_RETRIES = 5;
5
+ const BASE_DELAY_MS = 1000;
6
+ function getMMKV() {
7
+ try {
8
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
9
+ const { MMKV } = require('react-native-mmkv');
10
+ return new MMKV();
11
+ }
12
+ catch {
13
+ throw new Error('@mongrov/core OfflineQueue requires react-native-mmkv as a peer dependency');
14
+ }
15
+ }
16
+ export class OfflineQueue {
17
+ constructor(sendFn, options) {
18
+ this.queue = [];
19
+ this.networkSubscription = null;
20
+ this.flushing = false;
21
+ this.sendFn = sendFn;
22
+ this.maxSize = options?.maxSize ?? DEFAULT_MAX_SIZE;
23
+ this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
24
+ this.storage = options?.storage ?? getMMKV();
25
+ this.loadFromStorage();
26
+ this.listenForConnectivity();
27
+ }
28
+ enqueue(entries) {
29
+ this.queue.push(...entries);
30
+ // Drop oldest entries if over max size (FIFO)
31
+ if (this.queue.length > this.maxSize) {
32
+ this.queue = this.queue.slice(this.queue.length - this.maxSize);
33
+ }
34
+ this.saveToStorage();
35
+ }
36
+ async flush() {
37
+ if (this.flushing || this.queue.length === 0)
38
+ return;
39
+ const networkState = await getNetworkState();
40
+ if (!networkState.isConnected)
41
+ return;
42
+ this.flushing = true;
43
+ try {
44
+ // Take a snapshot of entries to send
45
+ const batch = [...this.queue];
46
+ await this.sendWithRetry(batch);
47
+ // On success, remove sent entries (preserving any enqueued during send)
48
+ this.queue = this.queue.slice(batch.length);
49
+ this.saveToStorage();
50
+ }
51
+ catch {
52
+ // Retries exhausted — entries stay in queue for next flush attempt
53
+ this.saveToStorage();
54
+ }
55
+ finally {
56
+ this.flushing = false;
57
+ }
58
+ }
59
+ getQueueSize() {
60
+ return this.queue.length;
61
+ }
62
+ destroy() {
63
+ if (this.networkSubscription) {
64
+ this.networkSubscription.remove();
65
+ this.networkSubscription = null;
66
+ }
67
+ }
68
+ async sendWithRetry(entries) {
69
+ for (let attempt = 0; attempt < this.maxRetries; attempt++) {
70
+ try {
71
+ await this.sendFn(entries);
72
+ return;
73
+ }
74
+ catch (error) {
75
+ if (attempt < this.maxRetries - 1) {
76
+ const delay = BASE_DELAY_MS * Math.pow(2, attempt);
77
+ await new Promise((resolve) => setTimeout(resolve, delay));
78
+ }
79
+ else {
80
+ // All retries exhausted — throw so caller knows entries were NOT sent
81
+ throw error;
82
+ }
83
+ }
84
+ }
85
+ }
86
+ loadFromStorage() {
87
+ try {
88
+ const raw = this.storage.getString(QUEUE_KEY);
89
+ if (raw) {
90
+ const parsed = JSON.parse(raw);
91
+ if (Array.isArray(parsed)) {
92
+ this.queue = parsed;
93
+ }
94
+ }
95
+ }
96
+ catch {
97
+ this.queue = [];
98
+ }
99
+ }
100
+ saveToStorage() {
101
+ try {
102
+ if (this.queue.length === 0) {
103
+ this.storage.delete(QUEUE_KEY);
104
+ }
105
+ else {
106
+ this.storage.set(QUEUE_KEY, JSON.stringify(this.queue));
107
+ }
108
+ }
109
+ catch {
110
+ // Storage failures are non-critical
111
+ }
112
+ }
113
+ listenForConnectivity() {
114
+ this.networkSubscription = addNetworkStateListener((state) => {
115
+ if (state.isConnected) {
116
+ this.flush().catch(() => { });
117
+ }
118
+ });
119
+ }
120
+ }
121
+ //# sourceMappingURL=offline-queue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline-queue.js","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LogEntry, LogTransport, FileConfig } from '../types';
2
+ export declare class FileTransport implements LogTransport {
3
+ readonly name = "file";
4
+ private readonly directory;
5
+ private readonly maxSizeMB;
6
+ private readonly retentionDays;
7
+ private initialized;
8
+ private writeChain;
9
+ private lastCleanup;
10
+ private readonly cleanupIntervalMs;
11
+ constructor(config?: FileConfig);
12
+ send(entries: LogEntry[]): Promise<void>;
13
+ private doWrite;
14
+ getLogFiles(): Promise<string[]>;
15
+ readFile(filename: string): Promise<string>;
16
+ private ensureDirectory;
17
+ private cleanupIfNeeded;
18
+ }
19
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAqClE,qBAAa,aAAc,YAAW,YAAY;IAChD,QAAQ,CAAC,IAAI,UAAS;IAEtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAQ;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAQ;IACtC,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,UAAU,CAAmC;IAGrD,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;gBAE/B,MAAM,CAAC,EAAE,UAAU;IAQzB,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAOhC,OAAO;IA8Bf,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAahC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAKnC,eAAe;YAUf,eAAe;CA4C9B"}
@@ -0,0 +1,136 @@
1
+ let FileSystemModule = null;
2
+ function getFileSystem() {
3
+ if (!FileSystemModule) {
4
+ try {
5
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
6
+ FileSystemModule = require('expo-file-system');
7
+ }
8
+ catch {
9
+ throw new Error('@mongrov/core FileTransport requires expo-file-system as a peer dependency');
10
+ }
11
+ }
12
+ return FileSystemModule;
13
+ }
14
+ function formatDate(date) {
15
+ const y = date.getFullYear();
16
+ const m = String(date.getMonth() + 1).padStart(2, '0');
17
+ const d = String(date.getDate()).padStart(2, '0');
18
+ return `${y}-${m}-${d}`;
19
+ }
20
+ export class FileTransport {
21
+ constructor(config) {
22
+ this.name = 'file';
23
+ this.initialized = false;
24
+ // Serial write queue to prevent concurrent read-then-write race conditions
25
+ this.writeChain = Promise.resolve();
26
+ // Throttle cleanup to once per minute
27
+ this.lastCleanup = 0;
28
+ this.cleanupIntervalMs = 60000;
29
+ const fs = getFileSystem();
30
+ this.directory =
31
+ config?.directory ?? `${fs.documentDirectory ?? ''}logs/`;
32
+ this.maxSizeMB = config?.maxSizeMB ?? 5;
33
+ this.retentionDays = config?.retentionDays ?? 7;
34
+ }
35
+ async send(entries) {
36
+ // Chain writes to serialize file access
37
+ const op = this.writeChain.then(() => this.doWrite(entries));
38
+ this.writeChain = op.catch(() => { });
39
+ return op;
40
+ }
41
+ async doWrite(entries) {
42
+ try {
43
+ await this.ensureDirectory();
44
+ const now = Date.now();
45
+ if (now - this.lastCleanup >= this.cleanupIntervalMs) {
46
+ await this.cleanupIfNeeded();
47
+ this.lastCleanup = now;
48
+ }
49
+ const lines = entries.map((e) => JSON.stringify(e)).join('\n') + '\n';
50
+ const filename = `logs-${formatDate(new Date())}.txt`;
51
+ const filePath = `${this.directory}${filename}`;
52
+ const fs = getFileSystem();
53
+ const info = await fs.getInfoAsync(filePath);
54
+ if (info.exists) {
55
+ // Append by reading existing content + new lines
56
+ const existing = await fs.readAsStringAsync(filePath);
57
+ await fs.writeAsStringAsync(filePath, existing + lines);
58
+ }
59
+ else {
60
+ await fs.writeAsStringAsync(filePath, lines);
61
+ }
62
+ }
63
+ catch (error) {
64
+ // Logging should never crash the app
65
+ console.warn('[FileTransport] Write failed:', error);
66
+ }
67
+ }
68
+ async getLogFiles() {
69
+ try {
70
+ const fs = getFileSystem();
71
+ const files = await fs.readDirectoryAsync(this.directory);
72
+ return files
73
+ .filter((f) => f.startsWith('logs-') && f.endsWith('.txt'))
74
+ .sort()
75
+ .reverse();
76
+ }
77
+ catch {
78
+ return [];
79
+ }
80
+ }
81
+ async readFile(filename) {
82
+ const fs = getFileSystem();
83
+ return fs.readAsStringAsync(`${this.directory}${filename}`);
84
+ }
85
+ async ensureDirectory() {
86
+ if (this.initialized)
87
+ return;
88
+ const fs = getFileSystem();
89
+ const info = await fs.getInfoAsync(this.directory);
90
+ if (!info.exists) {
91
+ await fs.makeDirectoryAsync(this.directory, { intermediates: true });
92
+ }
93
+ this.initialized = true;
94
+ }
95
+ async cleanupIfNeeded() {
96
+ try {
97
+ const fs = getFileSystem();
98
+ const files = await fs.readDirectoryAsync(this.directory);
99
+ const logFiles = files
100
+ .filter((f) => f.startsWith('logs-') && f.endsWith('.txt'))
101
+ .sort();
102
+ // Delete files older than retentionDays
103
+ const cutoffDate = new Date();
104
+ cutoffDate.setDate(cutoffDate.getDate() - this.retentionDays);
105
+ const cutoffStr = formatDate(cutoffDate);
106
+ for (const file of logFiles) {
107
+ const dateStr = file.replace('logs-', '').replace('.txt', '');
108
+ if (dateStr < cutoffStr) {
109
+ await fs.deleteAsync(`${this.directory}${file}`, { idempotent: true });
110
+ }
111
+ }
112
+ // Check total size and delete oldest if exceeding maxSizeMB
113
+ let totalSize = 0;
114
+ const remaining = (await fs.readDirectoryAsync(this.directory))
115
+ .filter((f) => f.startsWith('logs-') && f.endsWith('.txt'))
116
+ .sort();
117
+ for (const file of remaining) {
118
+ const info = await fs.getInfoAsync(`${this.directory}${file}`);
119
+ totalSize += info.size ?? 0;
120
+ }
121
+ const maxSizeBytes = this.maxSizeMB * 1024 * 1024;
122
+ let i = 0;
123
+ while (totalSize > maxSizeBytes && i < remaining.length) {
124
+ const file = remaining[i];
125
+ const info = await fs.getInfoAsync(`${this.directory}${file}`);
126
+ await fs.deleteAsync(`${this.directory}${file}`, { idempotent: true });
127
+ totalSize -= info.size ?? 0;
128
+ i++;
129
+ }
130
+ }
131
+ catch {
132
+ // Cleanup failures are non-critical
133
+ }
134
+ }
135
+ }
136
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { RingBufferTransport } from './ring-buffer';
2
+ export { FileTransport } from './file';
3
+ export { WebhookTransport } from './webhook';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transports/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,4 @@
1
+ export { RingBufferTransport } from './ring-buffer';
2
+ export { FileTransport } from './file';
3
+ export { WebhookTransport } from './webhook';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/transports/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAA;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAA"}
@@ -0,0 +1,15 @@
1
+ import type { LogEntry, LogFilter, LogTransport } from '../types';
2
+ export declare class RingBufferTransport implements LogTransport {
3
+ readonly name = "ring-buffer";
4
+ private buffer;
5
+ private head;
6
+ private count;
7
+ private readonly maxSize;
8
+ constructor(maxSize?: number);
9
+ send(entries: LogEntry[]): Promise<void>;
10
+ getEntries(filter?: LogFilter): LogEntry[];
11
+ clear(): void;
12
+ toJSON(): string;
13
+ private applyFilter;
14
+ }
15
+ //# sourceMappingURL=ring-buffer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.d.ts","sourceRoot":"","sources":["../../src/transports/ring-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAY,YAAY,EAAE,MAAM,UAAU,CAAA;AAS3E,qBAAa,mBAAoB,YAAW,YAAY;IACtD,QAAQ,CAAC,IAAI,iBAAgB;IAE7B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,IAAI,CAAI;IAChB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;gBAEpB,OAAO,SAAO;IAKpB,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAU9C,UAAU,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,EAAE;IAe1C,KAAK,IAAI,IAAI;IAMb,MAAM,IAAI,MAAM;IAIhB,OAAO,CAAC,WAAW;CA0BpB"}
@@ -0,0 +1,66 @@
1
+ const LEVEL_ORDER = {
2
+ debug: 0,
3
+ info: 1,
4
+ warn: 2,
5
+ error: 3,
6
+ };
7
+ export class RingBufferTransport {
8
+ constructor(maxSize = 1000) {
9
+ this.name = 'ring-buffer';
10
+ this.head = 0;
11
+ this.count = 0;
12
+ this.maxSize = maxSize;
13
+ this.buffer = new Array(maxSize).fill(null);
14
+ }
15
+ async send(entries) {
16
+ for (const entry of entries) {
17
+ this.buffer[this.head] = entry;
18
+ this.head = (this.head + 1) % this.maxSize;
19
+ if (this.count < this.maxSize) {
20
+ this.count++;
21
+ }
22
+ }
23
+ }
24
+ getEntries(filter) {
25
+ const entries = [];
26
+ // Read from newest to oldest
27
+ for (let i = 0; i < this.count; i++) {
28
+ const index = (this.head - 1 - i + this.maxSize) % this.maxSize;
29
+ const entry = this.buffer[index];
30
+ if (entry) {
31
+ entries.push(entry);
32
+ }
33
+ }
34
+ return this.applyFilter(entries, filter);
35
+ }
36
+ clear() {
37
+ this.buffer = new Array(this.maxSize).fill(null);
38
+ this.head = 0;
39
+ this.count = 0;
40
+ }
41
+ toJSON() {
42
+ return JSON.stringify(this.getEntries());
43
+ }
44
+ applyFilter(entries, filter) {
45
+ if (!filter)
46
+ return entries;
47
+ let result = entries;
48
+ if (filter.level) {
49
+ const minLevel = LEVEL_ORDER[filter.level];
50
+ result = result.filter((e) => LEVEL_ORDER[e.level] >= minLevel);
51
+ }
52
+ if (filter.since) {
53
+ const sinceTime = filter.since.getTime();
54
+ result = result.filter((e) => new Date(e.timestamp).getTime() >= sinceTime);
55
+ }
56
+ if (filter.search) {
57
+ const search = filter.search.toLowerCase();
58
+ result = result.filter((e) => e.message.toLowerCase().includes(search));
59
+ }
60
+ if (filter.limit && filter.limit > 0) {
61
+ result = result.slice(0, filter.limit);
62
+ }
63
+ return result;
64
+ }
65
+ }
66
+ //# sourceMappingURL=ring-buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring-buffer.js","sourceRoot":"","sources":["../../src/transports/ring-buffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { LogEntry, LogTransport, WebhookConfig } from '../types';
2
+ export declare class WebhookTransport implements LogTransport {
3
+ readonly name = "webhook";
4
+ private readonly config;
5
+ private batch;
6
+ private timer;
7
+ private offlineQueue;
8
+ private flushing;
9
+ constructor(config: WebhookConfig);
10
+ send(entries: LogEntry[]): Promise<void>;
11
+ flush(): Promise<void>;
12
+ destroy(): Promise<void>;
13
+ private startTimer;
14
+ private stopTimer;
15
+ private flushBatch;
16
+ private postEntries;
17
+ }
18
+ //# sourceMappingURL=webhook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/transports/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGrE,qBAAa,gBAAiB,YAAW,YAAY;IACnD,QAAQ,CAAC,IAAI,aAAY;IAEzB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAG2B;IAElD,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,QAAQ,CAAQ;gBAEZ,MAAM,EAAE,aAAa;IAkB3B,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAKtB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9B,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,SAAS;YAOH,UAAU;YAiBV,WAAW;CA2B1B"}
@@ -0,0 +1,88 @@
1
+ import { OfflineQueue } from '../offline-queue';
2
+ export class WebhookTransport {
3
+ constructor(config) {
4
+ this.name = 'webhook';
5
+ this.batch = [];
6
+ this.timer = null;
7
+ this.flushing = false;
8
+ this.config = {
9
+ url: config.url,
10
+ batchSize: config.batchSize ?? 10,
11
+ batchIntervalMs: config.batchIntervalMs ?? 5000,
12
+ maxRetries: config.maxRetries ?? 3,
13
+ headers: config.headers,
14
+ formatPayload: config.formatPayload,
15
+ };
16
+ this.offlineQueue = new OfflineQueue((entries) => this.postEntries(entries), { maxRetries: this.config.maxRetries });
17
+ this.startTimer();
18
+ }
19
+ async send(entries) {
20
+ this.batch.push(...entries);
21
+ if (this.batch.length >= this.config.batchSize) {
22
+ await this.flushBatch();
23
+ }
24
+ }
25
+ async flush() {
26
+ await this.flushBatch();
27
+ await this.offlineQueue.flush();
28
+ }
29
+ async destroy() {
30
+ this.stopTimer();
31
+ await this.flushBatch();
32
+ await this.offlineQueue.flush();
33
+ this.offlineQueue.destroy();
34
+ }
35
+ startTimer() {
36
+ this.timer = setInterval(() => {
37
+ if (this.batch.length > 0) {
38
+ this.flushBatch().catch(() => { });
39
+ }
40
+ }, this.config.batchIntervalMs);
41
+ }
42
+ stopTimer() {
43
+ if (this.timer) {
44
+ clearInterval(this.timer);
45
+ this.timer = null;
46
+ }
47
+ }
48
+ async flushBatch() {
49
+ if (this.flushing || this.batch.length === 0)
50
+ return;
51
+ this.flushing = true;
52
+ const entries = [...this.batch];
53
+ this.batch = [];
54
+ try {
55
+ await this.postEntries(entries);
56
+ }
57
+ catch (error) {
58
+ // Delegate to offline queue for retry
59
+ this.offlineQueue.enqueue(entries);
60
+ }
61
+ finally {
62
+ this.flushing = false;
63
+ }
64
+ }
65
+ async postEntries(entries) {
66
+ const payload = this.config.formatPayload
67
+ ? this.config.formatPayload(entries)
68
+ : { entries };
69
+ const response = await fetch(this.config.url, {
70
+ method: 'POST',
71
+ headers: {
72
+ 'Content-Type': 'application/json',
73
+ ...this.config.headers,
74
+ },
75
+ body: JSON.stringify(payload),
76
+ });
77
+ if (response.status >= 400 && response.status < 500) {
78
+ // Client error — drop entries, retrying won't help
79
+ console.warn(`[WebhookTransport] HTTP ${response.status}: dropping ${entries.length} entries`);
80
+ return;
81
+ }
82
+ if (!response.ok) {
83
+ // 5xx — throw to trigger offline queue retry
84
+ throw new Error(`HTTP ${response.status}`);
85
+ }
86
+ }
87
+ }
88
+ //# sourceMappingURL=webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook.js","sourceRoot":"","sources":["../../src/transports/webhook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
2
+ export interface LogContext {
3
+ userId?: string;
4
+ sessionId: string;
5
+ screenName?: string;
6
+ appVersion: string;
7
+ updateId?: string;
8
+ platform: 'ios' | 'android';
9
+ deviceId?: string;
10
+ }
11
+ export interface LogEntry {
12
+ id: string;
13
+ timestamp: string;
14
+ level: LogLevel;
15
+ message: string;
16
+ data?: Record<string, unknown>;
17
+ context: LogContext;
18
+ }
19
+ export interface LogFilter {
20
+ level?: LogLevel;
21
+ since?: Date;
22
+ search?: string;
23
+ limit?: number;
24
+ }
25
+ export interface LogTransport {
26
+ name: string;
27
+ send(entries: LogEntry[]): Promise<void>;
28
+ }
29
+ export interface RingBufferConfig {
30
+ maxSize?: number;
31
+ }
32
+ export interface FileConfig {
33
+ maxSizeMB?: number;
34
+ retentionDays?: number;
35
+ directory?: string;
36
+ }
37
+ export interface WebhookConfig {
38
+ url: string;
39
+ headers?: Record<string, string>;
40
+ batchSize?: number;
41
+ batchIntervalMs?: number;
42
+ maxRetries?: number;
43
+ formatPayload?: (entries: LogEntry[]) => unknown;
44
+ }
45
+ export interface LoggerConfig {
46
+ minLevel?: LogLevel;
47
+ ringBuffer?: RingBufferConfig | boolean;
48
+ file?: FileConfig | boolean;
49
+ webhook?: WebhookConfig;
50
+ transports?: LogTransport[];
51
+ appVersion: string;
52
+ updateId?: string;
53
+ /** @deprecated Use `onLog` instead. */
54
+ onError?: (entry: LogEntry) => void;
55
+ /** Called for every warn / error entry. Use for Sentry breadcrumbs, analytics, etc. */
56
+ onLog?: (entry: LogEntry) => void;
57
+ onException?: (error: Error, context?: Record<string, unknown>) => void;
58
+ }
59
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAE1D,MAAM,WAAW,UAAU;IACzB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,KAAK,GAAG,SAAS,CAAA;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,UAAU,CAAA;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACzC;AAED,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAA;CACjD;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB,UAAU,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAA;IACvC,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;IAC3B,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB,UAAU,CAAC,EAAE,YAAY,EAAE,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,uCAAuC;IACvC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACnC,uFAAuF;IACvF,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAA;IACjC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAA;CACxE"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}