@ubean/server 0.1.13 → 0.2.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.
Files changed (56) hide show
  1. package/dist/analytics-entry.d.ts +2 -0
  2. package/dist/analytics-entry.js +2 -0
  3. package/dist/cache-C84ix1Vq.js +173 -0
  4. package/dist/cache-b-MZlyv0.d.ts +48 -0
  5. package/dist/cache-directive-C1Nekkza.js +304 -0
  6. package/dist/cache-directive-CAxJAQyE.d.ts +175 -0
  7. package/dist/cache-directive.d.ts +2 -0
  8. package/dist/cache-directive.js +2 -0
  9. package/dist/cache-entry.d.ts +3 -0
  10. package/dist/cache-entry.js +3 -0
  11. package/dist/cron-entry.d.ts +2 -0
  12. package/dist/cron-entry.js +2 -0
  13. package/dist/cron-scheduler-BF33PPn4.d.ts +77 -0
  14. package/dist/cron-scheduler-BVuXv7nn.js +258 -0
  15. package/dist/database-CfpFznl-.d.ts +67 -0
  16. package/dist/database-DNrY44SQ.js +352 -0
  17. package/dist/database.d.ts +2 -0
  18. package/dist/database.js +2 -0
  19. package/dist/email-BjfRiR9b.js +354 -0
  20. package/dist/email-BvpEuNn_.d.ts +226 -0
  21. package/dist/email.d.ts +2 -0
  22. package/dist/email.js +2 -0
  23. package/dist/feature-flags-CdLwsMD2.js +657 -0
  24. package/dist/feature-flags-DWkS6p0D.d.ts +386 -0
  25. package/dist/fetch-memo-rbkxxnW4.js +338 -0
  26. package/dist/index.d.ts +183 -488
  27. package/dist/index.js +352 -2023
  28. package/dist/middleware.d.ts +2 -0
  29. package/dist/middleware.js +3 -0
  30. package/dist/observability-Cio6Qq1H.js +339 -0
  31. package/dist/observability-DUNUEjj3.d.ts +70 -0
  32. package/dist/observability.d.ts +2 -0
  33. package/dist/observability.js +2 -0
  34. package/dist/queue-Bwzi3mhK.js +210 -0
  35. package/dist/queue-GOfTAWlz.d.ts +55 -0
  36. package/dist/queue.d.ts +2 -0
  37. package/dist/queue.js +2 -0
  38. package/dist/realtime.d.ts +2 -0
  39. package/dist/realtime.js +2 -0
  40. package/dist/security.d.ts +2 -0
  41. package/dist/security.js +2 -0
  42. package/dist/sessions-BLqFFQTL.d.ts +217 -0
  43. package/dist/sessions-BsBsyFAG.js +450 -0
  44. package/dist/single-flight-BJyhDLdU.d.ts +422 -0
  45. package/dist/single-flight-mJ4ZKbx1.js +715 -0
  46. package/dist/sse-Ct72zhic.d.ts +95 -0
  47. package/dist/sse-a6Ky9Vcl.js +310 -0
  48. package/dist/static-DPHaovQe.js +90 -0
  49. package/dist/static-K2dRvjpS.d.ts +11 -0
  50. package/dist/static.d.ts +2 -0
  51. package/dist/static.js +2 -0
  52. package/dist/storage-BZLMaqHr.js +162 -0
  53. package/dist/storage-QdlPtPtR.d.ts +48 -0
  54. package/dist/storage.d.ts +2 -0
  55. package/dist/storage.js +2 -0
  56. package/package.json +68 -6
