@sailfish-ai/sf-veritas 0.3.2 → 0.4.0

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 (36) hide show
  1. package/dist/{contextManager-CZy0w11U.js → contextManager-C2ONL8XY.js} +43 -37
  2. package/dist/contextManager-CL0Qs7uI.cjs +1 -0
  3. package/dist/plugins/funcspanEsbuildPlugin.cjs +1 -1
  4. package/dist/plugins/funcspanEsbuildPlugin.mjs +1 -1
  5. package/dist/plugins/funcspanRollupPlugin.cjs +1 -1
  6. package/dist/plugins/funcspanRollupPlugin.mjs +1 -1
  7. package/dist/plugins/funcspanTscPlugin.cjs +1 -1
  8. package/dist/plugins/funcspanTscPlugin.mjs +1 -1
  9. package/dist/plugins/funcspanVitePlugin.cjs +1 -1
  10. package/dist/plugins/funcspanVitePlugin.mjs +1 -1
  11. package/dist/plugins/funcspanWebpackPlugin.cjs +1 -1
  12. package/dist/plugins/funcspanWebpackPlugin.mjs +1 -1
  13. package/dist/{runtimeConfig-ButdW4zP.js → runtimeConfig-BUJ13zxm.js} +1 -1
  14. package/dist/{runtimeConfig-C4_zc4Zg.cjs → runtimeConfig-xahsyRmN.cjs} +1 -1
  15. package/dist/sf-veritas.cjs +13 -13
  16. package/dist/sf-veritas.mjs +1643 -606
  17. package/dist/types/constants.d.ts +6 -0
  18. package/dist/types/contextManager.d.ts +15 -0
  19. package/dist/types/index.d.ts +2 -0
  20. package/dist/types/patches/asyncQueues/_stubs/bee-queue.d.ts +10 -0
  21. package/dist/types/patches/asyncQueues/_stubs/rabbitmq.d.ts +11 -0
  22. package/dist/types/patches/asyncQueues/_stubs/sqs.d.ts +9 -0
  23. package/dist/types/patches/asyncQueues/asyncQueueTracer.d.ts +127 -0
  24. package/dist/types/patches/asyncQueues/asyncQueues.bench.d.ts +1 -0
  25. package/dist/types/patches/asyncQueues/bullmq.d.ts +27 -0
  26. package/dist/types/patches/asyncQueues/bullmqPro.d.ts +3 -0
  27. package/dist/types/patches/asyncQueues/confluentKafkaJs.d.ts +3 -0
  28. package/dist/types/patches/asyncQueues/index.d.ts +15 -0
  29. package/dist/types/patches/asyncQueues/kafkajs.d.ts +7 -0
  30. package/dist/types/setupConfig.d.ts +1 -0
  31. package/dist/worker-pool-capture.cjs +1 -1
  32. package/dist/worker-pool-capture.mjs +1 -1
  33. package/dist/{workerPoolSpanCapture-BUFN_RMW.cjs → workerPoolSpanCapture-C3T98kWy.cjs} +1 -1
  34. package/dist/{workerPoolSpanCapture-BomWTMM2.js → workerPoolSpanCapture-DL8wfDIr.js} +1 -1
  35. package/package.json +2 -1
  36. package/dist/contextManager-qXvO_a5y.cjs +0 -1
@@ -3,6 +3,12 @@
3
3
  * for a request (e.g., during stack trace or debugging).
4
4
  */
5
5
  export declare const TRACE_HEADER = "x-sf3-rid";
6
+ /**
7
+ * Canonical header / metadata key for Sailfish trace propagation across any
8
+ * transport (HTTP, Kafka headers, Celery headers dict, BullMQ opts, etc).
9
+ * Use this constant everywhere a trace ID is written or read.
10
+ */
11
+ export declare const HEADER_TRACING = "X-Sf3-Rid";
6
12
  /**
7
13
  * Outbound parent-trace header (mirrors Python's PARENT_SESSION_ID_HEADER).
8
14
  * Carries the FULL inbound trace id (3 segments) so server-side code can
@@ -1,6 +1,7 @@
1
1
  import { AsyncLocalStorage } from "async_hooks";
2
2
  type Store = Map<string, unknown>;
3
3
  export declare const context: AsyncLocalStorage<Store>;
4
+ export declare const NONSESSION_APPLOGS = "nonsession-applogs";
4
5
  export declare const DEFAULT_DOMAINS_TO_EXCLUDE: readonly ["identitytoolkit.googleapis.com", "t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com"];
5
6
  type Context = {
6
7
  traceId?: string;
@@ -37,6 +38,20 @@ export declare class ContextManager {
37
38
  runWithSession<T>(sessionId: string, fn: () => T): T;
38
39
  /** Optional: clean up session context to avoid leaks in long-lived processes */
39
40
  deleteSession(sessionId: string): void;
41
+ /**
42
+ * Run `fn` inside a new AsyncLocalStorage scope whose Context is a shallow
43
+ * merge of the current context and `overrides`. Used by queue-consumer
44
+ * wrappers so each message's handler has its own trace without leaking into
45
+ * sibling iterations.
46
+ *
47
+ * H1: Context holds `Set` fields (`handledExceptions`, `excludedDomains`,
48
+ * `supportedDomains`). A naïve shallow merge would propagate the SAME Set
49
+ * reference from parent to child — child mutations would write into the
50
+ * parent's Set, leaking state across consumer-message scopes and growing
51
+ * unbounded. Clone the Sets when entering a new scope so each child gets
52
+ * its own copy.
53
+ */
54
+ runScoped<T>(overrides: Partial<Context>, fn: () => T): T;
40
55
  getTraceId(): string | undefined;
41
56
  getPageVisitUUID(): string | undefined;
42
57
  setTraceId(traceId: string): void;
