@warmdrift/kgauto-compiler 2.0.0-alpha.24 → 2.0.0-alpha.26
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/{chunk-NUTC7NUC.mjs → chunk-NBO4R5PC.mjs} +122 -107
- package/dist/chunk-RO22VFIF.mjs +29 -0
- package/dist/glassbox/index.d.mts +20 -3
- package/dist/glassbox/index.d.ts +20 -3
- package/dist/glassbox/index.js +42 -30
- package/dist/glassbox/index.mjs +6 -4
- package/dist/glassbox-routes/index.d.mts +12 -3
- package/dist/glassbox-routes/index.d.ts +12 -3
- package/dist/glassbox-routes/index.js +45 -43
- package/dist/glassbox-routes/index.mjs +11 -18
- package/dist/index.js +55 -42
- package/dist/index.mjs +7 -7
- package/dist/{types-DiWBWvxg.d.ts → types-bt0aVJb8.d.ts} +19 -10
- package/dist/{types-D9WndxeD.d.mts → types-o9etg93a.d.mts} +19 -10
- package/package.json +1 -1
- package/dist/chunk-VZGMWKRT.mjs +0 -19
|
@@ -1,92 +1,6 @@
|
|
|
1
1
|
// src/glassbox/types.ts
|
|
2
2
|
var GLASSBOX_STREAM_TTL_MS = 6e4;
|
|
3
3
|
|
|
4
|
-
// src/glassbox/pubsub-memory.ts
|
|
5
|
-
var MemoryPubSub = class {
|
|
6
|
-
subscribers = /* @__PURE__ */ new Map();
|
|
7
|
-
async publish(traceId, event) {
|
|
8
|
-
const subs = this.subscribers.get(traceId);
|
|
9
|
-
if (!subs || subs.size === 0) return;
|
|
10
|
-
for (const sub of subs) {
|
|
11
|
-
if (sub.closed) continue;
|
|
12
|
-
try {
|
|
13
|
-
sub.controller.enqueue(event);
|
|
14
|
-
} catch {
|
|
15
|
-
sub.closed = true;
|
|
16
|
-
continue;
|
|
17
|
-
}
|
|
18
|
-
this.refreshTtl(traceId, sub);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
subscribe(traceId) {
|
|
22
|
-
const self = this;
|
|
23
|
-
let sub;
|
|
24
|
-
return new ReadableStream({
|
|
25
|
-
start(controller) {
|
|
26
|
-
sub = {
|
|
27
|
-
controller,
|
|
28
|
-
ttlTimer: setTimeout(() => {
|
|
29
|
-
self.closeSubscriber(traceId, sub);
|
|
30
|
-
}, GLASSBOX_STREAM_TTL_MS),
|
|
31
|
-
closed: false
|
|
32
|
-
};
|
|
33
|
-
let set = self.subscribers.get(traceId);
|
|
34
|
-
if (!set) {
|
|
35
|
-
set = /* @__PURE__ */ new Set();
|
|
36
|
-
self.subscribers.set(traceId, set);
|
|
37
|
-
}
|
|
38
|
-
set.add(sub);
|
|
39
|
-
},
|
|
40
|
-
cancel() {
|
|
41
|
-
if (sub) self.removeSubscriber(traceId, sub);
|
|
42
|
-
}
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Refresh the rolling TTL for a subscriber after an event lands. Replaces
|
|
47
|
-
* the existing timer with a fresh 60s one.
|
|
48
|
-
*/
|
|
49
|
-
refreshTtl(traceId, sub) {
|
|
50
|
-
clearTimeout(sub.ttlTimer);
|
|
51
|
-
sub.ttlTimer = setTimeout(() => {
|
|
52
|
-
this.closeSubscriber(traceId, sub);
|
|
53
|
-
}, GLASSBOX_STREAM_TTL_MS);
|
|
54
|
-
}
|
|
55
|
-
/**
|
|
56
|
-
* Close the subscriber's stream cleanly and remove from the fan-out set.
|
|
57
|
-
* Idempotent — safe to call multiple times.
|
|
58
|
-
*/
|
|
59
|
-
closeSubscriber(traceId, sub) {
|
|
60
|
-
if (sub.closed) return;
|
|
61
|
-
sub.closed = true;
|
|
62
|
-
clearTimeout(sub.ttlTimer);
|
|
63
|
-
try {
|
|
64
|
-
sub.controller.close();
|
|
65
|
-
} catch {
|
|
66
|
-
}
|
|
67
|
-
this.removeSubscriber(traceId, sub);
|
|
68
|
-
}
|
|
69
|
-
removeSubscriber(traceId, sub) {
|
|
70
|
-
clearTimeout(sub.ttlTimer);
|
|
71
|
-
const set = this.subscribers.get(traceId);
|
|
72
|
-
if (!set) return;
|
|
73
|
-
set.delete(sub);
|
|
74
|
-
if (set.size === 0) this.subscribers.delete(traceId);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Test-only reset. Tears down all subscribers, clears all state. Calling
|
|
78
|
-
* outside of tests is harmless but cancels every active stream.
|
|
79
|
-
*/
|
|
80
|
-
_reset() {
|
|
81
|
-
for (const [, set] of this.subscribers) {
|
|
82
|
-
for (const sub of set) {
|
|
83
|
-
this.closeSubscriber("", sub);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
this.subscribers.clear();
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
|
|
90
4
|
// src/glassbox/pubsub-upstash.ts
|
|
91
5
|
var UpstashPubSub = class {
|
|
92
6
|
url;
|
|
@@ -101,8 +15,8 @@ var UpstashPubSub = class {
|
|
|
101
15
|
this.blockMs = cfg.blockMs ?? 100;
|
|
102
16
|
this.maxLen = cfg.maxLen ?? 100;
|
|
103
17
|
}
|
|
104
|
-
async publish(
|
|
105
|
-
const key =
|
|
18
|
+
async publish(channelKey, event) {
|
|
19
|
+
const key = channelKey;
|
|
106
20
|
const payload = JSON.stringify(event);
|
|
107
21
|
await this.cmd([
|
|
108
22
|
"XADD",
|
|
@@ -116,8 +30,8 @@ var UpstashPubSub = class {
|
|
|
116
30
|
]);
|
|
117
31
|
await this.cmd(["EXPIRE", key, String(Math.ceil(GLASSBOX_STREAM_TTL_MS / 1e3))]);
|
|
118
32
|
}
|
|
119
|
-
subscribe(
|
|
120
|
-
const key =
|
|
33
|
+
subscribe(channelKey) {
|
|
34
|
+
const key = channelKey;
|
|
121
35
|
const self = this;
|
|
122
36
|
let cursor = "$";
|
|
123
37
|
let cancelled = false;
|
|
@@ -191,9 +105,12 @@ var UpstashPubSub = class {
|
|
|
191
105
|
return json;
|
|
192
106
|
}
|
|
193
107
|
};
|
|
194
|
-
function
|
|
108
|
+
function traceChannel(traceId) {
|
|
195
109
|
return `glassbox:trace:${traceId}`;
|
|
196
110
|
}
|
|
111
|
+
function appChannel(appId) {
|
|
112
|
+
return `glassbox:app:${appId}`;
|
|
113
|
+
}
|
|
197
114
|
function decodeEvent(fields) {
|
|
198
115
|
const raw = fields["event"];
|
|
199
116
|
if (!raw) return void 0;
|
|
@@ -231,6 +148,92 @@ function parseXReadResult(raw) {
|
|
|
231
148
|
return { entries };
|
|
232
149
|
}
|
|
233
150
|
|
|
151
|
+
// src/glassbox/pubsub-memory.ts
|
|
152
|
+
var MemoryPubSub = class {
|
|
153
|
+
subscribers = /* @__PURE__ */ new Map();
|
|
154
|
+
async publish(channelKey, event) {
|
|
155
|
+
const subs = this.subscribers.get(channelKey);
|
|
156
|
+
if (!subs || subs.size === 0) return;
|
|
157
|
+
for (const sub of subs) {
|
|
158
|
+
if (sub.closed) continue;
|
|
159
|
+
try {
|
|
160
|
+
sub.controller.enqueue(event);
|
|
161
|
+
} catch {
|
|
162
|
+
sub.closed = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
this.refreshTtl(channelKey, sub);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
subscribe(channelKey) {
|
|
169
|
+
const self = this;
|
|
170
|
+
let sub;
|
|
171
|
+
return new ReadableStream({
|
|
172
|
+
start(controller) {
|
|
173
|
+
sub = {
|
|
174
|
+
controller,
|
|
175
|
+
ttlTimer: setTimeout(() => {
|
|
176
|
+
self.closeSubscriber(channelKey, sub);
|
|
177
|
+
}, GLASSBOX_STREAM_TTL_MS),
|
|
178
|
+
closed: false
|
|
179
|
+
};
|
|
180
|
+
let set = self.subscribers.get(channelKey);
|
|
181
|
+
if (!set) {
|
|
182
|
+
set = /* @__PURE__ */ new Set();
|
|
183
|
+
self.subscribers.set(channelKey, set);
|
|
184
|
+
}
|
|
185
|
+
set.add(sub);
|
|
186
|
+
},
|
|
187
|
+
cancel() {
|
|
188
|
+
if (sub) self.removeSubscriber(channelKey, sub);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Refresh the rolling TTL for a subscriber after an event lands. Replaces
|
|
194
|
+
* the existing timer with a fresh 60s one.
|
|
195
|
+
*/
|
|
196
|
+
refreshTtl(channelKey, sub) {
|
|
197
|
+
clearTimeout(sub.ttlTimer);
|
|
198
|
+
sub.ttlTimer = setTimeout(() => {
|
|
199
|
+
this.closeSubscriber(channelKey, sub);
|
|
200
|
+
}, GLASSBOX_STREAM_TTL_MS);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Close the subscriber's stream cleanly and remove from the fan-out set.
|
|
204
|
+
* Idempotent — safe to call multiple times.
|
|
205
|
+
*/
|
|
206
|
+
closeSubscriber(channelKey, sub) {
|
|
207
|
+
if (sub.closed) return;
|
|
208
|
+
sub.closed = true;
|
|
209
|
+
clearTimeout(sub.ttlTimer);
|
|
210
|
+
try {
|
|
211
|
+
sub.controller.close();
|
|
212
|
+
} catch {
|
|
213
|
+
}
|
|
214
|
+
this.removeSubscriber(channelKey, sub);
|
|
215
|
+
}
|
|
216
|
+
removeSubscriber(channelKey, sub) {
|
|
217
|
+
clearTimeout(sub.ttlTimer);
|
|
218
|
+
const set = this.subscribers.get(channelKey);
|
|
219
|
+
if (!set) return;
|
|
220
|
+
set.delete(sub);
|
|
221
|
+
if (set.size === 0) this.subscribers.delete(channelKey);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Test-only reset. Tears down all subscribers, clears all state. Calling
|
|
225
|
+
* outside of tests is harmless but cancels every active stream.
|
|
226
|
+
*/
|
|
227
|
+
_reset() {
|
|
228
|
+
for (const [, set] of this.subscribers) {
|
|
229
|
+
for (const sub of set) {
|
|
230
|
+
this.closeSubscriber("", sub);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
this.subscribers.clear();
|
|
234
|
+
}
|
|
235
|
+
};
|
|
236
|
+
|
|
234
237
|
// src/glassbox/emit.ts
|
|
235
238
|
var activePubSub;
|
|
236
239
|
function getPubSub() {
|
|
@@ -254,40 +257,52 @@ function readEnv(key) {
|
|
|
254
257
|
}
|
|
255
258
|
return void 0;
|
|
256
259
|
}
|
|
257
|
-
function emitGlassboxEvent(traceId, kind, data) {
|
|
260
|
+
function emitGlassboxEvent(traceId, appId, kind, data) {
|
|
258
261
|
if (!traceId) return;
|
|
259
262
|
const event = { kind, at: Date.now(), data };
|
|
260
263
|
const ps = getPubSub();
|
|
261
264
|
try {
|
|
262
|
-
const
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
+
const p1 = ps.publish(traceChannel(traceId), event);
|
|
266
|
+
if (p1 && typeof p1.then === "function") {
|
|
267
|
+
p1.catch(() => {
|
|
265
268
|
});
|
|
266
269
|
}
|
|
267
270
|
} catch {
|
|
268
271
|
}
|
|
272
|
+
if (appId) {
|
|
273
|
+
try {
|
|
274
|
+
const p2 = ps.publish(appChannel(appId), event);
|
|
275
|
+
if (p2 && typeof p2.then === "function") {
|
|
276
|
+
p2.catch(() => {
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
} catch {
|
|
280
|
+
}
|
|
281
|
+
}
|
|
269
282
|
}
|
|
270
|
-
function emitCompileStart(traceId, data) {
|
|
271
|
-
emitGlassboxEvent(traceId, "compile.start", data);
|
|
283
|
+
function emitCompileStart(traceId, appId, data) {
|
|
284
|
+
emitGlassboxEvent(traceId, appId, "compile.start", data);
|
|
272
285
|
}
|
|
273
|
-
function emitCompileDone(traceId, data) {
|
|
274
|
-
emitGlassboxEvent(traceId, "compile.done", data);
|
|
286
|
+
function emitCompileDone(traceId, appId, data) {
|
|
287
|
+
emitGlassboxEvent(traceId, appId, "compile.done", data);
|
|
275
288
|
}
|
|
276
|
-
function emitExecuteAttempt(traceId, data) {
|
|
277
|
-
emitGlassboxEvent(traceId, "execute.attempt", data);
|
|
289
|
+
function emitExecuteAttempt(traceId, appId, data) {
|
|
290
|
+
emitGlassboxEvent(traceId, appId, "execute.attempt", data);
|
|
278
291
|
}
|
|
279
|
-
function emitExecuteSuccess(traceId, data) {
|
|
280
|
-
emitGlassboxEvent(traceId, "execute.success", data);
|
|
292
|
+
function emitExecuteSuccess(traceId, appId, data) {
|
|
293
|
+
emitGlassboxEvent(traceId, appId, "execute.success", data);
|
|
281
294
|
}
|
|
282
|
-
function emitAdvisoryFired(traceId, data) {
|
|
283
|
-
emitGlassboxEvent(traceId, "advisory.fired", data);
|
|
295
|
+
function emitAdvisoryFired(traceId, appId, data) {
|
|
296
|
+
emitGlassboxEvent(traceId, appId, "advisory.fired", data);
|
|
284
297
|
}
|
|
285
|
-
function emitFallbackWalked(traceId, data) {
|
|
286
|
-
emitGlassboxEvent(traceId, "fallback.walked", data);
|
|
298
|
+
function emitFallbackWalked(traceId, appId, data) {
|
|
299
|
+
emitGlassboxEvent(traceId, appId, "fallback.walked", data);
|
|
287
300
|
}
|
|
288
301
|
|
|
289
302
|
export {
|
|
290
303
|
GLASSBOX_STREAM_TTL_MS,
|
|
304
|
+
traceChannel,
|
|
305
|
+
appChannel,
|
|
291
306
|
getPubSub,
|
|
292
307
|
emitCompileStart,
|
|
293
308
|
emitCompileDone,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
appChannel,
|
|
3
|
+
getPubSub,
|
|
4
|
+
traceChannel
|
|
5
|
+
} from "./chunk-NBO4R5PC.mjs";
|
|
6
|
+
|
|
7
|
+
// src/glassbox/subscribe.ts
|
|
8
|
+
function emptyStream() {
|
|
9
|
+
return new ReadableStream({
|
|
10
|
+
start(controller) {
|
|
11
|
+
controller.close();
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function subscribe(traceId) {
|
|
16
|
+
if (!traceId) return emptyStream();
|
|
17
|
+
return getPubSub().subscribe(traceChannel(traceId));
|
|
18
|
+
}
|
|
19
|
+
function subscribeApp({
|
|
20
|
+
appId
|
|
21
|
+
}) {
|
|
22
|
+
if (!appId) return emptyStream();
|
|
23
|
+
return getPubSub().subscribe(appChannel(appId));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
subscribe,
|
|
28
|
+
subscribeApp
|
|
29
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GlassboxEvent } from '../types-
|
|
2
|
-
export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-
|
|
1
|
+
import { G as GlassboxEvent } from '../types-o9etg93a.mjs';
|
|
2
|
+
export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-o9etg93a.mjs';
|
|
3
3
|
import '../ir-B9zqlwjH.mjs';
|
|
4
4
|
import '../dialect.mjs';
|
|
5
5
|
|
|
@@ -38,5 +38,22 @@ import '../dialect.mjs';
|
|
|
38
38
|
* down the subscription cleanly via the underlying adapter.
|
|
39
39
|
*/
|
|
40
40
|
declare function subscribe(traceId: string): ReadableStream<GlassboxEvent>;
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to Glass-Box events for ALL traces under an appId — the
|
|
43
|
+
* "tail-all" surface (alpha.26). Backs the extension's default Live mode:
|
|
44
|
+
* rather than needing a specific traceId ahead of time, the panel sees
|
|
45
|
+
* every event for the configured consumer as calls happen.
|
|
46
|
+
*
|
|
47
|
+
* Per-app routing fires only when emit call-sites pass `appId` (the typed
|
|
48
|
+
* builders thread `ir.appId` automatically). Per-trace channel continues to
|
|
49
|
+
* fire for `subscribe(traceId)` callers — both arms are independent.
|
|
50
|
+
*
|
|
51
|
+
* Cross-tenant isolation: the consumer's `/api/glassbox/stream` uses the
|
|
52
|
+
* factory's configured appId — no caller-supplied `?appId=` URL parameter,
|
|
53
|
+
* so a consumer cannot subscribe to another consumer's stream.
|
|
54
|
+
*/
|
|
55
|
+
declare function subscribeApp({ appId, }: {
|
|
56
|
+
appId: string;
|
|
57
|
+
}): ReadableStream<GlassboxEvent>;
|
|
41
58
|
|
|
42
|
-
export { GlassboxEvent, subscribe };
|
|
59
|
+
export { GlassboxEvent, subscribe, subscribeApp };
|
package/dist/glassbox/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { G as GlassboxEvent } from '../types-
|
|
2
|
-
export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-
|
|
1
|
+
import { G as GlassboxEvent } from '../types-bt0aVJb8.js';
|
|
2
|
+
export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-bt0aVJb8.js';
|
|
3
3
|
import '../ir-B_XX2LAO.js';
|
|
4
4
|
import '../dialect.js';
|
|
5
5
|
|
|
@@ -38,5 +38,22 @@ import '../dialect.js';
|
|
|
38
38
|
* down the subscription cleanly via the underlying adapter.
|
|
39
39
|
*/
|
|
40
40
|
declare function subscribe(traceId: string): ReadableStream<GlassboxEvent>;
|
|
41
|
+
/**
|
|
42
|
+
* Subscribe to Glass-Box events for ALL traces under an appId — the
|
|
43
|
+
* "tail-all" surface (alpha.26). Backs the extension's default Live mode:
|
|
44
|
+
* rather than needing a specific traceId ahead of time, the panel sees
|
|
45
|
+
* every event for the configured consumer as calls happen.
|
|
46
|
+
*
|
|
47
|
+
* Per-app routing fires only when emit call-sites pass `appId` (the typed
|
|
48
|
+
* builders thread `ir.appId` automatically). Per-trace channel continues to
|
|
49
|
+
* fire for `subscribe(traceId)` callers — both arms are independent.
|
|
50
|
+
*
|
|
51
|
+
* Cross-tenant isolation: the consumer's `/api/glassbox/stream` uses the
|
|
52
|
+
* factory's configured appId — no caller-supplied `?appId=` URL parameter,
|
|
53
|
+
* so a consumer cannot subscribe to another consumer's stream.
|
|
54
|
+
*/
|
|
55
|
+
declare function subscribeApp({ appId, }: {
|
|
56
|
+
appId: string;
|
|
57
|
+
}): ReadableStream<GlassboxEvent>;
|
|
41
58
|
|
|
42
|
-
export { GlassboxEvent, subscribe };
|
|
59
|
+
export { GlassboxEvent, subscribe, subscribeApp };
|
package/dist/glassbox/index.js
CHANGED
|
@@ -21,7 +21,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var glassbox_exports = {};
|
|
22
22
|
__export(glassbox_exports, {
|
|
23
23
|
GLASSBOX_STREAM_TTL_MS: () => GLASSBOX_STREAM_TTL_MS,
|
|
24
|
-
subscribe: () => subscribe
|
|
24
|
+
subscribe: () => subscribe,
|
|
25
|
+
subscribeApp: () => subscribeApp
|
|
25
26
|
});
|
|
26
27
|
module.exports = __toCommonJS(glassbox_exports);
|
|
27
28
|
|
|
@@ -31,8 +32,8 @@ var GLASSBOX_STREAM_TTL_MS = 6e4;
|
|
|
31
32
|
// src/glassbox/pubsub-memory.ts
|
|
32
33
|
var MemoryPubSub = class {
|
|
33
34
|
subscribers = /* @__PURE__ */ new Map();
|
|
34
|
-
async publish(
|
|
35
|
-
const subs = this.subscribers.get(
|
|
35
|
+
async publish(channelKey, event) {
|
|
36
|
+
const subs = this.subscribers.get(channelKey);
|
|
36
37
|
if (!subs || subs.size === 0) return;
|
|
37
38
|
for (const sub of subs) {
|
|
38
39
|
if (sub.closed) continue;
|
|
@@ -42,10 +43,10 @@ var MemoryPubSub = class {
|
|
|
42
43
|
sub.closed = true;
|
|
43
44
|
continue;
|
|
44
45
|
}
|
|
45
|
-
this.refreshTtl(
|
|
46
|
+
this.refreshTtl(channelKey, sub);
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
|
-
subscribe(
|
|
49
|
+
subscribe(channelKey) {
|
|
49
50
|
const self = this;
|
|
50
51
|
let sub;
|
|
51
52
|
return new ReadableStream({
|
|
@@ -53,19 +54,19 @@ var MemoryPubSub = class {
|
|
|
53
54
|
sub = {
|
|
54
55
|
controller,
|
|
55
56
|
ttlTimer: setTimeout(() => {
|
|
56
|
-
self.closeSubscriber(
|
|
57
|
+
self.closeSubscriber(channelKey, sub);
|
|
57
58
|
}, GLASSBOX_STREAM_TTL_MS),
|
|
58
59
|
closed: false
|
|
59
60
|
};
|
|
60
|
-
let set = self.subscribers.get(
|
|
61
|
+
let set = self.subscribers.get(channelKey);
|
|
61
62
|
if (!set) {
|
|
62
63
|
set = /* @__PURE__ */ new Set();
|
|
63
|
-
self.subscribers.set(
|
|
64
|
+
self.subscribers.set(channelKey, set);
|
|
64
65
|
}
|
|
65
66
|
set.add(sub);
|
|
66
67
|
},
|
|
67
68
|
cancel() {
|
|
68
|
-
if (sub) self.removeSubscriber(
|
|
69
|
+
if (sub) self.removeSubscriber(channelKey, sub);
|
|
69
70
|
}
|
|
70
71
|
});
|
|
71
72
|
}
|
|
@@ -73,17 +74,17 @@ var MemoryPubSub = class {
|
|
|
73
74
|
* Refresh the rolling TTL for a subscriber after an event lands. Replaces
|
|
74
75
|
* the existing timer with a fresh 60s one.
|
|
75
76
|
*/
|
|
76
|
-
refreshTtl(
|
|
77
|
+
refreshTtl(channelKey, sub) {
|
|
77
78
|
clearTimeout(sub.ttlTimer);
|
|
78
79
|
sub.ttlTimer = setTimeout(() => {
|
|
79
|
-
this.closeSubscriber(
|
|
80
|
+
this.closeSubscriber(channelKey, sub);
|
|
80
81
|
}, GLASSBOX_STREAM_TTL_MS);
|
|
81
82
|
}
|
|
82
83
|
/**
|
|
83
84
|
* Close the subscriber's stream cleanly and remove from the fan-out set.
|
|
84
85
|
* Idempotent — safe to call multiple times.
|
|
85
86
|
*/
|
|
86
|
-
closeSubscriber(
|
|
87
|
+
closeSubscriber(channelKey, sub) {
|
|
87
88
|
if (sub.closed) return;
|
|
88
89
|
sub.closed = true;
|
|
89
90
|
clearTimeout(sub.ttlTimer);
|
|
@@ -91,14 +92,14 @@ var MemoryPubSub = class {
|
|
|
91
92
|
sub.controller.close();
|
|
92
93
|
} catch {
|
|
93
94
|
}
|
|
94
|
-
this.removeSubscriber(
|
|
95
|
+
this.removeSubscriber(channelKey, sub);
|
|
95
96
|
}
|
|
96
|
-
removeSubscriber(
|
|
97
|
+
removeSubscriber(channelKey, sub) {
|
|
97
98
|
clearTimeout(sub.ttlTimer);
|
|
98
|
-
const set = this.subscribers.get(
|
|
99
|
+
const set = this.subscribers.get(channelKey);
|
|
99
100
|
if (!set) return;
|
|
100
101
|
set.delete(sub);
|
|
101
|
-
if (set.size === 0) this.subscribers.delete(
|
|
102
|
+
if (set.size === 0) this.subscribers.delete(channelKey);
|
|
102
103
|
}
|
|
103
104
|
/**
|
|
104
105
|
* Test-only reset. Tears down all subscribers, clears all state. Calling
|
|
@@ -128,8 +129,8 @@ var UpstashPubSub = class {
|
|
|
128
129
|
this.blockMs = cfg.blockMs ?? 100;
|
|
129
130
|
this.maxLen = cfg.maxLen ?? 100;
|
|
130
131
|
}
|
|
131
|
-
async publish(
|
|
132
|
-
const key =
|
|
132
|
+
async publish(channelKey, event) {
|
|
133
|
+
const key = channelKey;
|
|
133
134
|
const payload = JSON.stringify(event);
|
|
134
135
|
await this.cmd([
|
|
135
136
|
"XADD",
|
|
@@ -143,8 +144,8 @@ var UpstashPubSub = class {
|
|
|
143
144
|
]);
|
|
144
145
|
await this.cmd(["EXPIRE", key, String(Math.ceil(GLASSBOX_STREAM_TTL_MS / 1e3))]);
|
|
145
146
|
}
|
|
146
|
-
subscribe(
|
|
147
|
-
const key =
|
|
147
|
+
subscribe(channelKey) {
|
|
148
|
+
const key = channelKey;
|
|
148
149
|
const self = this;
|
|
149
150
|
let cursor = "$";
|
|
150
151
|
let cancelled = false;
|
|
@@ -218,9 +219,12 @@ var UpstashPubSub = class {
|
|
|
218
219
|
return json;
|
|
219
220
|
}
|
|
220
221
|
};
|
|
221
|
-
function
|
|
222
|
+
function traceChannel(traceId) {
|
|
222
223
|
return `glassbox:trace:${traceId}`;
|
|
223
224
|
}
|
|
225
|
+
function appChannel(appId) {
|
|
226
|
+
return `glassbox:app:${appId}`;
|
|
227
|
+
}
|
|
224
228
|
function decodeEvent(fields) {
|
|
225
229
|
const raw = fields["event"];
|
|
226
230
|
if (!raw) return void 0;
|
|
@@ -283,18 +287,26 @@ function readEnv(key) {
|
|
|
283
287
|
}
|
|
284
288
|
|
|
285
289
|
// src/glassbox/subscribe.ts
|
|
290
|
+
function emptyStream() {
|
|
291
|
+
return new ReadableStream({
|
|
292
|
+
start(controller) {
|
|
293
|
+
controller.close();
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
286
297
|
function subscribe(traceId) {
|
|
287
|
-
if (!traceId)
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
return getPubSub().subscribe(
|
|
298
|
+
if (!traceId) return emptyStream();
|
|
299
|
+
return getPubSub().subscribe(traceChannel(traceId));
|
|
300
|
+
}
|
|
301
|
+
function subscribeApp({
|
|
302
|
+
appId
|
|
303
|
+
}) {
|
|
304
|
+
if (!appId) return emptyStream();
|
|
305
|
+
return getPubSub().subscribe(appChannel(appId));
|
|
295
306
|
}
|
|
296
307
|
// Annotate the CommonJS export names for ESM import in node:
|
|
297
308
|
0 && (module.exports = {
|
|
298
309
|
GLASSBOX_STREAM_TTL_MS,
|
|
299
|
-
subscribe
|
|
310
|
+
subscribe,
|
|
311
|
+
subscribeApp
|
|
300
312
|
});
|
package/dist/glassbox/index.mjs
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
|
-
subscribe
|
|
3
|
-
|
|
2
|
+
subscribe,
|
|
3
|
+
subscribeApp
|
|
4
|
+
} from "../chunk-RO22VFIF.mjs";
|
|
4
5
|
import {
|
|
5
6
|
GLASSBOX_STREAM_TTL_MS
|
|
6
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-NBO4R5PC.mjs";
|
|
7
8
|
export {
|
|
8
9
|
GLASSBOX_STREAM_TTL_MS,
|
|
9
|
-
subscribe
|
|
10
|
+
subscribe,
|
|
11
|
+
subscribeApp
|
|
10
12
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GlassboxEvent } from '../types-
|
|
1
|
+
import { G as GlassboxEvent } from '../types-o9etg93a.mjs';
|
|
2
2
|
import '../ir-B9zqlwjH.mjs';
|
|
3
3
|
import '../dialect.mjs';
|
|
4
4
|
|
|
@@ -105,11 +105,20 @@ interface GlassboxRoutesConfig {
|
|
|
105
105
|
*/
|
|
106
106
|
fetch?: typeof fetch;
|
|
107
107
|
/**
|
|
108
|
-
* Test-only seam: override the live-stream subscriber. Production
|
|
109
|
-
* resolves to the alpha.17 `subscribe()` export; tests inject a fake
|
|
108
|
+
* Test-only seam: override the per-trace live-stream subscriber. Production
|
|
109
|
+
* code resolves to the alpha.17 `subscribe()` export; tests inject a fake
|
|
110
110
|
* source ReadableStream<GlassboxEvent>.
|
|
111
111
|
*/
|
|
112
112
|
subscribe?: (traceId: string) => ReadableStream<GlassboxEvent>;
|
|
113
|
+
/**
|
|
114
|
+
* Test-only seam: override the per-app "tail-all" subscriber (alpha.26).
|
|
115
|
+
* Production code resolves to the `subscribeApp()` export; tests inject
|
|
116
|
+
* a fake source. Backs the extension's default Live tab mode when no
|
|
117
|
+
* traceId is supplied in the URL.
|
|
118
|
+
*/
|
|
119
|
+
subscribeApp?: (args: {
|
|
120
|
+
appId: string;
|
|
121
|
+
}) => ReadableStream<GlassboxEvent>;
|
|
113
122
|
}
|
|
114
123
|
interface GlassboxRoutes {
|
|
115
124
|
/** GET /api/glassbox/proxy?traceId=<id> OR ?limit=20 (recent traces) */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { G as GlassboxEvent } from '../types-
|
|
1
|
+
import { G as GlassboxEvent } from '../types-bt0aVJb8.js';
|
|
2
2
|
import '../ir-B_XX2LAO.js';
|
|
3
3
|
import '../dialect.js';
|
|
4
4
|
|
|
@@ -105,11 +105,20 @@ interface GlassboxRoutesConfig {
|
|
|
105
105
|
*/
|
|
106
106
|
fetch?: typeof fetch;
|
|
107
107
|
/**
|
|
108
|
-
* Test-only seam: override the live-stream subscriber. Production
|
|
109
|
-
* resolves to the alpha.17 `subscribe()` export; tests inject a fake
|
|
108
|
+
* Test-only seam: override the per-trace live-stream subscriber. Production
|
|
109
|
+
* code resolves to the alpha.17 `subscribe()` export; tests inject a fake
|
|
110
110
|
* source ReadableStream<GlassboxEvent>.
|
|
111
111
|
*/
|
|
112
112
|
subscribe?: (traceId: string) => ReadableStream<GlassboxEvent>;
|
|
113
|
+
/**
|
|
114
|
+
* Test-only seam: override the per-app "tail-all" subscriber (alpha.26).
|
|
115
|
+
* Production code resolves to the `subscribeApp()` export; tests inject
|
|
116
|
+
* a fake source. Backs the extension's default Live tab mode when no
|
|
117
|
+
* traceId is supplied in the URL.
|
|
118
|
+
*/
|
|
119
|
+
subscribeApp?: (args: {
|
|
120
|
+
appId: string;
|
|
121
|
+
}) => ReadableStream<GlassboxEvent>;
|
|
113
122
|
}
|
|
114
123
|
interface GlassboxRoutes {
|
|
115
124
|
/** GET /api/glassbox/proxy?traceId=<id> OR ?limit=20 (recent traces) */
|
|
@@ -129,7 +129,7 @@ function createProxyHandler(config) {
|
|
|
129
129
|
const qs = new URLSearchParams();
|
|
130
130
|
qs.set("app_id", `eq.${appId}`);
|
|
131
131
|
if (traceId) {
|
|
132
|
-
qs.set("
|
|
132
|
+
qs.set("handle", `eq.${traceId}`);
|
|
133
133
|
} else {
|
|
134
134
|
qs.set("order", "created_at.desc");
|
|
135
135
|
qs.set("limit", String(limit));
|
|
@@ -190,13 +190,6 @@ var SSE_HEADERS = {
|
|
|
190
190
|
Connection: "keep-alive",
|
|
191
191
|
"X-Accel-Buffering": "no"
|
|
192
192
|
};
|
|
193
|
-
var JSON_HEADERS3 = { "Content-Type": "application/json" };
|
|
194
|
-
function jsonError3(status, code) {
|
|
195
|
-
return new Response(JSON.stringify({ error: code }), {
|
|
196
|
-
status,
|
|
197
|
-
headers: JSON_HEADERS3
|
|
198
|
-
});
|
|
199
|
-
}
|
|
200
193
|
function applyScrub2(event, scrub) {
|
|
201
194
|
if (!scrub) return event;
|
|
202
195
|
try {
|
|
@@ -216,17 +209,14 @@ data: ${JSON.stringify(data)}
|
|
|
216
209
|
|
|
217
210
|
`;
|
|
218
211
|
}
|
|
219
|
-
function createStreamHandler(config, subscribe2) {
|
|
220
|
-
const { installToken, extensionId, scrub } = config;
|
|
212
|
+
function createStreamHandler(config, subscribe2, subscribeApp2) {
|
|
213
|
+
const { installToken, extensionId, appId, scrub } = config;
|
|
221
214
|
return async function stream(req) {
|
|
222
215
|
const authFail = checkAuth(req, { installToken, extensionId });
|
|
223
216
|
if (authFail) return authFail;
|
|
224
217
|
const url = new URL(req.url);
|
|
225
218
|
const traceId = url.searchParams.get("traceId");
|
|
226
|
-
|
|
227
|
-
return jsonError3(400, "missing_trace_id");
|
|
228
|
-
}
|
|
229
|
-
const source = subscribe2(traceId);
|
|
219
|
+
const source = traceId ? subscribe2(traceId) : subscribeApp2({ appId });
|
|
230
220
|
const encoder = new TextEncoder();
|
|
231
221
|
let sourceReader;
|
|
232
222
|
let cancelled = false;
|
|
@@ -296,8 +286,8 @@ var GLASSBOX_STREAM_TTL_MS = 6e4;
|
|
|
296
286
|
// src/glassbox/pubsub-memory.ts
|
|
297
287
|
var MemoryPubSub = class {
|
|
298
288
|
subscribers = /* @__PURE__ */ new Map();
|
|
299
|
-
async publish(
|
|
300
|
-
const subs = this.subscribers.get(
|
|
289
|
+
async publish(channelKey, event) {
|
|
290
|
+
const subs = this.subscribers.get(channelKey);
|
|
301
291
|
if (!subs || subs.size === 0) return;
|
|
302
292
|
for (const sub of subs) {
|
|
303
293
|
if (sub.closed) continue;
|
|
@@ -307,10 +297,10 @@ var MemoryPubSub = class {
|
|
|
307
297
|
sub.closed = true;
|
|
308
298
|
continue;
|
|
309
299
|
}
|
|
310
|
-
this.refreshTtl(
|
|
300
|
+
this.refreshTtl(channelKey, sub);
|
|
311
301
|
}
|
|
312
302
|
}
|
|
313
|
-
subscribe(
|
|
303
|
+
subscribe(channelKey) {
|
|
314
304
|
const self = this;
|
|
315
305
|
let sub;
|
|
316
306
|
return new ReadableStream({
|
|
@@ -318,19 +308,19 @@ var MemoryPubSub = class {
|
|
|
318
308
|
sub = {
|
|
319
309
|
controller,
|
|
320
310
|
ttlTimer: setTimeout(() => {
|
|
321
|
-
self.closeSubscriber(
|
|
311
|
+
self.closeSubscriber(channelKey, sub);
|
|
322
312
|
}, GLASSBOX_STREAM_TTL_MS),
|
|
323
313
|
closed: false
|
|
324
314
|
};
|
|
325
|
-
let set = self.subscribers.get(
|
|
315
|
+
let set = self.subscribers.get(channelKey);
|
|
326
316
|
if (!set) {
|
|
327
317
|
set = /* @__PURE__ */ new Set();
|
|
328
|
-
self.subscribers.set(
|
|
318
|
+
self.subscribers.set(channelKey, set);
|
|
329
319
|
}
|
|
330
320
|
set.add(sub);
|
|
331
321
|
},
|
|
332
322
|
cancel() {
|
|
333
|
-
if (sub) self.removeSubscriber(
|
|
323
|
+
if (sub) self.removeSubscriber(channelKey, sub);
|
|
334
324
|
}
|
|
335
325
|
});
|
|
336
326
|
}
|
|
@@ -338,17 +328,17 @@ var MemoryPubSub = class {
|
|
|
338
328
|
* Refresh the rolling TTL for a subscriber after an event lands. Replaces
|
|
339
329
|
* the existing timer with a fresh 60s one.
|
|
340
330
|
*/
|
|
341
|
-
refreshTtl(
|
|
331
|
+
refreshTtl(channelKey, sub) {
|
|
342
332
|
clearTimeout(sub.ttlTimer);
|
|
343
333
|
sub.ttlTimer = setTimeout(() => {
|
|
344
|
-
this.closeSubscriber(
|
|
334
|
+
this.closeSubscriber(channelKey, sub);
|
|
345
335
|
}, GLASSBOX_STREAM_TTL_MS);
|
|
346
336
|
}
|
|
347
337
|
/**
|
|
348
338
|
* Close the subscriber's stream cleanly and remove from the fan-out set.
|
|
349
339
|
* Idempotent — safe to call multiple times.
|
|
350
340
|
*/
|
|
351
|
-
closeSubscriber(
|
|
341
|
+
closeSubscriber(channelKey, sub) {
|
|
352
342
|
if (sub.closed) return;
|
|
353
343
|
sub.closed = true;
|
|
354
344
|
clearTimeout(sub.ttlTimer);
|
|
@@ -356,14 +346,14 @@ var MemoryPubSub = class {
|
|
|
356
346
|
sub.controller.close();
|
|
357
347
|
} catch {
|
|
358
348
|
}
|
|
359
|
-
this.removeSubscriber(
|
|
349
|
+
this.removeSubscriber(channelKey, sub);
|
|
360
350
|
}
|
|
361
|
-
removeSubscriber(
|
|
351
|
+
removeSubscriber(channelKey, sub) {
|
|
362
352
|
clearTimeout(sub.ttlTimer);
|
|
363
|
-
const set = this.subscribers.get(
|
|
353
|
+
const set = this.subscribers.get(channelKey);
|
|
364
354
|
if (!set) return;
|
|
365
355
|
set.delete(sub);
|
|
366
|
-
if (set.size === 0) this.subscribers.delete(
|
|
356
|
+
if (set.size === 0) this.subscribers.delete(channelKey);
|
|
367
357
|
}
|
|
368
358
|
/**
|
|
369
359
|
* Test-only reset. Tears down all subscribers, clears all state. Calling
|
|
@@ -393,8 +383,8 @@ var UpstashPubSub = class {
|
|
|
393
383
|
this.blockMs = cfg.blockMs ?? 100;
|
|
394
384
|
this.maxLen = cfg.maxLen ?? 100;
|
|
395
385
|
}
|
|
396
|
-
async publish(
|
|
397
|
-
const key =
|
|
386
|
+
async publish(channelKey, event) {
|
|
387
|
+
const key = channelKey;
|
|
398
388
|
const payload = JSON.stringify(event);
|
|
399
389
|
await this.cmd([
|
|
400
390
|
"XADD",
|
|
@@ -408,8 +398,8 @@ var UpstashPubSub = class {
|
|
|
408
398
|
]);
|
|
409
399
|
await this.cmd(["EXPIRE", key, String(Math.ceil(GLASSBOX_STREAM_TTL_MS / 1e3))]);
|
|
410
400
|
}
|
|
411
|
-
subscribe(
|
|
412
|
-
const key =
|
|
401
|
+
subscribe(channelKey) {
|
|
402
|
+
const key = channelKey;
|
|
413
403
|
const self = this;
|
|
414
404
|
let cursor = "$";
|
|
415
405
|
let cancelled = false;
|
|
@@ -483,9 +473,12 @@ var UpstashPubSub = class {
|
|
|
483
473
|
return json;
|
|
484
474
|
}
|
|
485
475
|
};
|
|
486
|
-
function
|
|
476
|
+
function traceChannel(traceId) {
|
|
487
477
|
return `glassbox:trace:${traceId}`;
|
|
488
478
|
}
|
|
479
|
+
function appChannel(appId) {
|
|
480
|
+
return `glassbox:app:${appId}`;
|
|
481
|
+
}
|
|
489
482
|
function decodeEvent(fields) {
|
|
490
483
|
const raw = fields["event"];
|
|
491
484
|
if (!raw) return void 0;
|
|
@@ -548,15 +541,22 @@ function readEnv(key) {
|
|
|
548
541
|
}
|
|
549
542
|
|
|
550
543
|
// src/glassbox/subscribe.ts
|
|
544
|
+
function emptyStream() {
|
|
545
|
+
return new ReadableStream({
|
|
546
|
+
start(controller) {
|
|
547
|
+
controller.close();
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
551
|
function subscribe(traceId) {
|
|
552
|
-
if (!traceId)
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
return getPubSub().subscribe(
|
|
552
|
+
if (!traceId) return emptyStream();
|
|
553
|
+
return getPubSub().subscribe(traceChannel(traceId));
|
|
554
|
+
}
|
|
555
|
+
function subscribeApp({
|
|
556
|
+
appId
|
|
557
|
+
}) {
|
|
558
|
+
if (!appId) return emptyStream();
|
|
559
|
+
return getPubSub().subscribe(appChannel(appId));
|
|
560
560
|
}
|
|
561
561
|
|
|
562
562
|
// src/glassbox-routes/index.ts
|
|
@@ -587,9 +587,11 @@ function createGlassboxRoutes(config) {
|
|
|
587
587
|
{
|
|
588
588
|
installToken,
|
|
589
589
|
extensionId,
|
|
590
|
+
appId,
|
|
590
591
|
scrub: config.scrub
|
|
591
592
|
},
|
|
592
|
-
config.subscribe ?? subscribe
|
|
593
|
+
config.subscribe ?? subscribe,
|
|
594
|
+
config.subscribeApp ?? subscribeApp
|
|
593
595
|
);
|
|
594
596
|
return { proxy, stream };
|
|
595
597
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
subscribe
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
subscribe,
|
|
3
|
+
subscribeApp
|
|
4
|
+
} from "../chunk-RO22VFIF.mjs";
|
|
5
|
+
import "../chunk-NBO4R5PC.mjs";
|
|
5
6
|
|
|
6
7
|
// src/glassbox-routes/auth.ts
|
|
7
8
|
var JSON_HEADERS = { "Content-Type": "application/json" };
|
|
@@ -108,7 +109,7 @@ function createProxyHandler(config) {
|
|
|
108
109
|
const qs = new URLSearchParams();
|
|
109
110
|
qs.set("app_id", `eq.${appId}`);
|
|
110
111
|
if (traceId) {
|
|
111
|
-
qs.set("
|
|
112
|
+
qs.set("handle", `eq.${traceId}`);
|
|
112
113
|
} else {
|
|
113
114
|
qs.set("order", "created_at.desc");
|
|
114
115
|
qs.set("limit", String(limit));
|
|
@@ -169,13 +170,6 @@ var SSE_HEADERS = {
|
|
|
169
170
|
Connection: "keep-alive",
|
|
170
171
|
"X-Accel-Buffering": "no"
|
|
171
172
|
};
|
|
172
|
-
var JSON_HEADERS3 = { "Content-Type": "application/json" };
|
|
173
|
-
function jsonError3(status, code) {
|
|
174
|
-
return new Response(JSON.stringify({ error: code }), {
|
|
175
|
-
status,
|
|
176
|
-
headers: JSON_HEADERS3
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
173
|
function applyScrub2(event, scrub) {
|
|
180
174
|
if (!scrub) return event;
|
|
181
175
|
try {
|
|
@@ -195,17 +189,14 @@ data: ${JSON.stringify(data)}
|
|
|
195
189
|
|
|
196
190
|
`;
|
|
197
191
|
}
|
|
198
|
-
function createStreamHandler(config, subscribe2) {
|
|
199
|
-
const { installToken, extensionId, scrub } = config;
|
|
192
|
+
function createStreamHandler(config, subscribe2, subscribeApp2) {
|
|
193
|
+
const { installToken, extensionId, appId, scrub } = config;
|
|
200
194
|
return async function stream(req) {
|
|
201
195
|
const authFail = checkAuth(req, { installToken, extensionId });
|
|
202
196
|
if (authFail) return authFail;
|
|
203
197
|
const url = new URL(req.url);
|
|
204
198
|
const traceId = url.searchParams.get("traceId");
|
|
205
|
-
|
|
206
|
-
return jsonError3(400, "missing_trace_id");
|
|
207
|
-
}
|
|
208
|
-
const source = subscribe2(traceId);
|
|
199
|
+
const source = traceId ? subscribe2(traceId) : subscribeApp2({ appId });
|
|
209
200
|
const encoder = new TextEncoder();
|
|
210
201
|
let sourceReader;
|
|
211
202
|
let cancelled = false;
|
|
@@ -297,9 +288,11 @@ function createGlassboxRoutes(config) {
|
|
|
297
288
|
{
|
|
298
289
|
installToken,
|
|
299
290
|
extensionId,
|
|
291
|
+
appId,
|
|
300
292
|
scrub: config.scrub
|
|
301
293
|
},
|
|
302
|
-
config.subscribe ?? subscribe
|
|
294
|
+
config.subscribe ?? subscribe,
|
|
295
|
+
config.subscribeApp ?? subscribeApp
|
|
303
296
|
);
|
|
304
297
|
return { proxy, stream };
|
|
305
298
|
}
|
package/dist/index.js
CHANGED
|
@@ -3473,8 +3473,8 @@ var GLASSBOX_STREAM_TTL_MS = 6e4;
|
|
|
3473
3473
|
// src/glassbox/pubsub-memory.ts
|
|
3474
3474
|
var MemoryPubSub = class {
|
|
3475
3475
|
subscribers = /* @__PURE__ */ new Map();
|
|
3476
|
-
async publish(
|
|
3477
|
-
const subs = this.subscribers.get(
|
|
3476
|
+
async publish(channelKey, event) {
|
|
3477
|
+
const subs = this.subscribers.get(channelKey);
|
|
3478
3478
|
if (!subs || subs.size === 0) return;
|
|
3479
3479
|
for (const sub of subs) {
|
|
3480
3480
|
if (sub.closed) continue;
|
|
@@ -3484,10 +3484,10 @@ var MemoryPubSub = class {
|
|
|
3484
3484
|
sub.closed = true;
|
|
3485
3485
|
continue;
|
|
3486
3486
|
}
|
|
3487
|
-
this.refreshTtl(
|
|
3487
|
+
this.refreshTtl(channelKey, sub);
|
|
3488
3488
|
}
|
|
3489
3489
|
}
|
|
3490
|
-
subscribe(
|
|
3490
|
+
subscribe(channelKey) {
|
|
3491
3491
|
const self = this;
|
|
3492
3492
|
let sub;
|
|
3493
3493
|
return new ReadableStream({
|
|
@@ -3495,19 +3495,19 @@ var MemoryPubSub = class {
|
|
|
3495
3495
|
sub = {
|
|
3496
3496
|
controller,
|
|
3497
3497
|
ttlTimer: setTimeout(() => {
|
|
3498
|
-
self.closeSubscriber(
|
|
3498
|
+
self.closeSubscriber(channelKey, sub);
|
|
3499
3499
|
}, GLASSBOX_STREAM_TTL_MS),
|
|
3500
3500
|
closed: false
|
|
3501
3501
|
};
|
|
3502
|
-
let set = self.subscribers.get(
|
|
3502
|
+
let set = self.subscribers.get(channelKey);
|
|
3503
3503
|
if (!set) {
|
|
3504
3504
|
set = /* @__PURE__ */ new Set();
|
|
3505
|
-
self.subscribers.set(
|
|
3505
|
+
self.subscribers.set(channelKey, set);
|
|
3506
3506
|
}
|
|
3507
3507
|
set.add(sub);
|
|
3508
3508
|
},
|
|
3509
3509
|
cancel() {
|
|
3510
|
-
if (sub) self.removeSubscriber(
|
|
3510
|
+
if (sub) self.removeSubscriber(channelKey, sub);
|
|
3511
3511
|
}
|
|
3512
3512
|
});
|
|
3513
3513
|
}
|
|
@@ -3515,17 +3515,17 @@ var MemoryPubSub = class {
|
|
|
3515
3515
|
* Refresh the rolling TTL for a subscriber after an event lands. Replaces
|
|
3516
3516
|
* the existing timer with a fresh 60s one.
|
|
3517
3517
|
*/
|
|
3518
|
-
refreshTtl(
|
|
3518
|
+
refreshTtl(channelKey, sub) {
|
|
3519
3519
|
clearTimeout(sub.ttlTimer);
|
|
3520
3520
|
sub.ttlTimer = setTimeout(() => {
|
|
3521
|
-
this.closeSubscriber(
|
|
3521
|
+
this.closeSubscriber(channelKey, sub);
|
|
3522
3522
|
}, GLASSBOX_STREAM_TTL_MS);
|
|
3523
3523
|
}
|
|
3524
3524
|
/**
|
|
3525
3525
|
* Close the subscriber's stream cleanly and remove from the fan-out set.
|
|
3526
3526
|
* Idempotent — safe to call multiple times.
|
|
3527
3527
|
*/
|
|
3528
|
-
closeSubscriber(
|
|
3528
|
+
closeSubscriber(channelKey, sub) {
|
|
3529
3529
|
if (sub.closed) return;
|
|
3530
3530
|
sub.closed = true;
|
|
3531
3531
|
clearTimeout(sub.ttlTimer);
|
|
@@ -3533,14 +3533,14 @@ var MemoryPubSub = class {
|
|
|
3533
3533
|
sub.controller.close();
|
|
3534
3534
|
} catch {
|
|
3535
3535
|
}
|
|
3536
|
-
this.removeSubscriber(
|
|
3536
|
+
this.removeSubscriber(channelKey, sub);
|
|
3537
3537
|
}
|
|
3538
|
-
removeSubscriber(
|
|
3538
|
+
removeSubscriber(channelKey, sub) {
|
|
3539
3539
|
clearTimeout(sub.ttlTimer);
|
|
3540
|
-
const set = this.subscribers.get(
|
|
3540
|
+
const set = this.subscribers.get(channelKey);
|
|
3541
3541
|
if (!set) return;
|
|
3542
3542
|
set.delete(sub);
|
|
3543
|
-
if (set.size === 0) this.subscribers.delete(
|
|
3543
|
+
if (set.size === 0) this.subscribers.delete(channelKey);
|
|
3544
3544
|
}
|
|
3545
3545
|
/**
|
|
3546
3546
|
* Test-only reset. Tears down all subscribers, clears all state. Calling
|
|
@@ -3570,8 +3570,8 @@ var UpstashPubSub = class {
|
|
|
3570
3570
|
this.blockMs = cfg.blockMs ?? 100;
|
|
3571
3571
|
this.maxLen = cfg.maxLen ?? 100;
|
|
3572
3572
|
}
|
|
3573
|
-
async publish(
|
|
3574
|
-
const key =
|
|
3573
|
+
async publish(channelKey, event) {
|
|
3574
|
+
const key = channelKey;
|
|
3575
3575
|
const payload = JSON.stringify(event);
|
|
3576
3576
|
await this.cmd([
|
|
3577
3577
|
"XADD",
|
|
@@ -3585,8 +3585,8 @@ var UpstashPubSub = class {
|
|
|
3585
3585
|
]);
|
|
3586
3586
|
await this.cmd(["EXPIRE", key, String(Math.ceil(GLASSBOX_STREAM_TTL_MS / 1e3))]);
|
|
3587
3587
|
}
|
|
3588
|
-
subscribe(
|
|
3589
|
-
const key =
|
|
3588
|
+
subscribe(channelKey) {
|
|
3589
|
+
const key = channelKey;
|
|
3590
3590
|
const self = this;
|
|
3591
3591
|
let cursor = "$";
|
|
3592
3592
|
let cancelled = false;
|
|
@@ -3660,9 +3660,12 @@ var UpstashPubSub = class {
|
|
|
3660
3660
|
return json;
|
|
3661
3661
|
}
|
|
3662
3662
|
};
|
|
3663
|
-
function
|
|
3663
|
+
function traceChannel(traceId) {
|
|
3664
3664
|
return `glassbox:trace:${traceId}`;
|
|
3665
3665
|
}
|
|
3666
|
+
function appChannel(appId) {
|
|
3667
|
+
return `glassbox:app:${appId}`;
|
|
3668
|
+
}
|
|
3666
3669
|
function decodeEvent(fields) {
|
|
3667
3670
|
const raw = fields["event"];
|
|
3668
3671
|
if (!raw) return void 0;
|
|
@@ -3723,43 +3726,53 @@ function readEnv(key) {
|
|
|
3723
3726
|
}
|
|
3724
3727
|
return void 0;
|
|
3725
3728
|
}
|
|
3726
|
-
function emitGlassboxEvent(traceId, kind, data) {
|
|
3729
|
+
function emitGlassboxEvent(traceId, appId, kind, data) {
|
|
3727
3730
|
if (!traceId) return;
|
|
3728
3731
|
const event = { kind, at: Date.now(), data };
|
|
3729
3732
|
const ps = getPubSub();
|
|
3730
3733
|
try {
|
|
3731
|
-
const
|
|
3732
|
-
if (
|
|
3733
|
-
|
|
3734
|
+
const p1 = ps.publish(traceChannel(traceId), event);
|
|
3735
|
+
if (p1 && typeof p1.then === "function") {
|
|
3736
|
+
p1.catch(() => {
|
|
3734
3737
|
});
|
|
3735
3738
|
}
|
|
3736
3739
|
} catch {
|
|
3737
3740
|
}
|
|
3741
|
+
if (appId) {
|
|
3742
|
+
try {
|
|
3743
|
+
const p2 = ps.publish(appChannel(appId), event);
|
|
3744
|
+
if (p2 && typeof p2.then === "function") {
|
|
3745
|
+
p2.catch(() => {
|
|
3746
|
+
});
|
|
3747
|
+
}
|
|
3748
|
+
} catch {
|
|
3749
|
+
}
|
|
3750
|
+
}
|
|
3738
3751
|
}
|
|
3739
|
-
function emitCompileStart(traceId, data) {
|
|
3740
|
-
emitGlassboxEvent(traceId, "compile.start", data);
|
|
3752
|
+
function emitCompileStart(traceId, appId, data) {
|
|
3753
|
+
emitGlassboxEvent(traceId, appId, "compile.start", data);
|
|
3741
3754
|
}
|
|
3742
|
-
function emitCompileDone(traceId, data) {
|
|
3743
|
-
emitGlassboxEvent(traceId, "compile.done", data);
|
|
3755
|
+
function emitCompileDone(traceId, appId, data) {
|
|
3756
|
+
emitGlassboxEvent(traceId, appId, "compile.done", data);
|
|
3744
3757
|
}
|
|
3745
|
-
function emitExecuteAttempt(traceId, data) {
|
|
3746
|
-
emitGlassboxEvent(traceId, "execute.attempt", data);
|
|
3758
|
+
function emitExecuteAttempt(traceId, appId, data) {
|
|
3759
|
+
emitGlassboxEvent(traceId, appId, "execute.attempt", data);
|
|
3747
3760
|
}
|
|
3748
|
-
function emitExecuteSuccess(traceId, data) {
|
|
3749
|
-
emitGlassboxEvent(traceId, "execute.success", data);
|
|
3761
|
+
function emitExecuteSuccess(traceId, appId, data) {
|
|
3762
|
+
emitGlassboxEvent(traceId, appId, "execute.success", data);
|
|
3750
3763
|
}
|
|
3751
|
-
function emitAdvisoryFired(traceId, data) {
|
|
3752
|
-
emitGlassboxEvent(traceId, "advisory.fired", data);
|
|
3764
|
+
function emitAdvisoryFired(traceId, appId, data) {
|
|
3765
|
+
emitGlassboxEvent(traceId, appId, "advisory.fired", data);
|
|
3753
3766
|
}
|
|
3754
|
-
function emitFallbackWalked(traceId, data) {
|
|
3755
|
-
emitGlassboxEvent(traceId, "fallback.walked", data);
|
|
3767
|
+
function emitFallbackWalked(traceId, appId, data) {
|
|
3768
|
+
emitGlassboxEvent(traceId, appId, "fallback.walked", data);
|
|
3756
3769
|
}
|
|
3757
3770
|
|
|
3758
3771
|
// src/call.ts
|
|
3759
3772
|
async function call(ir, opts = {}) {
|
|
3760
3773
|
const traceId = generateTraceId();
|
|
3761
3774
|
safeEmit(
|
|
3762
|
-
() => emitCompileStart(traceId, {
|
|
3775
|
+
() => emitCompileStart(traceId, ir.appId, {
|
|
3763
3776
|
appId: ir.appId,
|
|
3764
3777
|
archetype: ir.intent.archetype,
|
|
3765
3778
|
models: ir.models
|
|
@@ -3767,7 +3780,7 @@ async function call(ir, opts = {}) {
|
|
|
3767
3780
|
);
|
|
3768
3781
|
const initial = compileAndRegister(ir, opts);
|
|
3769
3782
|
safeEmit(
|
|
3770
|
-
() => emitCompileDone(traceId, {
|
|
3783
|
+
() => emitCompileDone(traceId, ir.appId, {
|
|
3771
3784
|
target: initial.target,
|
|
3772
3785
|
provider: initial.provider,
|
|
3773
3786
|
fallbackChain: initial.fallbackChain,
|
|
@@ -3779,7 +3792,7 @@ async function call(ir, opts = {}) {
|
|
|
3779
3792
|
);
|
|
3780
3793
|
for (const adv of initial.advisories) {
|
|
3781
3794
|
safeEmit(
|
|
3782
|
-
() => emitAdvisoryFired(traceId, { code: adv.code, message: adv.message })
|
|
3795
|
+
() => emitAdvisoryFired(traceId, ir.appId, { code: adv.code, message: adv.message })
|
|
3783
3796
|
);
|
|
3784
3797
|
}
|
|
3785
3798
|
const start = Date.now();
|
|
@@ -3913,7 +3926,7 @@ async function call(ir, opts = {}) {
|
|
|
3913
3926
|
}
|
|
3914
3927
|
}
|
|
3915
3928
|
safeEmit(
|
|
3916
|
-
() => emitExecuteAttempt(traceId, { model: targetModel, attemptIndex: i })
|
|
3929
|
+
() => emitExecuteAttempt(traceId, ir.appId, { model: targetModel, attemptIndex: i })
|
|
3917
3930
|
);
|
|
3918
3931
|
const exec = await execute(activeCompile.request, {
|
|
3919
3932
|
apiKeys: opts.apiKeys,
|
|
@@ -3925,7 +3938,7 @@ async function call(ir, opts = {}) {
|
|
|
3925
3938
|
attempts.push({ model: targetModel, status: "success" });
|
|
3926
3939
|
const latencyMs2 = Date.now() - start;
|
|
3927
3940
|
safeEmit(
|
|
3928
|
-
() => emitExecuteSuccess(traceId, {
|
|
3941
|
+
() => emitExecuteSuccess(traceId, ir.appId, {
|
|
3929
3942
|
model: targetModel,
|
|
3930
3943
|
tokensIn: validated.response.tokens.input,
|
|
3931
3944
|
tokensOut: validated.response.tokens.output,
|
|
@@ -3953,7 +3966,7 @@ async function call(ir, opts = {}) {
|
|
|
3953
3966
|
const firstFailed = attempts.find((a) => a.status !== "success");
|
|
3954
3967
|
if (firstFailed) {
|
|
3955
3968
|
safeEmit(
|
|
3956
|
-
() => emitFallbackWalked(traceId, {
|
|
3969
|
+
() => emitFallbackWalked(traceId, ir.appId, {
|
|
3957
3970
|
from: initial.target,
|
|
3958
3971
|
to: targetModel,
|
|
3959
3972
|
reason: fallbackReason ?? "unknown",
|
package/dist/index.mjs
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
emitExecuteAttempt,
|
|
26
26
|
emitExecuteSuccess,
|
|
27
27
|
emitFallbackWalked
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-NBO4R5PC.mjs";
|
|
29
29
|
|
|
30
30
|
// src/tokenizer.ts
|
|
31
31
|
var tokenizerImpl = defaultCharBasedCounter;
|
|
@@ -2265,7 +2265,7 @@ function ensureCrossProviderTail(opts) {
|
|
|
2265
2265
|
async function call(ir, opts = {}) {
|
|
2266
2266
|
const traceId = generateTraceId();
|
|
2267
2267
|
safeEmit(
|
|
2268
|
-
() => emitCompileStart(traceId, {
|
|
2268
|
+
() => emitCompileStart(traceId, ir.appId, {
|
|
2269
2269
|
appId: ir.appId,
|
|
2270
2270
|
archetype: ir.intent.archetype,
|
|
2271
2271
|
models: ir.models
|
|
@@ -2273,7 +2273,7 @@ async function call(ir, opts = {}) {
|
|
|
2273
2273
|
);
|
|
2274
2274
|
const initial = compileAndRegister(ir, opts);
|
|
2275
2275
|
safeEmit(
|
|
2276
|
-
() => emitCompileDone(traceId, {
|
|
2276
|
+
() => emitCompileDone(traceId, ir.appId, {
|
|
2277
2277
|
target: initial.target,
|
|
2278
2278
|
provider: initial.provider,
|
|
2279
2279
|
fallbackChain: initial.fallbackChain,
|
|
@@ -2285,7 +2285,7 @@ async function call(ir, opts = {}) {
|
|
|
2285
2285
|
);
|
|
2286
2286
|
for (const adv of initial.advisories) {
|
|
2287
2287
|
safeEmit(
|
|
2288
|
-
() => emitAdvisoryFired(traceId, { code: adv.code, message: adv.message })
|
|
2288
|
+
() => emitAdvisoryFired(traceId, ir.appId, { code: adv.code, message: adv.message })
|
|
2289
2289
|
);
|
|
2290
2290
|
}
|
|
2291
2291
|
const start = Date.now();
|
|
@@ -2419,7 +2419,7 @@ async function call(ir, opts = {}) {
|
|
|
2419
2419
|
}
|
|
2420
2420
|
}
|
|
2421
2421
|
safeEmit(
|
|
2422
|
-
() => emitExecuteAttempt(traceId, { model: targetModel, attemptIndex: i })
|
|
2422
|
+
() => emitExecuteAttempt(traceId, ir.appId, { model: targetModel, attemptIndex: i })
|
|
2423
2423
|
);
|
|
2424
2424
|
const exec = await execute(activeCompile.request, {
|
|
2425
2425
|
apiKeys: opts.apiKeys,
|
|
@@ -2431,7 +2431,7 @@ async function call(ir, opts = {}) {
|
|
|
2431
2431
|
attempts.push({ model: targetModel, status: "success" });
|
|
2432
2432
|
const latencyMs2 = Date.now() - start;
|
|
2433
2433
|
safeEmit(
|
|
2434
|
-
() => emitExecuteSuccess(traceId, {
|
|
2434
|
+
() => emitExecuteSuccess(traceId, ir.appId, {
|
|
2435
2435
|
model: targetModel,
|
|
2436
2436
|
tokensIn: validated.response.tokens.input,
|
|
2437
2437
|
tokensOut: validated.response.tokens.output,
|
|
@@ -2459,7 +2459,7 @@ async function call(ir, opts = {}) {
|
|
|
2459
2459
|
const firstFailed = attempts.find((a) => a.status !== "success");
|
|
2460
2460
|
if (firstFailed) {
|
|
2461
2461
|
safeEmit(
|
|
2462
|
-
() => emitFallbackWalked(traceId, {
|
|
2462
|
+
() => emitFallbackWalked(traceId, ir.appId, {
|
|
2463
2463
|
from: initial.target,
|
|
2464
2464
|
to: targetModel,
|
|
2465
2465
|
reason: fallbackReason ?? "unknown",
|
|
@@ -92,20 +92,29 @@ interface FallbackWalkedData {
|
|
|
92
92
|
*/
|
|
93
93
|
interface GlassboxPubSub {
|
|
94
94
|
/**
|
|
95
|
-
* Publish a single event
|
|
96
|
-
*
|
|
97
|
-
*
|
|
95
|
+
* Publish a single event to a channel key. The channel is an opaque
|
|
96
|
+
* namespaced string — callers build it via `traceChannel(traceId)` or
|
|
97
|
+
* `appChannel(appId)` (see pubsub-upstash.ts). Returns a promise that
|
|
98
|
+
* resolves after the event is durably appended (or rejects on adapter
|
|
99
|
+
* failure — callers in emit.ts always swallow rejections).
|
|
100
|
+
*
|
|
101
|
+
* Pre-alpha.26 the parameter was named `traceId` because there was only
|
|
102
|
+
* one channel namespace; alpha.26 added per-app channels for the
|
|
103
|
+
* "tail-all" Live tab subscription. Behavior identical to the adapters —
|
|
104
|
+
* they treat the value as an opaque key — but the rename surfaces the
|
|
105
|
+
* generalization at the type level.
|
|
98
106
|
*/
|
|
99
|
-
publish(
|
|
107
|
+
publish(channelKey: string, event: GlassboxEvent): Promise<void>;
|
|
100
108
|
/**
|
|
101
|
-
* Subscribe to events
|
|
102
|
-
* GlassboxEvent objects as they're published. The stream closes
|
|
103
|
-
* after the
|
|
109
|
+
* Subscribe to events on a channel key. Returns a ReadableStream that
|
|
110
|
+
* emits GlassboxEvent objects as they're published. The stream closes
|
|
111
|
+
* cleanly after the channel-level TTL elapses since the LAST event
|
|
112
|
+
* (rolling 60s).
|
|
104
113
|
*
|
|
105
|
-
* If
|
|
106
|
-
* closes empty.
|
|
114
|
+
* If no publisher writes to the channel within 60s of subscription, the
|
|
115
|
+
* stream closes empty.
|
|
107
116
|
*/
|
|
108
|
-
subscribe(
|
|
117
|
+
subscribe(channelKey: string): ReadableStream<GlassboxEvent>;
|
|
109
118
|
/**
|
|
110
119
|
* Test-only escape hatch. Clears any in-memory state. Upstash adapter
|
|
111
120
|
* no-ops (server-side state isn't accessible from here). Tests reach for
|
|
@@ -92,20 +92,29 @@ interface FallbackWalkedData {
|
|
|
92
92
|
*/
|
|
93
93
|
interface GlassboxPubSub {
|
|
94
94
|
/**
|
|
95
|
-
* Publish a single event
|
|
96
|
-
*
|
|
97
|
-
*
|
|
95
|
+
* Publish a single event to a channel key. The channel is an opaque
|
|
96
|
+
* namespaced string — callers build it via `traceChannel(traceId)` or
|
|
97
|
+
* `appChannel(appId)` (see pubsub-upstash.ts). Returns a promise that
|
|
98
|
+
* resolves after the event is durably appended (or rejects on adapter
|
|
99
|
+
* failure — callers in emit.ts always swallow rejections).
|
|
100
|
+
*
|
|
101
|
+
* Pre-alpha.26 the parameter was named `traceId` because there was only
|
|
102
|
+
* one channel namespace; alpha.26 added per-app channels for the
|
|
103
|
+
* "tail-all" Live tab subscription. Behavior identical to the adapters —
|
|
104
|
+
* they treat the value as an opaque key — but the rename surfaces the
|
|
105
|
+
* generalization at the type level.
|
|
98
106
|
*/
|
|
99
|
-
publish(
|
|
107
|
+
publish(channelKey: string, event: GlassboxEvent): Promise<void>;
|
|
100
108
|
/**
|
|
101
|
-
* Subscribe to events
|
|
102
|
-
* GlassboxEvent objects as they're published. The stream closes
|
|
103
|
-
* after the
|
|
109
|
+
* Subscribe to events on a channel key. Returns a ReadableStream that
|
|
110
|
+
* emits GlassboxEvent objects as they're published. The stream closes
|
|
111
|
+
* cleanly after the channel-level TTL elapses since the LAST event
|
|
112
|
+
* (rolling 60s).
|
|
104
113
|
*
|
|
105
|
-
* If
|
|
106
|
-
* closes empty.
|
|
114
|
+
* If no publisher writes to the channel within 60s of subscription, the
|
|
115
|
+
* stream closes empty.
|
|
107
116
|
*/
|
|
108
|
-
subscribe(
|
|
117
|
+
subscribe(channelKey: string): ReadableStream<GlassboxEvent>;
|
|
109
118
|
/**
|
|
110
119
|
* Test-only escape hatch. Clears any in-memory state. Upstash adapter
|
|
111
120
|
* no-ops (server-side state isn't accessible from here). Tests reach for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@warmdrift/kgauto-compiler",
|
|
3
|
-
"version": "2.0.0-alpha.
|
|
3
|
+
"version": "2.0.0-alpha.26",
|
|
4
4
|
"description": "Prompt compiler + central learning brain for multi-model AI apps. Swap models without rewriting prompts.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
package/dist/chunk-VZGMWKRT.mjs
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getPubSub
|
|
3
|
-
} from "./chunk-NUTC7NUC.mjs";
|
|
4
|
-
|
|
5
|
-
// src/glassbox/subscribe.ts
|
|
6
|
-
function subscribe(traceId) {
|
|
7
|
-
if (!traceId) {
|
|
8
|
-
return new ReadableStream({
|
|
9
|
-
start(controller) {
|
|
10
|
-
controller.close();
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
return getPubSub().subscribe(traceId);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export {
|
|
18
|
-
subscribe
|
|
19
|
-
};
|