@wrongstack/core 0.310.1 → 0.313.1
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/dist/chronicle/index.js +84 -6391
- package/dist/chronicle/project-server.js +84 -4868
- package/dist/chunk-2BUUIMQB.js +225 -0
- package/dist/chunk-2FK4WTFF.js +207 -0
- package/dist/chunk-2FQL4PDC.js +292 -0
- package/dist/chunk-2KKODIQU.js +2256 -0
- package/dist/chunk-2YU4WVBW.js +134 -0
- package/dist/chunk-3E244UDA.js +356 -0
- package/dist/chunk-3XPVB7BA.js +135 -0
- package/dist/chunk-4LJJYBAU.js +388 -0
- package/dist/chunk-4VWO3ZXL.js +342 -0
- package/dist/chunk-4XV6IR37.js +187 -0
- package/dist/chunk-4ZHTKJHM.js +183 -0
- package/dist/chunk-52RTVH4M.js +361 -0
- package/dist/chunk-57GEWK5X.js +26 -0
- package/dist/chunk-5DSMEVA4.js +931 -0
- package/dist/chunk-5RP3QTRL.js +1223 -0
- package/dist/chunk-5S437PRC.js +50 -0
- package/dist/chunk-5XDUGTKN.js +511 -0
- package/dist/chunk-62V2AFVG.js +422 -0
- package/dist/chunk-65RDIOR2.js +2470 -0
- package/dist/chunk-6AKOTGLM.js +597 -0
- package/dist/chunk-7ZHZE5EO.js +28 -0
- package/dist/chunk-A455ATZB.js +140 -0
- package/dist/chunk-AD7ZFZCS.js +46 -0
- package/dist/chunk-AI4LLQ2U.js +856 -0
- package/dist/chunk-ASX6AW36.js +789 -0
- package/dist/chunk-AT4V4XGI.js +3522 -0
- package/dist/chunk-AWNQ6ED6.js +311 -0
- package/dist/chunk-B4AMLZPB.js +9 -0
- package/dist/chunk-BAKVJLEV.js +417 -0
- package/dist/chunk-BJHVULHO.js +55 -0
- package/dist/chunk-CB2HFKTP.js +9 -0
- package/dist/chunk-CE4ZOCOI.js +1640 -0
- package/dist/chunk-CQQL4ZOQ.js +151 -0
- package/dist/chunk-DEIQMBD2.js +65 -0
- package/dist/chunk-E6I5RXVK.js +58 -0
- package/dist/chunk-EFEHDQGY.js +1589 -0
- package/dist/chunk-EODDVJBM.js +82 -0
- package/dist/chunk-EPC3GZD4.js +308 -0
- package/dist/chunk-FAYRX2AD.js +13 -0
- package/dist/chunk-FFSX2QDQ.js +362 -0
- package/dist/chunk-FHAMQS7Q.js +5856 -0
- package/dist/chunk-FIV4IJL7.js +2263 -0
- package/dist/chunk-FNXVT7HF.js +52 -0
- package/dist/chunk-FSWCWSTS.js +395 -0
- package/dist/chunk-FW5LDDMJ.js +16464 -0
- package/dist/chunk-FXQLIX3K.js +211 -0
- package/dist/chunk-G5AAKEEZ.js +228 -0
- package/dist/chunk-G5S3S5ZN.js +38 -0
- package/dist/chunk-GAZEWQEZ.js +231 -0
- package/dist/chunk-GFJOMSHG.js +125 -0
- package/dist/chunk-GFXZTHNI.js +158 -0
- package/dist/chunk-GM54GJBU.js +960 -0
- package/dist/chunk-GPQ3NJPR.js +900 -0
- package/dist/chunk-GTCU6DZ3.js +1 -0
- package/dist/chunk-H5E77KUJ.js +15 -0
- package/dist/chunk-H72H4XDU.js +1023 -0
- package/dist/chunk-HA4ZYA6T.js +178 -0
- package/dist/chunk-I45KAW2N.js +5020 -0
- package/dist/chunk-IQ35HMQL.js +1396 -0
- package/dist/chunk-IYFBFX34.js +86 -0
- package/dist/chunk-JJPMWPB6.js +109 -0
- package/dist/chunk-JTHKOYWU.js +663 -0
- package/dist/chunk-JVGPR3TS.js +365 -0
- package/dist/chunk-JVKB2TBL.js +48 -0
- package/dist/chunk-JX7VBZDK.js +31 -0
- package/dist/chunk-K3G6JBUC.js +5232 -0
- package/dist/chunk-K4YUNKU7.js +589 -0
- package/dist/chunk-KBZGE6LN.js +710 -0
- package/dist/chunk-KDQJCT2J.js +45 -0
- package/dist/chunk-KI4L2DUL.js +560 -0
- package/dist/chunk-KJ2ZTQSL.js +47 -0
- package/dist/chunk-KSJ5UTP7.js +154 -0
- package/dist/chunk-LHOA5DWA.js +28 -0
- package/dist/chunk-LX5QWLBL.js +27 -0
- package/dist/chunk-LZDDLNCZ.js +279 -0
- package/dist/chunk-M2WF6AXG.js +115 -0
- package/dist/chunk-M7BS2K6U.js +1 -0
- package/dist/chunk-NDBIPFNY.js +102 -0
- package/dist/chunk-NEMIWEXC.js +1199 -0
- package/dist/chunk-NFAYHPRH.js +323 -0
- package/dist/chunk-O37BQ65S.js +21 -0
- package/dist/chunk-O74MJHXU.js +187 -0
- package/dist/chunk-OJZEX73F.js +112 -0
- package/dist/chunk-PAAWLLZX.js +74 -0
- package/dist/chunk-PFXFQQRT.js +339 -0
- package/dist/chunk-PFZO3C6H.js +14 -0
- package/dist/chunk-PHH7LD45.js +113 -0
- package/dist/chunk-QRTG4XTI.js +188 -0
- package/dist/chunk-QVOVMXJR.js +1351 -0
- package/dist/chunk-RCQYT2I4.js +757 -0
- package/dist/chunk-RD6DEE36.js +1178 -0
- package/dist/chunk-RJIZEJ42.js +30 -0
- package/dist/chunk-RPOA7IAE.js +150 -0
- package/dist/chunk-SN2DQRL6.js +1172 -0
- package/dist/chunk-SQJVFEBV.js +41 -0
- package/dist/chunk-SQP64RCS.js +5391 -0
- package/dist/chunk-SVT4RNTR.js +49 -0
- package/dist/chunk-SWUFN7XM.js +43 -0
- package/dist/chunk-SXMVYC5H.js +174 -0
- package/dist/chunk-SZ6AYUIZ.js +23 -0
- package/dist/chunk-T3KGZBU5.js +3171 -0
- package/dist/chunk-TBRL2RCC.js +9 -0
- package/dist/chunk-TRT2HRWZ.js +18 -0
- package/dist/chunk-TYW2GI5I.js +1077 -0
- package/dist/chunk-UIWONWVG.js +4959 -0
- package/dist/chunk-VB3H5WWB.js +151 -0
- package/dist/chunk-W4A6QA3D.js +258 -0
- package/dist/chunk-WBPVKEEE.js +227 -0
- package/dist/chunk-WEBMSQP2.js +123 -0
- package/dist/chunk-WOEZV3Q4.js +333 -0
- package/dist/chunk-WQQON3SV.js +473 -0
- package/dist/chunk-WQTOVMGV.js +119 -0
- package/dist/chunk-WZO23AWO.js +2779 -0
- package/dist/chunk-XBDP4QPW.js +7 -0
- package/dist/chunk-XEBHSJLT.js +103 -0
- package/dist/chunk-XQ2ECNK3.js +1 -0
- package/dist/chunk-XQ2XGIBF.js +2086 -0
- package/dist/chunk-Y2GE5TSI.js +355 -0
- package/dist/chunk-YBUJCZ57.js +351 -0
- package/dist/chunk-YNCVSFGF.js +149 -0
- package/dist/chunk-YUPMXOGP.js +282 -0
- package/dist/chunk-YY6APYUM.js +49 -0
- package/dist/chunk-Z2IJUO45.js +691 -0
- package/dist/chunk-ZEHUCJHY.js +129 -0
- package/dist/chunk-ZYU2YOJ6.js +1496 -0
- package/dist/chunk-ZZ4V3WIZ.js +163 -0
- package/dist/coordination/agents/index.js +145 -6260
- package/dist/coordination/index.js +365 -34323
- package/dist/coordination/mailbox-project-server.js +48 -3220
- package/dist/coordination/mailbox-types.d.ts +13 -1
- package/dist/coordination/provider-status-tracker.d.ts +4 -0
- package/dist/coordination/sqlite-mailbox.d.ts +2 -1
- package/dist/core/agent.d.ts +14 -1
- package/dist/core/index.js +267 -12479
- package/dist/core/model-ref.js +5 -23
- package/dist/core/provider-runner.d.ts +36 -1
- package/dist/design/index.js +50 -1087
- package/dist/execution/index.d.ts +1 -1
- package/dist/execution/index.js +1599 -21887
- package/dist/execution/prompt-enhancer.js +16 -535
- package/dist/execution/retry-policy.d.ts +31 -1
- package/dist/extension/index.js +7 -311
- package/dist/goal/index.js +33 -3435
- package/dist/hooks/index.js +14 -1138
- package/dist/hq/index.js +112 -5139
- package/dist/hq/protocol.js +21 -668
- package/dist/index.js +1410 -92655
- package/dist/infrastructure/index.js +64 -4811
- package/dist/kernel/events/provider-events.d.ts +15 -0
- package/dist/kernel/events/wrongtrace-events.d.ts +26 -0
- package/dist/kernel/events.d.ts +16 -7
- package/dist/kernel/index.js +14 -992
- package/dist/models/index.js +40 -1117
- package/dist/notifications/index.js +3 -108
- package/dist/observability/index.js +17 -279
- package/dist/plugin/index.js +584 -14835
- package/dist/prompts/index.js +14 -948
- package/dist/registry/index.js +9 -822
- package/dist/registry-R23UBE7H.js +14 -0
- package/dist/replay/index.js +6 -84
- package/dist/review-finding-store-DKAV3AS6.js +21 -0
- package/dist/review-report-store-OWY3EC3N.js +19 -0
- package/dist/security/index.js +114 -2202
- package/dist/session-catalog/index.js +36 -2103
- package/dist/session-catalog/project-server.js +42 -1435
- package/dist/skills/index.js +35 -1578
- package/dist/storage/index.js +182 -15600
- package/dist/tasking/index.js +10 -676
- package/dist/tools/index.js +52 -9589
- package/dist/types/config/autonomy.d.ts +5 -0
- package/dist/types/config/tools.d.ts +2 -2
- package/dist/types/config/ui.d.ts +1 -1
- package/dist/types/errors.d.ts +18 -0
- package/dist/types/index.js +121 -1341
- package/dist/types/provider-runner.d.ts +8 -0
- package/dist/types/session-markers.js +8 -144
- package/dist/utils/error.js +3 -4
- package/dist/utils/expect-defined.js +3 -9
- package/dist/utils/heap-watchdog.js +6 -706
- package/dist/utils/index.js +269 -5685
- package/dist/utils/sage-output-block.js +5 -42
- package/dist/wiring/proxy-rewrite.d.ts +92 -4
- package/dist/wiring/proxy-rewrite.js +20 -61
- package/dist/worktree/index.js +6 -887
- package/package.json +4 -4
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
// src/kernel/events.ts
|
|
2
|
+
var MAX_WILDCARDS = 500;
|
|
3
|
+
var MAX_NAMED_LISTENERS = 2e3;
|
|
4
|
+
var EventBus = class {
|
|
5
|
+
listeners = /* @__PURE__ */ new Map();
|
|
6
|
+
wildcards = [];
|
|
7
|
+
logger;
|
|
8
|
+
/**
|
|
9
|
+
* Dispatch arrays cached per event name, rebuilt lazily after a
|
|
10
|
+
* subscription change. See {@link namedSnapshot}. Every mutation of
|
|
11
|
+
* `listeners` must invalidate the matching entry, and every mutation of
|
|
12
|
+
* `wildcards` must null `wildcardSnapshotCache` — a missed invalidation
|
|
13
|
+
* means an emit dispatches to a stale listener set.
|
|
14
|
+
*/
|
|
15
|
+
listenerSnapshots = /* @__PURE__ */ new Map();
|
|
16
|
+
wildcardSnapshotCache = null;
|
|
17
|
+
setLogger(logger) {
|
|
18
|
+
this.logger = logger;
|
|
19
|
+
}
|
|
20
|
+
on(event, fn) {
|
|
21
|
+
if (this.listenerCount() >= MAX_NAMED_LISTENERS) {
|
|
22
|
+
this.logger?.error(
|
|
23
|
+
`EventBus named listener limit (~${MAX_NAMED_LISTENERS}) reached \u2014 rejecting on("${event}"). Callers must dispose their named listeners to prevent unbounded memory growth.`
|
|
24
|
+
);
|
|
25
|
+
return () => {
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
let set = this.listeners.get(event);
|
|
29
|
+
if (!set) {
|
|
30
|
+
set = /* @__PURE__ */ new Set();
|
|
31
|
+
this.listeners.set(event, set);
|
|
32
|
+
}
|
|
33
|
+
set.add(fn);
|
|
34
|
+
this.listenerSnapshots.delete(event);
|
|
35
|
+
return () => this.off(event, fn);
|
|
36
|
+
}
|
|
37
|
+
off(event, fn) {
|
|
38
|
+
const set = this.listeners.get(event);
|
|
39
|
+
if (!set) return;
|
|
40
|
+
set.delete(fn);
|
|
41
|
+
this.listenerSnapshots.delete(event);
|
|
42
|
+
if (set.size === 0) this.listeners.delete(event);
|
|
43
|
+
}
|
|
44
|
+
once(event, fn) {
|
|
45
|
+
const wrapper = (payload) => {
|
|
46
|
+
this.off(event, wrapper);
|
|
47
|
+
fn(payload);
|
|
48
|
+
};
|
|
49
|
+
this.on(event, wrapper);
|
|
50
|
+
return () => {
|
|
51
|
+
this.off(event, wrapper);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Subscribe to all events, regardless of name. Short-hand for
|
|
56
|
+
* `onPattern('*')`. Use for logging, debugging, or forwarding every
|
|
57
|
+
* event to another bus (as FleetBus does).
|
|
58
|
+
*
|
|
59
|
+
* Returns an unsubscribe function.
|
|
60
|
+
*/
|
|
61
|
+
onAny(fn, owner) {
|
|
62
|
+
return this.onPattern("*", fn, owner);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Subscribe to all events whose name matches a glob-style prefix.
|
|
66
|
+
* `'tool.*'` matches `tool.started`, `tool.executed`, `tool.progress`, etc.
|
|
67
|
+
* `'*'` matches every event.
|
|
68
|
+
*
|
|
69
|
+
* The handler receives `(eventName, payload)` with the event name as a
|
|
70
|
+
* string and the payload as `unknown`. Use for logging, debugging, or
|
|
71
|
+
* metrics collection across a family of events.
|
|
72
|
+
*
|
|
73
|
+
* Returns an unsubscribe function.
|
|
74
|
+
*/
|
|
75
|
+
onPattern(pattern, fn, owner) {
|
|
76
|
+
if (this.wildcards.length >= MAX_WILDCARDS) {
|
|
77
|
+
this.logger?.error(
|
|
78
|
+
`EventBus wildcard limit (${MAX_WILDCARDS}) reached \u2014 rejecting onPattern("${pattern}")` + (owner ? ` (owner: ${owner})` : "") + ". Callers must dispose their wildcard listeners to prevent unbounded growth."
|
|
79
|
+
);
|
|
80
|
+
return () => {
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
const match = makePatternMatcher(pattern);
|
|
84
|
+
const entry = { match, fn, owner };
|
|
85
|
+
this.wildcards.push(entry);
|
|
86
|
+
this.wildcardSnapshotCache = null;
|
|
87
|
+
return () => {
|
|
88
|
+
const idx = this.wildcards.indexOf(entry);
|
|
89
|
+
if (idx >= 0) {
|
|
90
|
+
this.wildcards.splice(idx, 1);
|
|
91
|
+
this.wildcardSnapshotCache = null;
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Subscribe to all events whose name matches a RegExp.
|
|
97
|
+
* More flexible than `onPattern` — use when you need regex features
|
|
98
|
+
* (alternation, character classes, capture groups).
|
|
99
|
+
*
|
|
100
|
+
* Returns an unsubscribe function.
|
|
101
|
+
*/
|
|
102
|
+
onRegex(regex, fn, owner) {
|
|
103
|
+
if (this.wildcards.length >= MAX_WILDCARDS) {
|
|
104
|
+
this.logger?.error(
|
|
105
|
+
`EventBus wildcard limit (${MAX_WILDCARDS}) reached \u2014 rejecting onRegex(${regex})` + (owner ? ` (owner: ${owner})` : "") + ". Callers must dispose their wildcard listeners to prevent unbounded growth."
|
|
106
|
+
);
|
|
107
|
+
return () => {
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const entry = { match: (e) => regex.test(e), fn, owner };
|
|
111
|
+
this.wildcards.push(entry);
|
|
112
|
+
this.wildcardSnapshotCache = null;
|
|
113
|
+
return () => {
|
|
114
|
+
const idx = this.wildcards.indexOf(entry);
|
|
115
|
+
if (idx >= 0) {
|
|
116
|
+
this.wildcards.splice(idx, 1);
|
|
117
|
+
this.wildcardSnapshotCache = null;
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
emit(event, payload) {
|
|
122
|
+
const snapshot = this.namedSnapshot(event);
|
|
123
|
+
if (snapshot !== void 0) {
|
|
124
|
+
for (const fn of snapshot) {
|
|
125
|
+
try {
|
|
126
|
+
fn(payload);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
this.logger?.error(`EventBus listener for "${event}" threw`, err);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (this.wildcards.length > 0) {
|
|
133
|
+
const name = event;
|
|
134
|
+
for (const { match, fn } of this.wildcardSnapshot()) {
|
|
135
|
+
if (!match(name)) continue;
|
|
136
|
+
try {
|
|
137
|
+
fn(name, payload);
|
|
138
|
+
} catch (err) {
|
|
139
|
+
this.logger?.error(`EventBus wildcard listener for "${name}" threw`, err);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Dispatch array for one event name, or `undefined` when nothing is
|
|
146
|
+
* subscribed.
|
|
147
|
+
*
|
|
148
|
+
* Dispatch iterates a stable array rather than the live Set so a listener
|
|
149
|
+
* that subscribes or unsubscribes mid-emit cannot change what this round
|
|
150
|
+
* delivers: an addition fires from the next emit, a removal may still fire
|
|
151
|
+
* this round. That is the contract callers rely on, and it is unchanged.
|
|
152
|
+
*
|
|
153
|
+
* What changed is who pays for it. Building the array per emit did O(number
|
|
154
|
+
* of listeners) copying on every event, including `tool.progress` and
|
|
155
|
+
* streaming deltas — the highest-frequency paths in the process. The array
|
|
156
|
+
* is now cached and rebuilt only when the subscription set actually changes,
|
|
157
|
+
* which is wiring time and essentially never during a run. Measured at 2M
|
|
158
|
+
* emits with 12 named + 6 wildcard listeners: 207 ms → 141 ms.
|
|
159
|
+
*
|
|
160
|
+
* This is a throughput win, not a footprint one: the per-emit arrays died in
|
|
161
|
+
* the nursery and never showed up as retained heap (measured heap growth was
|
|
162
|
+
* the same either way). Do not cite this as a memory fix.
|
|
163
|
+
*
|
|
164
|
+
* A mutation during dispatch invalidates the cache for the *next* emit while
|
|
165
|
+
* the in-flight loop keeps walking the array it started with — which is
|
|
166
|
+
* exactly the snapshot semantics described above.
|
|
167
|
+
*/
|
|
168
|
+
namedSnapshot(event) {
|
|
169
|
+
const cached = this.listenerSnapshots.get(event);
|
|
170
|
+
if (cached !== void 0) return cached;
|
|
171
|
+
const set = this.listeners.get(event);
|
|
172
|
+
if (!set || set.size === 0) return void 0;
|
|
173
|
+
const snapshot = [...set];
|
|
174
|
+
this.listenerSnapshots.set(event, snapshot);
|
|
175
|
+
return snapshot;
|
|
176
|
+
}
|
|
177
|
+
/** Wildcard counterpart to {@link namedSnapshot}; same caching rationale. */
|
|
178
|
+
wildcardSnapshot() {
|
|
179
|
+
this.wildcardSnapshotCache ??= this.wildcards.slice();
|
|
180
|
+
return this.wildcardSnapshotCache;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Emit a plugin-defined event that is intentionally outside EventMap.
|
|
184
|
+
* Custom events are delivered to wildcard/pattern listeners only; typed
|
|
185
|
+
* listeners remain reserved for core EventMap keys.
|
|
186
|
+
*/
|
|
187
|
+
emitCustom(event, payload) {
|
|
188
|
+
if (this.wildcards.length === 0) return;
|
|
189
|
+
for (const { match, fn } of this.wildcardSnapshot()) {
|
|
190
|
+
if (!match(event)) continue;
|
|
191
|
+
try {
|
|
192
|
+
fn(event, payload);
|
|
193
|
+
} catch (err) {
|
|
194
|
+
this.logger?.error(`EventBus wildcard listener for "${event}" threw`, err);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
clear() {
|
|
199
|
+
this.listeners.clear();
|
|
200
|
+
this.wildcards.length = 0;
|
|
201
|
+
this.listenerSnapshots.clear();
|
|
202
|
+
this.wildcardSnapshotCache = null;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* V2-D: introspection helper. Pass an `event` to count handlers for a
|
|
206
|
+
* single key, or omit to get the total across every event. Used by the
|
|
207
|
+
* leak-detection smoke test to flag handler accumulation across runs.
|
|
208
|
+
* Does NOT include wildcard listeners.
|
|
209
|
+
*/
|
|
210
|
+
listenerCount(event) {
|
|
211
|
+
if (event !== void 0) return this.listeners.get(event)?.size ?? 0;
|
|
212
|
+
let total = 0;
|
|
213
|
+
for (const set of this.listeners.values()) total += set.size;
|
|
214
|
+
return total;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Number of wildcard listeners currently registered.
|
|
218
|
+
*/
|
|
219
|
+
wildcardCount() {
|
|
220
|
+
return this.wildcards.length;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* True if anything would receive an emit for `event` — a named listener
|
|
224
|
+
* OR a wildcard/regex pattern that matches the event name. Unlike
|
|
225
|
+
* `listenerCount`, this DOES account for wildcards, so callers that gate
|
|
226
|
+
* behavior on "is anyone listening?" (e.g. SubagentBudget deciding whether
|
|
227
|
+
* to negotiate a soft limit vs hard-stop) don't misfire when the only
|
|
228
|
+
* subscriber is a pattern listener like the FleetBus's `onPattern('*')`.
|
|
229
|
+
*/
|
|
230
|
+
hasListenerFor(event) {
|
|
231
|
+
if ((this.listeners.get(event)?.size ?? 0) > 0) return true;
|
|
232
|
+
return this.wildcards.some((w) => w.match(event));
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
var ScopedEventBus = class extends EventBus {
|
|
236
|
+
// Track registrations by a unique counter key so that EventBus.once()'s
|
|
237
|
+
// internal listener-removal doesn't affect our tracking (once removes the
|
|
238
|
+
// fn from EventBus but we still need to call our unsub during teardown).
|
|
239
|
+
registrations = /* @__PURE__ */ new Map();
|
|
240
|
+
nextKey = 0;
|
|
241
|
+
/**
|
|
242
|
+
* Identical to `EventBus.on` but the listener is tracked so that
|
|
243
|
+
* `teardown()` will remove it automatically.
|
|
244
|
+
*/
|
|
245
|
+
on(event, fn) {
|
|
246
|
+
const key = this.nextKey++;
|
|
247
|
+
const unsub = super.on(event, fn);
|
|
248
|
+
this.registrations.set(key, unsub);
|
|
249
|
+
return () => {
|
|
250
|
+
this.registrations.delete(key);
|
|
251
|
+
unsub();
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Identical to `EventBus.once` but the listener is tracked so that
|
|
256
|
+
* `teardown()` will remove it automatically.
|
|
257
|
+
*
|
|
258
|
+
* Uses EventBus's public API directly to avoid triggering our own `on()`
|
|
259
|
+
* override (which would consume a key slot for the wrapper, then orphan
|
|
260
|
+
* our registration entry under a different key).
|
|
261
|
+
*
|
|
262
|
+
* When the wrapper fires, it cleans up BOTH the underlying EventBus
|
|
263
|
+
* listener AND the tracking entry — so `scopedListenerCount` returns to
|
|
264
|
+
* its pre-`once()` value without requiring the caller to invoke the
|
|
265
|
+
* returned unsubscribe. The returned `unsub` is still safe to call
|
|
266
|
+
* after auto-removal (its delete is a no-op and its off() finds
|
|
267
|
+
* nothing to remove).
|
|
268
|
+
*/
|
|
269
|
+
once(event, fn) {
|
|
270
|
+
const key = this.nextKey++;
|
|
271
|
+
const wrapper = (payload) => {
|
|
272
|
+
EventBus.prototype.off.call(this, event, wrapper);
|
|
273
|
+
this.registrations.delete(key);
|
|
274
|
+
fn(payload);
|
|
275
|
+
};
|
|
276
|
+
EventBus.prototype.on.call(this, event, wrapper);
|
|
277
|
+
const unsub = () => {
|
|
278
|
+
this.registrations.delete(key);
|
|
279
|
+
EventBus.prototype.off.call(this, event, wrapper);
|
|
280
|
+
};
|
|
281
|
+
this.registrations.set(key, unsub);
|
|
282
|
+
return unsub;
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Subscribe to all events. Alias for `onPattern('*')` — the listener is
|
|
286
|
+
* tracked so that `teardown()` will remove it automatically.
|
|
287
|
+
*/
|
|
288
|
+
onAny(fn, owner) {
|
|
289
|
+
if (this.wildcards.length >= MAX_WILDCARDS) {
|
|
290
|
+
this.logger?.error(
|
|
291
|
+
`EventBus wildcard limit (${MAX_WILDCARDS}) reached \u2014 rejecting onAny()` + (owner ? ` (owner: ${owner})` : "") + ". Callers must dispose their wildcard listeners to prevent unbounded growth."
|
|
292
|
+
);
|
|
293
|
+
return () => {
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
const key = this.nextKey++;
|
|
297
|
+
const unsub = EventBus.prototype.onPattern.call(this, "*", fn, owner);
|
|
298
|
+
this.registrations.set(key, unsub);
|
|
299
|
+
return () => {
|
|
300
|
+
this.registrations.delete(key);
|
|
301
|
+
unsub();
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Identical to `EventBus.onPattern` but the listener is tracked so that
|
|
306
|
+
* `teardown()` will remove it automatically.
|
|
307
|
+
*/
|
|
308
|
+
onPattern(pattern, fn, owner) {
|
|
309
|
+
if (this.wildcards.length >= MAX_WILDCARDS) {
|
|
310
|
+
this.logger?.error(
|
|
311
|
+
`EventBus wildcard limit (${MAX_WILDCARDS}) reached \u2014 rejecting onPattern("${pattern}")` + (owner ? ` (owner: ${owner})` : "") + ". Callers must dispose their wildcard listeners to prevent unbounded growth."
|
|
312
|
+
);
|
|
313
|
+
return () => {
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
const key = this.nextKey++;
|
|
317
|
+
const unsub = super.onPattern(pattern, fn, owner);
|
|
318
|
+
this.registrations.set(key, unsub);
|
|
319
|
+
return () => {
|
|
320
|
+
this.registrations.delete(key);
|
|
321
|
+
unsub();
|
|
322
|
+
};
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Identical to `EventBus.onRegex` but the listener is tracked so that
|
|
326
|
+
* `teardown()` will remove it automatically.
|
|
327
|
+
*/
|
|
328
|
+
onRegex(regex, fn, owner) {
|
|
329
|
+
if (this.wildcards.length >= MAX_WILDCARDS) {
|
|
330
|
+
this.logger?.error(
|
|
331
|
+
`EventBus wildcard limit (${MAX_WILDCARDS}) reached \u2014 rejecting onRegex(${regex})` + (owner ? ` (owner: ${owner})` : "") + ". Callers must dispose their wildcard listeners to prevent unbounded growth."
|
|
332
|
+
);
|
|
333
|
+
return () => {
|
|
334
|
+
};
|
|
335
|
+
}
|
|
336
|
+
const key = this.nextKey++;
|
|
337
|
+
const unsub = super.onRegex(regex, fn, owner);
|
|
338
|
+
this.registrations.set(key, unsub);
|
|
339
|
+
return () => {
|
|
340
|
+
this.registrations.delete(key);
|
|
341
|
+
unsub();
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Remove every listener that was registered through this scoped bus.
|
|
346
|
+
* Idempotent — calling it multiple times is safe.
|
|
347
|
+
*
|
|
348
|
+
* Also available as `[Symbol.dispose]` for explicit resource management:
|
|
349
|
+
* ```ts
|
|
350
|
+
* using scope = new ScopedEventBus();
|
|
351
|
+
* scope.on('tool.executed', handler);
|
|
352
|
+
* // automatically teardown()'d when scope exits
|
|
353
|
+
* ```
|
|
354
|
+
*/
|
|
355
|
+
teardown() {
|
|
356
|
+
for (const unsub of this.registrations.values()) {
|
|
357
|
+
try {
|
|
358
|
+
unsub();
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
this.registrations.clear();
|
|
363
|
+
this.clear();
|
|
364
|
+
}
|
|
365
|
+
/** Alias for `teardown()` — enables `using new ScopedEventBus()` in Node ≥ 22. */
|
|
366
|
+
[Symbol.dispose]() {
|
|
367
|
+
this.teardown();
|
|
368
|
+
}
|
|
369
|
+
/** Number of tracked registrations. */
|
|
370
|
+
get scopedListenerCount() {
|
|
371
|
+
return this.registrations.size;
|
|
372
|
+
}
|
|
373
|
+
};
|
|
374
|
+
var MATCH_ALL = () => true;
|
|
375
|
+
function makePatternMatcher(pattern) {
|
|
376
|
+
if (pattern === "*") return MATCH_ALL;
|
|
377
|
+
if (pattern.endsWith(".*")) {
|
|
378
|
+
const prefix = pattern.slice(0, -2);
|
|
379
|
+
return (e) => e.startsWith(`${prefix}.`);
|
|
380
|
+
}
|
|
381
|
+
return (e) => e === pattern;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export {
|
|
385
|
+
EventBus,
|
|
386
|
+
ScopedEventBus
|
|
387
|
+
};
|
|
388
|
+
//# sourceMappingURL=chunk-4LJJYBAU.js.map
|