@mongrov/core 0.5.0 → 0.6.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.
@@ -1,3 +1,4 @@
1
+ import { devConsoleLogger, FailureGate } from './internal-log';
1
2
  let cachedState = {
2
3
  isConnected: true,
3
4
  type: null,
@@ -5,6 +6,16 @@ let cachedState = {
5
6
  };
6
7
  const listeners = new Set();
7
8
  let pollingInterval = null;
9
+ // Module state has no logger of its own; `LoggingProvider` sets the app's.
10
+ let log = devConsoleLogger();
11
+ const pollFailures = new FailureGate();
12
+ /**
13
+ * Where connectivity changes and polling failures are reported. Called by
14
+ * `LoggingProvider`; `null` restores the dev-console fallback.
15
+ */
16
+ export function setNetworkStateLogger(logger) {
17
+ log = logger ?? devConsoleLogger();
18
+ }
8
19
  function getExpoNetwork() {
9
20
  try {
10
21
  return require('expo-network');
@@ -28,19 +39,43 @@ async function pollAndNotify() {
28
39
  const changed = newState.isConnected !== cachedState.isConnected
29
40
  || newState.type !== cachedState.type
30
41
  || newState.isInternetReachable !== cachedState.isInternetReachable;
42
+ const previous = cachedState;
31
43
  cachedState = newState;
44
+ const failed = pollFailures.recover();
45
+ if (failed > 0)
46
+ log.info('[Network] state readable again', { failedPolls: failed });
32
47
  if (changed) {
33
- listeners.forEach(cb => cb(newState));
48
+ log.info('[Network] state changed', {
49
+ isConnected: newState.isConnected,
50
+ type: newState.type,
51
+ isInternetReachable: newState.isInternetReachable,
52
+ wasConnected: previous.isConnected,
53
+ });
54
+ notify(newState);
34
55
  }
35
56
  }
36
- catch {
37
- // Silently ignore polling errors
57
+ catch (error) {
58
+ // The cached state stays as it was; listeners hear nothing until a poll
59
+ // succeeds. Reported once per run of failures (polls every 15s).
60
+ if (pollFailures.fail())
61
+ log.warn('[Network] state poll failed; keeping last known state', { error: String(error) });
38
62
  }
39
63
  }
64
+ function notify(state) {
65
+ listeners.forEach((cb) => {
66
+ // One throwing listener must not starve the others.
67
+ try {
68
+ cb(state);
69
+ }
70
+ catch (error) {
71
+ log.error('[Network] listener threw', { error: String(error) });
72
+ }
73
+ });
74
+ }
40
75
  function startPolling() {
41
76
  if (pollingInterval)
42
77
  return;
43
- pollAndNotify();
78
+ void pollAndNotify(); // never rejects: failures are reported inside
44
79
  pollingInterval = setInterval(pollAndNotify, 15000);
45
80
  }
46
81
  function stopPolling() {
@@ -74,7 +109,10 @@ export function useNetworkState() {
74
109
  const { useState, useEffect } = React;
75
110
  const [state, setState] = useState(cachedState);
76
111
  useEffect(() => {
77
- getNetworkState().then(setState);
112
+ getNetworkState().then(setState, (error) => {
113
+ // Keeps the cached state; the listener below picks up the next poll.
114
+ log.warn('[Network] initial state read failed', { error: String(error) });
115
+ });
78
116
  const subscription = addNetworkStateListener(setState);
79
117
  return () => subscription.remove();
80
118
  }, []);
@@ -1 +1 @@
1
- {"version":3,"file":"network-state.js","sourceRoot":"","sources":["../src/network-state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"network-state.js","sourceRoot":"","sources":["../src/network-state.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { InternalLogger } from './internal-log';
1
2
  import type { LogEntry } from './types';
2
3
  interface MMKVStorage {
3
4
  getString: (key: string) => string | undefined;
@@ -12,10 +13,15 @@ export declare class OfflineQueue {
12
13
  private storage;
13
14
  private networkSubscription;
14
15
  private flushing;
16
+ private readonly log;
17
+ private overflowDropped;
18
+ private readonly storageFailures;
15
19
  constructor(sendFn: (entries: LogEntry[]) => Promise<void>, options?: {
16
20
  maxSize?: number;
17
21
  maxRetries?: number;
18
22
  storage?: MMKVStorage;
23
+ /** Receives the queue's own failures; dev console when omitted. */
24
+ logger?: InternalLogger;
19
25
  });
20
26
  enqueue(entries: LogEntry[]): void;
21
27
  flush(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"offline-queue.d.ts","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAQvC,UAAU,WAAW;IACnB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC9C,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAcD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,mBAAmB,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAAQ;gBAGtB,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,OAAO,CAAC,EAAE,WAAW,CAAA;KACtB;IAUH,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAW5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyC5B,YAAY,IAAI,MAAM;IAItB,OAAO,IAAI,IAAI;YAOD,aAAa;IAmB3B,OAAO,CAAC,eAAe;IAevB,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,qBAAqB;CAO9B"}
1
+ {"version":3,"file":"offline-queue.d.ts","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AASvC,UAAU,WAAW;IACnB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC9C,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACzC,MAAM,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC9B;AAcD,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAQ;IACnC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwC;IAC/D,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,mBAAmB,CAAsC;IACjE,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IAEpC,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAoB;gBAGlD,MAAM,EAAE,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EAC9C,OAAO,CAAC,EAAE;QACR,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,OAAO,CAAC,EAAE,WAAW,CAAA;QACrB,mEAAmE;QACnE,MAAM,CAAC,EAAE,cAAc,CAAA;KACxB;IAWH,OAAO,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,IAAI;IAgB5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8D5B,YAAY,IAAI,MAAM;IAItB,OAAO,IAAI,IAAI;YAOD,aAAa;IAmB3B,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,aAAa;IAoBrB,OAAO,CAAC,qBAAqB;CAS9B"}
@@ -1,3 +1,4 @@
1
+ import { devConsoleLogger, FailureGate } from './internal-log';
1
2
  import { addNetworkStateListener, getNetworkState } from './network-state';
2
3
  const QUEUE_KEY = '@mongrov/log-queue';
3
4
  const DEFAULT_MAX_SIZE = 500;
@@ -17,6 +18,10 @@ export class OfflineQueue {
17
18
  this.queue = [];
18
19
  this.networkSubscription = null;
19
20
  this.flushing = false;
21
+ // Entries trimmed off the head since the last report.
22
+ this.overflowDropped = 0;
23
+ this.storageFailures = new FailureGate();
24
+ this.log = options?.logger ?? devConsoleLogger();
20
25
  this.sendFn = sendFn;
21
26
  this.maxSize = options?.maxSize ?? DEFAULT_MAX_SIZE;
22
27
  this.maxRetries = options?.maxRetries ?? DEFAULT_MAX_RETRIES;
@@ -28,20 +33,34 @@ export class OfflineQueue {
28
33
  this.queue.push(...entries);
29
34
  // Drop oldest entries if over max size (FIFO)
30
35
  if (this.queue.length > this.maxSize) {
31
- this.queue = this.queue.slice(this.queue.length - this.maxSize);
36
+ const dropped = this.queue.length - this.maxSize;
37
+ this.queue = this.queue.slice(dropped);
38
+ // Once per overflow run; the total is reported when the queue drains.
39
+ if (this.overflowDropped === 0)
40
+ this.log.warn('[OfflineQueue] full; dropping oldest entries', { maxSize: this.maxSize });
41
+ this.overflowDropped += dropped;
32
42
  }
33
43
  this.saveToStorage();
34
44
  }
35
45
  async flush() {
36
46
  if (this.flushing || this.queue.length === 0)
37
47
  return;
38
- const networkState = await getNetworkState();
48
+ let networkState;
49
+ try {
50
+ networkState = await getNetworkState();
51
+ }
52
+ catch (error) {
53
+ // No reading (expo-network missing or failing): keep the entries for
54
+ // the next attempt rather than throwing out of a background flush.
55
+ this.log.warn('[OfflineQueue] network state unavailable; flush skipped', { error: String(error) });
56
+ return;
57
+ }
39
58
  if (!networkState.isConnected)
40
59
  return;
41
60
  this.flushing = true;
61
+ const batch = [...this.queue];
62
+ const startedAt = Date.now();
42
63
  try {
43
- // Take a snapshot of entries to send
44
- const batch = [...this.queue];
45
64
  await this.sendWithRetry(batch);
46
65
  // Remove the delivered entries BY ID, not by slicing off `batch.length`
47
66
  // from the head.
@@ -59,9 +78,21 @@ export class OfflineQueue {
59
78
  const deliveredIds = new Set(batch.map(entry => entry.id));
60
79
  this.queue = this.queue.filter(entry => !deliveredIds.has(entry.id));
61
80
  this.saveToStorage();
81
+ this.log.info('[OfflineQueue] flushed', {
82
+ sent: batch.length,
83
+ remaining: this.queue.length,
84
+ droppedOnOverflow: this.overflowDropped,
85
+ durationMs: Date.now() - startedAt,
86
+ });
87
+ this.overflowDropped = 0;
62
88
  }
63
- catch {
89
+ catch (error) {
64
90
  // Retries exhausted — entries stay in queue for next flush attempt
91
+ this.log.warn('[OfflineQueue] flush failed; entries kept for next attempt', {
92
+ error: String(error),
93
+ attempts: this.maxRetries,
94
+ queued: this.queue.length,
95
+ });
65
96
  this.saveToStorage();
66
97
  }
67
98
  finally {
@@ -105,7 +136,9 @@ export class OfflineQueue {
105
136
  }
106
137
  }
107
138
  }
108
- catch {
139
+ catch (error) {
140
+ // A corrupt saved queue is discarded: those entries are lost.
141
+ this.log.warn('[OfflineQueue] saved queue unreadable; discarded', { error: String(error) });
109
142
  this.queue = [];
110
143
  }
111
144
  }
@@ -117,15 +150,23 @@ export class OfflineQueue {
117
150
  else {
118
151
  this.storage.set(QUEUE_KEY, JSON.stringify(this.queue));
119
152
  }
153
+ const failed = this.storageFailures.recover();
154
+ if (failed > 0)
155
+ this.log.info('[OfflineQueue] storage writes recovered', { failedWrites: failed });
120
156
  }
121
- catch {
122
- // Storage failures are non-critical
157
+ catch (error) {
158
+ // Non-critical while the app runs (the queue is in memory), but the
159
+ // queue will not survive a restart. Once per run of failures.
160
+ if (this.storageFailures.fail())
161
+ this.log.warn('[OfflineQueue] persist failed', { error: String(error) });
123
162
  }
124
163
  }
125
164
  listenForConnectivity() {
126
165
  this.networkSubscription = addNetworkStateListener((state) => {
127
166
  if (state.isConnected) {
128
- this.flush().catch(() => { });
167
+ this.flush().catch((error) => {
168
+ this.log.error('[OfflineQueue] flush on reconnect threw', { error: String(error) });
169
+ });
129
170
  }
130
171
  });
131
172
  }
@@ -1 +1 @@
1
- {"version":3,"file":"offline-queue.js","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"offline-queue.js","sourceRoot":"","sources":["../src/offline-queue.ts"],"names":[],"mappings":"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"}
@@ -1,18 +1,38 @@
1
+ import type { InternalLogger } from '../internal-log';
1
2
  import type { FileConfig, LogEntry, LogTransport } from '../types';
2
3
  export declare class FileTransport implements LogTransport {
3
4
  readonly name = "file";
4
5
  private readonly directory;
5
6
  private readonly maxSizeMB;
6
7
  private readonly retentionDays;
8
+ private readonly log;
9
+ private readonly writeFailures;
7
10
  private initialized;
8
- private writeChain;
11
+ private pending;
12
+ private pendingWaiters;
13
+ private writing;
9
14
  private lastCleanup;
10
15
  private readonly cleanupIntervalMs;
11
- constructor(config?: FileConfig);
16
+ /**
17
+ * `logger` receives this transport's own failures. `createLogger` passes
18
+ * one that skips this transport; standalone use falls back to the dev
19
+ * console.
20
+ */
21
+ constructor(config?: FileConfig, logger?: InternalLogger);
22
+ /** Resolves once these entries are on disk (or the write failed). */
12
23
  send(entries: LogEntry[]): Promise<void>;
24
+ /** Resolves once everything sent so far has been written. */
25
+ flush(): Promise<void>;
26
+ private drain;
13
27
  private doWrite;
14
28
  getLogFiles(): Promise<string[]>;
15
29
  readFile(filename: string): Promise<string>;
30
+ /**
31
+ * Every retained day file, oldest first: one JSON entry per line, oldest
32
+ * line first. Unlike the ring buffer this survives an app restart or crash.
33
+ * Waits for pending writes first, so the result includes everything sent.
34
+ */
35
+ readAll(): Promise<string>;
16
36
  private ensureDirectory;
17
37
  private cleanupIfNeeded;
18
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AA6ClE,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;IAgCf,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAchC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAKnC,eAAe;YAWf,eAAe;CA6C9B"}
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAoDlE,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,QAAQ,CAAC,GAAG,CAAgB;IACpC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAoB;IAClD,OAAO,CAAC,WAAW,CAAQ;IAQ3B,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,cAAc,CAAwB;IAC9C,OAAO,CAAC,OAAO,CAA6B;IAG5C,OAAO,CAAC,WAAW,CAAI;IACvB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAS;IAE3C;;;;OAIG;gBACS,MAAM,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,EAAE,cAAc;IASxD,qEAAqE;IACrE,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQxC,6DAA6D;IACvD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAKd,KAAK;YAaL,OAAO;IAwCf,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAehC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjD;;;;OAIG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;YAelB,eAAe;YAWf,eAAe;CA4D9B"}
@@ -1,3 +1,4 @@
1
+ import { devConsoleLogger, FailureGate } from '../internal-log';
1
2
  let FileSystemModule = null;
2
3
  function getFileSystem() {
3
4
  if (!FileSystemModule) {
@@ -17,32 +18,70 @@ function getFileSystem() {
17
18
  }
18
19
  return FileSystemModule;
19
20
  }
21
+ // UTC, the same clock as every entry's `timestamp`, so a file's name and the
22
+ // lines inside it agree on which day they belong to.
20
23
  function formatDate(date) {
21
- const y = date.getFullYear();
22
- const m = String(date.getMonth() + 1).padStart(2, '0');
23
- const d = String(date.getDate()).padStart(2, '0');
24
+ const y = date.getUTCFullYear();
25
+ const m = String(date.getUTCMonth() + 1).padStart(2, '0');
26
+ const d = String(date.getUTCDate()).padStart(2, '0');
24
27
  return `${y}-${m}-${d}`;
25
28
  }
29
+ function todayFilename() {
30
+ return `logs-${formatDate(new Date())}.txt`;
31
+ }
26
32
  export class FileTransport {
27
- constructor(config) {
33
+ /**
34
+ * `logger` receives this transport's own failures. `createLogger` passes
35
+ * one that skips this transport; standalone use falls back to the dev
36
+ * console.
37
+ */
38
+ constructor(config, logger) {
28
39
  this.name = 'file';
40
+ this.writeFailures = new FailureGate();
29
41
  this.initialized = false;
30
- // Serial write queue to prevent concurrent read-then-write race conditions
31
- this.writeChain = Promise.resolve();
42
+ // Entries waiting for the next write, and the callers waiting on them.
43
+ // expo-file-system has no append, so every write reads and rewrites the
44
+ // whole day file. Writing once per `send` made that cost per log line — a
45
+ // full ring sync logs hundreds of lines in seconds, each rewriting a file of
46
+ // up to `maxSizeMB`. Lines that arrive while a write is in flight are
47
+ // coalesced into the next one instead.
48
+ this.pending = [];
49
+ this.pendingWaiters = [];
50
+ this.writing = null;
32
51
  // Throttle cleanup to once per minute
33
52
  this.lastCleanup = 0;
34
53
  this.cleanupIntervalMs = 60000;
54
+ this.log = logger ?? devConsoleLogger();
35
55
  const fs = getFileSystem();
36
56
  this.directory
37
57
  = config?.directory ?? `${fs.documentDirectory ?? ''}logs/`;
38
58
  this.maxSizeMB = config?.maxSizeMB ?? 5;
39
59
  this.retentionDays = config?.retentionDays ?? 7;
40
60
  }
41
- async send(entries) {
42
- // Chain writes to serialize file access
43
- const op = this.writeChain.then(() => this.doWrite(entries));
44
- this.writeChain = op.catch(() => { });
45
- return op;
61
+ /** Resolves once these entries are on disk (or the write failed). */
62
+ send(entries) {
63
+ this.pending.push(...entries);
64
+ const done = new Promise(resolve => this.pendingWaiters.push(resolve));
65
+ if (!this.writing)
66
+ this.writing = this.drain();
67
+ return done;
68
+ }
69
+ /** Resolves once everything sent so far has been written. */
70
+ async flush() {
71
+ while (this.writing)
72
+ await this.writing;
73
+ }
74
+ async drain() {
75
+ while (this.pending.length > 0) {
76
+ const batch = this.pending;
77
+ const waiters = this.pendingWaiters;
78
+ this.pending = [];
79
+ this.pendingWaiters = [];
80
+ await this.doWrite(batch);
81
+ for (const resolve of waiters)
82
+ resolve();
83
+ }
84
+ this.writing = null;
46
85
  }
47
86
  async doWrite(entries) {
48
87
  try {
@@ -53,8 +92,7 @@ export class FileTransport {
53
92
  this.lastCleanup = now;
54
93
  }
55
94
  const lines = `${entries.map(e => JSON.stringify(e)).join('\n')}\n`;
56
- const filename = `logs-${formatDate(new Date())}.txt`;
57
- const filePath = `${this.directory}${filename}`;
95
+ const filePath = `${this.directory}${todayFilename()}`;
58
96
  const fs = getFileSystem();
59
97
  const info = await fs.getInfoAsync(filePath);
60
98
  if (info.exists) {
@@ -65,10 +103,19 @@ export class FileTransport {
65
103
  else {
66
104
  await fs.writeAsStringAsync(filePath, lines);
67
105
  }
106
+ const failed = this.writeFailures.recover();
107
+ if (failed > 0)
108
+ this.log.info('[FileTransport] writes recovered', { failedWrites: failed });
68
109
  }
69
110
  catch (error) {
70
- // Logging should never crash the app
71
- console.warn('[FileTransport] Write failed:', error);
111
+ // Logging must never crash the app. The lines are lost from the file
112
+ // (the ring buffer still has them); report once per run of failures.
113
+ if (this.writeFailures.fail()) {
114
+ this.log.error('[FileTransport] write failed; file log is missing lines', {
115
+ error: String(error),
116
+ lost: entries.length,
117
+ });
118
+ }
72
119
  }
73
120
  }
74
121
  async getLogFiles() {
@@ -81,6 +128,7 @@ export class FileTransport {
81
128
  .reverse();
82
129
  }
83
130
  catch {
131
+ // expected: no directory yet means no files have been written.
84
132
  return [];
85
133
  }
86
134
  }
@@ -88,6 +136,25 @@ export class FileTransport {
88
136
  const fs = getFileSystem();
89
137
  return fs.readAsStringAsync(`${this.directory}${filename}`);
90
138
  }
139
+ /**
140
+ * Every retained day file, oldest first: one JSON entry per line, oldest
141
+ * line first. Unlike the ring buffer this survives an app restart or crash.
142
+ * Waits for pending writes first, so the result includes everything sent.
143
+ */
144
+ async readAll() {
145
+ await this.flush();
146
+ const files = (await this.getLogFiles()).reverse();
147
+ let out = '';
148
+ for (const file of files) {
149
+ try {
150
+ out += await this.readFile(file);
151
+ }
152
+ catch {
153
+ // A file removed by cleanup mid-read is simply skipped.
154
+ }
155
+ }
156
+ return out;
157
+ }
91
158
  async ensureDirectory() {
92
159
  if (this.initialized)
93
160
  return;
@@ -115,7 +182,10 @@ export class FileTransport {
115
182
  await fs.deleteAsync(`${this.directory}${file}`, { idempotent: true });
116
183
  }
117
184
  }
118
- // Check total size and delete oldest if exceeding maxSizeMB
185
+ // Check total size and delete oldest if exceeding maxSizeMB. Today's
186
+ // file is never deleted — it holds the session being diagnosed. If it
187
+ // alone is over the cap, its oldest lines are dropped instead.
188
+ const today = todayFilename();
119
189
  let totalSize = 0;
120
190
  const remaining = (await fs.readDirectoryAsync(this.directory))
121
191
  .filter(f => f.startsWith('logs-') && f.endsWith('.txt'))
@@ -125,17 +195,28 @@ export class FileTransport {
125
195
  totalSize += info.size ?? 0;
126
196
  }
127
197
  const maxSizeBytes = this.maxSizeMB * 1024 * 1024;
198
+ const older = remaining.filter(f => f !== today);
128
199
  let i = 0;
129
- while (totalSize > maxSizeBytes && i < remaining.length) {
130
- const file = remaining[i];
200
+ while (totalSize > maxSizeBytes && i < older.length) {
201
+ const file = older[i];
131
202
  const info = await fs.getInfoAsync(`${this.directory}${file}`);
132
203
  await fs.deleteAsync(`${this.directory}${file}`, { idempotent: true });
133
204
  totalSize -= info.size ?? 0;
134
205
  i++;
135
206
  }
207
+ if (totalSize > maxSizeBytes && remaining.includes(today)) {
208
+ const path = `${this.directory}${today}`;
209
+ const content = await fs.readAsStringAsync(path);
210
+ // Keep the newest half of the cap, cut at a line boundary.
211
+ const tail = content.slice(content.length - Math.floor(maxSizeBytes / 2));
212
+ const firstBreak = tail.indexOf('\n');
213
+ await fs.writeAsStringAsync(path, firstBreak >= 0 ? tail.slice(firstBreak + 1) : '');
214
+ }
136
215
  }
137
- catch {
138
- // Cleanup failures are non-critical
216
+ catch (error) {
217
+ // Non-critical: the next cleanup (a minute on) tries again, but a
218
+ // cleanup that keeps failing lets the log directory grow unbounded.
219
+ this.log.warn('[FileTransport] cleanup failed', { error: String(error) });
139
220
  }
140
221
  }
141
222
  }
@@ -1 +1 @@
1
- {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/transports/file.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import type { InternalLogger } from '../internal-log';
1
2
  import type { LogEntry, LogTransport, WebhookConfig } from '../types';
2
3
  export declare class WebhookTransport implements LogTransport {
3
4
  readonly name = "webhook";
@@ -6,7 +7,16 @@ export declare class WebhookTransport implements LogTransport {
6
7
  private timer;
7
8
  private offlineQueue;
8
9
  private flushing;
9
- constructor(config: WebhookConfig);
10
+ private readonly log;
11
+ private readonly rejections;
12
+ private droppedEntries;
13
+ private readonly postFailures;
14
+ /**
15
+ * `logger` receives this transport's own failures. `createLogger` passes
16
+ * one that skips this transport (a report about a failing webhook must not
17
+ * be posted to that webhook); standalone use falls back to the dev console.
18
+ */
19
+ constructor(config: WebhookConfig, logger?: InternalLogger);
10
20
  send(entries: LogEntry[]): Promise<void>;
11
21
  flush(): Promise<void>;
12
22
  destroy(): Promise<void>;
@@ -1 +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;YAsBV,WAAW;CA2B1B"}
1
+ {"version":3,"file":"webhook.d.ts","sourceRoot":"","sources":["../../src/transports/webhook.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAIrE,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;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAgB;IAGpC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAC/C,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IAEjD;;;;OAIG;gBACS,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,cAAc;IAmBpD,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;IAUlB,OAAO,CAAC,SAAS;YAOH,UAAU;YA8BV,WAAW;CAwC1B"}