@lensmcp/memory-tracker 1.18.4 → 1.18.6

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/index.js CHANGED
@@ -1,5 +1 @@
1
- export { configureMemoryTracker, activeMemoryOptions, currentMemoryContext, resetMemoryTracker, } from './lib/context.js';
2
- export { trackContainer } from './lib/track-container.js';
3
- export { ensureOwner, allOwners, getOwner, ownerKey, resetOwners, markFlowStart, recordFlowDelta, flowGrowth, } from './lib/owners.js';
4
- export { emitMutation, emitRetention, emitStaleGeneration } from './lib/emit.js';
5
- export { onFlowStart, onFlowSettled, checkStaleGeneration, } from './lib/detectors.js';
1
+ "use strict";export{configureMemoryTracker,activeMemoryOptions,currentMemoryContext,resetMemoryTracker}from"./lib/context.js";export{trackContainer}from"./lib/track-container.js";export{ensureOwner,allOwners,getOwner,ownerKey,resetOwners,markFlowStart,recordFlowDelta,flowGrowth}from"./lib/owners.js";export{emitMutation,emitRetention,emitStaleGeneration}from"./lib/emit.js";export{onFlowStart,onFlowSettled,checkStaleGeneration}from"./lib/detectors.js";
package/lib/context.js CHANGED
@@ -1,30 +1 @@
1
- let contextGetter = () => undefined;
2
- let options;
3
- const DEFAULTS = {
4
- leakItemThreshold: 50,
5
- staleGenerationBytesThreshold: 1024 * 1024,
6
- settleMs: 1000,
7
- };
8
- export function configureMemoryTracker(opts) {
9
- options = {
10
- sessionId: opts.sessionId,
11
- sink: opts.sink,
12
- leakItemThreshold: opts.leakItemThreshold ?? DEFAULTS.leakItemThreshold,
13
- staleGenerationBytesThreshold: opts.staleGenerationBytesThreshold ?? DEFAULTS.staleGenerationBytesThreshold,
14
- settleMs: opts.settleMs ?? DEFAULTS.settleMs,
15
- };
16
- if (opts.contextGetter)
17
- contextGetter = opts.contextGetter;
18
- return options;
19
- }
20
- export function activeMemoryOptions() {
21
- return options;
22
- }
23
- export function currentMemoryContext() {
24
- return contextGetter();
25
- }
26
- /** Test hook. */
27
- export function resetMemoryTracker() {
28
- options = undefined;
29
- contextGetter = () => undefined;
30
- }
1
+ "use strict";var a=Object.defineProperty;var t=(e,n)=>a(e,"name",{value:n,configurable:!0});var c=Object.defineProperty,r=t((e,n)=>c(e,"name",{value:n,configurable:!0}),"t");let s=r(()=>{},"contextGetter"),o;const l={leakItemThreshold:50,staleGenerationBytesThreshold:1024*1024,settleMs:1e3};export function configureMemoryTracker(e){return o={sessionId:e.sessionId,sink:e.sink,leakItemThreshold:e.leakItemThreshold??l.leakItemThreshold,staleGenerationBytesThreshold:e.staleGenerationBytesThreshold??l.staleGenerationBytesThreshold,settleMs:e.settleMs??l.settleMs},e.contextGetter&&(s=e.contextGetter),o}t(configureMemoryTracker,"configureMemoryTracker"),r(configureMemoryTracker,"configureMemoryTracker");export function activeMemoryOptions(){return o}t(activeMemoryOptions,"activeMemoryOptions"),r(activeMemoryOptions,"activeMemoryOptions");export function currentMemoryContext(){return s()}t(currentMemoryContext,"currentMemoryContext"),r(currentMemoryContext,"currentMemoryContext");export function resetMemoryTracker(){o=void 0,s=r(()=>{},"contextGetter")}t(resetMemoryTracker,"resetMemoryTracker"),r(resetMemoryTracker,"resetMemoryTracker");
package/lib/detectors.js CHANGED
@@ -1,62 +1 @@
1
- /**
2
- * Suspect-leak + stale-generation detectors.
3
- *
4
- * `onFlowStart` / `onFlowSettled` bracket a flow: at start we snapshot
5
- * every owner's count; after the flow settles we compare. If an owner
6
- * grew past the threshold and didn't shrink back, we emit a
7
- * `memory-retention` event.
8
- *
9
- * `checkStaleGeneration` is called when a singleton instance is
10
- * disposed; if its sampled retained bytes exceed the threshold we emit
11
- * a `singleton-stale-generation` event.
12
- */
13
- import { activeMemoryOptions } from './context.js';
14
- import { clearFlowStart, flowGrowth, markFlowStart, } from './owners.js';
15
- import { emitRetention, emitStaleGeneration } from './emit.js';
16
- export function onFlowStart(flowId) {
17
- markFlowStart(flowId);
18
- }
19
- /**
20
- * Compare each owner's count at flow-start vs now. Owners that grew by
21
- * more than `leakItemThreshold` and didn't shrink are flagged. Returns
22
- * the list of flagged owner ids (also useful for tests).
23
- */
24
- export function onFlowSettled(flowId) {
25
- const opts = activeMemoryOptions();
26
- if (!opts)
27
- return [];
28
- const flagged = [];
29
- for (const g of flowGrowth(flowId)) {
30
- // Flag when THIS flow's attributed growth crosses the threshold AND
31
- // the items are still resident (the container didn't shrink back).
32
- if (g.growth >= opts.leakItemThreshold && g.endCount >= g.growth) {
33
- emitRetention({
34
- options: opts,
35
- ownerId: g.owner.ownerId,
36
- flowId,
37
- startCount: g.startCount,
38
- endCount: g.endCount,
39
- growth: g.growth,
40
- });
41
- flagged.push(g.owner.ownerId);
42
- }
43
- }
44
- clearFlowStart(flowId);
45
- return flagged;
46
- }
47
- export function checkStaleGeneration(args) {
48
- const opts = activeMemoryOptions();
49
- if (!opts)
50
- return false;
51
- if (args.retainedBytes > opts.staleGenerationBytesThreshold) {
52
- emitStaleGeneration({
53
- options: opts,
54
- logicalId: args.logicalId,
55
- instanceId: args.instanceId,
56
- generation: args.generation,
57
- retainedBytes: args.retainedBytes,
58
- });
59
- return true;
60
- }
61
- return false;
62
- }
1
+ "use strict";var s=Object.defineProperty;var n=(e,t)=>s(e,"name",{value:t,configurable:!0});var l=Object.defineProperty,r=n((e,t)=>l(e,"name",{value:t,configurable:!0}),"n");import{activeMemoryOptions as i}from"./context.js";import{clearFlowStart as c,flowGrowth as d,markFlowStart as w}from"./owners.js";import{emitRetention as u,emitStaleGeneration as f}from"./emit.js";export function onFlowStart(e){w(e)}n(onFlowStart,"onFlowStart"),r(onFlowStart,"onFlowStart");export function onFlowSettled(e){const t=i();if(!t)return[];const a=[];for(const o of d(e))o.growth>=t.leakItemThreshold&&o.endCount>=o.growth&&(u({options:t,ownerId:o.owner.ownerId,flowId:e,startCount:o.startCount,endCount:o.endCount,growth:o.growth}),a.push(o.owner.ownerId));return c(e),a}n(onFlowSettled,"onFlowSettled"),r(onFlowSettled,"onFlowSettled");export function checkStaleGeneration(e){const t=i();return t&&e.retainedBytes>t.staleGenerationBytesThreshold?(f({options:t,logicalId:e.logicalId,instanceId:e.instanceId,generation:e.generation,retainedBytes:e.retainedBytes}),!0):!1}n(checkStaleGeneration,"checkStaleGeneration"),r(checkStaleGeneration,"checkStaleGeneration");
package/lib/emit.js CHANGED
@@ -1,93 +1 @@
1
- let seq = 0;
2
- function memId(prefix) {
3
- seq = (seq + 1) % 0xffffff;
4
- return `${prefix}-${seq.toString(36)}`;
5
- }
6
- function baseContext(options, ctx) {
7
- return {
8
- sessionId: ctx?.sessionId ?? options.sessionId,
9
- ...(ctx?.flowId ? { flowId: ctx.flowId } : {}),
10
- ...(ctx?.requestId ? { requestId: ctx.requestId } : {}),
11
- ...(ctx?.originNodeId ? { originNodeId: ctx.originNodeId } : {}),
12
- };
13
- }
14
- export function emitMutation(args) {
15
- const { options } = args;
16
- const event = {
17
- id: memId('memmut'),
18
- sessionId: args.context?.sessionId ?? options.sessionId,
19
- timestamp: args.timestamp ?? nowMs(),
20
- source: 'memory',
21
- category: 'memory',
22
- severity: 'debug',
23
- context: baseContext(options, args.context),
24
- fingerprint: `memory-mutation:${args.ownerId}:${args.operation}`,
25
- title: `${args.operation} ${args.ownerId}`,
26
- raw: {
27
- kind: 'memory-mutation',
28
- mutation: {
29
- ownerNodeId: args.ownerId,
30
- operation: args.operation,
31
- beforeCount: args.beforeCount,
32
- afterCount: args.afterCount,
33
- estimatedDeltaBytes: args.estimatedDeltaBytes,
34
- keyPreview: args.keyPreview,
35
- },
36
- },
37
- };
38
- options.sink(event);
39
- }
40
- export function emitRetention(args) {
41
- const { options } = args;
42
- const event = {
43
- id: memId('memret'),
44
- sessionId: args.context?.sessionId ?? options.sessionId,
45
- timestamp: args.timestamp ?? nowMs(),
46
- source: 'memory',
47
- category: 'memory',
48
- severity: 'warning',
49
- context: { ...baseContext(options, args.context), flowId: args.flowId },
50
- fingerprint: `memory-retention:${args.ownerId}`,
51
- title: `Suspected leak: ${args.ownerId} grew by ${args.growth} and did not shrink`,
52
- raw: {
53
- kind: 'memory-retention',
54
- retention: {
55
- ownerId: args.ownerId,
56
- flowId: args.flowId,
57
- startCount: args.startCount,
58
- endCount: args.endCount,
59
- growth: args.growth,
60
- },
61
- },
62
- };
63
- options.sink(event);
64
- }
65
- export function emitStaleGeneration(args) {
66
- const { options } = args;
67
- const event = {
68
- id: memId('memstale'),
69
- sessionId: options.sessionId,
70
- timestamp: args.timestamp ?? nowMs(),
71
- source: 'memory',
72
- category: 'memory',
73
- severity: 'warning',
74
- context: { sessionId: options.sessionId },
75
- fingerprint: `memory-stale-generation:${args.logicalId}`,
76
- title: `Stale generation retained: ${args.logicalId} gen ${args.generation} holds ${args.retainedBytes} bytes`,
77
- raw: {
78
- kind: 'singleton-stale-generation',
79
- staleGeneration: {
80
- logicalId: args.logicalId,
81
- instanceId: args.instanceId,
82
- generation: args.generation,
83
- retainedBytes: args.retainedBytes,
84
- },
85
- },
86
- };
87
- options.sink(event);
88
- }
89
- function nowMs() {
90
- // `Date.now` is fine in library runtime code; the workflow-script ban
91
- // doesn't apply here.
92
- return Date.now();
93
- }
1
+ "use strict";var m=Object.defineProperty;var n=(t,e)=>m(t,"name",{value:e,configurable:!0});var I=Object.defineProperty,o=n((t,e)=>I(t,"name",{value:e,configurable:!0}),"n");let d=0;function r(t){return d=(d+1)%16777215,`${t}-${d.toString(36)}`}n(r,"d"),o(r,"memId");function a(t,e){return{sessionId:e?.sessionId??t.sessionId,...e?.flowId?{flowId:e.flowId}:{},...e?.requestId?{requestId:e.requestId}:{},...e?.originNodeId?{originNodeId:e.originNodeId}:{}}}n(a,"r"),o(a,"baseContext");export function emitMutation(t){const{options:e}=t,i={id:r("memmut"),sessionId:t.context?.sessionId??e.sessionId,timestamp:t.timestamp??s(),source:"memory",category:"memory",severity:"debug",context:a(e,t.context),fingerprint:`memory-mutation:${t.ownerId}:${t.operation}`,title:`${t.operation} ${t.ownerId}`,raw:{kind:"memory-mutation",mutation:{ownerNodeId:t.ownerId,operation:t.operation,beforeCount:t.beforeCount,afterCount:t.afterCount,estimatedDeltaBytes:t.estimatedDeltaBytes,keyPreview:t.keyPreview}}};e.sink(i)}n(emitMutation,"emitMutation"),o(emitMutation,"emitMutation");export function emitRetention(t){const{options:e}=t,i={id:r("memret"),sessionId:t.context?.sessionId??e.sessionId,timestamp:t.timestamp??s(),source:"memory",category:"memory",severity:"warning",context:{...a(e,t.context),flowId:t.flowId},fingerprint:`memory-retention:${t.ownerId}`,title:`Suspected leak: ${t.ownerId} grew by ${t.growth} and did not shrink`,raw:{kind:"memory-retention",retention:{ownerId:t.ownerId,flowId:t.flowId,startCount:t.startCount,endCount:t.endCount,growth:t.growth}}};e.sink(i)}n(emitRetention,"emitRetention"),o(emitRetention,"emitRetention");export function emitStaleGeneration(t){const{options:e}=t,i={id:r("memstale"),sessionId:e.sessionId,timestamp:t.timestamp??s(),source:"memory",category:"memory",severity:"warning",context:{sessionId:e.sessionId},fingerprint:`memory-stale-generation:${t.logicalId}`,title:`Stale generation retained: ${t.logicalId} gen ${t.generation} holds ${t.retainedBytes} bytes`,raw:{kind:"singleton-stale-generation",staleGeneration:{logicalId:t.logicalId,instanceId:t.instanceId,generation:t.generation,retainedBytes:t.retainedBytes}}};e.sink(i)}n(emitStaleGeneration,"emitStaleGeneration"),o(emitStaleGeneration,"emitStaleGeneration");function s(){return Date.now()}n(s,"s"),o(s,"nowMs");
package/lib/owners.js CHANGED
@@ -1,78 +1 @@
1
- const owners = new Map();
2
- export function ownerKey(ownerInstanceId, fieldName) {
3
- return `${ownerInstanceId}::${fieldName}`;
4
- }
5
- export function ensureOwner(args) {
6
- const id = ownerKey(args.ownerInstanceId, args.fieldName);
7
- let rec = owners.get(id);
8
- if (!rec) {
9
- rec = {
10
- ownerId: id,
11
- ownerInstanceId: args.ownerInstanceId,
12
- containerKind: args.containerKind,
13
- fieldName: args.fieldName,
14
- itemCount: 0,
15
- estimatedBytes: 0,
16
- startCount: 0,
17
- flowStartCounts: new Map(),
18
- flowDeltas: new Map(),
19
- };
20
- owners.set(id, rec);
21
- }
22
- return rec;
23
- }
24
- export function recordCount(rec, itemCount, estimatedBytes) {
25
- rec.itemCount = itemCount;
26
- rec.estimatedBytes = estimatedBytes;
27
- }
28
- export function markFlowStart(flowId) {
29
- for (const rec of owners.values()) {
30
- if (!rec.flowStartCounts.has(flowId)) {
31
- rec.flowStartCounts.set(flowId, rec.itemCount);
32
- }
33
- }
34
- }
35
- /** Attribute a net item delta to the flow whose mutation caused it. */
36
- export function recordFlowDelta(rec, flowId, delta) {
37
- rec.flowDeltas.set(flowId, (rec.flowDeltas.get(flowId) ?? 0) + delta);
38
- }
39
- export function flowGrowth(flowId) {
40
- const out = [];
41
- for (const rec of owners.values()) {
42
- // Only owners this flow actually mutated. `growth` is the flow's own
43
- // attributed net add, not the global item-count delta.
44
- const delta = rec.flowDeltas.get(flowId);
45
- if (delta === undefined)
46
- continue;
47
- out.push({
48
- owner: rec,
49
- startCount: rec.flowStartCounts.get(flowId) ?? 0,
50
- endCount: rec.itemCount,
51
- growth: delta,
52
- });
53
- }
54
- return out;
55
- }
56
- export function clearFlowStart(flowId) {
57
- for (const rec of owners.values()) {
58
- rec.flowStartCounts.delete(flowId);
59
- rec.flowDeltas.delete(flowId);
60
- }
61
- }
62
- export function allOwners() {
63
- return [...owners.values()].map((rec) => ({
64
- ownerId: rec.ownerId,
65
- ownerInstanceId: rec.ownerInstanceId,
66
- containerKind: rec.containerKind,
67
- fieldName: rec.fieldName,
68
- itemCount: rec.itemCount,
69
- estimatedBytes: rec.estimatedBytes,
70
- growthSinceStart: rec.itemCount - rec.startCount,
71
- }));
72
- }
73
- export function getOwner(ownerId) {
74
- return owners.get(ownerId);
75
- }
76
- export function resetOwners() {
77
- owners.clear();
78
- }
1
+ "use strict";var l=Object.defineProperty;var o=(e,t)=>l(e,"name",{value:t,configurable:!0});var w=Object.defineProperty,r=o((e,t)=>w(e,"name",{value:t,configurable:!0}),"o");const a=new Map;export function ownerKey(e,t){return`${e}::${t}`}o(ownerKey,"ownerKey"),r(ownerKey,"ownerKey");export function ensureOwner(e){const t=ownerKey(e.ownerInstanceId,e.fieldName);let n=a.get(t);return n||(n={ownerId:t,ownerInstanceId:e.ownerInstanceId,containerKind:e.containerKind,fieldName:e.fieldName,itemCount:0,estimatedBytes:0,startCount:0,flowStartCounts:new Map,flowDeltas:new Map},a.set(t,n)),n}o(ensureOwner,"ensureOwner"),r(ensureOwner,"ensureOwner");export function recordCount(e,t,n){e.itemCount=t,e.estimatedBytes=n}o(recordCount,"recordCount"),r(recordCount,"recordCount");export function markFlowStart(e){for(const t of a.values())t.flowStartCounts.has(e)||t.flowStartCounts.set(e,t.itemCount)}o(markFlowStart,"markFlowStart"),r(markFlowStart,"markFlowStart");export function recordFlowDelta(e,t,n){e.flowDeltas.set(t,(e.flowDeltas.get(t)??0)+n)}o(recordFlowDelta,"recordFlowDelta"),r(recordFlowDelta,"recordFlowDelta");export function flowGrowth(e){const t=[];for(const n of a.values()){const s=n.flowDeltas.get(e);s!==void 0&&t.push({owner:n,startCount:n.flowStartCounts.get(e)??0,endCount:n.itemCount,growth:s})}return t}o(flowGrowth,"flowGrowth"),r(flowGrowth,"flowGrowth");export function clearFlowStart(e){for(const t of a.values())t.flowStartCounts.delete(e),t.flowDeltas.delete(e)}o(clearFlowStart,"clearFlowStart"),r(clearFlowStart,"clearFlowStart");export function allOwners(){return[...a.values()].map(e=>({ownerId:e.ownerId,ownerInstanceId:e.ownerInstanceId,containerKind:e.containerKind,fieldName:e.fieldName,itemCount:e.itemCount,estimatedBytes:e.estimatedBytes,growthSinceStart:e.itemCount-e.startCount}))}o(allOwners,"allOwners"),r(allOwners,"allOwners");export function getOwner(e){return a.get(e)}o(getOwner,"getOwner"),r(getOwner,"getOwner");export function resetOwners(){a.clear()}o(resetOwners,"resetOwners"),r(resetOwners,"resetOwners");
@@ -1,155 +1 @@
1
- /**
2
- * Container tracking. Wraps the mutating methods of a Map / Set / Array
3
- * so each mutation:
4
- * 1. updates the owner's item count + byte estimate,
5
- * 2. emits a `memory-mutation` event attributed to the active flow.
6
- *
7
- * The wrapping is in-place (we patch the instance's own methods) and
8
- * non-destructive: original behaviour always runs, return values pass
9
- * through, and patching is idempotent (guarded by a Symbol flag).
10
- */
11
- import { activeMemoryOptions, currentMemoryContext } from './context.js';
12
- import { ensureOwner, recordCount, recordFlowDelta } from './owners.js';
13
- import { emitMutation } from './emit.js';
14
- const PATCHED = Symbol.for('@lensmcp/memory-tracker/patched');
15
- /** Rough per-item byte estimate; good enough for growth-trend detection. */
16
- const BYTES_PER_ITEM = 64;
17
- export function trackContainer(args) {
18
- const { container } = args;
19
- if (!container || typeof container !== 'object')
20
- return;
21
- if (container[PATCHED])
22
- return;
23
- let kind;
24
- if (container instanceof Map) {
25
- kind = 'Map';
26
- patchMap(args, container);
27
- }
28
- else if (container instanceof Set) {
29
- kind = 'Set';
30
- patchSet(args, container);
31
- }
32
- else if (Array.isArray(container)) {
33
- kind = 'Array';
34
- patchArray(args, container);
35
- }
36
- else {
37
- return;
38
- }
39
- container[PATCHED] = true;
40
- // Register the owner eagerly (at its current size) so a subsequent
41
- // `markFlowStart` snapshots a baseline even before the first mutation.
42
- const initial = sizeOf(container);
43
- const owner = ensureOwner({
44
- ownerInstanceId: args.ownerInstanceId,
45
- fieldName: args.fieldName,
46
- containerKind: kind,
47
- });
48
- recordCount(owner, initial, initial * BYTES_PER_ITEM);
49
- }
50
- function sizeOf(container) {
51
- if (container instanceof Map || container instanceof Set)
52
- return container.size;
53
- if (Array.isArray(container))
54
- return container.length;
55
- return 0;
56
- }
57
- function afterMutation(args, kind, operation, before, keyPreview) {
58
- const opts = activeMemoryOptions();
59
- if (!opts)
60
- return;
61
- const after = sizeOf(args.container);
62
- const owner = ensureOwner({
63
- ownerInstanceId: args.ownerInstanceId,
64
- fieldName: args.fieldName,
65
- containerKind: kind,
66
- });
67
- recordCount(owner, after, after * BYTES_PER_ITEM);
68
- const ctx = currentMemoryContext();
69
- // Attribute this mutation's net delta to the active flow so the leak
70
- // detector blames the flow that actually grew the container. Keyed by
71
- // requestId (preferred — the interceptor brackets onFlowStart/Settled
72
- // by requestId) with flowId as the fallback for non-request flows.
73
- const flowKey = ctx?.requestId ?? ctx?.flowId;
74
- if (flowKey)
75
- recordFlowDelta(owner, flowKey, after - before);
76
- emitMutation({
77
- options: opts,
78
- ownerId: owner.ownerId,
79
- operation,
80
- beforeCount: before,
81
- afterCount: after,
82
- estimatedDeltaBytes: (after - before) * BYTES_PER_ITEM,
83
- keyPreview,
84
- context: ctx,
85
- });
86
- }
87
- function patchMap(args, map) {
88
- const origSet = map.set.bind(map);
89
- const origDelete = map.delete.bind(map);
90
- const origClear = map.clear.bind(map);
91
- map.set = (k, v) => {
92
- const before = map.size;
93
- const r = origSet(k, v);
94
- afterMutation(args, 'Map', 'set', before, previewKey(k));
95
- return r;
96
- };
97
- map.delete = (k) => {
98
- const before = map.size;
99
- const r = origDelete(k);
100
- afterMutation(args, 'Map', 'delete', before, previewKey(k));
101
- return r;
102
- };
103
- map.clear = () => {
104
- const before = map.size;
105
- origClear();
106
- afterMutation(args, 'Map', 'clear', before);
107
- };
108
- }
109
- function patchSet(args, set) {
110
- const origAdd = set.add.bind(set);
111
- const origDelete = set.delete.bind(set);
112
- const origClear = set.clear.bind(set);
113
- set.add = (v) => {
114
- const before = set.size;
115
- const r = origAdd(v);
116
- afterMutation(args, 'Set', 'add', before, previewKey(v));
117
- return r;
118
- };
119
- set.delete = (v) => {
120
- const before = set.size;
121
- const r = origDelete(v);
122
- afterMutation(args, 'Set', 'delete', before, previewKey(v));
123
- return r;
124
- };
125
- set.clear = () => {
126
- const before = set.size;
127
- origClear();
128
- afterMutation(args, 'Set', 'clear', before);
129
- };
130
- }
131
- function patchArray(args, arr) {
132
- const origPush = arr.push.bind(arr);
133
- const origSplice = arr.splice.bind(arr);
134
- arr.push = (...items) => {
135
- const before = arr.length;
136
- const r = origPush(...items);
137
- afterMutation(args, 'Array', 'push', before);
138
- return r;
139
- };
140
- arr.splice = ((start, deleteCount, ...items) => {
141
- const before = arr.length;
142
- const r = deleteCount === undefined
143
- ? origSplice(start)
144
- : origSplice(start, deleteCount, ...items);
145
- afterMutation(args, 'Array', items.length > 0 ? 'push' : 'delete', before);
146
- return r;
147
- });
148
- }
149
- function previewKey(k) {
150
- if (typeof k === 'string')
151
- return k.slice(0, 40);
152
- if (typeof k === 'number' || typeof k === 'boolean')
153
- return String(k);
154
- return undefined;
155
- }
1
+ "use strict";var z=Object.defineProperty;var s=(t,e)=>z(t,"name",{value:e,configurable:!0});var A=Object.defineProperty,f=s((t,e)=>A(t,"name",{value:e,configurable:!0}),"s");import{activeMemoryOptions as g,currentMemoryContext as v}from"./context.js";import{ensureOwner as b,recordCount as h,recordFlowDelta as C}from"./owners.js";import{emitMutation as k}from"./emit.js";const I=Symbol.for("@lensmcp/memory-tracker/patched"),p=64;export function trackContainer(t){const{container:e}=t;if(!e||typeof e!="object"||e[I])return;let a;if(e instanceof Map)a="Map",w(t,e);else if(e instanceof Set)a="Set",M(t,e);else if(Array.isArray(e))a="Array",S(t,e);else return;e[I]=!0;const o=m(e),c=b({ownerInstanceId:t.ownerInstanceId,fieldName:t.fieldName,containerKind:a});h(c,o,o*p)}s(trackContainer,"trackContainer"),f(trackContainer,"trackContainer");function m(t){return t instanceof Map||t instanceof Set?t.size:Array.isArray(t)?t.length:0}s(m,"w"),f(m,"sizeOf");function d(t,e,a,o,c){const r=g();if(!r)return;const n=m(t.container),i=b({ownerInstanceId:t.ownerInstanceId,fieldName:t.fieldName,containerKind:e});h(i,n,n*p);const l=v(),y=l?.requestId??l?.flowId;y&&C(i,y,n-o),k({options:r,ownerId:i.ownerId,operation:a,beforeCount:o,afterCount:n,estimatedDeltaBytes:(n-o)*p,keyPreview:c,context:l})}s(d,"d"),f(d,"afterMutation");function w(t,e){const a=e.set.bind(e),o=e.delete.bind(e),c=e.clear.bind(e);e.set=(r,n)=>{const i=e.size,l=a(r,n);return d(t,"Map","set",i,u(r)),l},e.delete=r=>{const n=e.size,i=o(r);return d(t,"Map","delete",n,u(r)),i},e.clear=()=>{const r=e.size;c(),d(t,"Map","clear",r)}}s(w,"m"),f(w,"patchMap");function M(t,e){const a=e.add.bind(e),o=e.delete.bind(e),c=e.clear.bind(e);e.add=r=>{const n=e.size,i=a(r);return d(t,"Set","add",n,u(r)),i},e.delete=r=>{const n=e.size,i=o(r);return d(t,"Set","delete",n,u(r)),i},e.clear=()=>{const r=e.size;c(),d(t,"Set","clear",r)}}s(M,"C"),f(M,"patchSet");function S(t,e){const a=e.push.bind(e),o=e.splice.bind(e);e.push=(...c)=>{const r=e.length,n=a(...c);return d(t,"Array","push",r),n},e.splice=((c,r,...n)=>{const i=e.length,l=r===void 0?o(c):o(c,r,...n);return d(t,"Array",n.length>0?"push":"delete",i),l})}s(S,"D"),f(S,"patchArray");function u(t){if(typeof t=="string")return t.slice(0,40);if(typeof t=="number"||typeof t=="boolean")return String(t)}s(u,"u"),f(u,"previewKey");
package/lib/types.js CHANGED
@@ -1 +1 @@
1
- export {};
1
+ "use strict";export{};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lensmcp/memory-tracker",
3
- "version": "1.18.4",
3
+ "version": "1.18.6",
4
4
  "type": "module",
5
5
  "main": "./index.js",
6
6
  "module": "./index.js",
@@ -14,7 +14,7 @@
14
14
  }
15
15
  },
16
16
  "dependencies": {
17
- "@lensmcp/protocol-types": "1.18.4",
17
+ "@lensmcp/protocol-types": "1.18.6",
18
18
  "tslib": "^2.3.0"
19
19
  },
20
20
  "license": "Apache-2.0",