@@ -7,3 +7,5 @@ export { transformFunctionSpans, transformFunctionSpansSync, setSkipTypeScriptPl
7
7
  export { shouldEnableRuntimeHooks, isRuntimeModeEnabled, isProductionEnvironment } from "./runtime/runtimeConfig";
8
8
  export { isAlreadyInstrumented } from "./runtime/instrumentationDetector";
9
9
  export { initializeWorkerPoolPatching, isInitialized as isWorkerPoolInitialized } from "./patches/workerPool/index";
10
+ export { uninstallAsyncQueuePatches, isAsyncQueuePatchesInstalled, } from "./patches/asyncQueues/index";
11
+ export { _setAsyncQueueHopSpy } from "./patches/asyncQueues/asyncQueueTracer";
@@ -0,0 +1,10 @@
1
+ /**
2
+ * TODO(queue-tracing): bee-queue async-queue tracing patch.
3
+ *
4
+ * Placeholder. bee-queue is a lightweight Redis-backed queue similar to
5
+ * BullMQ but with a different API. Store the trace in `job.data._sf` or on
6
+ * a custom options field — see bullmq.ts for the pattern.
7
+ *
8
+ * See veritas/jsts-backend/CONTRIBUTING_QUEUES.md.
9
+ */
10
+ export declare function patchBeeQueue(): "not-installed";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * TODO(queue-tracing): RabbitMQ (amqplib) async-queue tracing patch.
3
+ *
4
+ * This is a placeholder. RabbitMQ messages have a `properties.headers` dict
5
+ * (amqplib) — the trace ID can go there. See the existing kafkajs.ts patch
6
+ * for the injection pattern.
7
+ *
8
+ * See veritas/jsts-backend/CONTRIBUTING_QUEUES.md for the step-by-step
9
+ * contributor guide on implementing this.
10
+ */
11
+ export declare function patchRabbitMQ(): "not-installed";
@@ -0,0 +1,9 @@
1
+ /**
2
+ * TODO(queue-tracing): AWS SQS (@aws-sdk/client-sqs) async-queue tracing patch.
3
+ *
4
+ * Placeholder. SQS `SendMessageCommand` input has a `MessageAttributes` dict
5
+ * — inject the trace ID there; the consumer reads it via `ReceiveMessage`.
6
+ *
7
+ * See veritas/jsts-backend/CONTRIBUTING_QUEUES.md.
8
+ */
9
+ export declare function patchSQS(): "not-installed";
@@ -0,0 +1,127 @@
1
+ import { NetworkHopTransmitter } from "../../networkHopTransmitter";
2
+ import { NetworkRequestData, NetworkRequestTransmitter } from "../../networkRequestTransmitter";
3
+ export declare const QUEUE_TRACE_HEADER = "X-Sf3-Rid";
4
+ /**
5
+ * Case-insensitive lookup of the Sailfish trace header (X-Sf3-Rid) in a
6
+ * headers object or array-of-{key,value} entries. Proxies (HAProxy, envoy,
7
+ * nginx) and some Kafka clients may normalize header case.
8
+ */
9
+ export declare function findSailfishTraceHeaderValue(headers: unknown): unknown;
10
+ export interface QueueProducerContext {
11
+ /** Short library identifier, e.g. 'bullmq', 'kafkajs'. */
12
+ library: string;
13
+ /** Synthetic URI describing the destination, e.g. 'kafka://broker/topic'. */
14
+ queueUri: string;
15
+ /** The user-supplied message payload (used for body capture). */
16
+ messagePayload?: unknown;
17
+ /**
18
+ * HTTP-method-style label on the emitted hop. Defaults to ``ENQUEUE``.
19
+ * Useful overrides: ``ENQUEUE_TX`` for Kafka transactional producers so
20
+ * the UI can visually distinguish "pending until commit" from normal
21
+ * enqueue.
22
+ */
23
+ method?: string;
24
+ }
25
+ export interface QueueConsumerContext {
26
+ library: string;
27
+ queueUri: string;
28
+ messagePayload?: unknown;
29
+ /** Override the emitted hop method. Defaults to ``CONSUME``. Used by
30
+ * BullMQ stalled-recovery path to tag ``CONSUME_STALLED``. */
31
+ method?: string;
32
+ /** Trace ID extracted from the incoming message header (if present). */
33
+ incomingTraceId?: string;
34
+ }
35
+ export interface ProducerHandle {
36
+ /** Trace ID with the third UUID freshly rotated. Inject this into the message. */
37
+ readonly traceId: string;
38
+ /** Call when the enqueue call settles (success or error). */
39
+ hopEnd: (err?: Error | null) => void;
40
+ }
41
+ declare function getNetworkRequestTransmitter(): NetworkRequestTransmitter;
42
+ declare function getNetworkHopTransmitter(): NetworkHopTransmitter;
43
+ export declare function isValidTraceShape(trace: unknown): trace is string;
44
+ /**
45
+ * Rotate only the last segment (requestId) of a Sailfish trace triplet while
46
+ * preserving session + pageVisit. Exported so per-library consumer patches can
47
+ * rotate on retry/redelivery without emitting a producer hop.
48
+ */
49
+ export declare function rotateTraceRequestId(trace: string): string;
50
+ /**
51
+ * Begin a producer span. Rotates the third UUID of the current trace, returns
52
+ * the new trace + a `hopEnd` callback.
53
+ *
54
+ * W1: snapshot the body string AT call time (rather than at `hopEnd` time) and
55
+ * extract every other ctx field we'll need into local variables before
56
+ * returning. The `hopEnd` closure must NOT close over `ctx`, otherwise
57
+ * `ctx.messagePayload` (potentially MB-sized) stays pinned in heap for the
58
+ * entire in-flight window of the user's `producer.send()`. Under producer
59
+ * backpressure (slow brokers, high concurrency) this multiplies memory
60
+ * residency by the number of in-flight enqueues.
61
+ */
62
+ export declare function beginProducer(ctx: QueueProducerContext): ProducerHandle;
63
+ /**
64
+ * Wrap a consumer's handler so:
65
+ * 1. The handler runs inside a scoped AsyncLocalStorage context seeded with
66
+ * the incoming trace ID (so child work sees it).
67
+ * 2. An inbound NetworkRequest span is emitted whose duration spans the
68
+ * entire handler execution (success or error).
69
+ */
70
+ export declare function wrapConsumerHandler<T>(ctx: QueueConsumerContext, handler: () => Promise<T> | T): Promise<T>;
71
+ export { getNetworkHopTransmitter, getNetworkRequestTransmitter };
72
+ /**
73
+ * W8: install a patched function onto a target prototype, returning whether
74
+ * the assignment succeeded. Customers who freeze library prototypes (security
75
+ * hardening, `Object.freeze(Queue.prototype)`) or other SDKs that install
76
+ * non-configurable properties on the same key would otherwise cause our
77
+ * assignment to throw TypeError in strict mode, aborting the entire installer
78
+ * mid-loop. We swallow the failure (logged under sfDebug) and let the rest
79
+ * of the patches in the same module continue.
80
+ */
81
+ /**
82
+ * Optional debug/QA hook: every hop the SDK is about to transmit is also
83
+ * passed to a spy callback (if registered) BEFORE the transmitter runs.
84
+ * Used by the QA test app to stream hop events to a browser UI in real time.
85
+ * Zero cost when no spy is registered.
86
+ *
87
+ * @internal — exposed publicly for QA tooling only. Not part of the
88
+ * stable customer-facing API.
89
+ */
90
+ type HopSpy = (data: NetworkRequestData) => void;
91
+ export declare function _setAsyncQueueHopSpy(spy: HopSpy | null): void;
92
+ /**
93
+ * E3: use globally-keyed Symbols instead of string property names for our
94
+ * "this function/object has already been instrumented" markers. Other
95
+ * observability SDKs that happen to also use the string `__sfPatched`
96
+ * would otherwise see our marker on a function they wrapped and skip
97
+ * their own instrumentation, silently breaking their tracing. Symbols
98
+ * registered with the same key collide only across vendors that
99
+ * deliberately pick the same registry key.
100
+ */
101
+ export declare const SF_PATCHED: unique symbol;
102
+ export declare const SF_INSTANCE_WRAPPED: unique symbol;
103
+ export declare function safeInstallPrototypeMethod(proto: any, key: string, patched: Function): boolean;
104
+ /**
105
+ * W3: revert every prototype patch we've installed. Best-effort —
106
+ * individual restorations that throw (frozen prototype, non-configurable
107
+ * descriptor) are skipped. Returns the number of methods restored.
108
+ *
109
+ * After uninstall, `installAsyncQueuePatches()` may be called again to
110
+ * re-install. Customers should treat this as an emergency revert: if the
111
+ * SDK is responsible for an incident, uninstall in-process and redeploy
112
+ * later with `SF_DISABLE_QUEUE_PATCHES=true`.
113
+ */
114
+ export declare function uninstallAllPrototypePatches(): number;
115
+ /**
116
+ * A1: run an instrumentation rewrite (compute a new args object, allocate
117
+ * tracking handles, etc.) and never let an exception in our code escape into
118
+ * the customer's call path. Returns the rewrite result on success, or
119
+ * `null` on failure (caller falls back to the user's original args, no
120
+ * hop emitted).
121
+ *
122
+ * Customer payloads can carry exotic shapes — Proxies with throwing traps,
123
+ * objects with throw-on-access getters, non-stringifiable Symbol keys —
124
+ * that make `{...x}` / `Buffer.from(x)` / `JSON.stringify(x)` throw. Our
125
+ * telemetry must absorb those failures, not propagate them.
126
+ */
127
+ export declare function tryInstrumentationRewrite<T>(rewrite: () => T, context: string): T | null;
@@ -0,0 +1,27 @@
1
+ /** Shape we mutate. We don't depend on BullMQ's types to avoid a hard dep. */
2
+ interface MutableJobOpts {
3
+ sf?: {
4
+ rid?: string;
5
+ };
6
+ [key: string]: unknown;
7
+ }
8
+ /**
9
+ * F9: queue-URI builder. For jobs we prefer (in order):
10
+ * 1. ``job.queueQualifiedName`` — BullMQ's prefix-aware canonical name
11
+ * (e.g. ``bull:my-queue``). Present on Worker side.
12
+ * 2. ``job.queueName`` — plain queue name.
13
+ * 3. ``worker.name`` or ``queue.name`` — fallback for edge cases.
14
+ *
15
+ * Callers pass whichever of these they have. We strip BullMQ's ``bull:``
16
+ * prefix if present since our URI already has a scheme.
17
+ */
18
+ export declare function buildQueueUri(queueName: string | undefined, jobName: string | undefined): string;
19
+ /**
20
+ * Pick the best-available queue-name field from a Job or Worker-like
21
+ * object. Prefers qualified (prefix-aware) names.
22
+ */
23
+ export declare function pickQueueNameFromJob(job: any): string | undefined;
24
+ export declare function injectTraceIntoOpts(opts: MutableJobOpts | undefined, traceId: string): MutableJobOpts;
25
+ type PatchInstallResult = "installed" | "not-installed" | "failed";
26
+ export declare function patchBullmq(injectedBullmq?: unknown): PatchInstallResult;
27
+ export {};
@@ -0,0 +1,3 @@
1
+ type PatchInstallResult = "installed" | "not-installed" | "failed";
2
+ export declare function patchBullmqPro(injectedModule?: unknown): PatchInstallResult;
3
+ export {};
@@ -0,0 +1,3 @@
1
+ type PatchInstallResult = "installed" | "not-installed" | "failed";
2
+ export declare function patchConfluentKafkaJs(injectedModule?: unknown): PatchInstallResult;
3
+ export {};
@@ -0,0 +1,15 @@
1
+ type PatchResult = "installed" | "not-installed" | "failed";
2
+ type PatchInstaller = () => PatchResult;
3
+ export declare function installAsyncQueuePatches(): void;
4
+ export declare function isAsyncQueuePatchesInstalled(): boolean;
5
+ /**
6
+ * W3: revert every async-queue prototype patch we've installed. Customers
7
+ * use this as an emergency revert when the SDK is implicated in an
8
+ * incident — restores library prototypes in-place and resets the
9
+ * `installed` guard so a later `installAsyncQueuePatches()` would
10
+ * install fresh. Returns the number of methods restored.
11
+ */
12
+ export declare function uninstallAsyncQueuePatches(): number;
13
+ /** Internal — used by subsequent subtasks to register their patch. */
14
+ export declare function _registerAsyncQueuePatch(name: string, install: PatchInstaller, envDisableKey?: string): void;
15
+ export * from "./asyncQueueTracer";
@@ -0,0 +1,7 @@
1
+ type PatchInstallResult = "installed" | "not-installed" | "failed";
2
+ /**
3
+ * @param injectedKafkajs test hook — passes a kafkajs-shaped module so the
4
+ * vitest specs can avoid CJS require interop issues.
5
+ */
6
+ export declare function patchKafkajs(injectedKafkajs?: unknown): PatchInstallResult;
7
+ export {};
@@ -156,6 +156,7 @@ declare class AppConfig {
156
156
  captureResponseBody: boolean;
157
157
  requestBodyLimitBytes: number;
158
158
  responseBodyLimitBytes: number;
159
+ bullmqBulkAggregateMode: boolean;
159
160
  retryOnClientError: "all" | "idempotent" | "none";
160
161
  private _serviceIdentificationReceived;
161
162
  constructor(options: SetupOptions);
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./workerPoolSpanCapture-BUFN_RMW.cjs");exports.captureWorkerPoolOperation=e.captureWorkerPoolOperation;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./workerPoolSpanCapture-C3T98kWy.cjs");exports.captureWorkerPoolOperation=e.captureWorkerPoolOperation;
@@ -1,4 +1,4 @@
1
- import { c as e } from "./workerPoolSpanCapture-BomWTMM2.js";
1
+ import { c as e } from "./workerPoolSpanCapture-DL8wfDIr.js";
2
2
  export {
3
3
  e as captureWorkerPoolOperation
4
4
  };
@@ -1,4 +1,4 @@
1
- "use strict";const j=require("async_hooks"),Q=require("fs"),$=require("worker_threads"),l=require("./contextManager-qXvO_a5y.cjs"),z=require("path"),X=require("url");class G{apiKey;endpoint;queryType="mutation";operationName="";serviceUUID=l.getConfig().serviceUUID;contextManager;constructor(){this.apiKey=l.getConfig().apiKey,this.endpoint=l.getConfig().apiGraphqlEndpoint,this.contextManager=l.ContextManager.getInstance()}get queryName(){return this.operationName?this.operationName.charAt(0).toLowerCase()+this.operationName.slice(1):""}getDefaultVariables(){const t=Date.now().toString(),o=this.contextManager.getOrSetSfTraceId(),a=this.contextManager.getCurrentFunctionSpanId();return{apiKey:this.apiKey,serviceUuid:this.serviceUUID,sessionId:o,timestampMs:t,parentSpanId:a}}getVariables(t={}){return{...this.getDefaultVariables(),...t}}setOperationName(t){this.operationName=t}setEndpoint(t){this.endpoint=t}setServiceUUID(t){this.serviceUUID=t}}const Z=typeof __dirname<"u"?__dirname:z.dirname(X.fileURLToPath(require("node:url").pathToFileURL(__filename).href)),Y=fetch;let I=!1;const ee=process.env.SF_NBPOST_DISABLE_BATCHING==="1",k=parseInt(process.env.SF_MAIN_BATCH_SIZE||"0",10);let m=null,C=!1;function B(){if(C)return null;if(m)return m;try{const n=z.join(Z,"telemetryWorker.cjs");return m=new $.Worker(n,{env:{...process.env,SF_NBPOST_BATCH_MAX:process.env.SF_NBPOST_BATCH_MAX||"50",SF_FLUSH_TELEMETRY_IN_BATCH:process.env.SF_FLUSH_TELEMETRY_IN_BATCH||"0",SF_BATCH_FLUSH_INTERVAL_MS:process.env.SF_BATCH_FLUSH_INTERVAL_MS||"50",SF_WORKER_MAX_CONCURRENT:process.env.SF_WORKER_MAX_CONCURRENT||"10"}}),m.unref(),m.on("error",()=>{C=!0,m=null}),m.on("exit",()=>{m=null}),m}catch{return C=!0,null}}let S=[],b=!1;function U(){if(S.length===0)return;const n=B();if(!n){for(const t of S)L(t.url,t.item.operationName,t.item.query,t.item.variables);return S=[],void(b=!1)}S.length===1?n.postMessage(S[0]):n.postMessage({batch:S}),S=[],b=!1}async function E(n,t,o,a){if(ee)return L(n,t,o,a);const s={url:n,item:{query:o,variables:a,operationName:t}};if(k===1){const i=B();return i?void i.postMessage(s):L(n,t,o,a)}S.push(s),k>1&&S.length>=k?U():b||(b=!0,queueMicrotask(U))}async function L(n,t,o,a){try{const s=l.getConfig();let i;try{i=JSON.stringify({query:o,variables:a,operationName:t})}catch{i=JSON.stringify({query:o,operationName:t})}I=!0,Y(n,{method:"POST",headers:{"Content-Type":"application/json"},body:i}).then(async e=>{if(I=!1,!e.ok)return void(s.sfDebug&&console.error(`GraphQL request failed with status ${e.status} for ${t}`));const r=await e.json();r.errors?.length?(function(u,g,c){const d=u&&typeof u=="object"&&!Array.isArray(u)?Object.keys(u)[0]:void 0;console.error(d==="identifyServiceDetails"?`IdentifyServiceDetails NOT sent successfully for service: UUID=${c.serviceUUID}`:`GraphQL request failed with errors: ${JSON.stringify(g)} for operation key ${d}`)})(r.data,r.errors,s):s.sfDebug&&(function(u,g,c){const d=u&&typeof u=="object"&&!Array.isArray(u)?Object.keys(u)[0]:void 0,p=u[d]||!1;d==="identifyServiceDetails"&&(c.setServiceIdentificationReceived(p),l.getConfig().sfDebug&&console.log(`IdentifyServiceDetails sent successfully for service: UUID=${c.serviceUUID}; serviceIdentificationReceived=${d==="identifyServiceDetails"?p:"N/A"}`))})(r.data,0,s)}).catch(e=>{I=!1,s.sfDebug&&(console.error(`[RequestUtils] Fetch error for ${t} to ${n}:`,e),e.cause&&console.error("[RequestUtils] Error cause:",e.cause))})}catch(s){I=!1,l.getConfig().sfDebug&&console.error("Error sending data to GraphQL server:",s)}}let V=!1;function h(n,t){if(!n)return t;const o=n.toLowerCase();return o==="true"||o==="1"||o==="yes"}const M="__sf_funcspanOverrideStorage";globalThis[M]||(globalThis[M]=new j.AsyncLocalStorage);const P=globalThis[M];function D(n,t){try{const o=JSON.stringify(n).length/1048576;return o<=t?n:{_truncated:!0,_originalSizeMB:o.toFixed(2),_limitMB:t,_preview:JSON.stringify(n).substring(0,500)+"..."}}catch{return{_error:"Failed to serialize data",_type:typeof n}}}function y(n,t){const o=process.env[n];return o===void 0?t:o==="true"||o==="1"}function q(n,t){const o=process.env[n];if(o===void 0)return t;const a=parseFloat(o);return isNaN(a)?t:a}function A(){return{enabled:y("SF_WORKER_POOL_ENABLED",!0),trackFs:y("SF_WORKER_POOL_TRACK_FS",!1),trackDns:y("SF_WORKER_POOL_TRACK_DNS",!1),trackCrypto:y("SF_WORKER_POOL_TRACK_CRYPTO",!1),trackZlib:y("SF_WORKER_POOL_TRACK_ZLIB",!1),captureArguments:y("SF_WORKER_POOL_CAPTURE_ARGUMENTS",!0),captureReturnValue:y("SF_WORKER_POOL_CAPTURE_RETURN_VALUE",!0),argLimitMb:q("SF_WORKER_POOL_ARG_LIMIT_MB",1),returnLimitMb:q("SF_WORKER_POOL_RETURN_LIMIT_MB",1)}}function x(n,t,o,a){let s;try{switch(n){case"fs":s=(function(i,e){const r={};switch(i){case"readFile":case"writeFile":case"appendFile":r.path=String(e[0]||""),e[1]&&typeof e[1]=="object"?(r.encoding=e[1].encoding||null,r.flag=e[1].flag||null):typeof e[1]=="string"&&(r.encoding=e[1]),i!=="writeFile"&&i!=="appendFile"||(Buffer.isBuffer(e[1])?(r.dataType="Buffer",r.dataSize=e[1].length):typeof e[1]=="string"&&(r.dataType="string",r.dataSize=e[1].length));break;case"readdir":case"stat":case"lstat":case"access":case"chmod":case"mkdir":case"rmdir":case"unlink":r.path=String(e[0]||""),e[1]&&typeof e[1]=="object"&&(r.options={...e[1]},delete r.options.callback);break;case"rename":r.oldPath=String(e[0]||""),r.newPath=String(e[1]||"");break;case"open":r.path=String(e[0]||""),r.flags=e[1],r.mode=e[2];break;case"close":case"fstat":r.fd=e[0];break;case"read":case"write":r.fd=e[0],Buffer.isBuffer(e[1])&&(r.bufferSize=e[1].length),r.offset=e[2],r.length=e[3],r.position=e[4];break;default:r.argsCount=e.length-1}return r})(t,o);break;case"dns":s=(function(i,e){const r={};switch(i){case"lookup":r.hostname=String(e[0]||""),typeof e[1]=="object"?(r.family=e[1].family,r.all=e[1].all):typeof e[1]=="number"&&(r.family=e[1]);break;case"resolve":case"resolve4":case"resolve6":case"resolveAny":case"resolveMx":case"resolveNs":case"resolveTxt":r.hostname=String(e[0]||"");break;case"reverse":r.ip=String(e[0]||"");break;default:r.argsCount=e.length-1}return r})(t,o);break;case"crypto":s=(function(i,e){const r={};switch(i){case"pbkdf2":r.passwordType=typeof e[0],r.saltType=typeof e[1],r.iterations=e[2],r.keylen=e[3],r.digest=e[4];break;case"scrypt":r.passwordType=typeof e[0],r.saltType=typeof e[1],r.keylen=e[2],typeof e[3]=="object"&&(r.N=e[3].N,r.r=e[3].r,r.p=e[3].p);break;case"randomBytes":r.size=e[0];break;case"generateKeyPair":r.type=e[0],typeof e[1]=="object"&&(r.modulusLength=e[1].modulusLength,r.namedCurve=e[1].namedCurve);break;default:r.argsCount=e.length-1}return r})(t,o);break;case"zlib":s=(function(i,e){const r={};return Buffer.isBuffer(e[0])?(r.inputType="Buffer",r.inputSize=e[0].length):typeof e[0]=="string"?(r.inputType="string",r.inputSize=e[0].length):r.inputType=typeof e[0],e[1]&&typeof e[1]=="object"&&typeof e[1]!="function"&&(r.options={...e[1]}),r})(0,o);break;default:return null}return a>0?D(s,a):s}catch{return{error:"Failed to capture arguments",argsCount:o.length-1}}}function J(n,t,o,a){let s;try{switch(n){case"fs":s=(function(i,e){if(!e)return null;switch(i){case"readFile":return Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:typeof e=="string"?{type:"string",size:e.length}:{type:typeof e};case"readdir":return{count:Array.isArray(e)?e.length:0,items:e};case"stat":case"lstat":case"fstat":return{size:e.size,mode:e.mode,isFile:e.isFile(),isDirectory:e.isDirectory()};case"open":return{fd:e};case"read":return{bytesRead:e};case"write":return{bytesWritten:e};default:return e}})(t,o);break;case"dns":s=(function(i,e){if(!e)return null;switch(i){case"lookup":return Array.isArray(e)?{count:e.length,addresses:e}:e;case"resolve":case"resolve4":case"resolve6":case"resolveAny":case"resolveMx":case"resolveNs":case"resolveTxt":return{count:Array.isArray(e)?e.length:0,records:e};case"reverse":return{hostnames:e};default:return e}})(t,o);break;case"crypto":s=(function(i,e){if(!e)return null;switch(i){case"pbkdf2":case"scrypt":case"randomBytes":return Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:{type:typeof e};case"generateKeyPair":return{hasPublicKey:!!e?.publicKey,hasPrivateKey:!!e?.privateKey};default:return e}})(t,o);break;case"zlib":s=(function(i,e){return e?Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:typeof e=="string"?{type:"string",size:e.length}:{type:typeof e}:null})(0,o);break;default:return null}return a>0?D(s,a):s}catch{return{error:"Failed to capture result",type:typeof o}}}function te(n){return n.operationType==="worker_pool"}class H extends G{constructor(){super(),this.operationName="CollectFunctionSpans"}send(t){const o=l.getConfig().sfDebug;o&&console.log(`[FunctionSpanTransmitter] Preparing to send ${t.length} function span(s)`);for(const a of t)try{if(te(a)){this.sendWorkerPoolSpan(a,o);continue}const s=a;let i;if(s.result!==void 0&&s.result!==null){const r=typeof s.result;i=JSON.stringify({type:r,has_value:!0,value:s.result})}else i=s.result===null?JSON.stringify({type:"null",has_value:!0,value:null}):JSON.stringify({type:"undefined",has_value:!1,value:null});const e=this.getVariables({library:"JS/TS BACKEND",version:l.getConfig().version,spanId:s.spanId,parentSpanId:s.parentSpanId,filePath:s.filePath,lineNumber:s.metadata.line,columnNumber:s.metadata.column,functionName:s.functionName,arguments:JSON.stringify(s.args||{}),returnValue:i,startTimeNs:(1e6*Date.now()-1e6*s.duration).toString(),durationNs:(1e6*s.duration).toString()});o&&(console.log(`[FunctionSpanTransmitter] Sending GraphQL mutation to ${this.endpoint}`),console.log("[FunctionSpanTransmitter] Variables:",JSON.stringify(e,null,2))),E(this.endpoint,this.operationName,this.getQuery(),e),o&&console.log(`[FunctionSpanTransmitter] Queued function span for ${s.functionName}`)}catch(s){console.error(`[FunctionSpanTransmitter] Error preparing function span for ${a.functionName}:`,s)}}sendWorkerPoolSpan(t,o){try{let a;if(t.result!==void 0&&t.result!==null){const i=typeof t.result;a=JSON.stringify({type:i,has_value:!0,value:t.result})}else a=t.result===null?JSON.stringify({type:"null",has_value:!0,value:null}):JSON.stringify({type:"undefined",has_value:!1,value:null});const s=this.getVariables({library:"JS/TS BACKEND",version:l.getConfig().version,spanId:t.spanId,operationName:t.operationName,moduleName:t.moduleName,methodName:t.methodName,startTimeNs:t.startTimeNs,durationNs:t.durationNs,arguments:JSON.stringify(t.args||{}),returnValue:a,error:t.error,pid:t.pid,threadId:t.threadId});o&&(console.log(`[FunctionSpanTransmitter] Sending worker pool span: ${t.operationName}`),console.log("[FunctionSpanTransmitter] Variables:",JSON.stringify(s,null,2))),E(this.endpoint,"CollectWorkerPoolSpans",this.getWorkerPoolQuery(),s),o&&console.log(`[FunctionSpanTransmitter] Queued worker pool span for ${t.operationName}`)}catch(a){console.error(`[FunctionSpanTransmitter] Error preparing worker pool span for ${t.operationName}:`,a)}}getWorkerPoolQuery(){return`
1
+ "use strict";const j=require("async_hooks"),Q=require("fs"),$=require("worker_threads"),l=require("./contextManager-CL0Qs7uI.cjs"),z=require("path"),X=require("url");class G{apiKey;endpoint;queryType="mutation";operationName="";serviceUUID=l.getConfig().serviceUUID;contextManager;constructor(){this.apiKey=l.getConfig().apiKey,this.endpoint=l.getConfig().apiGraphqlEndpoint,this.contextManager=l.ContextManager.getInstance()}get queryName(){return this.operationName?this.operationName.charAt(0).toLowerCase()+this.operationName.slice(1):""}getDefaultVariables(){const t=Date.now().toString(),o=this.contextManager.getOrSetSfTraceId(),a=this.contextManager.getCurrentFunctionSpanId();return{apiKey:this.apiKey,serviceUuid:this.serviceUUID,sessionId:o,timestampMs:t,parentSpanId:a}}getVariables(t={}){return{...this.getDefaultVariables(),...t}}setOperationName(t){this.operationName=t}setEndpoint(t){this.endpoint=t}setServiceUUID(t){this.serviceUUID=t}}const Z=typeof __dirname<"u"?__dirname:z.dirname(X.fileURLToPath(require("node:url").pathToFileURL(__filename).href)),Y=fetch;let I=!1;const ee=process.env.SF_NBPOST_DISABLE_BATCHING==="1",k=parseInt(process.env.SF_MAIN_BATCH_SIZE||"0",10);let m=null,C=!1;function B(){if(C)return null;if(m)return m;try{const n=z.join(Z,"telemetryWorker.cjs");return m=new $.Worker(n,{env:{...process.env,SF_NBPOST_BATCH_MAX:process.env.SF_NBPOST_BATCH_MAX||"50",SF_FLUSH_TELEMETRY_IN_BATCH:process.env.SF_FLUSH_TELEMETRY_IN_BATCH||"0",SF_BATCH_FLUSH_INTERVAL_MS:process.env.SF_BATCH_FLUSH_INTERVAL_MS||"50",SF_WORKER_MAX_CONCURRENT:process.env.SF_WORKER_MAX_CONCURRENT||"10"}}),m.unref(),m.on("error",()=>{C=!0,m=null}),m.on("exit",()=>{m=null}),m}catch{return C=!0,null}}let S=[],b=!1;function U(){if(S.length===0)return;const n=B();if(!n){for(const t of S)L(t.url,t.item.operationName,t.item.query,t.item.variables);return S=[],void(b=!1)}S.length===1?n.postMessage(S[0]):n.postMessage({batch:S}),S=[],b=!1}async function E(n,t,o,a){if(ee)return L(n,t,o,a);const s={url:n,item:{query:o,variables:a,operationName:t}};if(k===1){const i=B();return i?void i.postMessage(s):L(n,t,o,a)}S.push(s),k>1&&S.length>=k?U():b||(b=!0,queueMicrotask(U))}async function L(n,t,o,a){try{const s=l.getConfig();let i;try{i=JSON.stringify({query:o,variables:a,operationName:t})}catch{i=JSON.stringify({query:o,operationName:t})}I=!0,Y(n,{method:"POST",headers:{"Content-Type":"application/json"},body:i}).then(async e=>{if(I=!1,!e.ok)return void(s.sfDebug&&console.error(`GraphQL request failed with status ${e.status} for ${t}`));const r=await e.json();r.errors?.length?(function(u,g,c){const d=u&&typeof u=="object"&&!Array.isArray(u)?Object.keys(u)[0]:void 0;console.error(d==="identifyServiceDetails"?`IdentifyServiceDetails NOT sent successfully for service: UUID=${c.serviceUUID}`:`GraphQL request failed with errors: ${JSON.stringify(g)} for operation key ${d}`)})(r.data,r.errors,s):s.sfDebug&&(function(u,g,c){const d=u&&typeof u=="object"&&!Array.isArray(u)?Object.keys(u)[0]:void 0,p=u[d]||!1;d==="identifyServiceDetails"&&(c.setServiceIdentificationReceived(p),l.getConfig().sfDebug&&console.log(`IdentifyServiceDetails sent successfully for service: UUID=${c.serviceUUID}; serviceIdentificationReceived=${d==="identifyServiceDetails"?p:"N/A"}`))})(r.data,0,s)}).catch(e=>{I=!1,s.sfDebug&&(console.error(`[RequestUtils] Fetch error for ${t} to ${n}:`,e),e.cause&&console.error("[RequestUtils] Error cause:",e.cause))})}catch(s){I=!1,l.getConfig().sfDebug&&console.error("Error sending data to GraphQL server:",s)}}let V=!1;function h(n,t){if(!n)return t;const o=n.toLowerCase();return o==="true"||o==="1"||o==="yes"}const M="__sf_funcspanOverrideStorage";globalThis[M]||(globalThis[M]=new j.AsyncLocalStorage);const P=globalThis[M];function D(n,t){try{const o=JSON.stringify(n).length/1048576;return o<=t?n:{_truncated:!0,_originalSizeMB:o.toFixed(2),_limitMB:t,_preview:JSON.stringify(n).substring(0,500)+"..."}}catch{return{_error:"Failed to serialize data",_type:typeof n}}}function y(n,t){const o=process.env[n];return o===void 0?t:o==="true"||o==="1"}function q(n,t){const o=process.env[n];if(o===void 0)return t;const a=parseFloat(o);return isNaN(a)?t:a}function A(){return{enabled:y("SF_WORKER_POOL_ENABLED",!0),trackFs:y("SF_WORKER_POOL_TRACK_FS",!1),trackDns:y("SF_WORKER_POOL_TRACK_DNS",!1),trackCrypto:y("SF_WORKER_POOL_TRACK_CRYPTO",!1),trackZlib:y("SF_WORKER_POOL_TRACK_ZLIB",!1),captureArguments:y("SF_WORKER_POOL_CAPTURE_ARGUMENTS",!0),captureReturnValue:y("SF_WORKER_POOL_CAPTURE_RETURN_VALUE",!0),argLimitMb:q("SF_WORKER_POOL_ARG_LIMIT_MB",1),returnLimitMb:q("SF_WORKER_POOL_RETURN_LIMIT_MB",1)}}function x(n,t,o,a){let s;try{switch(n){case"fs":s=(function(i,e){const r={};switch(i){case"readFile":case"writeFile":case"appendFile":r.path=String(e[0]||""),e[1]&&typeof e[1]=="object"?(r.encoding=e[1].encoding||null,r.flag=e[1].flag||null):typeof e[1]=="string"&&(r.encoding=e[1]),i!=="writeFile"&&i!=="appendFile"||(Buffer.isBuffer(e[1])?(r.dataType="Buffer",r.dataSize=e[1].length):typeof e[1]=="string"&&(r.dataType="string",r.dataSize=e[1].length));break;case"readdir":case"stat":case"lstat":case"access":case"chmod":case"mkdir":case"rmdir":case"unlink":r.path=String(e[0]||""),e[1]&&typeof e[1]=="object"&&(r.options={...e[1]},delete r.options.callback);break;case"rename":r.oldPath=String(e[0]||""),r.newPath=String(e[1]||"");break;case"open":r.path=String(e[0]||""),r.flags=e[1],r.mode=e[2];break;case"close":case"fstat":r.fd=e[0];break;case"read":case"write":r.fd=e[0],Buffer.isBuffer(e[1])&&(r.bufferSize=e[1].length),r.offset=e[2],r.length=e[3],r.position=e[4];break;default:r.argsCount=e.length-1}return r})(t,o);break;case"dns":s=(function(i,e){const r={};switch(i){case"lookup":r.hostname=String(e[0]||""),typeof e[1]=="object"?(r.family=e[1].family,r.all=e[1].all):typeof e[1]=="number"&&(r.family=e[1]);break;case"resolve":case"resolve4":case"resolve6":case"resolveAny":case"resolveMx":case"resolveNs":case"resolveTxt":r.hostname=String(e[0]||"");break;case"reverse":r.ip=String(e[0]||"");break;default:r.argsCount=e.length-1}return r})(t,o);break;case"crypto":s=(function(i,e){const r={};switch(i){case"pbkdf2":r.passwordType=typeof e[0],r.saltType=typeof e[1],r.iterations=e[2],r.keylen=e[3],r.digest=e[4];break;case"scrypt":r.passwordType=typeof e[0],r.saltType=typeof e[1],r.keylen=e[2],typeof e[3]=="object"&&(r.N=e[3].N,r.r=e[3].r,r.p=e[3].p);break;case"randomBytes":r.size=e[0];break;case"generateKeyPair":r.type=e[0],typeof e[1]=="object"&&(r.modulusLength=e[1].modulusLength,r.namedCurve=e[1].namedCurve);break;default:r.argsCount=e.length-1}return r})(t,o);break;case"zlib":s=(function(i,e){const r={};return Buffer.isBuffer(e[0])?(r.inputType="Buffer",r.inputSize=e[0].length):typeof e[0]=="string"?(r.inputType="string",r.inputSize=e[0].length):r.inputType=typeof e[0],e[1]&&typeof e[1]=="object"&&typeof e[1]!="function"&&(r.options={...e[1]}),r})(0,o);break;default:return null}return a>0?D(s,a):s}catch{return{error:"Failed to capture arguments",argsCount:o.length-1}}}function J(n,t,o,a){let s;try{switch(n){case"fs":s=(function(i,e){if(!e)return null;switch(i){case"readFile":return Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:typeof e=="string"?{type:"string",size:e.length}:{type:typeof e};case"readdir":return{count:Array.isArray(e)?e.length:0,items:e};case"stat":case"lstat":case"fstat":return{size:e.size,mode:e.mode,isFile:e.isFile(),isDirectory:e.isDirectory()};case"open":return{fd:e};case"read":return{bytesRead:e};case"write":return{bytesWritten:e};default:return e}})(t,o);break;case"dns":s=(function(i,e){if(!e)return null;switch(i){case"lookup":return Array.isArray(e)?{count:e.length,addresses:e}:e;case"resolve":case"resolve4":case"resolve6":case"resolveAny":case"resolveMx":case"resolveNs":case"resolveTxt":return{count:Array.isArray(e)?e.length:0,records:e};case"reverse":return{hostnames:e};default:return e}})(t,o);break;case"crypto":s=(function(i,e){if(!e)return null;switch(i){case"pbkdf2":case"scrypt":case"randomBytes":return Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:{type:typeof e};case"generateKeyPair":return{hasPublicKey:!!e?.publicKey,hasPrivateKey:!!e?.privateKey};default:return e}})(t,o);break;case"zlib":s=(function(i,e){return e?Buffer.isBuffer(e)?{type:"Buffer",size:e.length}:typeof e=="string"?{type:"string",size:e.length}:{type:typeof e}:null})(0,o);break;default:return null}return a>0?D(s,a):s}catch{return{error:"Failed to capture result",type:typeof o}}}function te(n){return n.operationType==="worker_pool"}class H extends G{constructor(){super(),this.operationName="CollectFunctionSpans"}send(t){const o=l.getConfig().sfDebug;o&&console.log(`[FunctionSpanTransmitter] Preparing to send ${t.length} function span(s)`);for(const a of t)try{if(te(a)){this.sendWorkerPoolSpan(a,o);continue}const s=a;let i;if(s.result!==void 0&&s.result!==null){const r=typeof s.result;i=JSON.stringify({type:r,has_value:!0,value:s.result})}else i=s.result===null?JSON.stringify({type:"null",has_value:!0,value:null}):JSON.stringify({type:"undefined",has_value:!1,value:null});const e=this.getVariables({library:"JS/TS BACKEND",version:l.getConfig().version,spanId:s.spanId,parentSpanId:s.parentSpanId,filePath:s.filePath,lineNumber:s.metadata.line,columnNumber:s.metadata.column,functionName:s.functionName,arguments:JSON.stringify(s.args||{}),returnValue:i,startTimeNs:(1e6*Date.now()-1e6*s.duration).toString(),durationNs:(1e6*s.duration).toString()});o&&(console.log(`[FunctionSpanTransmitter] Sending GraphQL mutation to ${this.endpoint}`),console.log("[FunctionSpanTransmitter] Variables:",JSON.stringify(e,null,2))),E(this.endpoint,this.operationName,this.getQuery(),e),o&&console.log(`[FunctionSpanTransmitter] Queued function span for ${s.functionName}`)}catch(s){console.error(`[FunctionSpanTransmitter] Error preparing function span for ${a.functionName}:`,s)}}sendWorkerPoolSpan(t,o){try{let a;if(t.result!==void 0&&t.result!==null){const i=typeof t.result;a=JSON.stringify({type:i,has_value:!0,value:t.result})}else a=t.result===null?JSON.stringify({type:"null",has_value:!0,value:null}):JSON.stringify({type:"undefined",has_value:!1,value:null});const s=this.getVariables({library:"JS/TS BACKEND",version:l.getConfig().version,spanId:t.spanId,operationName:t.operationName,moduleName:t.moduleName,methodName:t.methodName,startTimeNs:t.startTimeNs,durationNs:t.durationNs,arguments:JSON.stringify(t.args||{}),returnValue:a,error:t.error,pid:t.pid,threadId:t.threadId});o&&(console.log(`[FunctionSpanTransmitter] Sending worker pool span: ${t.operationName}`),console.log("[FunctionSpanTransmitter] Variables:",JSON.stringify(s,null,2))),E(this.endpoint,"CollectWorkerPoolSpans",this.getWorkerPoolQuery(),s),o&&console.log(`[FunctionSpanTransmitter] Queued worker pool span for ${t.operationName}`)}catch(a){console.error(`[FunctionSpanTransmitter] Error preparing worker pool span for ${t.operationName}:`,a)}}getWorkerPoolQuery(){return`
2
2
  mutation CollectWorkerPoolSpans(
3
3
  $apiKey: String!,
4
4
  $serviceUuid: String!,
@@ -4,7 +4,7 @@ var y = (n, t, s) => X(n, typeof t != "symbol" ? t + "" : t, s);
4
4
  import { AsyncLocalStorage as Z, AsyncResource as Y } from "async_hooks";
5
5
  import { appendFileSync as ee } from "fs";
6
6
  import { Worker as te, threadId as O } from "worker_threads";
7
- import { g as S, C as L, v as j, a as M } from "./contextManager-CZy0w11U.js";
7
+ import { g as S, C as L, v as j, a as M } from "./contextManager-C2ONL8XY.js";
8
8
  import { dirname as ne, join as re } from "path";
9
9
  import { fileURLToPath as se } from "url";
10
10
  class oe {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sailfish-ai/sf-veritas",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "publishPublicly": true,
5
5
  "description": "A versatile Edge Runtime-compatible package for JavaScript and TypeScript backend systems and scripts.",
6
6
  "main": "./dist/sf-veritas.cjs",
@@ -65,6 +65,7 @@
65
65
  "dev": "vite",
66
66
  "lint": "eslint ./src --ext .ts",
67
67
  "test": "vitest",
68
+ "bench": "vitest bench --environment=node src/patches/asyncQueues",
68
69
  "test:fake-document": "node scripts/test-fake-document.js",
69
70
  "check:no-dom-in-cjs": "node -e \"const fs=require('fs'),g=require('glob');const files=g.sync('dist/**/*.cjs');let bad=false;for(const f of files){const s=fs.readFileSync(f,'utf8');if(/document\\.|currentScript|baseURI/.test(s)){console.error('DOM polyfill in:',f);bad=true;}}if(bad)process.exit(1);console.log('No DOM polyfills in CJS');\"",
70
71
  "prebuild": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' scripts/build-script.ts",
@@ -1 +0,0 @@
1
- "use strict";const L=require("async_hooks"),G=require("child_process"),O=require("fs"),H=require("fs/promises"),V=require("os");function P(s){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const t in s)if(t!=="default"){const r=Object.getOwnPropertyDescriptor(s,t);Object.defineProperty(e,t,r.get?r:{enumerable:!0,get:()=>s[t]})}}return e.default=s,Object.freeze(e)}const F=P(H),m=P(V),i=[];for(let s=0;s<256;++s)i.push((s+256).toString(16).slice(1));let R;const k=new Uint8Array(16),N={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function I(s,e,t){if(N.randomUUID&&!s)return N.randomUUID();const r=(s=s||{}).random??s.rng?.()??(function(){if(!R){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");R=crypto.getRandomValues.bind(crypto)}return R(k)})();if(r.length<16)throw new Error("Random bytes length must be >= 16");return r[6]=15&r[6]|64,r[8]=63&r[8]|128,(function(n,o=0){return(i[n[o+0]]+i[n[o+1]]+i[n[o+2]]+i[n[o+3]]+"-"+i[n[o+4]]+i[n[o+5]]+"-"+i[n[o+6]]+i[n[o+7]]+"-"+i[n[o+8]]+i[n[o+9]]+"-"+i[n[o+10]]+i[n[o+11]]+i[n[o+12]]+i[n[o+13]]+i[n[o+14]]+i[n[o+15]]).toLowerCase()})(r)}class w{apiKey;apiGraphqlEndpoint;sfDebug;serviceIdentifier;serviceVersion;serviceUUID;serviceAdditionalMetadata;profilingModeEnabled;profilingMaxDepth;profilingMaxVariableSizeKb;domainsToNotPropagateHeadersTo;domainsToPropagateHeadersTo;nodeModulesToCollectLocalVariablesOn;printConfigurationStatuses;logLevel;stackDepthLocals;stackDepthCodeTraceDepth;packageLibraryType;version;gitSha;gitOrg;gitRepo;gitProvider;serviceDisplayName;infrastructureType;infrastructureDetails;framework;additionalFrameworks;serviceRole;setupInterceptorsFile;setupInterceptorsLine;logIgnoreRegex;captureRequestHeaders;captureResponseHeaders;captureRequestBody;captureResponseBody;requestBodyLimitBytes;responseBodyLimitBytes;retryOnClientError;_serviceIdentificationReceived=!1;constructor(e){this.apiKey=e.apiKey,this.apiGraphqlEndpoint=e?.apiGraphqlEndpoint||process.env.SAILFISH_GRAPHQL_ENDPOINT||"https://api-service.sailfishqa.com/graphql/",this.sfDebug=e?.debug===!0||process.env.SF_DEBUG==="true",this.serviceIdentifier=e?.serviceIdentifier||process.env.SERVICE_IDENTIFIER,this.serviceUUID=I(),this.serviceVersion=e?.serviceVersion||process.env.SERVICE_VERSION,this.gitSha=e?.gitSha||process.env.GIT_SHA||process.env.GITHUB_SHA||process.env.CI_COMMIT_SHA||process.env.BITBUCKET_COMMIT||process.env.VERCEL_GIT_COMMIT_SHA||process.env.CIRCLE_SHA1||process.env.HEROKU_SLUG_COMMIT||process.env.RENDER_GIT_COMMIT||process.env.RAILWAY_GIT_COMMIT_SHA||process.env.CODEBUILD_RESOLVED_SOURCE_VERSION;const t=process.env.GITHUB_REPOSITORY?.split("/");this.gitOrg=e?.gitOrg||process.env.GIT_ORG||(t&&t.length>=2?t[0]:void 0)||process.env.CI_PROJECT_NAMESPACE||process.env.BITBUCKET_REPO_OWNER||process.env.VERCEL_GIT_REPO_OWNER||process.env.CIRCLE_PROJECT_USERNAME,this.gitRepo=e?.gitRepo||process.env.GIT_REPO||(t&&t.length>=2?t.slice(1).join("/"):void 0)||process.env.CI_PROJECT_NAME||process.env.BITBUCKET_REPO_SLUG||process.env.VERCEL_GIT_REPO_SLUG||process.env.CIRCLE_PROJECT_REPONAME,this.gitProvider=e?.gitProvider||process.env.GIT_PROVIDER||(process.env.GITHUB_ACTIONS?"github":void 0)||(process.env.GITLAB_CI?"gitlab":void 0)||(process.env.BITBUCKET_PIPELINE_UUID?"bitbucket":void 0)||(process.env.CIRCLECI?"circleci":void 0),this.serviceDisplayName=e?.serviceDisplayName||process.env.SERVICE_DISPLAY_NAME,this.serviceAdditionalMetadata=e?.serviceAdditionalMetadata||{},this.profilingModeEnabled=e?.profilingModeEnabled??!1,this.profilingMaxDepth=e?.profilingMaxDepth??5,this.profilingMaxVariableSizeKb=e?.profilingMaxVariableSizeKb??25,this.domainsToNotPropagateHeadersTo=e?.domainsToNotPropagateHeadersTo||[],this.domainsToPropagateHeadersTo=e?.domainsToPropagateHeadersTo!==void 0?e.domainsToPropagateHeadersTo:["*"],this.nodeModulesToCollectLocalVariablesOn=e?.nodeModulesToCollectLocalVariablesOn||["_all_"],this.printConfigurationStatuses=process.env.PRINT_CONFIGURATION_STATUSES||"true",this.logLevel=process.env.LOG_LEVEL||"INFO",this.stackDepthLocals=process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS!==void 0?parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_LOCALS,10):5,isNaN(this.stackDepthLocals)&&(this.stackDepthLocals=-1),this.stackDepthCodeTraceDepth=process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH!==void 0?parseInt(process.env.SAILFISH_EXCEPTION_STACK_DEPTH_CODE_TRACE_DEPTH,10):-1,isNaN(this.stackDepthCodeTraceDepth)&&(this.stackDepthCodeTraceDepth=-1),this.packageLibraryType="JS/TS BACKEND",this.version=this.getPackageVersion();const r=(function(){return process.env.KUBERNETES_SERVICE_HOST||O.existsSync("/var/run/secrets/kubernetes.io/serviceaccount/token")?{type:"Kubernetes",details:{namespace:process.env.POD_NAMESPACE||"",podName:process.env.HOSTNAME||"",nodeName:process.env.NODE_NAME||""}}:process.env.AWS_LAMBDA_FUNCTION_NAME?{type:"AWS Lambda",details:{functionName:process.env.AWS_LAMBDA_FUNCTION_NAME||"",region:process.env.AWS_REGION||"",runtime:process.env.AWS_EXECUTION_ENV||""}}:process.env.AWS_EXECUTION_ENV?{type:"AWS",details:{executionEnv:process.env.AWS_EXECUTION_ENV||"",region:process.env.AWS_REGION||""}}:process.env.GOOGLE_CLOUD_PROJECT?{type:"Google Cloud",details:{project:process.env.GOOGLE_CLOUD_PROJECT||""}}:process.env.AZURE_FUNCTIONS_ENVIRONMENT?{type:"Azure Functions",details:{environment:process.env.AZURE_FUNCTIONS_ENVIRONMENT||""}}:process.env.VERCEL?{type:"Vercel",details:{env:process.env.VERCEL_ENV||"",region:process.env.VERCEL_REGION||""}}:process.env.NETLIFY?{type:"Netlify",details:{}}:process.env.FLY_APP_NAME?{type:"Fly.io",details:{appName:process.env.FLY_APP_NAME||"",region:process.env.FLY_REGION||""}}:process.env.RENDER_SERVICE_ID?{type:"Render",details:{serviceId:process.env.RENDER_SERVICE_ID||""}}:process.env.RAILWAY_ENVIRONMENT?{type:"Railway",details:{environment:process.env.RAILWAY_ENVIRONMENT||""}}:O.existsSync("/.dockerenv")?{type:"Docker",details:{}}:{type:"Unknown",details:{os:m.platform(),arch:m.arch(),nodeVersion:process.version}}})();this.infrastructureType=r.type,this.infrastructureDetails=r.details;const n=(function(){const b=[{pkg:"@nestjs/core",name:"nestjs"},{pkg:"@apollo/server",name:"apollo-server"},{pkg:"apollo-server",name:"apollo-server"},{pkg:"mercurius",name:"mercurius"},{pkg:"next",name:"nextjs"},{pkg:"nuxt",name:"nuxtjs"},{pkg:"express",name:"express"},{pkg:"fastify",name:"fastify"},{pkg:"koa",name:"koa"},{pkg:"@hapi/hapi",name:"hapi"},{pkg:"hono",name:"hono"}],d=[],g=new Set;for(const{pkg:v,name:S}of b)if(!g.has(S))try{require.resolve(v),d.push(S),g.add(S)}catch{}if(typeof process<"u"){if(!g.has("nuxtjs")&&globalThis._importMeta_!==void 0){let v=!1;try{(globalThis._importMeta_?.url||"").includes(".output/server")&&(v=!0)}catch{}v&&(d.unshift("nuxtjs"),g.add("nuxtjs"))}!g.has("meteorjs")&&process.env.METEOR_SHELL_DIR&&(d.unshift("meteorjs"),g.add("meteorjs"))}return{framework:d.length>0?d[0]:null,additionalFrameworks:d.slice(1),serviceRole:d.includes("nextjs")||d.includes("nuxtjs")?"fullstack":"backend"}})();this.framework=n.framework??void 0,this.additionalFrameworks=n.additionalFrameworks,this.serviceRole=n.serviceRole;const o=process.env.SF_LOG_IGNORE_REGEX;if(o)try{this.logIgnoreRegex=new RegExp(o)}catch{}this.captureRequestHeaders=process.env.SF_NETWORKHOP_CAPTURE_REQUEST_HEADERS==="true",this.captureResponseHeaders=process.env.SF_NETWORKHOP_CAPTURE_RESPONSE_HEADERS==="true",this.captureRequestBody=process.env.SF_NETWORKHOP_CAPTURE_REQUEST_BODY==="true",this.captureResponseBody=process.env.SF_NETWORKHOP_CAPTURE_RESPONSE_BODY==="true";const a=parseInt(process.env.SF_NETWORKHOP_REQUEST_LIMIT_MB||"1",10);this.requestBodyLimitBytes=1024*(isNaN(a)?1:a)*1024;const c=parseInt(process.env.SF_NETWORKHOP_RESPONSE_LIMIT_MB||"1",10);this.responseBodyLimitBytes=1024*(isNaN(c)?1:c)*1024;const u=(process.env.SF_RETRY_ON_CLIENT_ERROR||"").toLowerCase(),x=u==="all"||u==="idempotent"||u==="none"?u:void 0;this.retryOnClientError=x??e.retryOnClientError??"all"}getPackageVersion(){return"0.2.14"}get serviceIdentificationReceived(){return this._serviceIdentificationReceived}setServiceIdentificationReceived(e){this._serviceIdentificationReceived=e}}const U=Symbol.for("sailfish.sf_config");function T(){return globalThis[U]}function C(){const s=T();if(!s)throw new Error("Configuration has not been initialized. Call getOrCreateConfig(options) first.");return s}const A=Symbol.for("sf.ctx.storeAls"),p=globalThis,f=p[A]??(p[A]=new L.AsyncLocalStorage),M=["identitytoolkit.googleapis.com","t.co","*.twitter.com","*.gravatar.com","*.googleapis.com","*.amazonaws.com","*.smooch.io","*.zendesk.com"],D=Symbol.for("sf.ctx.als"),_=p[D]??(p[D]=new L.AsyncLocalStorage),y=Symbol.for("sf.ctx.sessionRegistry"),E=p[y]??(p[y]=new Map),h={handledExceptions:new Set,reentrancyGuardLoggingActive:!1,reentrancyGuardLoggingPreActive:!1,reentrancyGuardPrintActive:!1,reentrancyGuardPrintPreActive:!1,reentrancyGuardExceptionActive:!1,reentrancyGuardExceptionPreActive:!1,excludedDomains:new Set(M),supportedDomains:new Set};class l{static GLOBAL_MANAGER_SYMBOL=Symbol.for("sf.ctx.manager");constructor(){}current(){return f.getStore()}ensureStore(){const e=this.current();if(e)return e;const t=new Map;return f.enterWith(t),t}runWith(e,t){const r=this.current()??new Map,n=new Map(r);for(const[o,a]of Object.entries(e))n.set(o,a);return f.run(n,t)}static getInstance(){return p[l.GLOBAL_MANAGER_SYMBOL]||(p[l.GLOBAL_MANAGER_SYMBOL]=new l),p[l.GLOBAL_MANAGER_SYMBOL]}getCurrentContext(){return _.getStore()||h}setCurrentContext(e){const t=_.getStore()||h;_.enterWith({...t,...e})}ensureSession(e){let t=E.get(e);return t||(t={...h},E.set(e,t)),t}getContextFor(e){return E.get(e)??h}updateContextFor(e,t){const r=this.ensureSession(e);E.set(e,{...r,...t})}runWithSession(e,t){const r={...this.ensureSession(e)};return _.run(r,t)}deleteSession(e){E.delete(e)}getTraceId(){return this.getCurrentContext().traceId}getPageVisitUUID(){return this.getCurrentContext().pageVisitUUID}setTraceId(e){this.setCurrentContext({traceId:e})}setPageVisitUUID(e){this.setCurrentContext({pageVisitUUID:e})}getCurrentFunctionSpanId(){return this.getCurrentContext().currentFunctionSpanId}setCurrentFunctionSpanId(e){this.setCurrentContext({currentFunctionSpanId:e})}clearCurrentFunctionSpanId(){this.setCurrentContext({currentFunctionSpanId:void 0})}getOrSetSfTraceId(e,t=!1){let r=this.getTraceId();return r||(r=e||(t?I():`nonsession-applogs-v3/${C().apiKey}/${I()}`),this.setTraceId(r),C().sfDebug&&console.log(" Created new trace ID:",r),r)}getOrSetPageVisitUUID(){let e=this.getPageVisitUUID();return e||(e=I(),this.setPageVisitUUID(e),C().sfDebug&&console.log(" Created new page visit UUID:",e),e)}getHandledExceptions(){return this.getCurrentContext().handledExceptions}markExceptionHandled(e){const t=this.getHandledExceptions();t.add(e),this.setCurrentContext({handledExceptions:t})}hasHandledException(e){return this.getHandledExceptions().has(e)}resetHandledExceptions(){this.setCurrentContext({handledExceptions:new Set})}getExcludedDomains(){return this.getCurrentContext().excludedDomains}getSupportedDomains(){return this.getCurrentContext().supportedDomains}addSupportedDomains(e){this.getCurrentContext().supportedDomains.add(e.toLowerCase().trim())}setTraceIdFor(e,t){this.updateContextFor(e,{traceId:t})}setPageVisitUUIDFor(e,t){this.updateContextFor(e,{pageVisitUUID:t})}}exports.ContextManager=l,exports.DEFAULT_DOMAINS_TO_EXCLUDE=M,exports.backfillGitInfoAsync=async function(s){if(!(s.gitOrg&&s.gitRepo&&s.gitProvider))try{const e=await(async function(){let t="";try{t=await new Promise((r,n)=>{G.execFile("git",["remote","get-url","origin"],{timeout:3e3},(o,a)=>{o?n(o):r((a||"").trim())})})}catch{try{const r=(await F.readFile(".git/config","utf-8")).match(/\[remote "origin"\][^[]*url\s*=\s*(.+)/m);r&&(t=r[1].trim())}catch{}}return t?(function(r){let n,o,a;if(r.includes("github.com")?n="github":r.includes("gitlab.com")?n="gitlab":r.includes("bitbucket.org")&&(n="bitbucket"),r.startsWith("https://")||r.startsWith("http://")){const c=r.split("/");c.length>=5&&(o=c[3],a=c[4].replace(/\.git$/,""))}else{const c=r.indexOf(":");if(c>0){const u=r.substring(c+1).replace(/\.git$/,"").split("/");u.length>=2&&(o=u[0],a=u[1])}}return{org:o,repo:a,provider:n}})(t):{}})();s.gitOrg||(s.gitOrg=e.org),s.gitRepo||(s.gitRepo=e.repo),s.gitProvider||(s.gitProvider=e.provider)}catch{}},exports.getConfig=C,exports.getCurrentFunctionSpanId=function(){return l.getInstance().getCurrentFunctionSpanId()},exports.getGlobalConfigUnsafe=T,exports.getOrCreateConfig=function(s){const e=T();if(e)return{config:e};const t=new w(s);return(function(r){globalThis[U]=r})(t),t.sfDebug&&console.log("[[getOrCreateConfig]] Created global config:",t),{config:t}},exports.runWithContext=function(s){const e={...l.getInstance().getCurrentContext()};_.run(e,()=>{s()})},exports.v4=I;