zario 0.3.1 → 0.3.5

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 (35) hide show
  1. package/README.md +161 -1
  2. package/dist/cjs/aggregation/LogAggregator.js +110 -0
  3. package/dist/cjs/aggregation/index.js +17 -0
  4. package/dist/cjs/core/Logger.js +106 -2
  5. package/dist/cjs/filters/Filter.js +56 -0
  6. package/dist/cjs/filters/SpecificFilters.js +71 -0
  7. package/dist/cjs/filters/index.js +18 -0
  8. package/dist/cjs/index.js +18 -1
  9. package/dist/cjs/structured/StructuredExtensions.js +112 -0
  10. package/dist/cjs/structured/index.js +17 -0
  11. package/dist/cjs/transports/FilterableTransport.js +39 -0
  12. package/dist/cjs/transports/index.js +1 -0
  13. package/dist/esm/aggregation/LogAggregator.d.ts +60 -0
  14. package/dist/esm/aggregation/LogAggregator.js +104 -0
  15. package/dist/esm/aggregation/index.d.ts +1 -0
  16. package/dist/esm/aggregation/index.js +1 -0
  17. package/dist/esm/core/Logger.d.ts +33 -0
  18. package/dist/esm/core/Logger.js +106 -2
  19. package/dist/esm/filters/Filter.d.ts +47 -0
  20. package/dist/esm/filters/Filter.js +49 -0
  21. package/dist/esm/filters/SpecificFilters.d.ts +41 -0
  22. package/dist/esm/filters/SpecificFilters.js +64 -0
  23. package/dist/esm/filters/index.d.ts +2 -0
  24. package/dist/esm/filters/index.js +2 -0
  25. package/dist/esm/index.d.ts +6 -3
  26. package/dist/esm/index.js +11 -2
  27. package/dist/esm/structured/StructuredExtensions.d.ts +31 -0
  28. package/dist/esm/structured/StructuredExtensions.js +74 -0
  29. package/dist/esm/structured/index.d.ts +1 -0
  30. package/dist/esm/structured/index.js +1 -0
  31. package/dist/esm/transports/FilterableTransport.d.ts +14 -0
  32. package/dist/esm/transports/FilterableTransport.js +35 -0
  33. package/dist/esm/transports/index.d.ts +1 -0
  34. package/dist/esm/transports/index.js +1 -0
  35. package/package.json +8 -4
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.LogEnrichmentPipeline = exports.MetadataEnricher = void 0;
37
+ const os = __importStar(require("os"));
38
+ /**
39
+ * Enriches logs with additional metadata
40
+ */
41
+ class MetadataEnricher {
42
+ static addStaticFields(staticFields) {
43
+ return (logData) => {
44
+ return {
45
+ ...logData,
46
+ metadata: {
47
+ ...logData.metadata,
48
+ ...staticFields
49
+ }
50
+ };
51
+ };
52
+ }
53
+ static addDynamicFields(dynamicFields) {
54
+ return (logData) => {
55
+ const fields = dynamicFields();
56
+ return {
57
+ ...logData,
58
+ metadata: {
59
+ ...logData.metadata,
60
+ ...fields
61
+ }
62
+ };
63
+ };
64
+ }
65
+ static addProcessInfo() {
66
+ return (logData) => {
67
+ return {
68
+ ...logData,
69
+ metadata: {
70
+ ...logData.metadata,
71
+ pid: process.pid,
72
+ hostname: os.hostname(),
73
+ nodeVersion: process.version
74
+ }
75
+ };
76
+ };
77
+ }
78
+ static addEnvironmentInfo() {
79
+ return (logData) => {
80
+ return {
81
+ ...logData,
82
+ metadata: {
83
+ ...logData.metadata,
84
+ environment: process.env.NODE_ENV || 'development',
85
+ platform: process.platform,
86
+ arch: process.arch
87
+ }
88
+ };
89
+ };
90
+ }
91
+ }
92
+ exports.MetadataEnricher = MetadataEnricher;
93
+ MetadataEnricher.addContext = MetadataEnricher.addStaticFields;
94
+ /**
95
+ * Applies a series of enrichers to a log record
96
+ */
97
+ class LogEnrichmentPipeline {
98
+ constructor(enrichers = []) {
99
+ this.enrichers = enrichers;
100
+ }
101
+ add(enricher) {
102
+ this.enrichers.push(enricher);
103
+ return this;
104
+ }
105
+ process(logData) {
106
+ return this.enrichers.reduce((data, enricher) => enricher(data), logData);
107
+ }
108
+ getEnrichers() {
109
+ return [...this.enrichers]; // Return a copy to prevent external modification
110
+ }
111
+ }
112
+ exports.LogEnrichmentPipeline = LogEnrichmentPipeline;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./StructuredExtensions.js"), exports);
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FilterableTransport = void 0;
4
+ /**
5
+ * A transport wrapper that applies filters before writing logs
6
+ */
7
+ class FilterableTransport {
8
+ constructor(transport, filters) {
9
+ this.transport = transport;
10
+ this.filters = filters;
11
+ }
12
+ write(data, formatter) {
13
+ // Check if the log should be emitted based on all filters
14
+ if (this.filters.every(filter => filter.shouldEmit(data))) {
15
+ this.transport.write(data, formatter);
16
+ }
17
+ }
18
+ writeAsync(data, formatter) {
19
+ // Check if the log should be emitted based on all filters
20
+ if (this.filters.every(filter => filter.shouldEmit(data))) {
21
+ if (this.transport.writeAsync) {
22
+ return this.transport.writeAsync(data, formatter);
23
+ }
24
+ else {
25
+ return new Promise((resolve, reject) => {
26
+ try {
27
+ this.transport.write(data, formatter);
28
+ resolve();
29
+ }
30
+ catch (error) {
31
+ reject(error);
32
+ }
33
+ });
34
+ }
35
+ }
36
+ return Promise.resolve();
37
+ }
38
+ }
39
+ exports.FilterableTransport = FilterableTransport;
@@ -18,3 +18,4 @@ __exportStar(require("./Transport.js"), exports);
18
18
  __exportStar(require("./ConsoleTransport.js"), exports);