@@ -0,0 +1,2 @@
1
+ import { A as createFetchMemoizationMiddleware, B as RateLimitOptions, C as isDraftMode, D as FetchInitWithNext, E as FetchCacheOptions, F as after, G as defineRateLimit, H as RateLimitStoreEntry, I as createAfterMiddleware, J as defineCors, K as CorsOptions, L as flushAfterCallbacks, M as getDataCacheSize, N as revalidateDataCachePath, O as clearFetchDataCache, P as revalidateDataCacheTag, R as getAfterCallbackCount, S as enableDraftMode, T as DataCacheMiddlewareOptions, U as createMemoryRateLimitStore, V as RateLimitStore, W as createRateLimitMiddleware, _ as DraftMode, a as RevalidationResult, b as defineDraftMode, c as createSingleFlightMiddleware, d as getInvalidatedKeys, f as getRevalidationEntries, g as unregisterRevalidation, h as runRevalidation, i as RevalidationKey, j as createMemoizedFetch, k as createDataCacheMiddleware, l as defineRevalidation, m as invalidateKey, n as RevalidationEntry, o as SingleFlightOptions, p as invalidate, q as createCorsMiddleware, r as RevalidationFetcher, s as clearRevalidationRegistry, t as RevalidationContext, u as defineSingleFlight, v as DraftModeOptions, w as useDraftMode, x as disableDraftMode, y as createDraftModeMiddleware, z as RateLimitInfo } from "./single-flight-BJyhDLdU.js";
2
+ export { CorsOptions, DataCacheMiddlewareOptions, DraftMode, DraftModeOptions, FetchCacheOptions, FetchInitWithNext, RateLimitInfo, RateLimitOptions, RateLimitStore, RateLimitStoreEntry, RevalidationContext, RevalidationEntry, RevalidationFetcher, RevalidationKey, RevalidationResult, SingleFlightOptions, after, clearFetchDataCache, clearRevalidationRegistry, createAfterMiddleware, createCorsMiddleware, createDataCacheMiddleware, createDraftModeMiddleware, createFetchMemoizationMiddleware, createMemoizedFetch, createMemoryRateLimitStore, createRateLimitMiddleware, createSingleFlightMiddleware, defineCors, defineDraftMode, defineRateLimit, defineRevalidation, defineSingleFlight, disableDraftMode, enableDraftMode, flushAfterCallbacks, getAfterCallbackCount, getDataCacheSize, getInvalidatedKeys, getRevalidationEntries, invalidate, invalidateKey, isDraftMode, revalidateDataCachePath, revalidateDataCacheTag, runRevalidation, unregisterRevalidation, useDraftMode };
@@ -0,0 +1,3 @@
1
+ import { C as defineRateLimit, S as createRateLimitMiddleware, T as defineCors, _ as after, a as getInvalidatedKeys, b as getAfterCallbackCount, c as invalidateKey, d as createDraftModeMiddleware, f as defineDraftMode, g as useDraftMode, h as isDraftMode, i as defineSingleFlight, l as runRevalidation, m as enableDraftMode, n as createSingleFlightMiddleware, o as getRevalidationEntries, p as disableDraftMode, r as defineRevalidation, s as invalidate, t as clearRevalidationRegistry, u as unregisterRevalidation, v as createAfterMiddleware, w as createCorsMiddleware, x as createMemoryRateLimitStore, y as flushAfterCallbacks } from "./single-flight-mJ4ZKbx1.js";
2
+ import { a as getDataCacheSize, i as createMemoizedFetch, n as createDataCacheMiddleware, o as revalidateDataCachePath, r as createFetchMemoizationMiddleware, s as revalidateDataCacheTag, t as clearFetchDataCache } from "./fetch-memo-rbkxxnW4.js";
3
+ export { after, clearFetchDataCache, clearRevalidationRegistry, createAfterMiddleware, createCorsMiddleware, createDataCacheMiddleware, createDraftModeMiddleware, createFetchMemoizationMiddleware, createMemoizedFetch, createMemoryRateLimitStore, createRateLimitMiddleware, createSingleFlightMiddleware, defineCors, defineDraftMode, defineRateLimit, defineRevalidation, defineSingleFlight, disableDraftMode, enableDraftMode, flushAfterCallbacks, getAfterCallbackCount, getDataCacheSize, getInvalidatedKeys, getRevalidationEntries, invalidate, invalidateKey, isDraftMode, revalidateDataCachePath, revalidateDataCacheTag, runRevalidation, unregisterRevalidation, useDraftMode };
@@ -0,0 +1,339 @@
1
+ import { createHooks } from "hookable";
2
+ //#region src/observability.ts
3
+ const REQUEST_ID_HEADER = "x-request-id";
4
+ function generateRequestId() {
5
+ if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
6
+ return `req_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`;
7
+ }
8
+ function getRequestId(c) {
9
+ return c.get("requestId");
10
+ }
11
+ function generateSpanId() {
12
+ if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID().replace(/-/g, "").slice(0, 16);
13
+ return Array.from({ length: 16 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
14
+ }
15
+ function generateTraceId() {
16
+ if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID().replace(/-/g, "") + crypto.randomUUID().replace(/-/g, "").slice(0, 16);
17
+ return Array.from({ length: 32 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
18
+ }
19
+ function createSpan(options) {
20
+ let ended = false;
21
+ const ctx = {
22
+ traceId: generateTraceId(),
23
+ spanId: generateSpanId()
24
+ };
25
+ if (options.parent) {
26
+ if ("context" in options.parent) {
27
+ ctx.traceId = options.parent.context.traceId;
28
+ ctx.parentSpanId = options.parent.context.spanId;
29
+ } else {
30
+ ctx.traceId = options.parent.traceId;
31
+ ctx.parentSpanId = options.parent.spanId;
32
+ }
33
+ }
34
+ const span = {
35
+ name: options.name,
36
+ context: ctx,
37
+ startTime: Date.now(),
38
+ status: "ok",
39
+ attributes: { ...options.attributes },
40
+ events: [],
41
+ parent: options.parent && "context" in options.parent ? options.parent : void 0,
42
+ end(opts) {
43
+ if (ended) return;
44
+ ended = true;
45
+ span.endTime = Date.now();
46
+ if (opts?.status) span.status = opts.status;
47
+ if (opts?.attributes) Object.assign(span.attributes, opts.attributes);
48
+ if (opts?.error) {
49
+ span.error = opts.error;
50
+ span.status = "error";
51
+ }
52
+ },
53
+ setAttribute(key, value) {
54
+ if (!ended) span.attributes[key] = value;
55
+ },
56
+ setAttributes(attrs) {
57
+ if (!ended) Object.assign(span.attributes, attrs);
58
+ },
59
+ addEvent(name, attributes) {
60
+ if (!ended) span.events.push({
61
+ name,
62
+ timestamp: Date.now(),
63
+ attributes
64
+ });
65
+ },
66
+ isRecording() {
67
+ return !ended;
68
+ },
69
+ duration() {
70
+ if (span.endTime === void 0) return void 0;
71
+ return span.endTime - span.startTime;
72
+ }
73
+ };
74
+ return span;
75
+ }
76
+ function createObservabilityTracer(config = {}) {
77
+ const hooks = createHooks();
78
+ const exporters = [...config.exporters || []];
79
+ const sensitiveKeys = new Set((config.sensitiveKeys || [
80
+ "password",
81
+ "passwd",
82
+ "secret",
83
+ "token",
84
+ "authorization",
85
+ "api_key",
86
+ "apikey",
87
+ "access_token",
88
+ "refresh_token",
89
+ "private_key",
90
+ "credit_card",
91
+ "ssn",
92
+ "auth"
93
+ ]).map((k) => k.toLowerCase()));
94
+ const enabled = config.enabled !== false;
95
+ function addExporter(exporter) {
96
+ exporters.push(exporter);
97
+ }
98
+ function removeExporter(name) {
99
+ const idx = exporters.findIndex((e) => e.name === name);
100
+ if (idx >= 0) exporters.splice(idx, 1);
101
+ }
102
+ function redactAttributes(attrs) {
103
+ const result = {};
104
+ for (const [key, value] of Object.entries(attrs)) if (sensitiveKeys.has(key.toLowerCase())) result[key] = "[REDACTED]";
105
+ else if (typeof value === "string" && value.length > 2048) result[key] = `${value.slice(0, 2048)}...[truncated]`;
106
+ else result[key] = value;
107
+ return result;
108
+ }
109
+ function startTracedSpan(options) {
110
+ if (!enabled) return createSpan(options);
111
+ const span = createSpan({
112
+ ...options,
113
+ attributes: {
114
+ ...config.defaultAttributes,
115
+ ...options.attributes
116
+ }
117
+ });
118
+ hooks.callHook("span:start", span);
119
+ const originalEnd = span.end.bind(span);
120
+ span.end = function(opts) {
121
+ if (opts?.attributes) opts.attributes = redactAttributes(opts.attributes);
122
+ span.attributes = redactAttributes(span.attributes);
123
+ originalEnd(opts);
124
+ hooks.callHook("span:end", span);
125
+ if (span.error) hooks.callHook("span:error", span, span.error);
126
+ for (const exporter of exporters) try {
127
+ exporter.exportSpan(span);
128
+ } catch {}
129
+ };
130
+ return span;
131
+ }
132
+ async function tracedWithSpan(options, fn) {
133
+ const span = startTracedSpan(typeof options === "string" ? { name: options } : options);
134
+ try {
135
+ const result = await fn(span);
136
+ span.end();
137
+ return result;
138
+ } catch (err) {
139
+ span.end({
140
+ error: err instanceof Error ? err : new Error(String(err)),
141
+ status: "error"
142
+ });
143
+ throw err;
144
+ }
145
+ }
146
+ function getActiveSpan() {}
147
+ async function flush() {
148
+ await Promise.all(exporters.map((e) => e.flush?.()));
149
+ }
150
+ async function shutdown() {
151
+ await flush();
152
+ await Promise.all(exporters.map((e) => e.shutdown?.()));
153
+ }
154
+ return {
155
+ hooks,
156
+ startSpan: startTracedSpan,
157
+ withSpan: tracedWithSpan,
158
+ getActiveSpan,
159
+ addExporter,
160
+ removeExporter,
161
+ redactAttributes,
162
+ flush,
163
+ shutdown,
164
+ createSpan
165
+ };
166
+ }
167
+ let globalTracer = null;
168
+ function setGlobalTracer(tracer) {
169
+ globalTracer = tracer;
170
+ }
171
+ function getGlobalTracer() {
172
+ if (!globalTracer) globalTracer = createObservabilityTracer();
173
+ return globalTracer;
174
+ }
175
+ function startSpan(options) {
176
+ return getGlobalTracer().startSpan(typeof options === "string" ? { name: options } : options);
177
+ }
178
+ function withSpan(options, fn) {
179
+ return getGlobalTracer().withSpan(options, fn);
180
+ }
181
+ function createOpenTelemetryExporter(options = {}) {
182
+ const url = options.url || "http://localhost:4318/v1/traces";
183
+ const headers = options.headers || {};
184
+ const serviceName = options.serviceName || "ubean-app";
185
+ const serviceVersion = options.serviceVersion || "0.0.0";
186
+ const fetchImpl = options.fetchImpl || (typeof fetch !== "undefined" ? fetch : void 0);
187
+ const batch = [];
188
+ let batchTimer = null;
189
+ const BATCH_SIZE = 512;
190
+ const FLUSH_INTERVAL = 5e3;
191
+ function spanToOTLP(span) {
192
+ const attributes = [];
193
+ for (const [k, v] of Object.entries(span.attributes)) {
194
+ if (v === void 0 || v === null) continue;
195
+ attributes.push({
196
+ key: k,
197
+ value: typeof v === "string" ? { stringValue: v } : typeof v === "number" ? { intValue: String(Math.floor(v)) } : typeof v === "boolean" ? { boolValue: v } : { stringValue: String(v) }
198
+ });
199
+ }
200
+ const events = span.events.map((e) => ({
201
+ timeUnixNano: e.timestamp * 1e6,
202
+ name: e.name,
203
+ attributes: e.attributes ? Object.entries(e.attributes).filter(([, v]) => v !== void 0 && v !== null).map(([k, v]) => ({
204
+ key: k,
205
+ value: typeof v === "string" ? { stringValue: v } : typeof v === "number" ? { intValue: String(Math.floor(v)) } : { stringValue: String(v) }
206
+ })) : []
207
+ }));
208
+ return {
209
+ traceId: span.context.traceId,
210
+ spanId: span.context.spanId,
211
+ parentSpanId: span.context.parentSpanId || "",
212
+ name: span.name,
213
+ kind: "SPAN_KIND_INTERNAL",
214
+ startTimeUnixNano: span.startTime * 1e6,
215
+ endTimeUnixNano: (span.endTime || Date.now()) * 1e6,
216
+ attributes,
217
+ events,
218
+ status: span.status === "error" ? {
219
+ code: "STATUS_CODE_ERROR",
220
+ message: span.error?.message || ""
221
+ } : { code: "STATUS_CODE_OK" },
222
+ droppedAttributesCount: 0,
223
+ droppedEventsCount: 0
224
+ };
225
+ }
226
+ async function exportBatch() {
227
+ if (batch.length === 0 || !fetchImpl) return;
228
+ const spans = batch.splice(0, BATCH_SIZE);
229
+ try {
230
+ await fetchImpl(url, {
231
+ method: "POST",
232
+ headers: {
233
+ "Content-Type": "application/json",
234
+ ...headers
235
+ },
236
+ body: JSON.stringify({ resourceSpans: [{
237
+ resource: { attributes: [{
238
+ key: "service.name",
239
+ value: { stringValue: serviceName }
240
+ }, {
241
+ key: "service.version",
242
+ value: { stringValue: serviceVersion }
243
+ }] },
244
+ scopeSpans: [{
245
+ scope: { name: "ubean" },
246
+ spans
247
+ }]
248
+ }] })
249
+ });
250
+ } catch {}
251
+ }
252
+ function scheduleFlush() {
253
+ if (batchTimer) return;
254
+ batchTimer = setTimeout(() => {
255
+ batchTimer = null;
256
+ exportBatch();
257
+ }, FLUSH_INTERVAL);
258
+ }
259
+ return {
260
+ name: "opentelemetry",
261
+ exportSpan(span) {
262
+ batch.push(spanToOTLP(span));
263
+ if (batch.length >= BATCH_SIZE) exportBatch();
264
+ else scheduleFlush();
265
+ },
266
+ async flush() {
267
+ while (batch.length > 0) await exportBatch();
268
+ },
269
+ async shutdown() {
270
+ if (batchTimer) {
271
+ clearTimeout(batchTimer);
272
+ batchTimer = null;
273
+ }
274
+ await this.flush?.();
275
+ }
276
+ };
277
+ }
278
+ function createConsoleExporter(options = {}) {
279
+ const slowThreshold = options.slowThreshold ?? 1e3;
280
+ return {
281
+ name: "console",
282
+ exportSpan(span) {
283
+ const duration = span.duration() ?? 0;
284
+ const status = span.status === "error" ? "✗" : span.status === "cancelled" ? "○" : "✓";
285
+ const slow = duration >= slowThreshold ? " (slow)" : "";
286
+ const errMsg = span.error ? ` — ${span.error.message}` : "";
287
+ if (!(typeof globalThis.console !== "undefined")) return;
288
+ const msg = `${status} [${duration}ms] ${span.name}${slow}${errMsg}`;
289
+ if (span.status === "error") console.error(msg);
290
+ else if (slow) console.warn(msg);
291
+ else console.debug(msg);
292
+ }
293
+ };
294
+ }
295
+ function createTracingMiddleware(options = {}) {
296
+ const tracer = options.tracer || getGlobalTracer();
297
+ const headerFilter = options.headerFilter || (() => false);
298
+ const includeHeaders = options.includeHeaders ?? false;
299
+ return async function tracingMiddleware(c, next) {
300
+ const method = c.req.method || "GET";
301
+ const path = c.req.path || "/";
302
+ const requestId = getRequestId(c);
303
+ const span = tracer.startSpan({
304
+ name: `${method} ${path}`,
305
+ attributes: {
306
+ "http.method": method,
307
+ "http.url": path,
308
+ "http.request_id": requestId
309
+ }
310
+ });
311
+ c.set("span", span);
312
+ if (includeHeaders) {
313
+ const headers = {};
314
+ for (const [k, v] of Object.entries(c.req.header?.() || {})) if (!headerFilter(k)) headers[k] = v;
315
+ span.setAttributes(tracer.redactAttributes(headers));
316
+ }
317
+ const start = Date.now();
318
+ try {
319
+ await next();
320
+ const statusCode = c.res?.status || 200;
321
+ span.setAttribute("http.status_code", statusCode);
322
+ if (statusCode >= 500) span.end({ status: "error" });
323
+ else span.end({ status: statusCode >= 400 ? "error" : "ok" });
324
+ } catch (err) {
325
+ const duration = Date.now() - start;
326
+ span.setAttribute("error.duration_ms", duration);
327
+ span.end({
328
+ error: err instanceof Error ? err : new Error(String(err)),
329
+ status: "error"
330
+ });
331
+ throw err;
332
+ }
333
+ };
334
+ }
335
+ function getSpan(c) {
336
+ return c.get("span");
337
+ }
338
+ //#endregion
339
+ export { createSpan as a, getGlobalTracer as c, setGlobalTracer as d, startSpan as f, createOpenTelemetryExporter as i, getRequestId as l, createConsoleExporter as n, createTracingMiddleware as o, withSpan as p, createObservabilityTracer as r, generateRequestId as s, REQUEST_ID_HEADER as t, getSpan as u };
@@ -0,0 +1,70 @@
1
+ import { Hookable } from "hookable";
2
+ import { Span, Span as Span$1, SpanAttributes, SpanAttributes as SpanAttributes$1, SpanContext, SpanEndOptions, SpanEvent, SpanOptions, SpanOptions as SpanOptions$1, SpanStatus } from "@ubean/shared";
3
+ //#region src/observability.d.ts
4
+ declare const REQUEST_ID_HEADER = "x-request-id";
5
+ interface RequestIdOptions {
6
+ headerName?: string;
7
+ limitLength?: number;
8
+ generator?: (c: any) => string;
9
+ }
10
+ declare function generateRequestId(): string;
11
+ declare function getRequestId(c: {
12
+ get: (key: 'requestId') => string;
13
+ }): string;
14
+ interface ObservabilityHooks {
15
+ 'span:start': (span: Span) => void | Promise<void>;
16
+ 'span:end': (span: Span) => void | Promise<void>;
17
+ 'span:error': (span: Span, error: Error) => void | Promise<void>;
18
+ }
19
+ interface ObservabilityExporter {
20
+ name: string;
21
+ exportSpan(span: Readonly<Span>): void | Promise<void>;
22
+ flush?(): Promise<void>;
23
+ shutdown?(): Promise<void>;
24
+ }
25
+ interface ObservabilityConfig {
26
+ defaultAttributes?: SpanAttributes;
27
+ sensitiveKeys?: string[];
28
+ exporters?: ObservabilityExporter[];
29
+ enabled?: boolean;
30
+ }
31
+ declare function createSpan(options: SpanOptions): Span;
32
+ declare function createObservabilityTracer(config?: ObservabilityConfig): {
33
+ hooks: Hookable<ObservabilityHooks, import("hookable").HookKeys<ObservabilityHooks>>;
34
+ startSpan: (options: SpanOptions) => Span;
35
+ withSpan: <T>(options: SpanOptions | string, fn: (span: Span) => T | Promise<T>) => Promise<T>;
36
+ getActiveSpan: () => Span | undefined;
37
+ addExporter: (exporter: ObservabilityExporter) => void;
38
+ removeExporter: (name: string) => void;
39
+ redactAttributes: (attrs: SpanAttributes) => SpanAttributes;
40
+ flush: () => Promise<void>;
41
+ shutdown: () => Promise<void>;
42
+ createSpan: typeof createSpan;
43
+ };
44
+ type ObservabilityTracer = ReturnType<typeof createObservabilityTracer>;
45
+ declare function setGlobalTracer(tracer: ObservabilityTracer | null): void;
46
+ declare function getGlobalTracer(): ObservabilityTracer;
47
+ declare function startSpan(options: SpanOptions | string): Span;
48
+ declare function withSpan<T>(options: SpanOptions | string, fn: (span: Span) => T | Promise<T>): Promise<T>;
49
+ declare function createOpenTelemetryExporter(options?: {
50
+ url?: string;
51
+ headers?: Record<string, string>;
52
+ serviceName?: string;
53
+ serviceVersion?: string;
54
+ fetchImpl?: typeof fetch;
55
+ }): ObservabilityExporter;
56
+ declare function createConsoleExporter(options?: {
57
+ colors?: boolean;
58
+ slowThreshold?: number;
59
+ }): ObservabilityExporter;
60
+ interface TracingMiddlewareOptions {
61
+ tracer?: ObservabilityTracer;
62
+ includeHeaders?: boolean;
63
+ headerFilter?: (name: string) => boolean;
64
+ }
65
+ declare function createTracingMiddleware(options?: TracingMiddlewareOptions): (c: any, next: any) => Promise<void>;
66
+ declare function getSpan(c: {
67
+ get: (key: string) => unknown;
68
+ }): Span | undefined;
69
+ //#endregion
70
+ export { getSpan as C, withSpan as E, getRequestId as S, startSpan as T, createOpenTelemetryExporter as _, REQUEST_ID_HEADER as a, generateRequestId as b, SpanAttributes$1 as c, SpanEvent as d, SpanOptions$1 as f, createObservabilityTracer as g, createConsoleExporter as h, ObservabilityTracer as i, SpanContext as l, TracingMiddlewareOptions as m, ObservabilityExporter as n, RequestIdOptions as o, SpanStatus as p, ObservabilityHooks as r, Span$1 as s, ObservabilityConfig as t, SpanEndOptions as u, createSpan as v, setGlobalTracer as w, getGlobalTracer as x, createTracingMiddleware as y };
@@ -0,0 +1,2 @@
1
+ import { C as getSpan, E as withSpan, S as getRequestId, T as startSpan, _ as createOpenTelemetryExporter, a as REQUEST_ID_HEADER, b as generateRequestId, c as SpanAttributes, d as SpanEvent, f as SpanOptions, g as createObservabilityTracer, h as createConsoleExporter, i as ObservabilityTracer, l as SpanContext, m as TracingMiddlewareOptions, n as ObservabilityExporter, o as RequestIdOptions, p as SpanStatus, r as ObservabilityHooks, s as Span, t as ObservabilityConfig, u as SpanEndOptions, v as createSpan, w as setGlobalTracer, x as getGlobalTracer, y as createTracingMiddleware } from "./observability-DUNUEjj3.js";
2
+ export { ObservabilityConfig, ObservabilityExporter, ObservabilityHooks, ObservabilityTracer, REQUEST_ID_HEADER, RequestIdOptions, type Span, type SpanAttributes, type SpanContext, type SpanEndOptions, type SpanEvent, type SpanOptions, type SpanStatus, TracingMiddlewareOptions, createConsoleExporter, createObservabilityTracer, createOpenTelemetryExporter, createSpan, createTracingMiddleware, generateRequestId, getGlobalTracer, getRequestId, getSpan, setGlobalTracer, startSpan, withSpan };
@@ -0,0 +1,2 @@
1
+ import { a as createSpan, c as getGlobalTracer, d as setGlobalTracer, f as startSpan, i as createOpenTelemetryExporter, l as getRequestId, n as createConsoleExporter, o as createTracingMiddleware, p as withSpan, r as createObservabilityTracer, s as generateRequestId, t as REQUEST_ID_HEADER, u as getSpan } from "./observability-Cio6Qq1H.js";
2
+ export { REQUEST_ID_HEADER, createConsoleExporter, createObservabilityTracer, createOpenTelemetryExporter, createSpan, createTracingMiddleware, generateRequestId, getGlobalTracer, getRequestId, getSpan, setGlobalTracer, startSpan, withSpan };
@@ -0,0 +1,210 @@
1
+ //#region src/queue.ts
2
+ const queueDefinitions = /* @__PURE__ */ new Map();
3
+ let globalDriver = null;
4
+ const inMemoryQueues = /* @__PURE__ */ new Map();
5
+ function generateId() {
6
+ if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
7
+ return `msg_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
8
+ }
9
+ function defineQueue(options, handler) {
10
+ if (!options.name) throw new Error("[ubean] Queue must have a name");
11
+ const finalHandler = handler || options.handler;
12
+ if (!finalHandler) throw new Error(`[ubean] Queue "${options.name}" must have a handler`);
13
+ const def = {
14
+ name: options.name,
15
+ handler: finalHandler,
16
+ concurrency: options.concurrency ?? 5,
17
+ retries: options.retries ?? 3,
18
+ retryDelay: options.retryDelay ?? 1e3,
19
+ deadLetterQueue: options.deadLetterQueue
20
+ };
21
+ queueDefinitions.set(options.name, def);
22
+ const untypedDef = def;
23
+ if (globalDriver?.registerHandler) globalDriver.registerHandler(options.name, finalHandler, untypedDef);
24
+ ensureInMemoryQueue(options.name, untypedDef);
25
+ return def;
26
+ }
27
+ function ensureInMemoryQueue(name, options) {
28
+ if (!inMemoryQueues.has(name)) inMemoryQueues.set(name, {
29
+ messages: [],
30
+ processing: /* @__PURE__ */ new Set(),
31
+ stats: {
32
+ pending: 0,
33
+ processing: 0,
34
+ completed: 0,
35
+ failed: 0
36
+ },
37
+ options: {
38
+ name,
39
+ ...options
40
+ }
41
+ });
42
+ return inMemoryQueues.get(name);
43
+ }
44
+ function createMemoryQueueDriver() {
45
+ let running = false;
46
+ let processTimer = null;
47
+ async function processQueue(name) {
48
+ const queue = inMemoryQueues.get(name);
49
+ if (!queue) return;
50
+ const def = queueDefinitions.get(name);
51
+ const concurrency = def?.concurrency ?? 5;
52
+ const retries = def?.retries ?? 3;
53
+ const retryDelay = def?.retryDelay ?? 1e3;
54
+ while (queue.processing.size < concurrency && queue.messages.length > 0) {
55
+ const msg = queue.messages.shift();
56
+ if (!msg) break;
57
+ queue.processing.add(msg.id);
58
+ queue.stats.processing++;
59
+ queue.stats.pending--;
60
+ processMessage(name, msg).catch(() => {});
61
+ }
62
+ async function processMessage(queueName, message) {
63
+ const q = inMemoryQueues.get(queueName);
64
+ if (!q) return;
65
+ const handler = queueDefinitions.get(queueName)?.handler;
66
+ if (!handler) {
67
+ q.processing.delete(message.id);
68
+ q.stats.processing--;
69
+ return;
70
+ }
71
+ try {
72
+ await handler(message);
73
+ q.processing.delete(message.id);
74
+ q.stats.processing--;
75
+ q.stats.completed++;
76
+ } catch (err) {
77
+ q.processing.delete(message.id);
78
+ q.stats.processing--;
79
+ message.attempts++;
80
+ if (message.attempts >= retries) {
81
+ q.stats.failed++;
82
+ const dlq = def?.deadLetterQueue;
83
+ if (dlq) await driver.send(dlq, message.body, { headers: { "x-error": err instanceof Error ? err.message : String(err) } });
84
+ } else {
85
+ await new Promise((resolve) => setTimeout(resolve, retryDelay * message.attempts));
86
+ q.messages.unshift(message);
87
+ q.stats.pending++;
88
+ }
89
+ }
90
+ }
91
+ }
92
+ const driver = {
93
+ async send(queueName, body, options = {}) {
94
+ const queue = ensureInMemoryQueue(queueName);
95
+ const id = generateId();
96
+ const message = {
97
+ id,
98
+ body,
99
+ timestamp: Date.now(),
100
+ attempts: 0,
101
+ headers: options.headers
102
+ };
103
+ if (options.delay && options.delay > 0) setTimeout(() => {
104
+ queue.messages.push(message);
105
+ queue.stats.pending++;
106
+ if (running) processQueue(queueName);
107
+ }, options.delay);
108
+ else {
109
+ queue.messages.push(message);
110
+ queue.stats.pending++;
111
+ if (running) processQueue(queueName);
112
+ }
113
+ return id;
114
+ },
115
+ async sendBatch(queueName, bodies, options = {}) {
116
+ const ids = [];
117
+ for (const body of bodies) {
118
+ const id = await this.send(queueName, body, options);
119
+ ids.push(id);
120
+ }
121
+ return ids;
122
+ },
123
+ registerHandler(queueName, handler, options) {
124
+ const queue = ensureInMemoryQueue(queueName, options);
125
+ queue.handler = handler;
126
+ },
127
+ async start() {
128
+ if (running) return;
129
+ running = true;
130
+ for (const [name, def] of queueDefinitions) {
131
+ const queue = ensureInMemoryQueue(name, def);
132
+ queue.handler = def.handler;
133
+ }
134
+ processTimer = setInterval(() => {
135
+ for (const name of inMemoryQueues.keys()) processQueue(name);
136
+ }, 100);
137
+ for (const name of inMemoryQueues.keys()) processQueue(name);
138
+ },
139
+ async stop() {
140
+ running = false;
141
+ if (processTimer) {
142
+ clearInterval(processTimer);
143
+ processTimer = null;
144
+ }
145
+ },
146
+ async getQueueDepth(queueName) {
147
+ const queue = inMemoryQueues.get(queueName);
148
+ if (!queue) return 0;
149
+ return queue.messages.length;
150
+ },
151
+ async deleteMessage(queueName, messageId) {
152
+ const queue = inMemoryQueues.get(queueName);
153
+ if (!queue) return false;
154
+ const idx = queue.messages.findIndex((m) => m.id === messageId);
155
+ if (idx >= 0) {
156
+ queue.messages.splice(idx, 1);
157
+ queue.stats.pending--;
158
+ return true;
159
+ }
160
+ if (queue.processing.has(messageId)) {
161
+ queue.processing.delete(messageId);
162
+ queue.stats.processing--;
163
+ return true;
164
+ }
165
+ return false;
166
+ }
167
+ };
168
+ return driver;
169
+ }
170
+ function useQueueDriver() {
171
+ if (!globalDriver) globalDriver = createMemoryQueueDriver();
172
+ return globalDriver;
173
+ }
174
+ function setQueueDriver(driver) {
175
+ globalDriver = driver;
176
+ for (const [name, def] of queueDefinitions) if (driver.registerHandler) driver.registerHandler(name, def.handler, def);
177
+ }
178
+ async function sendMessage(queueName, body, options) {
179
+ return useQueueDriver().send(queueName, body, options);
180
+ }
181
+ async function sendMessages(queueName, bodies, options) {
182
+ return useQueueDriver().sendBatch(queueName, bodies, options);
183
+ }
184
+ function getQueueDefinitions() {
185
+ return Array.from(queueDefinitions.values());
186
+ }
187
+ function clearQueueDefinitions() {
188
+ queueDefinitions.clear();
189
+ inMemoryQueues.clear();
190
+ }
191
+ async function startQueueWorkers() {
192
+ const driver = useQueueDriver();
193
+ if (driver.start) await driver.start();
194
+ }
195
+ async function stopQueueWorkers() {
196
+ const driver = useQueueDriver();
197
+ if (driver.stop) await driver.stop();
198
+ }
199
+ function getQueueStats(queueName) {
200
+ const queue = inMemoryQueues.get(queueName);
201
+ if (!queue) return void 0;
202
+ return { ...queue.stats };
203
+ }
204
+ function getAllQueueStats() {
205
+ const result = {};
206
+ for (const [name, queue] of inMemoryQueues) result[name] = { ...queue.stats };
207
+ return result;
208
+ }
209
+ //#endregion
210
+ export { getQueueDefinitions as a, sendMessages as c, stopQueueWorkers as d, useQueueDriver as f, getAllQueueStats as i, setQueueDriver as l, createMemoryQueueDriver as n, getQueueStats as o, defineQueue as r, sendMessage as s, clearQueueDefinitions as t, startQueueWorkers as u };