@blac/logging-plugin 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  Logging and debugging plugin for BlaC state management. Logs instance lifecycle, state changes, events, and monitors for potential memory issues.
4
4
 
5
+ **[Full documentation](https://jsnanigans.github.io/blac/plugins/logging)**
6
+
5
7
  ## Installation
6
8
 
7
9
  ```bash
@@ -69,7 +71,7 @@ new LoggingPlugin({
69
71
  **Simple format:**
70
72
 
71
73
  ```
72
- [BlaC] Created CounterCubit#abc12345 (isolated)
74
+ [BlaC] Created CounterCubit#abc12345
73
75
  [BlaC] CounterCubit#abc12345 state: 0 → 1
74
76
  [BlaC] Disposed CounterCubit#abc12345 (lived 5.2s)
75
77
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"LoggingPlugin.d.ts","sourceRoot":"","sources":["../src/LoggingPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK5E,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,SAAS,CAAC;AAKjB,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,WAAW;IAE3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,gBAAgB,CAAmB;IAG3C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,0BAA0B,CAAS;gBAE/B,MAAM,GAAE,mBAAwB;IAmB5C,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAWvC,WAAW,IAAI,IAAI;IAenB,iBAAiB,CACf,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IA6BP,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7B,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,aAAa,EAAE,CAAC,EAChB,YAAY,EAAE,CAAC,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IAyDP,kBAAkB,CAChB,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IAkCP,QAAQ,IAAI,IAAI;IAWhB,OAAO,CAAC,SAAS;IA2BjB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,UAAU;CAOnB"}
1
+ {"version":3,"file":"LoggingPlugin.d.ts","sourceRoot":"","sources":["../src/LoggingPlugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAK5E,OAAO,KAAK,EACV,mBAAmB,EAGpB,MAAM,SAAS,CAAC;AAKjB,qBAAa,aAAc,YAAW,UAAU;IAC9C,QAAQ,CAAC,IAAI,mBAAmB;IAChC,QAAQ,CAAC,OAAO,WAAW;IAE3B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,OAAO,CAAC,CAAgB;IAChC,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,gBAAgB,CAAmB;IAC3C,OAAO,CAAC,oBAAoB,CAAuB;IACnD,OAAO,CAAC,gBAAgB,CAAmB;IAG3C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,0BAA0B,CAAS;gBAE/B,MAAM,GAAE,mBAAwB;IAmB5C,SAAS,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;IAWvC,WAAW,IAAI,IAAI;IAenB,iBAAiB,CACf,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IAsBP,cAAc,CAAC,CAAC,SAAS,MAAM,EAC7B,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,aAAa,EAAE,CAAC,EAChB,YAAY,EAAE,CAAC,EACf,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IAkDP,kBAAkB,CAChB,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,EAC7B,OAAO,EAAE,aAAa,GACrB,IAAI;IA2BP,QAAQ,IAAI,IAAI;IAWhB,OAAO,CAAC,SAAS;IAyBjB,OAAO,CAAC,kBAAkB;IAK1B,OAAO,CAAC,qBAAqB;IAS7B,OAAO,CAAC,UAAU;CAOnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"GroupedFormatter.d.ts","sourceRoot":"","sources":["../../src/formatters/GroupedFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAU,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,cAAc;IAKlC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,QAAQ;IAMhB,UAAU,CAAC,KAAK,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAO5E,YAAY,IAAI,IAAI;IAIpB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAa3E,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,GACvB,IAAI;IASP,eAAe,CACb,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,gBAAgB,EAAE,OAAO,GACxB,IAAI;IAWP,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpE,QAAQ,CAAC,KAAK,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,GAAG,IAAI;IAQR,OAAO,CAAC,cAAc;CAKvB"}
1
+ {"version":3,"file":"GroupedFormatter.d.ts","sourceRoot":"","sources":["../../src/formatters/GroupedFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAU,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvD,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,cAAc;IAKlC,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,KAAK;IAUb,OAAO,CAAC,QAAQ;IAMhB,UAAU,CAAC,KAAK,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAO5E,YAAY,IAAI,IAAI;IAIpB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,YAAY,EAAE,OAAO,GAAG,IAAI;IAY3E,mBAAmB,CACjB,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,EAAE,MAAM,EAClB,gBAAgB,EAAE,MAAM,GACvB,IAAI;IASP,eAAe,CACb,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,gBAAgB,EAAE,OAAO,GACxB,IAAI;IAWP,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpE,QAAQ,CAAC,KAAK,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,GAAG,IAAI;IAQR,OAAO,CAAC,cAAc;CAKvB"}
@@ -1 +1 @@
1
- {"version":3,"file":"SimpleFormatter.d.ts","sourceRoot":"","sources":["../../src/formatters/SimpleFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAU,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,cAAc;IAKlC,OAAO,CAAC,gBAAgB;IAKxB,UAAU,CAAC,KAAK,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAM5E,YAAY,IAAI,IAAI;IAIpB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAMpD,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAQzE,eAAe,CACb,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,EACrB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,EAAE,OAAO,GACxB,IAAI;IAWP,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,QAAQ,CAAC,KAAK,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,GAAG,IAAI;IAMR,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,cAAc;CAKvB"}
1
+ {"version":3,"file":"SimpleFormatter.d.ts","sourceRoot":"","sources":["../../src/formatters/SimpleFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAU,cAAc,EAAE,MAAM,UAAU,CAAC;AAEvD,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,cAAc;IAKlC,OAAO,CAAC,gBAAgB;IAKxB,UAAU,CAAC,KAAK,EAAE;QAAE,eAAe,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAM5E,YAAY,IAAI,IAAI;IAIpB,kBAAkB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAKpD,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAQzE,eAAe,CACb,QAAQ,EAAE,gBAAgB,EAC1B,aAAa,EAAE,OAAO,EACtB,YAAY,EAAE,OAAO,EACrB,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,gBAAgB,EAAE,OAAO,GACxB,IAAI;IAWP,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAIjC,QAAQ,CAAC,KAAK,EAAE;QACd,eAAe,EAAE,MAAM,CAAC;QACxB,cAAc,EAAE,MAAM,CAAC;QACvB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,GAAG,IAAI;IAMR,OAAO,CAAC,WAAW;IAcnB,OAAO,CAAC,cAAc;CAKvB"}
package/dist/index.cjs CHANGED
@@ -1,4 +1,4 @@
1
-
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  //#region src/formatters/SimpleFormatter.ts
3
3
  var SimpleFormatter = class {
4
4
  constructor(config) {
@@ -16,8 +16,7 @@ var SimpleFormatter = class {
16
16
  }
17
17
  logInstanceCreated(metadata) {
18
18
  const instanceId = this.formatInstanceId(metadata.className, metadata.id);
19
- const isolated = metadata.isIsolated ? " (isolated)" : "";
20
- this.logger.log(`${this.prefix} Created ${instanceId}${isolated}`);
19
+ this.logger.log(`${this.prefix} Created ${instanceId}`);
21
20
  }
22
21
  logInstanceDisposed(metadata, lifespanMs) {
23
22
  const instanceId = this.formatInstanceId(metadata.className, metadata.id);
@@ -54,7 +53,6 @@ var SimpleFormatter = class {
54
53
  return `${(ms / 6e4).toFixed(1)}m`;
55
54
  }
56
55
  };
57
-
58
56
  //#endregion
59
57
  //#region src/formatters/GroupedFormatter.ts
60
58
  var GroupedFormatter = class {
@@ -87,7 +85,6 @@ var GroupedFormatter = class {
87
85
  this.group(`${this.prefix} Created ${instanceId}`);
88
86
  this.logger.log("Class:", metadata.className);
89
87
  this.logger.log("Instance ID:", metadata.id);
90
- this.logger.log("Isolated:", metadata.isIsolated);
91
88
  this.logger.log("Initial state:", initialState);
92
89
  if (metadata.callstack) this.logger.log("Callstack:", metadata.callstack);
93
90
  this.groupEnd();
@@ -128,7 +125,6 @@ var GroupedFormatter = class {
128
125
  return `${(ms / 6e4).toFixed(1)}m`;
129
126
  }
130
127
  };
131
-
132
128
  //#endregion
133
129
  //#region src/monitors/InstanceCountMonitor.ts
134
130
  var InstanceCountMonitor = class {
@@ -163,7 +159,6 @@ var InstanceCountMonitor = class {
163
159
  this.warnedClasses.clear();
164
160
  }
165
161
  };
166
-
167
162
  //#endregion
168
163
  //#region src/monitors/LifecycleMonitor.ts
169
164
  var LifecycleMonitor = class {
@@ -231,7 +226,6 @@ var LifecycleMonitor = class {
231
226
  this.warnedClasses.clear();
232
227
  }
233
228
  };
234
-
235
229
  //#endregion
236
230
  //#region src/types.ts
237
231
  function resolveConfig(config = {}) {
@@ -252,7 +246,6 @@ function resolveConfig(config = {}) {
252
246
  prefix: config.prefix ?? "[BlaC]"
253
247
  };
254
248
  }
255
-
256
249
  //#endregion
257
250
  //#region src/LoggingPlugin.ts
258
251
  const STATE_CHANGE_RATE_LIMIT = 1e3;
@@ -290,7 +283,7 @@ var LoggingPlugin = class {
290
283
  }
291
284
  onInstanceCreated(instance, context) {
292
285
  const metadata = context.getInstanceMetadata(instance);
293
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
286
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
294
287
  this.instanceCountMonitor.onInstanceCreated(metadata.className);
295
288
  this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);
296
289
  if (!this.shouldLogLifecycle()) return;
@@ -299,7 +292,7 @@ var LoggingPlugin = class {
299
292
  }
300
293
  onStateChanged(instance, previousState, currentState, callstack, context) {
301
294
  const metadata = context.getInstanceMetadata(instance);
302
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
295
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
303
296
  this.lifecycleMonitor.onStateChanged(metadata.id);
304
297
  if (!this.shouldLogStateChanges()) return;
305
298
  if (this.stateChangeLoggingDisabled) return;
@@ -319,7 +312,7 @@ var LoggingPlugin = class {
319
312
  }
320
313
  onInstanceDisposed(instance, context) {
321
314
  const metadata = context.getInstanceMetadata(instance);
322
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
315
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
323
316
  const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);
324
317
  const lifespanMs = info ? Date.now() - info.createdAt : 0;
325
318
  const stateChangeCount = info?.stateChangeCount ?? 0;
@@ -335,15 +328,14 @@ var LoggingPlugin = class {
335
328
  if (this.config.format === "simple") this.simpleFormatter.logStats(stats);
336
329
  else this.groupedFormatter.logStats(stats);
337
330
  }
338
- shouldLog(instance, className, instanceId, isIsolated) {
331
+ shouldLog(instance, className, instanceId) {
339
332
  if (this.config.include && !this.config.include.includes(className)) return false;
340
333
  if (this.config.exclude?.includes(className)) return false;
341
334
  if (this.config.filter) {
342
335
  const ctx = {
343
336
  instance,
344
337
  className,
345
- instanceId,
346
- isIsolated
338
+ instanceId
347
339
  };
348
340
  return this.config.filter(ctx);
349
341
  }
@@ -362,7 +354,7 @@ var LoggingPlugin = class {
362
354
  else this.groupedFormatter.logWarning(message, details);
363
355
  }
364
356
  };
365
-
366
357
  //#endregion
367
358
  exports.LoggingPlugin = LoggingPlugin;
359
+
368
360
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":[],"sources":["../src/formatters/SimpleFormatter.ts","../src/formatters/GroupedFormatter.ts","../src/monitors/InstanceCountMonitor.ts","../src/monitors/LifecycleMonitor.ts","../src/types.ts","../src/LoggingPlugin.ts"],"sourcesContent":["import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class SimpleFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.logger.log(\n `${this.prefix} Plugin installed (${stats.registeredTypes} types, ${stats.totalInstances} instances)`,\n );\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const isolated = metadata.isIsolated ? ' (isolated)' : '';\n this.logger.log(`${this.prefix} Created ${instanceId}${isolated}`);\n }\n\n logInstanceDisposed(metadata: InstanceMetadata, lifespanMs: number): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const lifespan = this.formatDuration(lifespanMs);\n this.logger.log(\n `${this.prefix} Disposed ${instanceId} (lived ${lifespan})`,\n );\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n _callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const prev = this.formatState(previousState);\n const curr = this.formatState(currentState);\n this.logger.log(`${this.prefix} ${instanceId} state: ${prev} → ${curr}`);\n\n if (includeCallstack && _callstack) {\n this.logger.log(`${this.prefix} Callstack: ${_callstack}`);\n }\n }\n\n logWarning(message: string): void {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.logger.log(\n `${this.prefix} Stats: ${stats.totalInstances} instances across ${stats.registeredTypes} types`,\n );\n }\n\n private formatState(state: unknown): string {\n if (state === null) return 'null';\n if (state === undefined) return 'undefined';\n if (typeof state === 'object') {\n try {\n const str = JSON.stringify(state);\n return str.length > 50 ? str.slice(0, 50) + '...' : str;\n } catch {\n return '[Object]';\n }\n }\n return String(state);\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class GroupedFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n private group(label: string, collapsed = true): void {\n if (collapsed && this.logger.groupCollapsed) {\n this.logger.groupCollapsed(label);\n } else if (this.logger.group) {\n this.logger.group(label);\n } else {\n this.logger.log(label);\n }\n }\n\n private groupEnd(): void {\n if (this.logger.groupEnd) {\n this.logger.groupEnd();\n }\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.group(`${this.prefix} Plugin installed`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.groupEnd();\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata, initialState: unknown): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Created ${instanceId}`);\n this.logger.log('Class:', metadata.className);\n this.logger.log('Instance ID:', metadata.id);\n this.logger.log('Isolated:', metadata.isIsolated);\n this.logger.log('Initial state:', initialState);\n if (metadata.callstack) {\n this.logger.log('Callstack:', metadata.callstack);\n }\n this.groupEnd();\n }\n\n logInstanceDisposed(\n metadata: InstanceMetadata,\n lifespanMs: number,\n stateChangeCount: number,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Disposed ${instanceId}`);\n this.logger.log('Lifespan:', this.formatDuration(lifespanMs));\n this.logger.log('State changes:', stateChangeCount);\n this.logger.log('Final state:', metadata.state);\n this.groupEnd();\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} ${instanceId} state changed`);\n this.logger.log('Previous:', previousState);\n this.logger.log('Current:', currentState);\n if (includeCallstack && callstack) {\n this.logger.log('Callstack:', callstack);\n }\n this.groupEnd();\n }\n\n logWarning(message: string, details?: Record<string, unknown>): void {\n if (details) {\n this.group(`${this.prefix} ⚠️ ${message}`, false);\n for (const [key, value] of Object.entries(details)) {\n this.logger.log(`${key}:`, value);\n }\n this.groupEnd();\n } else {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.group(`${this.prefix} Stats`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.logger.log('Breakdown:', stats.typeBreakdown);\n this.groupEnd();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { ResolvedConfig } from '../types';\n\nexport class InstanceCountMonitor {\n private instanceCounts = new Map<string, number>();\n private warnedClasses = new Set<string>();\n private threshold: number;\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.threshold = config.instanceCountWarningThreshold;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string): void {\n const count = (this.instanceCounts.get(className) ?? 0) + 1;\n this.instanceCounts.set(className, count);\n\n if (count >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `High instance count: ${className} has ${count} instances`,\n {\n className,\n count,\n threshold: this.threshold,\n },\n );\n }\n }\n\n onInstanceDisposed(className: string): void {\n const count = this.instanceCounts.get(className) ?? 0;\n if (count > 0) {\n this.instanceCounts.set(className, count - 1);\n }\n\n if (count - 1 < this.threshold) {\n this.warnedClasses.delete(className);\n }\n }\n\n getStats(): Map<string, number> {\n return new Map(this.instanceCounts);\n }\n\n reset(): void {\n this.instanceCounts.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { ResolvedConfig } from '../types';\n\ninterface LifecycleEvent {\n timestamp: number;\n type: 'created' | 'disposed';\n}\n\ninterface InstanceInfo {\n createdAt: number;\n stateChangeCount: number;\n}\n\nexport class LifecycleMonitor {\n private lifecycleHistory = new Map<string, LifecycleEvent[]>();\n private instanceInfo = new Map<string, InstanceInfo>();\n private windowMs: number;\n private threshold: number;\n private enabled: boolean;\n private warnedClasses = new Set<string>();\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.windowMs = config.rapidLifecycleWindowMs;\n this.threshold = config.rapidLifecycleThreshold;\n this.enabled = config.detectRapidLifecycles;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.set(instanceId, {\n createdAt: Date.now(),\n stateChangeCount: 0,\n });\n\n this.recordEvent(className, 'created');\n this.checkRapidLifecycle(className);\n }\n\n onInstanceDisposed(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.delete(instanceId);\n this.recordEvent(className, 'disposed');\n this.checkRapidLifecycle(className);\n }\n\n onStateChanged(instanceId: string): void {\n const info = this.instanceInfo.get(instanceId);\n if (info) {\n info.stateChangeCount++;\n }\n }\n\n getInstanceInfo(instanceId: string): InstanceInfo | undefined {\n return this.instanceInfo.get(instanceId);\n }\n\n private recordEvent(className: string, type: 'created' | 'disposed'): void {\n const now = Date.now();\n const events = this.lifecycleHistory.get(className) ?? [];\n\n events.push({ timestamp: now, type });\n\n const cutoff = now - this.windowMs;\n const filtered = events.filter((e) => e.timestamp > cutoff);\n this.lifecycleHistory.set(className, filtered);\n }\n\n private checkRapidLifecycle(className: string): void {\n const events = this.lifecycleHistory.get(className) ?? [];\n const cycleCount = Math.min(\n events.filter((e) => e.type === 'created').length,\n events.filter((e) => e.type === 'disposed').length,\n );\n\n if (cycleCount >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `Rapid lifecycle: ${className} created/disposed ${cycleCount} times in ${this.windowMs}ms`,\n {\n className,\n cycleCount,\n windowMs: this.windowMs,\n threshold: this.threshold,\n },\n );\n\n setTimeout(() => {\n this.warnedClasses.delete(className);\n }, this.windowMs);\n }\n }\n\n reset(): void {\n this.lifecycleHistory.clear();\n this.instanceInfo.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { StateContainer } from '@blac/core';\n\nexport type LogLevel = 'minimal' | 'info' | 'debug' | 'verbose';\n\nexport type LogFormat = 'simple' | 'grouped';\n\nexport interface Logger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n group?(label: string): void;\n groupEnd?(): void;\n groupCollapsed?(label: string): void;\n}\n\nexport interface FilterContext {\n instance: StateContainer<any>;\n className: string;\n instanceId: string;\n isIsolated: boolean;\n}\n\nexport type FilterFn = (ctx: FilterContext) => boolean;\n\nexport interface LoggingPluginConfig {\n /** Log verbosity level (default: 'info') */\n level?: LogLevel;\n\n /** Output format (default: 'grouped') */\n format?: LogFormat;\n\n /** Custom logger implementation (default: console) */\n logger?: Logger;\n\n /** Filter which instances to log */\n filter?: FilterFn;\n\n /** Include class names to log (whitelist) */\n include?: string[];\n\n /** Exclude class names from logging (blacklist) */\n exclude?: string[];\n\n /** Log instance creation/disposal (default: true) */\n logLifecycle?: boolean;\n\n /** Log state changes (default: true) */\n logStateChanges?: boolean;\n\n /** Include callstack in state change logs (default: false) */\n includeCallstack?: boolean;\n\n /** Warn when instance count exceeds threshold (default: 50) */\n instanceCountWarningThreshold?: number;\n\n /** Warn on rapid init/dispose cycles (default: true) */\n detectRapidLifecycles?: boolean;\n\n /** Time window for rapid lifecycle detection in ms (default: 1000) */\n rapidLifecycleWindowMs?: number;\n\n /** Number of cycles in window to trigger warning (default: 5) */\n rapidLifecycleThreshold?: number;\n\n /** Log prefix (default: '[BlaC]') */\n prefix?: string;\n}\n\nexport interface ResolvedConfig {\n level: LogLevel;\n format: LogFormat;\n logger: Logger;\n filter: FilterFn | undefined;\n include: string[] | undefined;\n exclude: string[] | undefined;\n logLifecycle: boolean;\n logStateChanges: boolean;\n includeCallstack: boolean;\n instanceCountWarningThreshold: number;\n detectRapidLifecycles: boolean;\n rapidLifecycleWindowMs: number;\n rapidLifecycleThreshold: number;\n prefix: string;\n}\n\nexport function resolveConfig(\n config: LoggingPluginConfig = {},\n): ResolvedConfig {\n return {\n level: config.level ?? 'info',\n format: config.format ?? 'grouped',\n logger: config.logger ?? console,\n filter: config.filter,\n include: config.include,\n exclude: config.exclude,\n logLifecycle: config.logLifecycle ?? true,\n logStateChanges: config.logStateChanges ?? true,\n includeCallstack: config.includeCallstack ?? false,\n instanceCountWarningThreshold: config.instanceCountWarningThreshold ?? 50,\n detectRapidLifecycles: config.detectRapidLifecycles ?? true,\n rapidLifecycleWindowMs: config.rapidLifecycleWindowMs ?? 1000,\n rapidLifecycleThreshold: config.rapidLifecycleThreshold ?? 5,\n prefix: config.prefix ?? '[BlaC]',\n };\n}\n","import type { BlacPlugin, PluginContext, StateContainer } from '@blac/core';\nimport { SimpleFormatter } from './formatters/SimpleFormatter';\nimport { GroupedFormatter } from './formatters/GroupedFormatter';\nimport { InstanceCountMonitor } from './monitors/InstanceCountMonitor';\nimport { LifecycleMonitor } from './monitors/LifecycleMonitor';\nimport type {\n LoggingPluginConfig,\n ResolvedConfig,\n FilterContext,\n} from './types';\nimport { resolveConfig } from './types';\n\nconst STATE_CHANGE_RATE_LIMIT = 1000; // max state changes per second\n\nexport class LoggingPlugin implements BlacPlugin {\n readonly name = 'LoggingPlugin';\n readonly version = '1.0.0';\n\n private config: ResolvedConfig;\n private context?: PluginContext;\n private simpleFormatter: SimpleFormatter;\n private groupedFormatter: GroupedFormatter;\n private instanceCountMonitor: InstanceCountMonitor;\n private lifecycleMonitor: LifecycleMonitor;\n\n // Rate limiting for state changes\n private stateChangeCount = 0;\n private stateChangeWindowStart = Date.now();\n private stateChangeLoggingDisabled = false;\n\n constructor(config: LoggingPluginConfig = {}) {\n this.config = resolveConfig(config);\n\n const warningHandler = (\n message: string,\n details?: Record<string, unknown>,\n ) => {\n this.logWarning(message, details);\n };\n\n this.simpleFormatter = new SimpleFormatter(this.config);\n this.groupedFormatter = new GroupedFormatter(this.config);\n this.instanceCountMonitor = new InstanceCountMonitor(\n this.config,\n warningHandler,\n );\n this.lifecycleMonitor = new LifecycleMonitor(this.config, warningHandler);\n }\n\n onInstall(context: PluginContext): void {\n this.context = context;\n const stats = context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstall(stats);\n } else {\n this.groupedFormatter.logInstall(stats);\n }\n }\n\n onUninstall(): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logUninstall();\n } else {\n this.groupedFormatter.logUninstall();\n }\n\n this.instanceCountMonitor.reset();\n this.lifecycleMonitor.reset();\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = Date.now();\n this.stateChangeLoggingDisabled = false;\n this.context = undefined;\n }\n\n onInstanceCreated(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n this.instanceCountMonitor.onInstanceCreated(metadata.className);\n this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceCreated(metadata);\n } else {\n this.groupedFormatter.logInstanceCreated(\n metadata,\n context.getState(instance),\n );\n }\n }\n\n onStateChanged<S extends object>(\n instance: StateContainer<S>,\n previousState: S,\n currentState: S,\n callstack: string | undefined,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n this.lifecycleMonitor.onStateChanged(metadata.id);\n\n if (!this.shouldLogStateChanges()) return;\n\n // Check rate limit\n if (this.stateChangeLoggingDisabled) return;\n\n const now = Date.now();\n if (now - this.stateChangeWindowStart >= 1000) {\n // Reset window\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = now;\n }\n\n this.stateChangeCount++;\n\n if (this.stateChangeCount > STATE_CHANGE_RATE_LIMIT) {\n this.stateChangeLoggingDisabled = true;\n this.logWarning(\n `State change logging disabled: exceeded ${STATE_CHANGE_RATE_LIMIT} changes/second`,\n );\n return;\n }\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n } else {\n this.groupedFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n }\n }\n\n onInstanceDisposed(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);\n const lifespanMs = info ? Date.now() - info.createdAt : 0;\n const stateChangeCount = info?.stateChangeCount ?? 0;\n\n this.instanceCountMonitor.onInstanceDisposed(metadata.className);\n this.lifecycleMonitor.onInstanceDisposed(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceDisposed(metadata, lifespanMs);\n } else {\n this.groupedFormatter.logInstanceDisposed(\n metadata,\n lifespanMs,\n stateChangeCount,\n );\n }\n }\n\n logStats(): void {\n if (!this.context) return;\n const stats = this.context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStats(stats);\n } else {\n this.groupedFormatter.logStats(stats);\n }\n }\n\n private shouldLog(\n instance: StateContainer<any>,\n className: string,\n instanceId: string,\n isIsolated: boolean,\n ): boolean {\n if (this.config.include && !this.config.include.includes(className)) {\n return false;\n }\n\n if (this.config.exclude?.includes(className)) {\n return false;\n }\n\n if (this.config.filter) {\n const ctx: FilterContext = {\n instance,\n className,\n instanceId,\n isIsolated,\n };\n return this.config.filter(ctx);\n }\n\n return true;\n }\n\n private shouldLogLifecycle(): boolean {\n if (!this.config.logLifecycle) return false;\n return this.config.level !== 'minimal';\n }\n\n private shouldLogStateChanges(): boolean {\n if (!this.config.logStateChanges) return false;\n return (\n this.config.level === 'info' ||\n this.config.level === 'debug' ||\n this.config.level === 'verbose'\n );\n }\n\n private logWarning(message: string, details?: Record<string, unknown>): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logWarning(message);\n } else {\n this.groupedFormatter.logWarning(message, details);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":[],"sources":["../src/formatters/SimpleFormatter.ts","../src/formatters/GroupedFormatter.ts","../src/monitors/InstanceCountMonitor.ts","../src/monitors/LifecycleMonitor.ts","../src/types.ts","../src/LoggingPlugin.ts"],"sourcesContent":["import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class SimpleFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.logger.log(\n `${this.prefix} Plugin installed (${stats.registeredTypes} types, ${stats.totalInstances} instances)`,\n );\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.logger.log(`${this.prefix} Created ${instanceId}`);\n }\n\n logInstanceDisposed(metadata: InstanceMetadata, lifespanMs: number): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const lifespan = this.formatDuration(lifespanMs);\n this.logger.log(\n `${this.prefix} Disposed ${instanceId} (lived ${lifespan})`,\n );\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n _callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const prev = this.formatState(previousState);\n const curr = this.formatState(currentState);\n this.logger.log(`${this.prefix} ${instanceId} state: ${prev} → ${curr}`);\n\n if (includeCallstack && _callstack) {\n this.logger.log(`${this.prefix} Callstack: ${_callstack}`);\n }\n }\n\n logWarning(message: string): void {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.logger.log(\n `${this.prefix} Stats: ${stats.totalInstances} instances across ${stats.registeredTypes} types`,\n );\n }\n\n private formatState(state: unknown): string {\n if (state === null) return 'null';\n if (state === undefined) return 'undefined';\n if (typeof state === 'object') {\n try {\n const str = JSON.stringify(state);\n return str.length > 50 ? str.slice(0, 50) + '...' : str;\n } catch {\n return '[Object]';\n }\n }\n return String(state);\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class GroupedFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n private group(label: string, collapsed = true): void {\n if (collapsed && this.logger.groupCollapsed) {\n this.logger.groupCollapsed(label);\n } else if (this.logger.group) {\n this.logger.group(label);\n } else {\n this.logger.log(label);\n }\n }\n\n private groupEnd(): void {\n if (this.logger.groupEnd) {\n this.logger.groupEnd();\n }\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.group(`${this.prefix} Plugin installed`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.groupEnd();\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata, initialState: unknown): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Created ${instanceId}`);\n this.logger.log('Class:', metadata.className);\n this.logger.log('Instance ID:', metadata.id);\n this.logger.log('Initial state:', initialState);\n if (metadata.callstack) {\n this.logger.log('Callstack:', metadata.callstack);\n }\n this.groupEnd();\n }\n\n logInstanceDisposed(\n metadata: InstanceMetadata,\n lifespanMs: number,\n stateChangeCount: number,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Disposed ${instanceId}`);\n this.logger.log('Lifespan:', this.formatDuration(lifespanMs));\n this.logger.log('State changes:', stateChangeCount);\n this.logger.log('Final state:', metadata.state);\n this.groupEnd();\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} ${instanceId} state changed`);\n this.logger.log('Previous:', previousState);\n this.logger.log('Current:', currentState);\n if (includeCallstack && callstack) {\n this.logger.log('Callstack:', callstack);\n }\n this.groupEnd();\n }\n\n logWarning(message: string, details?: Record<string, unknown>): void {\n if (details) {\n this.group(`${this.prefix} ⚠️ ${message}`, false);\n for (const [key, value] of Object.entries(details)) {\n this.logger.log(`${key}:`, value);\n }\n this.groupEnd();\n } else {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.group(`${this.prefix} Stats`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.logger.log('Breakdown:', stats.typeBreakdown);\n this.groupEnd();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { ResolvedConfig } from '../types';\n\nexport class InstanceCountMonitor {\n private instanceCounts = new Map<string, number>();\n private warnedClasses = new Set<string>();\n private threshold: number;\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.threshold = config.instanceCountWarningThreshold;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string): void {\n const count = (this.instanceCounts.get(className) ?? 0) + 1;\n this.instanceCounts.set(className, count);\n\n if (count >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `High instance count: ${className} has ${count} instances`,\n {\n className,\n count,\n threshold: this.threshold,\n },\n );\n }\n }\n\n onInstanceDisposed(className: string): void {\n const count = this.instanceCounts.get(className) ?? 0;\n if (count > 0) {\n this.instanceCounts.set(className, count - 1);\n }\n\n if (count - 1 < this.threshold) {\n this.warnedClasses.delete(className);\n }\n }\n\n getStats(): Map<string, number> {\n return new Map(this.instanceCounts);\n }\n\n reset(): void {\n this.instanceCounts.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { ResolvedConfig } from '../types';\n\ninterface LifecycleEvent {\n timestamp: number;\n type: 'created' | 'disposed';\n}\n\ninterface InstanceInfo {\n createdAt: number;\n stateChangeCount: number;\n}\n\nexport class LifecycleMonitor {\n private lifecycleHistory = new Map<string, LifecycleEvent[]>();\n private instanceInfo = new Map<string, InstanceInfo>();\n private windowMs: number;\n private threshold: number;\n private enabled: boolean;\n private warnedClasses = new Set<string>();\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.windowMs = config.rapidLifecycleWindowMs;\n this.threshold = config.rapidLifecycleThreshold;\n this.enabled = config.detectRapidLifecycles;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.set(instanceId, {\n createdAt: Date.now(),\n stateChangeCount: 0,\n });\n\n this.recordEvent(className, 'created');\n this.checkRapidLifecycle(className);\n }\n\n onInstanceDisposed(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.delete(instanceId);\n this.recordEvent(className, 'disposed');\n this.checkRapidLifecycle(className);\n }\n\n onStateChanged(instanceId: string): void {\n const info = this.instanceInfo.get(instanceId);\n if (info) {\n info.stateChangeCount++;\n }\n }\n\n getInstanceInfo(instanceId: string): InstanceInfo | undefined {\n return this.instanceInfo.get(instanceId);\n }\n\n private recordEvent(className: string, type: 'created' | 'disposed'): void {\n const now = Date.now();\n const events = this.lifecycleHistory.get(className) ?? [];\n\n events.push({ timestamp: now, type });\n\n const cutoff = now - this.windowMs;\n const filtered = events.filter((e) => e.timestamp > cutoff);\n this.lifecycleHistory.set(className, filtered);\n }\n\n private checkRapidLifecycle(className: string): void {\n const events = this.lifecycleHistory.get(className) ?? [];\n const cycleCount = Math.min(\n events.filter((e) => e.type === 'created').length,\n events.filter((e) => e.type === 'disposed').length,\n );\n\n if (cycleCount >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `Rapid lifecycle: ${className} created/disposed ${cycleCount} times in ${this.windowMs}ms`,\n {\n className,\n cycleCount,\n windowMs: this.windowMs,\n threshold: this.threshold,\n },\n );\n\n setTimeout(() => {\n this.warnedClasses.delete(className);\n }, this.windowMs);\n }\n }\n\n reset(): void {\n this.lifecycleHistory.clear();\n this.instanceInfo.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { StateContainer } from '@blac/core';\n\nexport type LogLevel = 'minimal' | 'info' | 'debug' | 'verbose';\n\nexport type LogFormat = 'simple' | 'grouped';\n\nexport interface Logger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n group?(label: string): void;\n groupEnd?(): void;\n groupCollapsed?(label: string): void;\n}\n\nexport interface FilterContext {\n instance: StateContainer<any>;\n className: string;\n instanceId: string;\n}\n\nexport type FilterFn = (ctx: FilterContext) => boolean;\n\nexport interface LoggingPluginConfig {\n /** Log verbosity level (default: 'info') */\n level?: LogLevel;\n\n /** Output format (default: 'grouped') */\n format?: LogFormat;\n\n /** Custom logger implementation (default: console) */\n logger?: Logger;\n\n /** Filter which instances to log */\n filter?: FilterFn;\n\n /** Include class names to log (whitelist) */\n include?: string[];\n\n /** Exclude class names from logging (blacklist) */\n exclude?: string[];\n\n /** Log instance creation/disposal (default: true) */\n logLifecycle?: boolean;\n\n /** Log state changes (default: true) */\n logStateChanges?: boolean;\n\n /** Include callstack in state change logs (default: false) */\n includeCallstack?: boolean;\n\n /** Warn when instance count exceeds threshold (default: 50) */\n instanceCountWarningThreshold?: number;\n\n /** Warn on rapid init/dispose cycles (default: true) */\n detectRapidLifecycles?: boolean;\n\n /** Time window for rapid lifecycle detection in ms (default: 1000) */\n rapidLifecycleWindowMs?: number;\n\n /** Number of cycles in window to trigger warning (default: 5) */\n rapidLifecycleThreshold?: number;\n\n /** Log prefix (default: '[BlaC]') */\n prefix?: string;\n}\n\nexport interface ResolvedConfig {\n level: LogLevel;\n format: LogFormat;\n logger: Logger;\n filter: FilterFn | undefined;\n include: string[] | undefined;\n exclude: string[] | undefined;\n logLifecycle: boolean;\n logStateChanges: boolean;\n includeCallstack: boolean;\n instanceCountWarningThreshold: number;\n detectRapidLifecycles: boolean;\n rapidLifecycleWindowMs: number;\n rapidLifecycleThreshold: number;\n prefix: string;\n}\n\nexport function resolveConfig(\n config: LoggingPluginConfig = {},\n): ResolvedConfig {\n return {\n level: config.level ?? 'info',\n format: config.format ?? 'grouped',\n logger: config.logger ?? console,\n filter: config.filter,\n include: config.include,\n exclude: config.exclude,\n logLifecycle: config.logLifecycle ?? true,\n logStateChanges: config.logStateChanges ?? true,\n includeCallstack: config.includeCallstack ?? false,\n instanceCountWarningThreshold: config.instanceCountWarningThreshold ?? 50,\n detectRapidLifecycles: config.detectRapidLifecycles ?? true,\n rapidLifecycleWindowMs: config.rapidLifecycleWindowMs ?? 1000,\n rapidLifecycleThreshold: config.rapidLifecycleThreshold ?? 5,\n prefix: config.prefix ?? '[BlaC]',\n };\n}\n","import type { BlacPlugin, PluginContext, StateContainer } from '@blac/core';\nimport { SimpleFormatter } from './formatters/SimpleFormatter';\nimport { GroupedFormatter } from './formatters/GroupedFormatter';\nimport { InstanceCountMonitor } from './monitors/InstanceCountMonitor';\nimport { LifecycleMonitor } from './monitors/LifecycleMonitor';\nimport type {\n LoggingPluginConfig,\n ResolvedConfig,\n FilterContext,\n} from './types';\nimport { resolveConfig } from './types';\n\nconst STATE_CHANGE_RATE_LIMIT = 1000; // max state changes per second\n\nexport class LoggingPlugin implements BlacPlugin {\n readonly name = 'LoggingPlugin';\n readonly version = '1.0.0';\n\n private config: ResolvedConfig;\n private context?: PluginContext;\n private simpleFormatter: SimpleFormatter;\n private groupedFormatter: GroupedFormatter;\n private instanceCountMonitor: InstanceCountMonitor;\n private lifecycleMonitor: LifecycleMonitor;\n\n // Rate limiting for state changes\n private stateChangeCount = 0;\n private stateChangeWindowStart = Date.now();\n private stateChangeLoggingDisabled = false;\n\n constructor(config: LoggingPluginConfig = {}) {\n this.config = resolveConfig(config);\n\n const warningHandler = (\n message: string,\n details?: Record<string, unknown>,\n ) => {\n this.logWarning(message, details);\n };\n\n this.simpleFormatter = new SimpleFormatter(this.config);\n this.groupedFormatter = new GroupedFormatter(this.config);\n this.instanceCountMonitor = new InstanceCountMonitor(\n this.config,\n warningHandler,\n );\n this.lifecycleMonitor = new LifecycleMonitor(this.config, warningHandler);\n }\n\n onInstall(context: PluginContext): void {\n this.context = context;\n const stats = context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstall(stats);\n } else {\n this.groupedFormatter.logInstall(stats);\n }\n }\n\n onUninstall(): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logUninstall();\n } else {\n this.groupedFormatter.logUninstall();\n }\n\n this.instanceCountMonitor.reset();\n this.lifecycleMonitor.reset();\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = Date.now();\n this.stateChangeLoggingDisabled = false;\n this.context = undefined;\n }\n\n onInstanceCreated(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n this.instanceCountMonitor.onInstanceCreated(metadata.className);\n this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceCreated(metadata);\n } else {\n this.groupedFormatter.logInstanceCreated(\n metadata,\n context.getState(instance),\n );\n }\n }\n\n onStateChanged<S extends object>(\n instance: StateContainer<S>,\n previousState: S,\n currentState: S,\n callstack: string | undefined,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n this.lifecycleMonitor.onStateChanged(metadata.id);\n\n if (!this.shouldLogStateChanges()) return;\n\n // Check rate limit\n if (this.stateChangeLoggingDisabled) return;\n\n const now = Date.now();\n if (now - this.stateChangeWindowStart >= 1000) {\n // Reset window\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = now;\n }\n\n this.stateChangeCount++;\n\n if (this.stateChangeCount > STATE_CHANGE_RATE_LIMIT) {\n this.stateChangeLoggingDisabled = true;\n this.logWarning(\n `State change logging disabled: exceeded ${STATE_CHANGE_RATE_LIMIT} changes/second`,\n );\n return;\n }\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n } else {\n this.groupedFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n }\n }\n\n onInstanceDisposed(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);\n const lifespanMs = info ? Date.now() - info.createdAt : 0;\n const stateChangeCount = info?.stateChangeCount ?? 0;\n\n this.instanceCountMonitor.onInstanceDisposed(metadata.className);\n this.lifecycleMonitor.onInstanceDisposed(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceDisposed(metadata, lifespanMs);\n } else {\n this.groupedFormatter.logInstanceDisposed(\n metadata,\n lifespanMs,\n stateChangeCount,\n );\n }\n }\n\n logStats(): void {\n if (!this.context) return;\n const stats = this.context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStats(stats);\n } else {\n this.groupedFormatter.logStats(stats);\n }\n }\n\n private shouldLog(\n instance: StateContainer<any>,\n className: string,\n instanceId: string,\n ): boolean {\n if (this.config.include && !this.config.include.includes(className)) {\n return false;\n }\n\n if (this.config.exclude?.includes(className)) {\n return false;\n }\n\n if (this.config.filter) {\n const ctx: FilterContext = {\n instance,\n className,\n instanceId,\n };\n return this.config.filter(ctx);\n }\n\n return true;\n }\n\n private shouldLogLifecycle(): boolean {\n if (!this.config.logLifecycle) return false;\n return this.config.level !== 'minimal';\n }\n\n private shouldLogStateChanges(): boolean {\n if (!this.config.logStateChanges) return false;\n return (\n this.config.level === 'info' ||\n this.config.level === 'debug' ||\n this.config.level === 'verbose'\n );\n }\n\n private logWarning(message: string, details?: Record<string, unknown>): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logWarning(message);\n } else {\n this.groupedFormatter.logWarning(message, details);\n }\n }\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,8 +15,7 @@ var SimpleFormatter = class {
15
15
  }
16
16
  logInstanceCreated(metadata) {
17
17
  const instanceId = this.formatInstanceId(metadata.className, metadata.id);
18
- const isolated = metadata.isIsolated ? " (isolated)" : "";
19
- this.logger.log(`${this.prefix} Created ${instanceId}${isolated}`);
18
+ this.logger.log(`${this.prefix} Created ${instanceId}`);
20
19
  }
21
20
  logInstanceDisposed(metadata, lifespanMs) {
22
21
  const instanceId = this.formatInstanceId(metadata.className, metadata.id);
@@ -53,7 +52,6 @@ var SimpleFormatter = class {
53
52
  return `${(ms / 6e4).toFixed(1)}m`;
54
53
  }
55
54
  };
56
-
57
55
  //#endregion
58
56
  //#region src/formatters/GroupedFormatter.ts
59
57
  var GroupedFormatter = class {
@@ -86,7 +84,6 @@ var GroupedFormatter = class {
86
84
  this.group(`${this.prefix} Created ${instanceId}`);
87
85
  this.logger.log("Class:", metadata.className);
88
86
  this.logger.log("Instance ID:", metadata.id);
89
- this.logger.log("Isolated:", metadata.isIsolated);
90
87
  this.logger.log("Initial state:", initialState);
91
88
  if (metadata.callstack) this.logger.log("Callstack:", metadata.callstack);
92
89
  this.groupEnd();
@@ -127,7 +124,6 @@ var GroupedFormatter = class {
127
124
  return `${(ms / 6e4).toFixed(1)}m`;
128
125
  }
129
126
  };
130
-
131
127
  //#endregion
132
128
  //#region src/monitors/InstanceCountMonitor.ts
133
129
  var InstanceCountMonitor = class {
@@ -162,7 +158,6 @@ var InstanceCountMonitor = class {
162
158
  this.warnedClasses.clear();
163
159
  }
164
160
  };
165
-
166
161
  //#endregion
167
162
  //#region src/monitors/LifecycleMonitor.ts
168
163
  var LifecycleMonitor = class {
@@ -230,7 +225,6 @@ var LifecycleMonitor = class {
230
225
  this.warnedClasses.clear();
231
226
  }
232
227
  };
233
-
234
228
  //#endregion
235
229
  //#region src/types.ts
236
230
  function resolveConfig(config = {}) {
@@ -251,7 +245,6 @@ function resolveConfig(config = {}) {
251
245
  prefix: config.prefix ?? "[BlaC]"
252
246
  };
253
247
  }
254
-
255
248
  //#endregion
256
249
  //#region src/LoggingPlugin.ts
257
250
  const STATE_CHANGE_RATE_LIMIT = 1e3;
@@ -289,7 +282,7 @@ var LoggingPlugin = class {
289
282
  }
290
283
  onInstanceCreated(instance, context) {
291
284
  const metadata = context.getInstanceMetadata(instance);
292
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
285
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
293
286
  this.instanceCountMonitor.onInstanceCreated(metadata.className);
294
287
  this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);
295
288
  if (!this.shouldLogLifecycle()) return;
@@ -298,7 +291,7 @@ var LoggingPlugin = class {
298
291
  }
299
292
  onStateChanged(instance, previousState, currentState, callstack, context) {
300
293
  const metadata = context.getInstanceMetadata(instance);
301
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
294
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
302
295
  this.lifecycleMonitor.onStateChanged(metadata.id);
303
296
  if (!this.shouldLogStateChanges()) return;
304
297
  if (this.stateChangeLoggingDisabled) return;
@@ -318,7 +311,7 @@ var LoggingPlugin = class {
318
311
  }
319
312
  onInstanceDisposed(instance, context) {
320
313
  const metadata = context.getInstanceMetadata(instance);
321
- if (!this.shouldLog(instance, metadata.className, metadata.id, metadata.isIsolated)) return;
314
+ if (!this.shouldLog(instance, metadata.className, metadata.id)) return;
322
315
  const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);
323
316
  const lifespanMs = info ? Date.now() - info.createdAt : 0;
324
317
  const stateChangeCount = info?.stateChangeCount ?? 0;
@@ -334,15 +327,14 @@ var LoggingPlugin = class {
334
327
  if (this.config.format === "simple") this.simpleFormatter.logStats(stats);
335
328
  else this.groupedFormatter.logStats(stats);
336
329
  }
337
- shouldLog(instance, className, instanceId, isIsolated) {
330
+ shouldLog(instance, className, instanceId) {
338
331
  if (this.config.include && !this.config.include.includes(className)) return false;
339
332
  if (this.config.exclude?.includes(className)) return false;
340
333
  if (this.config.filter) {
341
334
  const ctx = {
342
335
  instance,
343
336
  className,
344
- instanceId,
345
- isIsolated
337
+ instanceId
346
338
  };
347
339
  return this.config.filter(ctx);
348
340
  }
@@ -361,7 +353,7 @@ var LoggingPlugin = class {
361
353
  else this.groupedFormatter.logWarning(message, details);
362
354
  }
363
355
  };
364
-
365
356
  //#endregion
366
357
  export { LoggingPlugin };
358
+
367
359
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/formatters/SimpleFormatter.ts","../src/formatters/GroupedFormatter.ts","../src/monitors/InstanceCountMonitor.ts","../src/monitors/LifecycleMonitor.ts","../src/types.ts","../src/LoggingPlugin.ts"],"sourcesContent":["import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class SimpleFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.logger.log(\n `${this.prefix} Plugin installed (${stats.registeredTypes} types, ${stats.totalInstances} instances)`,\n );\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const isolated = metadata.isIsolated ? ' (isolated)' : '';\n this.logger.log(`${this.prefix} Created ${instanceId}${isolated}`);\n }\n\n logInstanceDisposed(metadata: InstanceMetadata, lifespanMs: number): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const lifespan = this.formatDuration(lifespanMs);\n this.logger.log(\n `${this.prefix} Disposed ${instanceId} (lived ${lifespan})`,\n );\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n _callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const prev = this.formatState(previousState);\n const curr = this.formatState(currentState);\n this.logger.log(`${this.prefix} ${instanceId} state: ${prev} → ${curr}`);\n\n if (includeCallstack && _callstack) {\n this.logger.log(`${this.prefix} Callstack: ${_callstack}`);\n }\n }\n\n logWarning(message: string): void {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.logger.log(\n `${this.prefix} Stats: ${stats.totalInstances} instances across ${stats.registeredTypes} types`,\n );\n }\n\n private formatState(state: unknown): string {\n if (state === null) return 'null';\n if (state === undefined) return 'undefined';\n if (typeof state === 'object') {\n try {\n const str = JSON.stringify(state);\n return str.length > 50 ? str.slice(0, 50) + '...' : str;\n } catch {\n return '[Object]';\n }\n }\n return String(state);\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class GroupedFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n private group(label: string, collapsed = true): void {\n if (collapsed && this.logger.groupCollapsed) {\n this.logger.groupCollapsed(label);\n } else if (this.logger.group) {\n this.logger.group(label);\n } else {\n this.logger.log(label);\n }\n }\n\n private groupEnd(): void {\n if (this.logger.groupEnd) {\n this.logger.groupEnd();\n }\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.group(`${this.prefix} Plugin installed`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.groupEnd();\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata, initialState: unknown): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Created ${instanceId}`);\n this.logger.log('Class:', metadata.className);\n this.logger.log('Instance ID:', metadata.id);\n this.logger.log('Isolated:', metadata.isIsolated);\n this.logger.log('Initial state:', initialState);\n if (metadata.callstack) {\n this.logger.log('Callstack:', metadata.callstack);\n }\n this.groupEnd();\n }\n\n logInstanceDisposed(\n metadata: InstanceMetadata,\n lifespanMs: number,\n stateChangeCount: number,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Disposed ${instanceId}`);\n this.logger.log('Lifespan:', this.formatDuration(lifespanMs));\n this.logger.log('State changes:', stateChangeCount);\n this.logger.log('Final state:', metadata.state);\n this.groupEnd();\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} ${instanceId} state changed`);\n this.logger.log('Previous:', previousState);\n this.logger.log('Current:', currentState);\n if (includeCallstack && callstack) {\n this.logger.log('Callstack:', callstack);\n }\n this.groupEnd();\n }\n\n logWarning(message: string, details?: Record<string, unknown>): void {\n if (details) {\n this.group(`${this.prefix} ⚠️ ${message}`, false);\n for (const [key, value] of Object.entries(details)) {\n this.logger.log(`${key}:`, value);\n }\n this.groupEnd();\n } else {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.group(`${this.prefix} Stats`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.logger.log('Breakdown:', stats.typeBreakdown);\n this.groupEnd();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { ResolvedConfig } from '../types';\n\nexport class InstanceCountMonitor {\n private instanceCounts = new Map<string, number>();\n private warnedClasses = new Set<string>();\n private threshold: number;\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.threshold = config.instanceCountWarningThreshold;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string): void {\n const count = (this.instanceCounts.get(className) ?? 0) + 1;\n this.instanceCounts.set(className, count);\n\n if (count >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `High instance count: ${className} has ${count} instances`,\n {\n className,\n count,\n threshold: this.threshold,\n },\n );\n }\n }\n\n onInstanceDisposed(className: string): void {\n const count = this.instanceCounts.get(className) ?? 0;\n if (count > 0) {\n this.instanceCounts.set(className, count - 1);\n }\n\n if (count - 1 < this.threshold) {\n this.warnedClasses.delete(className);\n }\n }\n\n getStats(): Map<string, number> {\n return new Map(this.instanceCounts);\n }\n\n reset(): void {\n this.instanceCounts.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { ResolvedConfig } from '../types';\n\ninterface LifecycleEvent {\n timestamp: number;\n type: 'created' | 'disposed';\n}\n\ninterface InstanceInfo {\n createdAt: number;\n stateChangeCount: number;\n}\n\nexport class LifecycleMonitor {\n private lifecycleHistory = new Map<string, LifecycleEvent[]>();\n private instanceInfo = new Map<string, InstanceInfo>();\n private windowMs: number;\n private threshold: number;\n private enabled: boolean;\n private warnedClasses = new Set<string>();\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.windowMs = config.rapidLifecycleWindowMs;\n this.threshold = config.rapidLifecycleThreshold;\n this.enabled = config.detectRapidLifecycles;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.set(instanceId, {\n createdAt: Date.now(),\n stateChangeCount: 0,\n });\n\n this.recordEvent(className, 'created');\n this.checkRapidLifecycle(className);\n }\n\n onInstanceDisposed(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.delete(instanceId);\n this.recordEvent(className, 'disposed');\n this.checkRapidLifecycle(className);\n }\n\n onStateChanged(instanceId: string): void {\n const info = this.instanceInfo.get(instanceId);\n if (info) {\n info.stateChangeCount++;\n }\n }\n\n getInstanceInfo(instanceId: string): InstanceInfo | undefined {\n return this.instanceInfo.get(instanceId);\n }\n\n private recordEvent(className: string, type: 'created' | 'disposed'): void {\n const now = Date.now();\n const events = this.lifecycleHistory.get(className) ?? [];\n\n events.push({ timestamp: now, type });\n\n const cutoff = now - this.windowMs;\n const filtered = events.filter((e) => e.timestamp > cutoff);\n this.lifecycleHistory.set(className, filtered);\n }\n\n private checkRapidLifecycle(className: string): void {\n const events = this.lifecycleHistory.get(className) ?? [];\n const cycleCount = Math.min(\n events.filter((e) => e.type === 'created').length,\n events.filter((e) => e.type === 'disposed').length,\n );\n\n if (cycleCount >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `Rapid lifecycle: ${className} created/disposed ${cycleCount} times in ${this.windowMs}ms`,\n {\n className,\n cycleCount,\n windowMs: this.windowMs,\n threshold: this.threshold,\n },\n );\n\n setTimeout(() => {\n this.warnedClasses.delete(className);\n }, this.windowMs);\n }\n }\n\n reset(): void {\n this.lifecycleHistory.clear();\n this.instanceInfo.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { StateContainer } from '@blac/core';\n\nexport type LogLevel = 'minimal' | 'info' | 'debug' | 'verbose';\n\nexport type LogFormat = 'simple' | 'grouped';\n\nexport interface Logger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n group?(label: string): void;\n groupEnd?(): void;\n groupCollapsed?(label: string): void;\n}\n\nexport interface FilterContext {\n instance: StateContainer<any>;\n className: string;\n instanceId: string;\n isIsolated: boolean;\n}\n\nexport type FilterFn = (ctx: FilterContext) => boolean;\n\nexport interface LoggingPluginConfig {\n /** Log verbosity level (default: 'info') */\n level?: LogLevel;\n\n /** Output format (default: 'grouped') */\n format?: LogFormat;\n\n /** Custom logger implementation (default: console) */\n logger?: Logger;\n\n /** Filter which instances to log */\n filter?: FilterFn;\n\n /** Include class names to log (whitelist) */\n include?: string[];\n\n /** Exclude class names from logging (blacklist) */\n exclude?: string[];\n\n /** Log instance creation/disposal (default: true) */\n logLifecycle?: boolean;\n\n /** Log state changes (default: true) */\n logStateChanges?: boolean;\n\n /** Include callstack in state change logs (default: false) */\n includeCallstack?: boolean;\n\n /** Warn when instance count exceeds threshold (default: 50) */\n instanceCountWarningThreshold?: number;\n\n /** Warn on rapid init/dispose cycles (default: true) */\n detectRapidLifecycles?: boolean;\n\n /** Time window for rapid lifecycle detection in ms (default: 1000) */\n rapidLifecycleWindowMs?: number;\n\n /** Number of cycles in window to trigger warning (default: 5) */\n rapidLifecycleThreshold?: number;\n\n /** Log prefix (default: '[BlaC]') */\n prefix?: string;\n}\n\nexport interface ResolvedConfig {\n level: LogLevel;\n format: LogFormat;\n logger: Logger;\n filter: FilterFn | undefined;\n include: string[] | undefined;\n exclude: string[] | undefined;\n logLifecycle: boolean;\n logStateChanges: boolean;\n includeCallstack: boolean;\n instanceCountWarningThreshold: number;\n detectRapidLifecycles: boolean;\n rapidLifecycleWindowMs: number;\n rapidLifecycleThreshold: number;\n prefix: string;\n}\n\nexport function resolveConfig(\n config: LoggingPluginConfig = {},\n): ResolvedConfig {\n return {\n level: config.level ?? 'info',\n format: config.format ?? 'grouped',\n logger: config.logger ?? console,\n filter: config.filter,\n include: config.include,\n exclude: config.exclude,\n logLifecycle: config.logLifecycle ?? true,\n logStateChanges: config.logStateChanges ?? true,\n includeCallstack: config.includeCallstack ?? false,\n instanceCountWarningThreshold: config.instanceCountWarningThreshold ?? 50,\n detectRapidLifecycles: config.detectRapidLifecycles ?? true,\n rapidLifecycleWindowMs: config.rapidLifecycleWindowMs ?? 1000,\n rapidLifecycleThreshold: config.rapidLifecycleThreshold ?? 5,\n prefix: config.prefix ?? '[BlaC]',\n };\n}\n","import type { BlacPlugin, PluginContext, StateContainer } from '@blac/core';\nimport { SimpleFormatter } from './formatters/SimpleFormatter';\nimport { GroupedFormatter } from './formatters/GroupedFormatter';\nimport { InstanceCountMonitor } from './monitors/InstanceCountMonitor';\nimport { LifecycleMonitor } from './monitors/LifecycleMonitor';\nimport type {\n LoggingPluginConfig,\n ResolvedConfig,\n FilterContext,\n} from './types';\nimport { resolveConfig } from './types';\n\nconst STATE_CHANGE_RATE_LIMIT = 1000; // max state changes per second\n\nexport class LoggingPlugin implements BlacPlugin {\n readonly name = 'LoggingPlugin';\n readonly version = '1.0.0';\n\n private config: ResolvedConfig;\n private context?: PluginContext;\n private simpleFormatter: SimpleFormatter;\n private groupedFormatter: GroupedFormatter;\n private instanceCountMonitor: InstanceCountMonitor;\n private lifecycleMonitor: LifecycleMonitor;\n\n // Rate limiting for state changes\n private stateChangeCount = 0;\n private stateChangeWindowStart = Date.now();\n private stateChangeLoggingDisabled = false;\n\n constructor(config: LoggingPluginConfig = {}) {\n this.config = resolveConfig(config);\n\n const warningHandler = (\n message: string,\n details?: Record<string, unknown>,\n ) => {\n this.logWarning(message, details);\n };\n\n this.simpleFormatter = new SimpleFormatter(this.config);\n this.groupedFormatter = new GroupedFormatter(this.config);\n this.instanceCountMonitor = new InstanceCountMonitor(\n this.config,\n warningHandler,\n );\n this.lifecycleMonitor = new LifecycleMonitor(this.config, warningHandler);\n }\n\n onInstall(context: PluginContext): void {\n this.context = context;\n const stats = context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstall(stats);\n } else {\n this.groupedFormatter.logInstall(stats);\n }\n }\n\n onUninstall(): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logUninstall();\n } else {\n this.groupedFormatter.logUninstall();\n }\n\n this.instanceCountMonitor.reset();\n this.lifecycleMonitor.reset();\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = Date.now();\n this.stateChangeLoggingDisabled = false;\n this.context = undefined;\n }\n\n onInstanceCreated(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n this.instanceCountMonitor.onInstanceCreated(metadata.className);\n this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceCreated(metadata);\n } else {\n this.groupedFormatter.logInstanceCreated(\n metadata,\n context.getState(instance),\n );\n }\n }\n\n onStateChanged<S extends object>(\n instance: StateContainer<S>,\n previousState: S,\n currentState: S,\n callstack: string | undefined,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n this.lifecycleMonitor.onStateChanged(metadata.id);\n\n if (!this.shouldLogStateChanges()) return;\n\n // Check rate limit\n if (this.stateChangeLoggingDisabled) return;\n\n const now = Date.now();\n if (now - this.stateChangeWindowStart >= 1000) {\n // Reset window\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = now;\n }\n\n this.stateChangeCount++;\n\n if (this.stateChangeCount > STATE_CHANGE_RATE_LIMIT) {\n this.stateChangeLoggingDisabled = true;\n this.logWarning(\n `State change logging disabled: exceeded ${STATE_CHANGE_RATE_LIMIT} changes/second`,\n );\n return;\n }\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n } else {\n this.groupedFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n }\n }\n\n onInstanceDisposed(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (\n !this.shouldLog(\n instance,\n metadata.className,\n metadata.id,\n metadata.isIsolated,\n )\n ) {\n return;\n }\n\n const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);\n const lifespanMs = info ? Date.now() - info.createdAt : 0;\n const stateChangeCount = info?.stateChangeCount ?? 0;\n\n this.instanceCountMonitor.onInstanceDisposed(metadata.className);\n this.lifecycleMonitor.onInstanceDisposed(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceDisposed(metadata, lifespanMs);\n } else {\n this.groupedFormatter.logInstanceDisposed(\n metadata,\n lifespanMs,\n stateChangeCount,\n );\n }\n }\n\n logStats(): void {\n if (!this.context) return;\n const stats = this.context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStats(stats);\n } else {\n this.groupedFormatter.logStats(stats);\n }\n }\n\n private shouldLog(\n instance: StateContainer<any>,\n className: string,\n instanceId: string,\n isIsolated: boolean,\n ): boolean {\n if (this.config.include && !this.config.include.includes(className)) {\n return false;\n }\n\n if (this.config.exclude?.includes(className)) {\n return false;\n }\n\n if (this.config.filter) {\n const ctx: FilterContext = {\n instance,\n className,\n instanceId,\n isIsolated,\n };\n return this.config.filter(ctx);\n }\n\n return true;\n }\n\n private shouldLogLifecycle(): boolean {\n if (!this.config.logLifecycle) return false;\n return this.config.level !== 'minimal';\n }\n\n private shouldLogStateChanges(): boolean {\n if (!this.config.logStateChanges) return false;\n return (\n this.config.level === 'info' ||\n this.config.level === 'debug' ||\n this.config.level === 'verbose'\n );\n }\n\n private logWarning(message: string, details?: Record<string, unknown>): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logWarning(message);\n } else {\n this.groupedFormatter.logWarning(message, details);\n }\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/formatters/SimpleFormatter.ts","../src/formatters/GroupedFormatter.ts","../src/monitors/InstanceCountMonitor.ts","../src/monitors/LifecycleMonitor.ts","../src/types.ts","../src/LoggingPlugin.ts"],"sourcesContent":["import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class SimpleFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.logger.log(\n `${this.prefix} Plugin installed (${stats.registeredTypes} types, ${stats.totalInstances} instances)`,\n );\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.logger.log(`${this.prefix} Created ${instanceId}`);\n }\n\n logInstanceDisposed(metadata: InstanceMetadata, lifespanMs: number): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const lifespan = this.formatDuration(lifespanMs);\n this.logger.log(\n `${this.prefix} Disposed ${instanceId} (lived ${lifespan})`,\n );\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n _callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n const prev = this.formatState(previousState);\n const curr = this.formatState(currentState);\n this.logger.log(`${this.prefix} ${instanceId} state: ${prev} → ${curr}`);\n\n if (includeCallstack && _callstack) {\n this.logger.log(`${this.prefix} Callstack: ${_callstack}`);\n }\n }\n\n logWarning(message: string): void {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.logger.log(\n `${this.prefix} Stats: ${stats.totalInstances} instances across ${stats.registeredTypes} types`,\n );\n }\n\n private formatState(state: unknown): string {\n if (state === null) return 'null';\n if (state === undefined) return 'undefined';\n if (typeof state === 'object') {\n try {\n const str = JSON.stringify(state);\n return str.length > 50 ? str.slice(0, 50) + '...' : str;\n } catch {\n return '[Object]';\n }\n }\n return String(state);\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { InstanceMetadata } from '@blac/core';\nimport type { Logger, ResolvedConfig } from '../types';\n\nexport class GroupedFormatter {\n private logger: Logger;\n private prefix: string;\n\n constructor(config: ResolvedConfig) {\n this.logger = config.logger;\n this.prefix = config.prefix;\n }\n\n private formatInstanceId(className: string, id: string): string {\n const shortId = id.length > 8 ? id.slice(0, 8) : id;\n return `${className}#${shortId}`;\n }\n\n private group(label: string, collapsed = true): void {\n if (collapsed && this.logger.groupCollapsed) {\n this.logger.groupCollapsed(label);\n } else if (this.logger.group) {\n this.logger.group(label);\n } else {\n this.logger.log(label);\n }\n }\n\n private groupEnd(): void {\n if (this.logger.groupEnd) {\n this.logger.groupEnd();\n }\n }\n\n logInstall(stats: { registeredTypes: number; totalInstances: number }): void {\n this.group(`${this.prefix} Plugin installed`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.groupEnd();\n }\n\n logUninstall(): void {\n this.logger.log(`${this.prefix} Plugin uninstalled`);\n }\n\n logInstanceCreated(metadata: InstanceMetadata, initialState: unknown): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Created ${instanceId}`);\n this.logger.log('Class:', metadata.className);\n this.logger.log('Instance ID:', metadata.id);\n this.logger.log('Initial state:', initialState);\n if (metadata.callstack) {\n this.logger.log('Callstack:', metadata.callstack);\n }\n this.groupEnd();\n }\n\n logInstanceDisposed(\n metadata: InstanceMetadata,\n lifespanMs: number,\n stateChangeCount: number,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} Disposed ${instanceId}`);\n this.logger.log('Lifespan:', this.formatDuration(lifespanMs));\n this.logger.log('State changes:', stateChangeCount);\n this.logger.log('Final state:', metadata.state);\n this.groupEnd();\n }\n\n logStateChanged(\n metadata: InstanceMetadata,\n previousState: unknown,\n currentState: unknown,\n callstack: string | undefined,\n includeCallstack: boolean,\n ): void {\n const instanceId = this.formatInstanceId(metadata.className, metadata.id);\n this.group(`${this.prefix} ${instanceId} state changed`);\n this.logger.log('Previous:', previousState);\n this.logger.log('Current:', currentState);\n if (includeCallstack && callstack) {\n this.logger.log('Callstack:', callstack);\n }\n this.groupEnd();\n }\n\n logWarning(message: string, details?: Record<string, unknown>): void {\n if (details) {\n this.group(`${this.prefix} ⚠️ ${message}`, false);\n for (const [key, value] of Object.entries(details)) {\n this.logger.log(`${key}:`, value);\n }\n this.groupEnd();\n } else {\n this.logger.warn(`${this.prefix} ⚠️ ${message}`);\n }\n }\n\n logStats(stats: {\n registeredTypes: number;\n totalInstances: number;\n typeBreakdown: Record<string, number>;\n }): void {\n this.group(`${this.prefix} Stats`);\n this.logger.log('Registered types:', stats.registeredTypes);\n this.logger.log('Total instances:', stats.totalInstances);\n this.logger.log('Breakdown:', stats.typeBreakdown);\n this.groupEnd();\n }\n\n private formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n }\n}\n","import type { ResolvedConfig } from '../types';\n\nexport class InstanceCountMonitor {\n private instanceCounts = new Map<string, number>();\n private warnedClasses = new Set<string>();\n private threshold: number;\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.threshold = config.instanceCountWarningThreshold;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string): void {\n const count = (this.instanceCounts.get(className) ?? 0) + 1;\n this.instanceCounts.set(className, count);\n\n if (count >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `High instance count: ${className} has ${count} instances`,\n {\n className,\n count,\n threshold: this.threshold,\n },\n );\n }\n }\n\n onInstanceDisposed(className: string): void {\n const count = this.instanceCounts.get(className) ?? 0;\n if (count > 0) {\n this.instanceCounts.set(className, count - 1);\n }\n\n if (count - 1 < this.threshold) {\n this.warnedClasses.delete(className);\n }\n }\n\n getStats(): Map<string, number> {\n return new Map(this.instanceCounts);\n }\n\n reset(): void {\n this.instanceCounts.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { ResolvedConfig } from '../types';\n\ninterface LifecycleEvent {\n timestamp: number;\n type: 'created' | 'disposed';\n}\n\ninterface InstanceInfo {\n createdAt: number;\n stateChangeCount: number;\n}\n\nexport class LifecycleMonitor {\n private lifecycleHistory = new Map<string, LifecycleEvent[]>();\n private instanceInfo = new Map<string, InstanceInfo>();\n private windowMs: number;\n private threshold: number;\n private enabled: boolean;\n private warnedClasses = new Set<string>();\n private onWarning: (\n message: string,\n details?: Record<string, unknown>,\n ) => void;\n\n constructor(\n config: ResolvedConfig,\n onWarning: (message: string, details?: Record<string, unknown>) => void,\n ) {\n this.windowMs = config.rapidLifecycleWindowMs;\n this.threshold = config.rapidLifecycleThreshold;\n this.enabled = config.detectRapidLifecycles;\n this.onWarning = onWarning;\n }\n\n onInstanceCreated(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.set(instanceId, {\n createdAt: Date.now(),\n stateChangeCount: 0,\n });\n\n this.recordEvent(className, 'created');\n this.checkRapidLifecycle(className);\n }\n\n onInstanceDisposed(className: string, instanceId: string): void {\n if (!this.enabled) return;\n\n this.instanceInfo.delete(instanceId);\n this.recordEvent(className, 'disposed');\n this.checkRapidLifecycle(className);\n }\n\n onStateChanged(instanceId: string): void {\n const info = this.instanceInfo.get(instanceId);\n if (info) {\n info.stateChangeCount++;\n }\n }\n\n getInstanceInfo(instanceId: string): InstanceInfo | undefined {\n return this.instanceInfo.get(instanceId);\n }\n\n private recordEvent(className: string, type: 'created' | 'disposed'): void {\n const now = Date.now();\n const events = this.lifecycleHistory.get(className) ?? [];\n\n events.push({ timestamp: now, type });\n\n const cutoff = now - this.windowMs;\n const filtered = events.filter((e) => e.timestamp > cutoff);\n this.lifecycleHistory.set(className, filtered);\n }\n\n private checkRapidLifecycle(className: string): void {\n const events = this.lifecycleHistory.get(className) ?? [];\n const cycleCount = Math.min(\n events.filter((e) => e.type === 'created').length,\n events.filter((e) => e.type === 'disposed').length,\n );\n\n if (cycleCount >= this.threshold && !this.warnedClasses.has(className)) {\n this.warnedClasses.add(className);\n this.onWarning(\n `Rapid lifecycle: ${className} created/disposed ${cycleCount} times in ${this.windowMs}ms`,\n {\n className,\n cycleCount,\n windowMs: this.windowMs,\n threshold: this.threshold,\n },\n );\n\n setTimeout(() => {\n this.warnedClasses.delete(className);\n }, this.windowMs);\n }\n }\n\n reset(): void {\n this.lifecycleHistory.clear();\n this.instanceInfo.clear();\n this.warnedClasses.clear();\n }\n}\n","import type { StateContainer } from '@blac/core';\n\nexport type LogLevel = 'minimal' | 'info' | 'debug' | 'verbose';\n\nexport type LogFormat = 'simple' | 'grouped';\n\nexport interface Logger {\n log(...args: unknown[]): void;\n warn(...args: unknown[]): void;\n error(...args: unknown[]): void;\n group?(label: string): void;\n groupEnd?(): void;\n groupCollapsed?(label: string): void;\n}\n\nexport interface FilterContext {\n instance: StateContainer<any>;\n className: string;\n instanceId: string;\n}\n\nexport type FilterFn = (ctx: FilterContext) => boolean;\n\nexport interface LoggingPluginConfig {\n /** Log verbosity level (default: 'info') */\n level?: LogLevel;\n\n /** Output format (default: 'grouped') */\n format?: LogFormat;\n\n /** Custom logger implementation (default: console) */\n logger?: Logger;\n\n /** Filter which instances to log */\n filter?: FilterFn;\n\n /** Include class names to log (whitelist) */\n include?: string[];\n\n /** Exclude class names from logging (blacklist) */\n exclude?: string[];\n\n /** Log instance creation/disposal (default: true) */\n logLifecycle?: boolean;\n\n /** Log state changes (default: true) */\n logStateChanges?: boolean;\n\n /** Include callstack in state change logs (default: false) */\n includeCallstack?: boolean;\n\n /** Warn when instance count exceeds threshold (default: 50) */\n instanceCountWarningThreshold?: number;\n\n /** Warn on rapid init/dispose cycles (default: true) */\n detectRapidLifecycles?: boolean;\n\n /** Time window for rapid lifecycle detection in ms (default: 1000) */\n rapidLifecycleWindowMs?: number;\n\n /** Number of cycles in window to trigger warning (default: 5) */\n rapidLifecycleThreshold?: number;\n\n /** Log prefix (default: '[BlaC]') */\n prefix?: string;\n}\n\nexport interface ResolvedConfig {\n level: LogLevel;\n format: LogFormat;\n logger: Logger;\n filter: FilterFn | undefined;\n include: string[] | undefined;\n exclude: string[] | undefined;\n logLifecycle: boolean;\n logStateChanges: boolean;\n includeCallstack: boolean;\n instanceCountWarningThreshold: number;\n detectRapidLifecycles: boolean;\n rapidLifecycleWindowMs: number;\n rapidLifecycleThreshold: number;\n prefix: string;\n}\n\nexport function resolveConfig(\n config: LoggingPluginConfig = {},\n): ResolvedConfig {\n return {\n level: config.level ?? 'info',\n format: config.format ?? 'grouped',\n logger: config.logger ?? console,\n filter: config.filter,\n include: config.include,\n exclude: config.exclude,\n logLifecycle: config.logLifecycle ?? true,\n logStateChanges: config.logStateChanges ?? true,\n includeCallstack: config.includeCallstack ?? false,\n instanceCountWarningThreshold: config.instanceCountWarningThreshold ?? 50,\n detectRapidLifecycles: config.detectRapidLifecycles ?? true,\n rapidLifecycleWindowMs: config.rapidLifecycleWindowMs ?? 1000,\n rapidLifecycleThreshold: config.rapidLifecycleThreshold ?? 5,\n prefix: config.prefix ?? '[BlaC]',\n };\n}\n","import type { BlacPlugin, PluginContext, StateContainer } from '@blac/core';\nimport { SimpleFormatter } from './formatters/SimpleFormatter';\nimport { GroupedFormatter } from './formatters/GroupedFormatter';\nimport { InstanceCountMonitor } from './monitors/InstanceCountMonitor';\nimport { LifecycleMonitor } from './monitors/LifecycleMonitor';\nimport type {\n LoggingPluginConfig,\n ResolvedConfig,\n FilterContext,\n} from './types';\nimport { resolveConfig } from './types';\n\nconst STATE_CHANGE_RATE_LIMIT = 1000; // max state changes per second\n\nexport class LoggingPlugin implements BlacPlugin {\n readonly name = 'LoggingPlugin';\n readonly version = '1.0.0';\n\n private config: ResolvedConfig;\n private context?: PluginContext;\n private simpleFormatter: SimpleFormatter;\n private groupedFormatter: GroupedFormatter;\n private instanceCountMonitor: InstanceCountMonitor;\n private lifecycleMonitor: LifecycleMonitor;\n\n // Rate limiting for state changes\n private stateChangeCount = 0;\n private stateChangeWindowStart = Date.now();\n private stateChangeLoggingDisabled = false;\n\n constructor(config: LoggingPluginConfig = {}) {\n this.config = resolveConfig(config);\n\n const warningHandler = (\n message: string,\n details?: Record<string, unknown>,\n ) => {\n this.logWarning(message, details);\n };\n\n this.simpleFormatter = new SimpleFormatter(this.config);\n this.groupedFormatter = new GroupedFormatter(this.config);\n this.instanceCountMonitor = new InstanceCountMonitor(\n this.config,\n warningHandler,\n );\n this.lifecycleMonitor = new LifecycleMonitor(this.config, warningHandler);\n }\n\n onInstall(context: PluginContext): void {\n this.context = context;\n const stats = context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstall(stats);\n } else {\n this.groupedFormatter.logInstall(stats);\n }\n }\n\n onUninstall(): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logUninstall();\n } else {\n this.groupedFormatter.logUninstall();\n }\n\n this.instanceCountMonitor.reset();\n this.lifecycleMonitor.reset();\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = Date.now();\n this.stateChangeLoggingDisabled = false;\n this.context = undefined;\n }\n\n onInstanceCreated(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n this.instanceCountMonitor.onInstanceCreated(metadata.className);\n this.lifecycleMonitor.onInstanceCreated(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceCreated(metadata);\n } else {\n this.groupedFormatter.logInstanceCreated(\n metadata,\n context.getState(instance),\n );\n }\n }\n\n onStateChanged<S extends object>(\n instance: StateContainer<S>,\n previousState: S,\n currentState: S,\n callstack: string | undefined,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n this.lifecycleMonitor.onStateChanged(metadata.id);\n\n if (!this.shouldLogStateChanges()) return;\n\n // Check rate limit\n if (this.stateChangeLoggingDisabled) return;\n\n const now = Date.now();\n if (now - this.stateChangeWindowStart >= 1000) {\n // Reset window\n this.stateChangeCount = 0;\n this.stateChangeWindowStart = now;\n }\n\n this.stateChangeCount++;\n\n if (this.stateChangeCount > STATE_CHANGE_RATE_LIMIT) {\n this.stateChangeLoggingDisabled = true;\n this.logWarning(\n `State change logging disabled: exceeded ${STATE_CHANGE_RATE_LIMIT} changes/second`,\n );\n return;\n }\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n } else {\n this.groupedFormatter.logStateChanged(\n metadata,\n previousState,\n currentState,\n callstack,\n this.config.includeCallstack,\n );\n }\n }\n\n onInstanceDisposed(\n instance: StateContainer<any>,\n context: PluginContext,\n ): void {\n const metadata = context.getInstanceMetadata(instance);\n\n if (!this.shouldLog(instance, metadata.className, metadata.id)) {\n return;\n }\n\n const info = this.lifecycleMonitor.getInstanceInfo(metadata.id);\n const lifespanMs = info ? Date.now() - info.createdAt : 0;\n const stateChangeCount = info?.stateChangeCount ?? 0;\n\n this.instanceCountMonitor.onInstanceDisposed(metadata.className);\n this.lifecycleMonitor.onInstanceDisposed(metadata.className, metadata.id);\n\n if (!this.shouldLogLifecycle()) return;\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logInstanceDisposed(metadata, lifespanMs);\n } else {\n this.groupedFormatter.logInstanceDisposed(\n metadata,\n lifespanMs,\n stateChangeCount,\n );\n }\n }\n\n logStats(): void {\n if (!this.context) return;\n const stats = this.context.getStats();\n\n if (this.config.format === 'simple') {\n this.simpleFormatter.logStats(stats);\n } else {\n this.groupedFormatter.logStats(stats);\n }\n }\n\n private shouldLog(\n instance: StateContainer<any>,\n className: string,\n instanceId: string,\n ): boolean {\n if (this.config.include && !this.config.include.includes(className)) {\n return false;\n }\n\n if (this.config.exclude?.includes(className)) {\n return false;\n }\n\n if (this.config.filter) {\n const ctx: FilterContext = {\n instance,\n className,\n instanceId,\n };\n return this.config.filter(ctx);\n }\n\n return true;\n }\n\n private shouldLogLifecycle(): boolean {\n if (!this.config.logLifecycle) return false;\n return this.config.level !== 'minimal';\n }\n\n private shouldLogStateChanges(): boolean {\n if (!this.config.logStateChanges) return false;\n return (\n this.config.level === 'info' ||\n this.config.level === 'debug' ||\n this.config.level === 'verbose'\n );\n }\n\n private logWarning(message: string, details?: Record<string, unknown>): void {\n if (this.config.format === 'simple') {\n this.simpleFormatter.logWarning(message);\n } else {\n this.groupedFormatter.logWarning(message, details);\n }\n }\n}\n"],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -13,7 +13,6 @@ export interface FilterContext {
13
13
  instance: StateContainer<any>;
14
14
  className: string;
15
15
  instanceId: string;
16
- isIsolated: boolean;
17
16
  }
18
17
  export type FilterFn = (ctx: FilterContext) => boolean;
19
18
  export interface LoggingPluginConfig {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhE,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,QAAQ,CAAC;IAEjB,yCAAyC;IACzC,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,wCAAwC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,+DAA+D;IAC/D,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAEvC,wDAAwD;IACxD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sEAAsE;IACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC,iEAAiE;IACjE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,MAAM,CAAC;IACtC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,aAAa,CAC3B,MAAM,GAAE,mBAAwB,GAC/B,cAAc,CAiBhB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,SAAS,CAAC;AAEhE,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;AAE7C,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC9B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChC,KAAK,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,CAAC,IAAI,IAAI,CAAC;IAClB,cAAc,CAAC,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,cAAc,CAAC,GAAG,CAAC,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,KAAK,CAAC,EAAE,QAAQ,CAAC;IAEjB,yCAAyC;IACzC,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAElB,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB,qDAAqD;IACrD,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,wCAAwC;IACxC,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,+DAA+D;IAC/D,6BAA6B,CAAC,EAAE,MAAM,CAAC;IAEvC,wDAAwD;IACxD,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAEhC,sEAAsE;IACtE,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAEhC,iEAAiE;IACjE,uBAAuB,CAAC,EAAE,MAAM,CAAC;IAEjC,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,SAAS,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,OAAO,CAAC;IACzB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,6BAA6B,EAAE,MAAM,CAAC;IACtC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,uBAAuB,EAAE,MAAM,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,aAAa,CAC3B,MAAM,GAAE,mBAAwB,GAC/B,cAAc,CAiBhB"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blac/logging-plugin",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "license": "MIT",
5
5
  "author": "Brendan Mullins <jsnanigans@gmail.com>",
6
6
  "description": "Logging and debugging plugin for BlaC state management",
@@ -13,6 +13,7 @@
13
13
  "bugs": {
14
14
  "url": "https://github.com/jsnanigans/blac/issues"
15
15
  },
16
+ "type": "module",
16
17
  "main": "./dist/index.cjs",
17
18
  "module": "./dist/index.js",
18
19
  "types": "./dist/index.d.ts",
@@ -33,6 +34,9 @@
33
34
  "README.md",
34
35
  "LICENSE"
35
36
  ],
37
+ "publishConfig": {
38
+ "access": "public"
39
+ },
36
40
  "sideEffects": false,
37
41
  "keywords": [
38
42
  "blac",
@@ -41,15 +45,16 @@
41
45
  "state-management",
42
46
  "devtools"
43
47
  ],
44
- "dependencies": {
45
- "@blac/core": "2.0.5"
48
+ "peerDependencies": {
49
+ "@blac/core": "^2.0.7"
46
50
  },
47
51
  "devDependencies": {
48
52
  "prettier": "^3.6.2",
49
53
  "typescript": "^5.9.2",
50
54
  "vitest": "3.2.4",
51
55
  "publint": "^0.3.12",
52
- "tsdown": "^0.15.7"
56
+ "tsdown": "^0.15.7",
57
+ "@blac/core": "2.0.7"
53
58
  },
54
59
  "scripts": {
55
60
  "dev": "tsdown --watch",
@@ -58,7 +63,8 @@
58
63
  "format": "prettier --write \".\"",
59
64
  "lint": "eslint src --ext .ts,.tsx",
60
65
  "lint:fix": "eslint src --ext .ts,.tsx --fix",
61
- "verify": "publint",
66
+ "test": "node ../../scripts/run-workspace-bin.mjs vitest run --passWithNoTests",
67
+ "verify": "node ../../scripts/run-workspace-bin.mjs publint",
62
68
  "typecheck": "tsc --noEmit",
63
69
  "deploy": "pnpm publish --access public"
64
70
  }