19
19
  __exportStar(require("./FileTransport.js"), exports);
20
20
  __exportStar(require("./HttpTransport.js"), exports);
21
+ __exportStar(require("./FilterableTransport.js"), exports);
@@ -0,0 +1,60 @@
1
+ import { LogData } from '../types/index.js';
2
+ import { Formatter } from '../core/Formatter.js';
3
+ /**
4
+ * Interface for log aggregation targets
5
+ */
6
+ export interface LogAggregator {
7
+ /**
8
+ * Process a log record for aggregation
9
+ * @param logData The structured log record
10
+ * @param formatter The formatter used for the log
11
+ */
12
+ aggregate(logData: LogData, formatter: Formatter): void;
13
+ /**
14
+ * Flush any pending aggregated logs
15
+ */
16
+ flush(): Promise<void> | void;
17
+ }
18
+ /**
19
+ * Aggregates logs in memory and flushes them in batches
20
+ */
21
+ export declare class BatchAggregator implements LogAggregator {
22
+ private logs;
23
+ private maxSize;
24
+ private flushCallback;
25
+ constructor(maxSize: number | undefined, flushCallback: (logs: {
26
+ logData: LogData;
27
+ formatter: Formatter;
28
+ }[]) => Promise<void> | void);
29
+ aggregate(logData: LogData, formatter: Formatter): void;
30
+ flush(): Promise<void> | void;
31
+ }
32
+ /**
33
+ * Aggregates logs based on a time interval
34
+ */
35
+ export declare class TimeBasedAggregator implements LogAggregator {
36
+ private logs;
37
+ private flushInterval;
38
+ private flushCallback;
39
+ private timer;
40
+ constructor(flushInterval: number, // in milliseconds
41
+ flushCallback: (logs: {
42
+ logData: LogData;
43
+ formatter: Formatter;
44
+ }[]) => Promise<void> | void);
45
+ aggregate(logData: LogData, formatter: Formatter): void;
46
+ flush(): Promise<void> | void;
47
+ /**
48
+ * Stop the aggregator and cancel any pending timer without flushing
49
+ */
50
+ stop(): void;
51
+ }
52
+ /**
53
+ * Combines multiple aggregators
54
+ */
55
+ export declare class CompositeAggregator implements LogAggregator {
56
+ private aggregators;
57
+ constructor(aggregators: LogAggregator[]);
58
+ aggregate(logData: LogData, formatter: Formatter): void;
59
+ flush(): Promise<void> | void;
60
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Aggregates logs in memory and flushes them in batches
3
+ */
4
+ export class BatchAggregator {
5
+ constructor(maxSize = 100, flushCallback) {
6
+ this.logs = [];
7
+ this.maxSize = maxSize;
8
+ this.flushCallback = flushCallback;
9
+ }
10
+ aggregate(logData, formatter) {
11
+ this.logs.push({ logData, formatter });
12
+ if (this.logs.length >= this.maxSize) {
13
+ const result = this.flush();
14
+ // Handle the case where flush returns a Promise (async flushCallback)
15
+ if (result instanceof Promise) {
16
+ result.catch(error => {
17
+ console.error('Error in BatchAggregator flush callback:', error);
18
+ });
19
+ }
20
+ }
21
+ }
22
+ flush() {
23
+ if (this.logs.length > 0) {
24
+ const logsToFlush = [...this.logs];
25
+ this.logs = [];
26
+ return this.flushCallback(logsToFlush);
27
+ }
28
+ }
29
+ }
30
+ /**
31
+ * Aggregates logs based on a time interval
32
+ */
33
+ export class TimeBasedAggregator {
34
+ constructor(flushInterval, // in milliseconds
35
+ flushCallback) {
36
+ this.logs = [];
37
+ this.timer = null;
38
+ this.flushInterval = flushInterval;
39
+ this.flushCallback = flushCallback;
40
+ }
41
+ aggregate(logData, formatter) {
42
+ this.logs.push({ logData, formatter });
43
+ // Start the timer if it's not already running
44
+ if (!this.timer) {
45
+ this.timer = setTimeout(() => {
46
+ const result = this.flush();
47
+ // Handle the case where flush returns a Promise (async flushCallback)
48
+ if (result instanceof Promise) {
49
+ result.catch(error => {
50
+ console.error('Error in TimeBasedAggregator flush callback:', error);
51
+ });
52
+ }
53
+ }, this.flushInterval);
54
+ }
55
+ }
56
+ flush() {
57
+ if (this.logs.length > 0) {
58
+ // Clear the timer if it exists
59
+ if (this.timer) {
60
+ clearTimeout(this.timer);
61
+ this.timer = null;
62
+ }
63
+ const logsToFlush = [...this.logs];
64
+ this.logs = [];
65
+ return this.flushCallback(logsToFlush);
66
+ }
67
+ }
68
+ /**
69
+ * Stop the aggregator and cancel any pending timer without flushing
70
+ */
71
+ stop() {
72
+ if (this.timer) {
73
+ clearTimeout(this.timer);
74
+ this.timer = null;
75
+ }
76
+ }
77
+ }
78
+ /**
79
+ * Combines multiple aggregators
80
+ */
81
+ export class CompositeAggregator {
82
+ constructor(aggregators) {
83
+ this.aggregators = aggregators;
84
+ }
85
+ aggregate(logData, formatter) {
86
+ for (const aggregator of this.aggregators) {
87
+ aggregator.aggregate(logData, formatter);
88
+ }
89
+ }
90
+ flush() {
91
+ const results = [];
92
+ for (const aggregator of this.aggregators) {
93
+ const result = aggregator.flush();
94
+ if (result) {
95
+ results.push(result);
96
+ }
97
+ }
98
+ // If any aggregator returns a promise, wait for all of them
99
+ if (results.some(r => r instanceof Promise)) {
100
+ const promiseResults = results.filter(r => r instanceof Promise);
101
+ return Promise.all(promiseResults).then(() => { });
102
+ }
103
+ }
104
+ }
@@ -0,0 +1 @@
1
+ export * from './LogAggregator.js';
@@ -0,0 +1 @@
1
+ export * from './LogAggregator.js';
@@ -1,6 +1,9 @@
1
1
  import { LogLevel } from "./LogLevel.js";
2
2
  import { Transport } from "../transports/Transport.js";
3
3
  import { TransportConfig } from "../types/index.js";
4
+ import { Filter } from "../filters/Filter.js";
5
+ import { LogAggregator } from "../aggregation/LogAggregator.js";
6
+ import { LogEnricher, LogEnrichmentPipeline } from "../structured/StructuredExtensions.js";
4
7
  export interface LoggerOptions {
5
8
  level?: LogLevel;
6
9
  colorize?: boolean;
@@ -18,6 +21,9 @@ export interface LoggerOptions {
18
21
  customColors?: {
19
22
  [level: string]: string;
20
23
  };
24
+ filters?: Filter[];
25
+ aggregators?: LogAggregator[];
26
+ enrichers?: LogEnrichmentPipeline;
21
27
  }
22
28
  export declare class Logger {
23
29
  private level;
@@ -27,6 +33,9 @@ export declare class Logger {
27
33
  private parent;
28
34
  private asyncMode;
29
35
  private customLevels;
36
+ private filters;
37
+ private aggregators;
38
+ private enrichers;
30
39
  private static _global;
31
40
  static defaultTransportsFactory: ((isProd: boolean) => TransportConfig[]) | null;
32
41
  private static readonly LEVEL_PRIORITIES;
@@ -63,4 +72,28 @@ export declare class Logger {
63
72
  static get global(): Logger;
64
73
  createChild(options?: LoggerOptions): Logger;
65
74
  startTimer(name: string): any;
75
+ /**
76
+ * Add a filter to the logger
77
+ */
78
+ addFilter(filter: Filter): void;
79
+ /**
80
+ * Remove a filter from the logger
81
+ */
82
+ removeFilter(filter: Filter): boolean;
83
+ /**
84
+ * Add an aggregator to the logger
85
+ */
86
+ addAggregator(aggregator: LogAggregator): void;
87
+ /**
88
+ * Remove an aggregator from the logger
89
+ */
90
+ removeAggregator(aggregator: LogAggregator): boolean;
91
+ /**
92
+ * Add an enricher to the logger
93
+ */
94
+ addEnricher(enricher: LogEnricher): void;
95
+ /**
96
+ * Flush all aggregators
97
+ */
98
+ flushAggregators(): Promise<void>;
66
99
  }
@@ -1,13 +1,19 @@
1
1
  import { Formatter } from "./Formatter.js";
2
2
  import { ConsoleTransport } from "../transports/ConsoleTransport.js";
3
+ import { LogEnrichmentPipeline } from "../structured/StructuredExtensions.js";
3
4
  export class Logger {
4
5
  constructor(options = {}) {
5
6
  this.transports = [];
6
- const { level, colorize, json, transports = [], timestampFormat = "YYYY-MM-DD HH:mm:ss", prefix, timestamp, context = {}, parent, asyncMode, customLevels = {}, customColors = {}, } = options;
7
+ this.filters = [];
8
+ this.aggregators = [];
9
+ const { level, colorize, json, transports = [], timestampFormat = "YYYY-MM-DD HH:mm:ss", prefix, timestamp, context = {}, parent, asyncMode, customLevels = {}, customColors = {}, filters = [], aggregators = [], enrichers, } = options;
7
10
  this.parent = parent; // Set parent
8
11
  this.context = { ...context }; // Init context
9
12
  this.customLevels = customLevels; // custom log store
10
13
  this.asyncMode = false;
14
+ this.filters = [...filters]; // Copy filters
15
+ this.aggregators = [...aggregators]; // Copy aggregators
16
+ this.enrichers = enrichers ?? new LogEnrichmentPipeline(); // Set enrichers, default to new instance
11
17
  if (this.parent) {
12
18
  this.level = level ?? this.parent.level;
13
19
  this.prefix = prefix ?? this.parent.prefix;
@@ -33,6 +39,21 @@ export class Logger {
33
39
  this.context = { ...this.parent.context, ...this.context };
34
40
  // Merge custom levels with parent's custom levels
35
41
  this.customLevels = { ...this.parent.customLevels, ...customLevels };
42
+ // Merge filters with parent's filters
43
+ this.filters = [...this.parent.filters, ...filters];
44
+ // Merge aggregators with parent's aggregators
45
+ this.aggregators = [...this.parent.aggregators, ...aggregators];
46
+ // If child logger doesn't provide its own enrichers, use parent's
47
+ // If child logger provides enrichers, merge parent and child enrichers
48
+ if (enrichers) {
49
+ // Create a new pipeline that combines parent and child enrichers
50
+ const parentEnrichers = this.parent.enrichers.getEnrichers();
51
+ const childEnrichers = enrichers.getEnrichers();
52
+ this.enrichers = new LogEnrichmentPipeline([...parentEnrichers, ...childEnrichers]);
53
+ }
54
+ else {
55
+ this.enrichers = this.parent.enrichers;
56
+ }
36
57
  }
37
58
  else {
38
59
  // Auto-configure based on environment
@@ -137,7 +158,7 @@ export class Logger {
137
158
  finalMetadata = metadata;
138
159
  }
139
160
  // Only add metadata if it's not empty after merging
140
- const logData = {
161
+ let logData = {
141
162
  level,
142
163
  message,
143
164
  timestamp,
@@ -146,6 +167,17 @@ export class Logger {
146
167
  : undefined,
147
168
  prefix: this.prefix,
148
169
  };
170
+ // Apply enrichers to the log data
171
+ logData = this.enrichers.process(logData);
172
+ // Check if the log should be emitted based on filters
173
+ // Use a copy to prevent concurrent modification issues if filters are modified during logging
174
+ const currentFilters = [...this.filters];
175
+ if (currentFilters.length > 0) {
176
+ const shouldEmit = currentFilters.every(filter => filter.shouldEmit(logData));
177
+ if (!shouldEmit) {
178
+ return; // Don't emit if any filter rejects the log
179
+ }
180
+ }
149
181
  if (this.asyncMode) {
150
182
  for (const transport of this.transports) {
151
183
  if (transport.writeAsync) {
@@ -165,6 +197,17 @@ export class Logger {
165
197
  transport.write(logData, this.formatter);
166
198
  }
167
199
  }
200
+ // Send to aggregators if any exist
201
+ if (this.aggregators.length > 0) {
202
+ for (const aggregator of this.aggregators) {
203
+ try {
204
+ aggregator.aggregate(logData, this.formatter);
205
+ }
206
+ catch (error) {
207
+ console.error('Error in aggregator:', error);
208
+ }
209
+ }
210
+ }
168
211
  }
169
212
  debug(message, metadata) {
170
213
  this.log("debug", message, metadata);
@@ -218,6 +261,67 @@ export class Logger {
218
261
  const { Timer } = require("../utils/Timerutil");
219
262
  return new Timer(name, (message) => this.info(message));
220
263
  }
264
+ /**
265
+ * Add a filter to the logger
266
+ */
267
+ addFilter(filter) {
268
+ this.filters.push(filter);
269
+ }
270
+ /**
271
+ * Remove a filter from the logger
272
+ */
273
+ removeFilter(filter) {
274
+ const index = this.filters.indexOf(filter);
275
+ if (index !== -1) {
276
+ this.filters.splice(index, 1);
277
+ return true;
278
+ }
279
+ return false;
280
+ }
281
+ /**
282
+ * Add an aggregator to the logger
283
+ */
284
+ addAggregator(aggregator) {
285
+ this.aggregators.push(aggregator);
286
+ }
287
+ /**
288
+ * Remove an aggregator from the logger
289
+ */
290
+ removeAggregator(aggregator) {
291
+ const index = this.aggregators.indexOf(aggregator);
292
+ if (index !== -1) {
293
+ this.aggregators.splice(index, 1);
294
+ return true;
295
+ }
296
+ return false;
297
+ }
298
+ /**
299
+ * Add an enricher to the logger
300
+ */
301
+ addEnricher(enricher) {
302
+ this.enrichers.add(enricher);
303
+ }
304
+ /**
305
+ * Flush all aggregators
306
+ */
307
+ async flushAggregators() {
308
+ const flushPromises = [];
309
+ for (const aggregator of this.aggregators) {
310
+ try {
311
+ const result = aggregator.flush();
312
+ if (result instanceof Promise) {
313
+ // Wrap the promise to catch and log rejections, so one failure doesn't stop others
314
+ flushPromises.push(result.catch(error => {
315
+ console.error('Error flushing aggregator:', error);
316
+ }));
317
+ }
318
+ }
319
+ catch (error) {
320
+ console.error('Error flushing aggregator:', error);
321
+ }
322
+ }
323
+ await Promise.all(flushPromises);
324
+ }
221
325
  }
222
326
  Logger.defaultTransportsFactory = null;
223
327
  Logger.LEVEL_PRIORITIES = {
@@ -0,0 +1,47 @@
1
+ import { LogData } from '../types/index.js';
2
+ export interface Filter {
3
+ /**
4
+ * Determines if a log record should be emitted
5
+ * @param logData The structured log record
6
+ * @returns true if the log should be emitted, false if it should be filtered out
7
+ */
8
+ shouldEmit(logData: LogData): boolean;
9
+ }
10
+ export type FilterPredicate = (logData: LogData) => boolean;
11
+ /**
12
+ * A filter that combines multiple filters with AND logic
13
+ * Note: With an empty array of filters, this returns true (allows all logs).
14
+ * This follows the mathematical concept of vacuous truth - "all" conditions
15
+ * are satisfied when there are no conditions to check.
16
+ */
17
+ export declare class CompositeFilter implements Filter {
18
+ private filters;
19
+ constructor(filters: Filter[]);
20
+ shouldEmit(logData: LogData): boolean;
21
+ }
22
+ /**
23
+ * A filter that combines multiple filters with OR logic
24
+ * Note: With an empty array of filters, this returns false (blocks all logs).
25
+ * This is because there are no matching conditions when the filter array is empty.
26
+ */
27
+ export declare class OrFilter implements Filter {
28
+ private filters;
29
+ constructor(filters: Filter[]);
30
+ shouldEmit(logData: LogData): boolean;
31
+ }
32
+ /**
33
+ * A filter that negates another filter
34
+ */
35
+ export declare class NotFilter implements Filter {
36
+ private filter;
37
+ constructor(filter: Filter);
38
+ shouldEmit(logData: LogData): boolean;
39
+ }
40
+ /**
41
+ * A filter based on a predicate function
42
+ */
43
+ export declare class PredicateFilter implements Filter {
44
+ private predicate;
45
+ constructor(predicate: FilterPredicate);
46
+ shouldEmit(logData: LogData): boolean;
47
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * A filter that combines multiple filters with AND logic
3
+ * Note: With an empty array of filters, this returns true (allows all logs).
4
+ * This follows the mathematical concept of vacuous truth - "all" conditions
5
+ * are satisfied when there are no conditions to check.
6
+ */
7
+ export class CompositeFilter {
8
+ constructor(filters) {
9
+ this.filters = filters;
10
+ }
11
+ shouldEmit(logData) {
12
+ return this.filters.every(filter => filter.shouldEmit(logData));
13
+ }
14
+ }
15
+ /**
16
+ * A filter that combines multiple filters with OR logic
17
+ * Note: With an empty array of filters, this returns false (blocks all logs).
18
+ * This is because there are no matching conditions when the filter array is empty.
19
+ */
20
+ export class OrFilter {
21
+ constructor(filters) {
22
+ this.filters = filters;
23
+ }
24
+ shouldEmit(logData) {
25
+ return this.filters.some(filter => filter.shouldEmit(logData));
26
+ }
27
+ }
28
+ /**
29
+ * A filter that negates another filter
30
+ */
31
+ export class NotFilter {
32
+ constructor(filter) {
33
+ this.filter = filter;
34
+ }
35
+ shouldEmit(logData) {
36
+ return !this.filter.shouldEmit(logData);
37
+ }
38
+ }
39
+ /**
40
+ * A filter based on a predicate function
41
+ */
42
+ export class PredicateFilter {
43
+ constructor(predicate) {
44
+ this.predicate = predicate;
45
+ }
46
+ shouldEmit(logData) {
47
+ return this.predicate(logData);
48
+ }
49
+ }