@shogo-ai/core 1.4.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.
@@ -0,0 +1,43 @@
1
+ import { Span } from '@opentelemetry/api';
2
+
3
+ /**
4
+ * OpenTelemetry tracing setup for Shogo runtime services.
5
+ *
6
+ * Wires a `NodeSDK` with an OTLP HTTP trace exporter pointed at
7
+ * `OTEL_EXPORTER_OTLP_ENDPOINT`, optionally authenticated via
8
+ * `SIGNOZ_INGESTION_KEY`. In production / staging, spans are batched
9
+ * before flush; in development a `SimpleSpanProcessor` flushes
10
+ * eagerly so traces are visible immediately.
11
+ *
12
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT.
13
+ * The OpenTelemetry packages are optional `peerDependencies` of the SDK
14
+ * — only consumers that actually call `initInstrumentation` need them
15
+ * installed.
16
+ *
17
+ * @example
18
+ * import { initInstrumentation, traceOperation, shutdownInstrumentation }
19
+ * from '@shogo-ai/sdk/instrumentation'
20
+ *
21
+ * initInstrumentation({ serviceName: 'my-api', serviceVersion: '1.0.0' })
22
+ *
23
+ * await traceOperation('my-api', 'cold-start', { region: 'us-west' }, async (span) => {
24
+ * // ... boot work ...
25
+ * span.setAttribute('warm-pool-size', 4)
26
+ * })
27
+ *
28
+ * process.on('SIGTERM', () => shutdownInstrumentation())
29
+ */
30
+
31
+ interface InstrumentationConfig {
32
+ serviceName: string;
33
+ serviceVersion?: string;
34
+ }
35
+ declare function initInstrumentation(config: InstrumentationConfig): void;
36
+ declare function shutdownInstrumentation(): Promise<void>;
37
+ /**
38
+ * Trace a function execution with automatic error recording and timing.
39
+ * Use for key operations like cold starts, builds, tool calls, etc.
40
+ */
41
+ declare function traceOperation<T>(tracerName: string, spanName: string, attributes: Record<string, string | number | boolean>, fn: (span: Span) => Promise<T>): Promise<T>;
42
+
43
+ export { type InstrumentationConfig, initInstrumentation, shutdownInstrumentation, traceOperation };
@@ -0,0 +1,43 @@
1
+ import { Span } from '@opentelemetry/api';
2
+
3
+ /**
4
+ * OpenTelemetry tracing setup for Shogo runtime services.
5
+ *
6
+ * Wires a `NodeSDK` with an OTLP HTTP trace exporter pointed at
7
+ * `OTEL_EXPORTER_OTLP_ENDPOINT`, optionally authenticated via
8
+ * `SIGNOZ_INGESTION_KEY`. In production / staging, spans are batched
9
+ * before flush; in development a `SimpleSpanProcessor` flushes
10
+ * eagerly so traces are visible immediately.
11
+ *
12
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT.
13
+ * The OpenTelemetry packages are optional `peerDependencies` of the SDK
14
+ * — only consumers that actually call `initInstrumentation` need them
15
+ * installed.
16
+ *
17
+ * @example
18
+ * import { initInstrumentation, traceOperation, shutdownInstrumentation }
19
+ * from '@shogo-ai/sdk/instrumentation'
20
+ *
21
+ * initInstrumentation({ serviceName: 'my-api', serviceVersion: '1.0.0' })
22
+ *
23
+ * await traceOperation('my-api', 'cold-start', { region: 'us-west' }, async (span) => {
24
+ * // ... boot work ...
25
+ * span.setAttribute('warm-pool-size', 4)
26
+ * })
27
+ *
28
+ * process.on('SIGTERM', () => shutdownInstrumentation())
29
+ */
30
+
31
+ interface InstrumentationConfig {
32
+ serviceName: string;
33
+ serviceVersion?: string;
34
+ }
35
+ declare function initInstrumentation(config: InstrumentationConfig): void;
36
+ declare function shutdownInstrumentation(): Promise<void>;
37
+ /**
38
+ * Trace a function execution with automatic error recording and timing.
39
+ * Use for key operations like cold starts, builds, tool calls, etc.
40
+ */
41
+ declare function traceOperation<T>(tracerName: string, spanName: string, attributes: Record<string, string | number | boolean>, fn: (span: Span) => Promise<T>): Promise<T>;
42
+
43
+ export { type InstrumentationConfig, initInstrumentation, shutdownInstrumentation, traceOperation };
@@ -0,0 +1,11 @@
1
+ import {
2
+ initInstrumentation,
3
+ shutdownInstrumentation,
4
+ traceOperation
5
+ } from "./chunk-IDGVRGAL.js";
6
+ export {
7
+ initInstrumentation,
8
+ shutdownInstrumentation,
9
+ traceOperation
10
+ };
11
+ //# sourceMappingURL=instrumentation.js.map
@@ -0,0 +1,81 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/logger.ts
21
+ var logger_exports = {};
22
+ __export(logger_exports, {
23
+ createLogger: () => createLogger
24
+ });
25
+ module.exports = __toCommonJS(logger_exports);
26
+ var LOG_LEVELS = {
27
+ debug: 0,
28
+ info: 1,
29
+ warn: 2,
30
+ error: 3
31
+ };
32
+ var isProduction = process.env.NODE_ENV === "production" || process.env.NODE_ENV === "staging";
33
+ var minLevel = LOG_LEVELS[process.env.LOG_LEVEL || "info"] ?? 1;
34
+ function shouldLog(level) {
35
+ return LOG_LEVELS[level] >= minLevel;
36
+ }
37
+ function formatEntry(entry) {
38
+ if (isProduction) {
39
+ return JSON.stringify(entry);
40
+ }
41
+ const { level: _level, msg, service, timestamp: _timestamp, ...extra } = entry;
42
+ const extraStr = Object.keys(extra).length > 0 ? " " + JSON.stringify(extra) : "";
43
+ return `[${service}] ${msg}${extraStr}`;
44
+ }
45
+ function createLogger(service, defaultExtra) {
46
+ function log(level, msg, extra) {
47
+ if (!shouldLog(level)) return;
48
+ const entry = {
49
+ level,
50
+ msg,
51
+ service,
52
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
53
+ ...defaultExtra,
54
+ ...extra
55
+ };
56
+ const formatted = formatEntry(entry);
57
+ switch (level) {
58
+ case "error":
59
+ console.error(formatted);
60
+ break;
61
+ case "warn":
62
+ console.warn(formatted);
63
+ break;
64
+ default:
65
+ console.log(formatted);
66
+ break;
67
+ }
68
+ }
69
+ return {
70
+ debug: (msg, extra) => log("debug", msg, extra),
71
+ info: (msg, extra) => log("info", msg, extra),
72
+ warn: (msg, extra) => log("warn", msg, extra),
73
+ error: (msg, extra) => log("error", msg, extra),
74
+ child: (extra) => createLogger(service, { ...defaultExtra, ...extra })
75
+ };
76
+ }
77
+ // Annotate the CommonJS export names for ESM import in node:
78
+ 0 && (module.exports = {
79
+ createLogger
80
+ });
81
+ //# sourceMappingURL=logger.cjs.map
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Structured logger for Shogo runtime services.
3
+ *
4
+ * Outputs JSON lines in production / staging (suitable for SigNoz log
5
+ * collection or any structured log pipeline) and a human-readable
6
+ * `[service] msg {extra}` format in development.
7
+ *
8
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT
9
+ * so userland agent/app code can import the same logger the runtime
10
+ * services use without dragging an AGPL workspace dependency.
11
+ *
12
+ * @example
13
+ * import { createLogger } from '@shogo-ai/sdk/logger'
14
+ *
15
+ * const log = createLogger('my-service')
16
+ * log.info('boot complete', { port: 8002 })
17
+ *
18
+ * const reqLog = log.child({ requestId: 'r-123' })
19
+ * reqLog.warn('slow query', { ms: 4200 })
20
+ */
21
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
22
+ interface Logger {
23
+ debug(msg: string, extra?: Record<string, unknown>): void;
24
+ info(msg: string, extra?: Record<string, unknown>): void;
25
+ warn(msg: string, extra?: Record<string, unknown>): void;
26
+ error(msg: string, extra?: Record<string, unknown>): void;
27
+ /** Returns a new logger that merges `extra` into every log entry. */
28
+ child(extra: Record<string, unknown>): Logger;
29
+ }
30
+ declare function createLogger(service: string, defaultExtra?: Record<string, unknown>): Logger;
31
+
32
+ export { type LogLevel, type Logger, createLogger };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Structured logger for Shogo runtime services.
3
+ *
4
+ * Outputs JSON lines in production / staging (suitable for SigNoz log
5
+ * collection or any structured log pipeline) and a human-readable
6
+ * `[service] msg {extra}` format in development.
7
+ *
8
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT
9
+ * so userland agent/app code can import the same logger the runtime
10
+ * services use without dragging an AGPL workspace dependency.
11
+ *
12
+ * @example
13
+ * import { createLogger } from '@shogo-ai/sdk/logger'
14
+ *
15
+ * const log = createLogger('my-service')
16
+ * log.info('boot complete', { port: 8002 })
17
+ *
18
+ * const reqLog = log.child({ requestId: 'r-123' })
19
+ * reqLog.warn('slow query', { ms: 4200 })
20
+ */
21
+ type LogLevel = 'debug' | 'info' | 'warn' | 'error';
22
+ interface Logger {
23
+ debug(msg: string, extra?: Record<string, unknown>): void;
24
+ info(msg: string, extra?: Record<string, unknown>): void;
25
+ warn(msg: string, extra?: Record<string, unknown>): void;
26
+ error(msg: string, extra?: Record<string, unknown>): void;
27
+ /** Returns a new logger that merges `extra` into every log entry. */
28
+ child(extra: Record<string, unknown>): Logger;
29
+ }
30
+ declare function createLogger(service: string, defaultExtra?: Record<string, unknown>): Logger;
31
+
32
+ export { type LogLevel, type Logger, createLogger };
package/dist/logger.js ADDED
@@ -0,0 +1,7 @@
1
+ import {
2
+ createLogger
3
+ } from "./chunk-24AL3V6R.js";
4
+ export {
5
+ createLogger
6
+ };
7
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/macos-junk.ts
21
+ var macos_junk_exports = {};
22
+ __export(macos_junk_exports, {
23
+ isMacOSJunkName: () => isMacOSJunkName,
24
+ isMacOSJunkPath: () => isMacOSJunkPath
25
+ });
26
+ module.exports = __toCommonJS(macos_junk_exports);
27
+ var MACOS_JUNK_BASENAMES = /* @__PURE__ */ new Set([
28
+ ".DS_Store",
29
+ ".AppleDouble",
30
+ ".LSOverride",
31
+ ".Spotlight-V100",
32
+ ".Trashes",
33
+ ".fseventsd",
34
+ ".TemporaryItems",
35
+ ".VolumeIcon.icns",
36
+ ".com.apple.timemachine.donotpresent",
37
+ "__MACOSX"
38
+ ]);
39
+ var ICON_CR = "Icon\r";
40
+ function isMacOSJunkName(name) {
41
+ if (!name) return false;
42
+ if (name.startsWith("._")) return true;
43
+ if (MACOS_JUNK_BASENAMES.has(name)) return true;
44
+ if (name === ICON_CR) return true;
45
+ return false;
46
+ }
47
+ function isMacOSJunkPath(relPath) {
48
+ if (!relPath) return false;
49
+ return relPath.split("/").some(isMacOSJunkName);
50
+ }
51
+ // Annotate the CommonJS export names for ESM import in node:
52
+ 0 && (module.exports = {
53
+ isMacOSJunkName,
54
+ isMacOSJunkPath
55
+ });
56
+ //# sourceMappingURL=macos-junk.cjs.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Filter for macOS-specific filesystem detritus that must never round-trip
3
+ * through a project export. The motivating bug: AppleDouble sidecars
4
+ * (`._foo.ts`, `._\_layout.tsx`) are binary resource-fork blobs but share
5
+ * the source-file extension. When an imported workspace contains them,
6
+ * Metro's Babel parser tries to parse `._\_layout.tsx` as TypeScript and
7
+ * crashes the bundler.
8
+ *
9
+ * Used by every export path (S3 sync tar, /download tar, .shogo-project
10
+ * ZIP, agent-runtime workspace bundle) and by the post-extract scrubber so
11
+ * legacy archives already in S3 also get cleaned on import.
12
+ *
13
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT.
14
+ * The original `@shogo/shared-runtime/macos-junk` re-exports this module
15
+ * unchanged for backwards compatibility.
16
+ */
17
+ declare function isMacOSJunkName(name: string): boolean;
18
+ declare function isMacOSJunkPath(relPath: string): boolean;
19
+
20
+ export { isMacOSJunkName, isMacOSJunkPath };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Filter for macOS-specific filesystem detritus that must never round-trip
3
+ * through a project export. The motivating bug: AppleDouble sidecars
4
+ * (`._foo.ts`, `._\_layout.tsx`) are binary resource-fork blobs but share
5
+ * the source-file extension. When an imported workspace contains them,
6
+ * Metro's Babel parser tries to parse `._\_layout.tsx` as TypeScript and
7
+ * crashes the bundler.
8
+ *
9
+ * Used by every export path (S3 sync tar, /download tar, .shogo-project
10
+ * ZIP, agent-runtime workspace bundle) and by the post-extract scrubber so
11
+ * legacy archives already in S3 also get cleaned on import.
12
+ *
13
+ * Lifted into the SDK from `@shogo/shared-runtime` (was AGPL) under MIT.
14
+ * The original `@shogo/shared-runtime/macos-junk` re-exports this module
15
+ * unchanged for backwards compatibility.
16
+ */
17
+ declare function isMacOSJunkName(name: string): boolean;
18
+ declare function isMacOSJunkPath(relPath: string): boolean;
19
+
20
+ export { isMacOSJunkName, isMacOSJunkPath };
@@ -0,0 +1,9 @@
1
+ import {
2
+ isMacOSJunkName,
3
+ isMacOSJunkPath
4
+ } from "./chunk-VTD7O7YC.js";
5
+ export {
6
+ isMacOSJunkName,
7
+ isMacOSJunkPath
8
+ };
9
+ //# sourceMappingURL=macos-junk.js.map
@@ -0,0 +1,261 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/stream-buffer.ts
21
+ var stream_buffer_exports = {};
22
+ __export(stream_buffer_exports, {
23
+ StreamBufferStore: () => StreamBufferStore,
24
+ createBufferingTransform: () => createBufferingTransform
25
+ });
26
+ module.exports = __toCommonJS(stream_buffer_exports);
27
+ var CLEANUP_INTERVAL_MS = 6e4;
28
+ var MAX_BUFFER_AGE_MS = 30 * 6e4;
29
+ var COMPLETED_GRACE_MS = 3e4;
30
+ var StreamBufferStore = class {
31
+ constructor() {
32
+ this.buffers = /* @__PURE__ */ new Map();
33
+ this.cleanupTimer = null;
34
+ this.cleanupTimer = setInterval(() => this.cleanup(), CLEANUP_INTERVAL_MS);
35
+ const handle = this.cleanupTimer;
36
+ if (handle && typeof handle.unref === "function") {
37
+ handle.unref();
38
+ }
39
+ }
40
+ /**
41
+ * Create (or replace) a buffer for the given key. Any existing active
42
+ * buffer is completed and discarded. Returns a writer bound to this
43
+ * specific buffer instance, including the new `turnId`.
44
+ */
45
+ create(key, opts) {
46
+ const existing = this.buffers.get(key);
47
+ if (existing && existing.status === "active") {
48
+ this.completeBuffer(existing, "replaced");
49
+ }
50
+ const now = Date.now();
51
+ const turnId = opts?.turnId || generateTurnId();
52
+ const buf = {
53
+ turnId,
54
+ frames: [],
55
+ subscribers: /* @__PURE__ */ new Set(),
56
+ status: "active",
57
+ terminal: null,
58
+ createdAt: now,
59
+ completedAt: null,
60
+ lastEventAt: now,
61
+ nextSeq: 1
62
+ };
63
+ this.buffers.set(key, buf);
64
+ return {
65
+ get turnId() {
66
+ return buf.turnId;
67
+ },
68
+ get lastSeq() {
69
+ return buf.nextSeq - 1;
70
+ },
71
+ append: (chunk) => {
72
+ if (buf.status !== "active") return -1;
73
+ const seq = buf.nextSeq++;
74
+ buf.frames.push({ seq, chunk });
75
+ buf.lastEventAt = Date.now();
76
+ for (const ctrl of buf.subscribers) {
77
+ try {
78
+ ctrl.enqueue(chunk);
79
+ } catch {
80
+ buf.subscribers.delete(ctrl);
81
+ }
82
+ }
83
+ return seq;
84
+ },
85
+ complete: (reason) => {
86
+ this.completeBuffer(buf, reason);
87
+ },
88
+ fail: (error) => {
89
+ this.failBuffer(buf, error);
90
+ }
91
+ };
92
+ }
93
+ /**
94
+ * Append a chunk by key (loose, untyped writer). Returns the seq assigned,
95
+ * or -1 if the buffer is unknown/inactive.
96
+ */
97
+ append(key, chunk) {
98
+ const buf = this.buffers.get(key);
99
+ if (!buf || buf.status !== "active") return -1;
100
+ const seq = buf.nextSeq++;
101
+ buf.frames.push({ seq, chunk });
102
+ buf.lastEventAt = Date.now();
103
+ for (const ctrl of buf.subscribers) {
104
+ try {
105
+ ctrl.enqueue(chunk);
106
+ } catch {
107
+ buf.subscribers.delete(ctrl);
108
+ }
109
+ }
110
+ return seq;
111
+ }
112
+ /** Mark a buffer as completed by key. Optional terminal reason. */
113
+ complete(key, reason) {
114
+ const buf = this.buffers.get(key);
115
+ if (!buf) return;
116
+ this.completeBuffer(buf, reason);
117
+ }
118
+ /**
119
+ * Abort a stream: complete subscribers and remove the buffer entirely.
120
+ * Future resume/replay requests for this key will return null (→ 204).
121
+ */
122
+ abort(key) {
123
+ const buf = this.buffers.get(key);
124
+ if (!buf) return;
125
+ this.completeBuffer(buf, "aborted");
126
+ buf.status = "aborted";
127
+ this.buffers.delete(key);
128
+ }
129
+ has(key) {
130
+ return this.buffers.has(key);
131
+ }
132
+ /** Read-only metadata about a buffered turn. Useful for resume responses. */
133
+ snapshot(key) {
134
+ const buf = this.buffers.get(key);
135
+ if (!buf) return null;
136
+ return {
137
+ turnId: buf.turnId,
138
+ status: buf.status,
139
+ lastSeq: buf.nextSeq - 1,
140
+ terminal: buf.terminal,
141
+ createdAt: buf.createdAt,
142
+ completedAt: buf.completedAt,
143
+ lastEventAt: buf.lastEventAt
144
+ };
145
+ }
146
+ /**
147
+ * Create a ReadableStream that first replays all buffered chunks past
148
+ * `opts.fromSeq` (default: 0 → replay everything), then subscribes for
149
+ * any further live chunks until the stream completes.
150
+ *
151
+ * Returns null if no buffer exists for the key.
152
+ */
153
+ createReplayStream(key, opts = {}) {
154
+ const buf = this.buffers.get(key);
155
+ if (!buf) return null;
156
+ const fromSeq = Math.max(0, opts.fromSeq ?? 0);
157
+ let subscribedController = null;
158
+ return new ReadableStream({
159
+ start(controller) {
160
+ for (const frame of buf.frames) {
161
+ if (frame.seq <= fromSeq) continue;
162
+ try {
163
+ controller.enqueue(frame.chunk);
164
+ } catch {
165
+ return;
166
+ }
167
+ }
168
+ if (buf.status !== "active") {
169
+ try {
170
+ controller.close();
171
+ } catch {
172
+ }
173
+ return;
174
+ }
175
+ subscribedController = controller;
176
+ buf.subscribers.add(controller);
177
+ },
178
+ cancel() {
179
+ if (subscribedController) {
180
+ buf.subscribers.delete(subscribedController);
181
+ subscribedController = null;
182
+ }
183
+ }
184
+ });
185
+ }
186
+ cleanup() {
187
+ const now = Date.now();
188
+ for (const [key, buf] of this.buffers) {
189
+ if (buf.status !== "active" && buf.completedAt && now - buf.completedAt > COMPLETED_GRACE_MS) {
190
+ this.buffers.delete(key);
191
+ } else if (now - buf.createdAt > MAX_BUFFER_AGE_MS && buf.subscribers.size === 0) {
192
+ this.completeBuffer(buf, "expired");
193
+ this.buffers.delete(key);
194
+ }
195
+ }
196
+ }
197
+ dispose() {
198
+ if (this.cleanupTimer) {
199
+ clearInterval(this.cleanupTimer);
200
+ this.cleanupTimer = null;
201
+ }
202
+ for (const buf of this.buffers.values()) {
203
+ this.completeBuffer(buf, "disposed");
204
+ }
205
+ this.buffers.clear();
206
+ }
207
+ completeBuffer(buf, reason) {
208
+ if (buf.status !== "active") return;
209
+ buf.status = "completed";
210
+ buf.terminal = { reason };
211
+ buf.completedAt = Date.now();
212
+ buf.lastEventAt = buf.completedAt;
213
+ for (const ctrl of buf.subscribers) {
214
+ try {
215
+ ctrl.close();
216
+ } catch {
217
+ }
218
+ }
219
+ buf.subscribers.clear();
220
+ }
221
+ failBuffer(buf, error) {
222
+ if (buf.status !== "active") return;
223
+ buf.status = "failed";
224
+ buf.terminal = { error };
225
+ buf.completedAt = Date.now();
226
+ buf.lastEventAt = buf.completedAt;
227
+ for (const ctrl of buf.subscribers) {
228
+ try {
229
+ ctrl.close();
230
+ } catch {
231
+ }
232
+ }
233
+ buf.subscribers.clear();
234
+ }
235
+ };
236
+ function generateTurnId() {
237
+ try {
238
+ if (typeof globalThis.crypto?.randomUUID === "function") {
239
+ return globalThis.crypto.randomUUID();
240
+ }
241
+ } catch {
242
+ }
243
+ return `turn_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
244
+ }
245
+ function createBufferingTransform(store, key) {
246
+ return new TransformStream({
247
+ transform(chunk, controller) {
248
+ store.append(key, chunk);
249
+ controller.enqueue(chunk);
250
+ },
251
+ flush() {
252
+ store.complete(key);
253
+ }
254
+ });
255
+ }
256
+ // Annotate the CommonJS export names for ESM import in node:
257
+ 0 && (module.exports = {
258
+ StreamBufferStore,
259
+ createBufferingTransform
260
+ });
261
+ //# sourceMappingURL=stream-buffer.cjs.map