@sentry/cloudflare 10.53.1 → 10.54.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.
- package/build/cjs/async.js +4 -30
- package/build/cjs/async.js.map +1 -1
- package/build/cjs/client.js +31 -58
- package/build/cjs/client.js.map +1 -1
- package/build/cjs/d1.js +26 -80
- package/build/cjs/d1.js.map +1 -1
- package/build/cjs/debug-build.js +0 -5
- package/build/cjs/debug-build.js.map +1 -1
- package/build/cjs/durableobject.js +44 -131
- package/build/cjs/durableobject.js.map +1 -1
- package/build/cjs/flush.js +47 -34
- package/build/cjs/flush.js.map +1 -1
- package/build/cjs/instrument.js +7 -48
- package/build/cjs/instrument.js.map +1 -1
- package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js +9 -34
- package/build/cjs/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js +20 -54
- package/build/cjs/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js +12 -66
- package/build/cjs/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentEmail.js +21 -43
- package/build/cjs/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentEnv.js +12 -42
- package/build/cjs/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentFetch.js +20 -34
- package/build/cjs/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentFetcher.js +5 -19
- package/build/cjs/instrumentations/worker/instrumentFetcher.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentQueue.js +30 -62
- package/build/cjs/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentQueueProducer.js +31 -57
- package/build/cjs/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentScheduled.js +25 -54
- package/build/cjs/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/cjs/instrumentations/worker/instrumentTail.js +16 -43
- package/build/cjs/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/cjs/integrations/fetch.js +24 -56
- package/build/cjs/integrations/fetch.js.map +1 -1
- package/build/cjs/integrations/hono.js +7 -38
- package/build/cjs/integrations/hono.js.map +1 -1
- package/build/cjs/integrations/httpServer.js +6 -39
- package/build/cjs/integrations/httpServer.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai.js +3 -31
- package/build/cjs/integrations/tracing/vercelai.js.map +1 -1
- package/build/cjs/opentelemetry/tracer.js +17 -45
- package/build/cjs/opentelemetry/tracer.js.map +1 -1
- package/build/cjs/options.js +10 -46
- package/build/cjs/options.js.map +1 -1
- package/build/cjs/pages-plugin.js +9 -42
- package/build/cjs/pages-plugin.js.map +1 -1
- package/build/cjs/request.js +21 -67
- package/build/cjs/request.js.map +1 -1
- package/build/cjs/scope-utils.js +4 -15
- package/build/cjs/scope-utils.js.map +1 -1
- package/build/cjs/sdk.js +8 -25
- package/build/cjs/sdk.js.map +1 -1
- package/build/cjs/transport.js +14 -48
- package/build/cjs/transport.js.map +1 -1
- package/build/cjs/utils/instrumentContext.js +16 -52
- package/build/cjs/utils/instrumentContext.js.map +1 -1
- package/build/cjs/utils/isBinding.js +3 -23
- package/build/cjs/utils/isBinding.js.map +1 -1
- package/build/cjs/utils/isCloudflareClass.js +2 -8
- package/build/cjs/utils/isCloudflareClass.js.map +1 -1
- package/build/cjs/utils/rpcMeta.js +8 -32
- package/build/cjs/utils/rpcMeta.js.map +1 -1
- package/build/cjs/utils/rpcOptions.js +9 -32
- package/build/cjs/utils/rpcOptions.js.map +1 -1
- package/build/cjs/utils/streaming.js +3 -29
- package/build/cjs/utils/streaming.js.map +1 -1
- package/build/cjs/utils/traceLinks.js +8 -33
- package/build/cjs/utils/traceLinks.js.map +1 -1
- package/build/cjs/vendor/stacktrace.js +6 -27
- package/build/cjs/vendor/stacktrace.js.map +1 -1
- package/build/cjs/withSentry.js +16 -47
- package/build/cjs/withSentry.js.map +1 -1
- package/build/cjs/workflows.js +40 -100
- package/build/cjs/workflows.js.map +1 -1
- package/build/cjs/wrapMethodWithSentry.js +110 -167
- package/build/cjs/wrapMethodWithSentry.js.map +1 -1
- package/build/esm/async.js +4 -30
- package/build/esm/async.js.map +1 -1
- package/build/esm/client.js +31 -58
- package/build/esm/client.js.map +1 -1
- package/build/esm/d1.js +26 -80
- package/build/esm/d1.js.map +1 -1
- package/build/esm/debug-build.js +0 -5
- package/build/esm/debug-build.js.map +1 -1
- package/build/esm/durableobject.js +44 -131
- package/build/esm/durableobject.js.map +1 -1
- package/build/esm/flush.js +47 -34
- package/build/esm/flush.js.map +1 -1
- package/build/esm/instrument.js +7 -48
- package/build/esm/instrument.js.map +1 -1
- package/build/esm/instrumentations/instrumentDurableObjectNamespace.js +9 -34
- package/build/esm/instrumentations/instrumentDurableObjectNamespace.js.map +1 -1
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js +20 -54
- package/build/esm/instrumentations/instrumentDurableObjectStorage.js.map +1 -1
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js +12 -66
- package/build/esm/instrumentations/instrumentWorkerEntrypoint.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentEmail.js +21 -43
- package/build/esm/instrumentations/worker/instrumentEmail.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentEnv.js +12 -42
- package/build/esm/instrumentations/worker/instrumentEnv.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentFetch.js +20 -34
- package/build/esm/instrumentations/worker/instrumentFetch.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentFetcher.js +5 -19
- package/build/esm/instrumentations/worker/instrumentFetcher.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentQueue.js +30 -62
- package/build/esm/instrumentations/worker/instrumentQueue.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentQueueProducer.js +31 -57
- package/build/esm/instrumentations/worker/instrumentQueueProducer.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentScheduled.js +25 -54
- package/build/esm/instrumentations/worker/instrumentScheduled.js.map +1 -1
- package/build/esm/instrumentations/worker/instrumentTail.js +16 -43
- package/build/esm/instrumentations/worker/instrumentTail.js.map +1 -1
- package/build/esm/integrations/fetch.js +24 -56
- package/build/esm/integrations/fetch.js.map +1 -1
- package/build/esm/integrations/hono.js +7 -38
- package/build/esm/integrations/hono.js.map +1 -1
- package/build/esm/integrations/httpServer.js +6 -39
- package/build/esm/integrations/httpServer.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai.js +3 -31
- package/build/esm/integrations/tracing/vercelai.js.map +1 -1
- package/build/esm/opentelemetry/tracer.js +17 -45
- package/build/esm/opentelemetry/tracer.js.map +1 -1
- package/build/esm/options.js +10 -46
- package/build/esm/options.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/pages-plugin.js +9 -42
- package/build/esm/pages-plugin.js.map +1 -1
- package/build/esm/request.js +21 -67
- package/build/esm/request.js.map +1 -1
- package/build/esm/scope-utils.js +4 -15
- package/build/esm/scope-utils.js.map +1 -1
- package/build/esm/sdk.js +8 -25
- package/build/esm/sdk.js.map +1 -1
- package/build/esm/transport.js +14 -48
- package/build/esm/transport.js.map +1 -1
- package/build/esm/utils/instrumentContext.js +16 -52
- package/build/esm/utils/instrumentContext.js.map +1 -1
- package/build/esm/utils/isBinding.js +3 -23
- package/build/esm/utils/isBinding.js.map +1 -1
- package/build/esm/utils/isCloudflareClass.js +2 -8
- package/build/esm/utils/isCloudflareClass.js.map +1 -1
- package/build/esm/utils/rpcMeta.js +8 -32
- package/build/esm/utils/rpcMeta.js.map +1 -1
- package/build/esm/utils/rpcOptions.js +9 -32
- package/build/esm/utils/rpcOptions.js.map +1 -1
- package/build/esm/utils/streaming.js +3 -29
- package/build/esm/utils/streaming.js.map +1 -1
- package/build/esm/utils/traceLinks.js +8 -33
- package/build/esm/utils/traceLinks.js.map +1 -1
- package/build/esm/vendor/stacktrace.js +6 -27
- package/build/esm/vendor/stacktrace.js.map +1 -1
- package/build/esm/withSentry.js +16 -47
- package/build/esm/withSentry.js.map +1 -1
- package/build/esm/workflows.js +40 -100
- package/build/esm/workflows.js.map +1 -1
- package/build/esm/wrapMethodWithSentry.js +110 -167
- package/build/esm/wrapMethodWithSentry.js.map +1 -1
- package/build/types/client.d.ts.map +1 -1
- package/build/types/flush.d.ts.map +1 -1
- package/build/types/instrumentations/worker/instrumentFetch.d.ts.map +1 -1
- package/build/types/pages-plugin.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -1,43 +1,28 @@
|
|
|
1
1
|
import { instrumentDurableObjectStorage } from '../instrumentations/instrumentDurableObjectStorage.js';
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Instruments an execution context or DurableObjectState with Sentry tracing.
|
|
5
|
-
*
|
|
6
|
-
* Creates a copy of the context that:
|
|
7
|
-
* - Allows overriding of methods (e.g., waitUntil)
|
|
8
|
-
* - For DurableObjectState: instruments storage operations (get, put, delete, list, etc.)
|
|
9
|
-
* to create Sentry spans automatically
|
|
10
|
-
*
|
|
11
|
-
* @param ctx - The execution context or DurableObjectState to instrument
|
|
12
|
-
* @returns An instrumented copy of the context
|
|
13
|
-
*/
|
|
14
3
|
function instrumentContext(ctx) {
|
|
15
4
|
if (!ctx) return ctx;
|
|
16
|
-
|
|
17
|
-
const overrides = new Map();
|
|
5
|
+
const overrides = /* @__PURE__ */ new Map();
|
|
18
6
|
const contextPrototype = Object.getPrototypeOf(ctx);
|
|
19
|
-
const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype)
|
|
20
|
-
const ownPropertyNames = Object.getOwnPropertyNames(ctx)
|
|
21
|
-
const instrumented = new Set([
|
|
7
|
+
const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype);
|
|
8
|
+
const ownPropertyNames = Object.getOwnPropertyNames(ctx);
|
|
9
|
+
const instrumented = /* @__PURE__ */ new Set(["constructor"]);
|
|
22
10
|
const descriptors = [...ownPropertyNames, ...prototypeMethodNames].reduce(
|
|
23
11
|
(prevDescriptors, methodName) => {
|
|
24
12
|
if (instrumented.has(methodName)) return prevDescriptors;
|
|
25
|
-
if (typeof ctx[methodName] !==
|
|
13
|
+
if (typeof ctx[methodName] !== "function") return prevDescriptors;
|
|
26
14
|
instrumented.add(methodName);
|
|
27
15
|
const overridableDescriptor = makeOverridableDescriptor(overrides, ctx, methodName);
|
|
28
16
|
return {
|
|
29
17
|
...prevDescriptors,
|
|
30
|
-
[methodName]: overridableDescriptor
|
|
18
|
+
[methodName]: overridableDescriptor
|
|
31
19
|
};
|
|
32
20
|
},
|
|
33
|
-
{}
|
|
21
|
+
{}
|
|
34
22
|
);
|
|
35
|
-
|
|
36
|
-
// Check if this is a DurableObjectState context with a storage property
|
|
37
|
-
// If so, wrap the storage with instrumentation
|
|
38
|
-
if ('storage' in ctx && ctx.storage) {
|
|
23
|
+
if ("storage" in ctx && ctx.storage) {
|
|
39
24
|
const originalStorage = ctx.storage;
|
|
40
|
-
const waitUntil =
|
|
25
|
+
const waitUntil = "waitUntil" in ctx && typeof ctx.waitUntil === "function" ? ctx.waitUntil.bind(ctx) : void 0;
|
|
41
26
|
let instrumentedStorage;
|
|
42
27
|
descriptors.storage = {
|
|
43
28
|
configurable: true,
|
|
@@ -47,54 +32,33 @@ function instrumentContext(ctx) {
|
|
|
47
32
|
instrumentedStorage = instrumentDurableObjectStorage(originalStorage, waitUntil);
|
|
48
33
|
}
|
|
49
34
|
return instrumentedStorage;
|
|
50
|
-
}
|
|
35
|
+
}
|
|
51
36
|
};
|
|
52
|
-
// Expose the original uninstrumented storage for internal Sentry operations
|
|
53
|
-
// This avoids creating spans for internal storage operations
|
|
54
37
|
descriptors.originalStorage = {
|
|
55
38
|
configurable: true,
|
|
56
39
|
enumerable: false,
|
|
57
|
-
get: () => originalStorage
|
|
40
|
+
get: () => originalStorage
|
|
58
41
|
};
|
|
59
42
|
}
|
|
60
|
-
|
|
61
43
|
return Object.create(ctx, descriptors);
|
|
62
44
|
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Creates a property descriptor that allows overriding of a method on the given context object.
|
|
66
|
-
*
|
|
67
|
-
* This descriptor supports property overriding with functions only. It delegates method calls to
|
|
68
|
-
* the provided store if an override exists or to the original method on the context otherwise.
|
|
69
|
-
*
|
|
70
|
-
* @param {OverridesStore<ContextType>} store - The storage for overridden methods specific to the context type.
|
|
71
|
-
* @param {ContextType} ctx - The context object that contains the method to be overridden.
|
|
72
|
-
* @param {keyof ContextType} method - The method on the context object to create the overridable descriptor for.
|
|
73
|
-
* @return {PropertyDescriptor} A property descriptor enabling the overriding of the specified method.
|
|
74
|
-
*/
|
|
75
|
-
function makeOverridableDescriptor(
|
|
76
|
-
store,
|
|
77
|
-
ctx,
|
|
78
|
-
method,
|
|
79
|
-
) {
|
|
45
|
+
function makeOverridableDescriptor(store, ctx, method) {
|
|
80
46
|
return {
|
|
81
47
|
configurable: true,
|
|
82
48
|
enumerable: true,
|
|
83
|
-
set: newValue => {
|
|
84
|
-
if (typeof newValue ==
|
|
49
|
+
set: (newValue) => {
|
|
50
|
+
if (typeof newValue == "function") {
|
|
85
51
|
store.set(method, newValue);
|
|
86
52
|
return;
|
|
87
53
|
}
|
|
88
54
|
Reflect.set(ctx, method, newValue);
|
|
89
55
|
},
|
|
90
|
-
|
|
91
56
|
get: () => {
|
|
92
57
|
if (store.has(method)) return store.get(method);
|
|
93
58
|
const methodFunction = Reflect.get(ctx, method);
|
|
94
|
-
if (typeof methodFunction !==
|
|
95
|
-
// We should do bind() to make sure that the method is bound to the context object - otherwise it will not work
|
|
59
|
+
if (typeof methodFunction !== "function") return methodFunction;
|
|
96
60
|
return methodFunction.bind(ctx);
|
|
97
|
-
}
|
|
61
|
+
}
|
|
98
62
|
};
|
|
99
63
|
}
|
|
100
64
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentContext.js","sources":["../../../src/utils/instrumentContext.ts"],"sourcesContent":["import { type DurableObjectState, type DurableObjectStorage, type ExecutionContext } from '@cloudflare/workers-types';\nimport { instrumentDurableObjectStorage } from '../instrumentations/instrumentDurableObjectStorage';\n\ntype ContextType = ExecutionContext | DurableObjectState;\ntype OverridesStore<T extends ContextType> = Map<keyof T, (...args: unknown[]) => unknown>;\n\n/**\n * Instruments an execution context or DurableObjectState with Sentry tracing.\n *\n * Creates a copy of the context that:\n * - Allows overriding of methods (e.g., waitUntil)\n * - For DurableObjectState: instruments storage operations (get, put, delete, list, etc.)\n * to create Sentry spans automatically\n *\n * @param ctx - The execution context or DurableObjectState to instrument\n * @returns An instrumented copy of the context\n */\nexport function instrumentContext<T extends ContextType>(ctx: T): T {\n if (!ctx) return ctx;\n\n const overrides: OverridesStore<T> = new Map();\n const contextPrototype = Object.getPrototypeOf(ctx);\n const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype) as unknown as (keyof T)[];\n const ownPropertyNames = Object.getOwnPropertyNames(ctx) as unknown as (keyof T)[];\n const instrumented = new Set<unknown>(['constructor']);\n const descriptors: PropertyDescriptorMap = [...ownPropertyNames, ...prototypeMethodNames].reduce(\n (prevDescriptors, methodName) => {\n if (instrumented.has(methodName)) return prevDescriptors;\n if (typeof ctx[methodName] !== 'function') return prevDescriptors;\n instrumented.add(methodName);\n const overridableDescriptor = makeOverridableDescriptor(overrides, ctx, methodName);\n return {\n ...prevDescriptors,\n [methodName]: overridableDescriptor,\n };\n },\n {} as PropertyDescriptorMap,\n );\n\n // Check if this is a DurableObjectState context with a storage property\n // If so, wrap the storage with instrumentation\n if ('storage' in ctx && ctx.storage) {\n const originalStorage = ctx.storage;\n const waitUntil = 'waitUntil' in ctx && typeof ctx.waitUntil === 'function' ? ctx.waitUntil.bind(ctx) : undefined;\n let instrumentedStorage: DurableObjectStorage | undefined;\n descriptors.storage = {\n configurable: true,\n enumerable: true,\n get: () => {\n if (!instrumentedStorage) {\n instrumentedStorage = instrumentDurableObjectStorage(originalStorage, waitUntil);\n }\n return instrumentedStorage;\n },\n };\n // Expose the original uninstrumented storage for internal Sentry operations\n // This avoids creating spans for internal storage operations\n descriptors.originalStorage = {\n configurable: true,\n enumerable: false,\n get: () => originalStorage,\n };\n }\n\n return Object.create(ctx, descriptors);\n}\n\n/**\n * Creates a property descriptor that allows overriding of a method on the given context object.\n *\n * This descriptor supports property overriding with functions only. It delegates method calls to\n * the provided store if an override exists or to the original method on the context otherwise.\n *\n * @param {OverridesStore<ContextType>} store - The storage for overridden methods specific to the context type.\n * @param {ContextType} ctx - The context object that contains the method to be overridden.\n * @param {keyof ContextType} method - The method on the context object to create the overridable descriptor for.\n * @return {PropertyDescriptor} A property descriptor enabling the overriding of the specified method.\n */\nfunction makeOverridableDescriptor<T extends ContextType>(\n store: OverridesStore<T>,\n ctx: T,\n method: keyof T,\n): PropertyDescriptor {\n return {\n configurable: true,\n enumerable: true,\n set: newValue => {\n if (typeof newValue == 'function') {\n store.set(method, newValue);\n return;\n }\n Reflect.set(ctx, method, newValue);\n },\n\n get: () => {\n if (store.has(method)) return store.get(method);\n const methodFunction = Reflect.get(ctx, method);\n if (typeof methodFunction !== 'function') return methodFunction;\n // We should do bind() to make sure that the method is bound to the context object - otherwise it will not work\n return methodFunction.bind(ctx);\n },\n };\n}\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"instrumentContext.js","sources":["../../../src/utils/instrumentContext.ts"],"sourcesContent":["import { type DurableObjectState, type DurableObjectStorage, type ExecutionContext } from '@cloudflare/workers-types';\nimport { instrumentDurableObjectStorage } from '../instrumentations/instrumentDurableObjectStorage';\n\ntype ContextType = ExecutionContext | DurableObjectState;\ntype OverridesStore<T extends ContextType> = Map<keyof T, (...args: unknown[]) => unknown>;\n\n/**\n * Instruments an execution context or DurableObjectState with Sentry tracing.\n *\n * Creates a copy of the context that:\n * - Allows overriding of methods (e.g., waitUntil)\n * - For DurableObjectState: instruments storage operations (get, put, delete, list, etc.)\n * to create Sentry spans automatically\n *\n * @param ctx - The execution context or DurableObjectState to instrument\n * @returns An instrumented copy of the context\n */\nexport function instrumentContext<T extends ContextType>(ctx: T): T {\n if (!ctx) return ctx;\n\n const overrides: OverridesStore<T> = new Map();\n const contextPrototype = Object.getPrototypeOf(ctx);\n const prototypeMethodNames = Object.getOwnPropertyNames(contextPrototype) as unknown as (keyof T)[];\n const ownPropertyNames = Object.getOwnPropertyNames(ctx) as unknown as (keyof T)[];\n const instrumented = new Set<unknown>(['constructor']);\n const descriptors: PropertyDescriptorMap = [...ownPropertyNames, ...prototypeMethodNames].reduce(\n (prevDescriptors, methodName) => {\n if (instrumented.has(methodName)) return prevDescriptors;\n if (typeof ctx[methodName] !== 'function') return prevDescriptors;\n instrumented.add(methodName);\n const overridableDescriptor = makeOverridableDescriptor(overrides, ctx, methodName);\n return {\n ...prevDescriptors,\n [methodName]: overridableDescriptor,\n };\n },\n {} as PropertyDescriptorMap,\n );\n\n // Check if this is a DurableObjectState context with a storage property\n // If so, wrap the storage with instrumentation\n if ('storage' in ctx && ctx.storage) {\n const originalStorage = ctx.storage;\n const waitUntil = 'waitUntil' in ctx && typeof ctx.waitUntil === 'function' ? ctx.waitUntil.bind(ctx) : undefined;\n let instrumentedStorage: DurableObjectStorage | undefined;\n descriptors.storage = {\n configurable: true,\n enumerable: true,\n get: () => {\n if (!instrumentedStorage) {\n instrumentedStorage = instrumentDurableObjectStorage(originalStorage, waitUntil);\n }\n return instrumentedStorage;\n },\n };\n // Expose the original uninstrumented storage for internal Sentry operations\n // This avoids creating spans for internal storage operations\n descriptors.originalStorage = {\n configurable: true,\n enumerable: false,\n get: () => originalStorage,\n };\n }\n\n return Object.create(ctx, descriptors);\n}\n\n/**\n * Creates a property descriptor that allows overriding of a method on the given context object.\n *\n * This descriptor supports property overriding with functions only. It delegates method calls to\n * the provided store if an override exists or to the original method on the context otherwise.\n *\n * @param {OverridesStore<ContextType>} store - The storage for overridden methods specific to the context type.\n * @param {ContextType} ctx - The context object that contains the method to be overridden.\n * @param {keyof ContextType} method - The method on the context object to create the overridable descriptor for.\n * @return {PropertyDescriptor} A property descriptor enabling the overriding of the specified method.\n */\nfunction makeOverridableDescriptor<T extends ContextType>(\n store: OverridesStore<T>,\n ctx: T,\n method: keyof T,\n): PropertyDescriptor {\n return {\n configurable: true,\n enumerable: true,\n set: newValue => {\n if (typeof newValue == 'function') {\n store.set(method, newValue);\n return;\n }\n Reflect.set(ctx, method, newValue);\n },\n\n get: () => {\n if (store.has(method)) return store.get(method);\n const methodFunction = Reflect.get(ctx, method);\n if (typeof methodFunction !== 'function') return methodFunction;\n // We should do bind() to make sure that the method is bound to the context object - otherwise it will not work\n return methodFunction.bind(ctx);\n },\n };\n}\n"],"names":[],"mappings":";;AAiBO,SAAS,kBAAyC,GAAA,EAAW;AAClE,EAAA,IAAI,CAAC,KAAK,OAAO,GAAA;AAEjB,EAAA,MAAM,SAAA,uBAAmC,GAAA,EAAI;AAC7C,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,cAAA,CAAe,GAAG,CAAA;AAClD,EAAA,MAAM,oBAAA,GAAuB,MAAA,CAAO,mBAAA,CAAoB,gBAAgB,CAAA;AACxE,EAAA,MAAM,gBAAA,GAAmB,MAAA,CAAO,mBAAA,CAAoB,GAAG,CAAA;AACvD,EAAA,MAAM,YAAA,mBAAe,IAAI,GAAA,CAAa,CAAC,aAAa,CAAC,CAAA;AACrD,EAAA,MAAM,cAAqC,CAAC,GAAG,gBAAA,EAAkB,GAAG,oBAAoB,CAAA,CAAE,MAAA;AAAA,IACxF,CAAC,iBAAiB,UAAA,KAAe;AAC/B,MAAA,IAAI,YAAA,CAAa,GAAA,CAAI,UAAU,CAAA,EAAG,OAAO,eAAA;AACzC,MAAA,IAAI,OAAO,GAAA,CAAI,UAAU,CAAA,KAAM,YAAY,OAAO,eAAA;AAClD,MAAA,YAAA,CAAa,IAAI,UAAU,CAAA;AAC3B,MAAA,MAAM,qBAAA,GAAwB,yBAAA,CAA0B,SAAA,EAAW,GAAA,EAAK,UAAU,CAAA;AAClF,MAAA,OAAO;AAAA,QACL,GAAG,eAAA;AAAA,QACH,CAAC,UAAU,GAAG;AAAA,OAChB;AAAA,IACF,CAAA;AAAA,IACA;AAAC,GACH;AAIA,EAAA,IAAI,SAAA,IAAa,GAAA,IAAO,GAAA,CAAI,OAAA,EAAS;AACnC,IAAA,MAAM,kBAAkB,GAAA,CAAI,OAAA;AAC5B,IAAA,MAAM,SAAA,GAAY,WAAA,IAAe,GAAA,IAAO,OAAO,GAAA,CAAI,SAAA,KAAc,UAAA,GAAa,GAAA,CAAI,SAAA,CAAU,IAAA,CAAK,GAAG,CAAA,GAAI,MAAA;AACxG,IAAA,IAAI,mBAAA;AACJ,IAAA,WAAA,CAAY,OAAA,GAAU;AAAA,MACpB,YAAA,EAAc,IAAA;AAAA,MACd,UAAA,EAAY,IAAA;AAAA,MACZ,KAAK,MAAM;AACT,QAAA,IAAI,CAAC,mBAAA,EAAqB;AACxB,UAAA,mBAAA,GAAsB,8BAAA,CAA+B,iBAAiB,SAAS,CAAA;AAAA,QACjF;AACA,QAAA,OAAO,mBAAA;AAAA,MACT;AAAA,KACF;AAGA,IAAA,WAAA,CAAY,eAAA,GAAkB;AAAA,MAC5B,YAAA,EAAc,IAAA;AAAA,MACd,UAAA,EAAY,KAAA;AAAA,MACZ,KAAK,MAAM;AAAA,KACb;AAAA,EACF;AAEA,EAAA,OAAO,MAAA,CAAO,MAAA,CAAO,GAAA,EAAK,WAAW,CAAA;AACvC;AAaA,SAAS,yBAAA,CACP,KAAA,EACA,GAAA,EACA,MAAA,EACoB;AACpB,EAAA,OAAO;AAAA,IACL,YAAA,EAAc,IAAA;AAAA,IACd,UAAA,EAAY,IAAA;AAAA,IACZ,KAAK,CAAA,QAAA,KAAY;AACf,MAAA,IAAI,OAAO,YAAY,UAAA,EAAY;AACjC,QAAA,KAAA,CAAM,GAAA,CAAI,QAAQ,QAAQ,CAAA;AAC1B,QAAA;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,IACnC,CAAA;AAAA,IAEA,KAAK,MAAM;AACT,MAAA,IAAI,MAAM,GAAA,CAAI,MAAM,GAAG,OAAO,KAAA,CAAM,IAAI,MAAM,CAAA;AAC9C,MAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,GAAA,CAAI,GAAA,EAAK,MAAM,CAAA;AAC9C,MAAA,IAAI,OAAO,cAAA,KAAmB,UAAA,EAAY,OAAO,cAAA;AAEjD,MAAA,OAAO,cAAA,CAAe,KAAK,GAAG,CAAA;AAAA,IAChC;AAAA,GACF;AACF;;;;"}
|
|
@@ -1,36 +1,16 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Checks if a value is a JSRPC proxy (service binding).
|
|
3
|
-
*
|
|
4
|
-
* JSRPC proxies return a truthy value for ANY property access, including
|
|
5
|
-
* properties that don't exist. This makes other duck-type checks unreliable
|
|
6
|
-
* unless we exclude JSRPC first.
|
|
7
|
-
*
|
|
8
|
-
* Must be checked before other binding type checks.
|
|
9
|
-
*/
|
|
10
1
|
function isJSRPC(item) {
|
|
11
2
|
try {
|
|
12
|
-
return !!
|
|
3
|
+
return !!item[`__some_property_that_will_never_exist__${Math.random()}`];
|
|
13
4
|
} catch {
|
|
14
5
|
return false;
|
|
15
6
|
}
|
|
16
7
|
}
|
|
17
|
-
|
|
18
8
|
const isNotJSRPC = (item) => !isJSRPC(item);
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Duck-type check for DurableObjectNamespace bindings.
|
|
22
|
-
* DurableObjectNamespace has `idFromName`, `idFromString`, `get`, `newUniqueId`.
|
|
23
|
-
*/
|
|
24
9
|
function isDurableObjectNamespace(item) {
|
|
25
|
-
return item != null && isNotJSRPC(item) && typeof item.idFromName ===
|
|
10
|
+
return item != null && isNotJSRPC(item) && typeof item.idFromName === "function";
|
|
26
11
|
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Duck-type check for Queue producer bindings.
|
|
30
|
-
* Queue has `send` and `sendBatch` async methods.
|
|
31
|
-
*/
|
|
32
12
|
function isQueue(item) {
|
|
33
|
-
return item != null && isNotJSRPC(item) && typeof item.send ===
|
|
13
|
+
return item != null && isNotJSRPC(item) && typeof item.send === "function" && typeof item.sendBatch === "function";
|
|
34
14
|
}
|
|
35
15
|
|
|
36
16
|
export { isDurableObjectNamespace, isJSRPC, isQueue };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isBinding.js","sources":["../../../src/utils/isBinding.ts"],"sourcesContent":["/**\n * Adapted from https://github.com/evanderkoogh/otel-cf-workers/blob/effeb549f0a4ed1c55ea0c4f0d8e8e37e5494fb3/src/instrumentation/env.ts\n *\n * BSD 3-Clause License\n *\n * Copyright (c) 2023, Erwin van der Koogh\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * 3. Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport type { DurableObjectNamespace, Queue } from '@cloudflare/workers-types';\n\n/**\n * Checks if a value is a JSRPC proxy (service binding).\n *\n * JSRPC proxies return a truthy value for ANY property access, including\n * properties that don't exist. This makes other duck-type checks unreliable\n * unless we exclude JSRPC first.\n *\n * Must be checked before other binding type checks.\n */\nexport function isJSRPC(item: unknown): item is Service {\n try {\n return !!(item as Record<string, unknown>)[`__some_property_that_will_never_exist__${Math.random()}`];\n } catch {\n return false;\n }\n}\n\nconst isNotJSRPC = (item: unknown): item is Record<string, unknown> => !isJSRPC(item);\n\n/**\n * Duck-type check for DurableObjectNamespace bindings.\n * DurableObjectNamespace has `idFromName`, `idFromString`, `get`, `newUniqueId`.\n */\nexport function isDurableObjectNamespace(item: unknown): item is DurableObjectNamespace {\n return item != null && isNotJSRPC(item) && typeof item.idFromName === 'function';\n}\n\n/**\n * Duck-type check for Queue producer bindings.\n * Queue has `send` and `sendBatch` async methods.\n */\nexport function isQueue(item: unknown): item is Queue {\n return item != null && isNotJSRPC(item) && typeof item.send === 'function' && typeof item.sendBatch === 'function';\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"isBinding.js","sources":["../../../src/utils/isBinding.ts"],"sourcesContent":["/**\n * Adapted from https://github.com/evanderkoogh/otel-cf-workers/blob/effeb549f0a4ed1c55ea0c4f0d8e8e37e5494fb3/src/instrumentation/env.ts\n *\n * BSD 3-Clause License\n *\n * Copyright (c) 2023, Erwin van der Koogh\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n * 1. Redistributions of source code must retain the above copyright notice, this\n * list of conditions and the following disclaimer.\n *\n * 2. Redistributions in binary form must reproduce the above copyright notice,\n * this list of conditions and the following disclaimer in the documentation\n * and/or other materials provided with the distribution.\n *\n * 3. Neither the name of the copyright holder nor the names of its\n * contributors may be used to endorse or promote products derived from\n * this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n */\n\nimport type { DurableObjectNamespace, Queue } from '@cloudflare/workers-types';\n\n/**\n * Checks if a value is a JSRPC proxy (service binding).\n *\n * JSRPC proxies return a truthy value for ANY property access, including\n * properties that don't exist. This makes other duck-type checks unreliable\n * unless we exclude JSRPC first.\n *\n * Must be checked before other binding type checks.\n */\nexport function isJSRPC(item: unknown): item is Service {\n try {\n return !!(item as Record<string, unknown>)[`__some_property_that_will_never_exist__${Math.random()}`];\n } catch {\n return false;\n }\n}\n\nconst isNotJSRPC = (item: unknown): item is Record<string, unknown> => !isJSRPC(item);\n\n/**\n * Duck-type check for DurableObjectNamespace bindings.\n * DurableObjectNamespace has `idFromName`, `idFromString`, `get`, `newUniqueId`.\n */\nexport function isDurableObjectNamespace(item: unknown): item is DurableObjectNamespace {\n return item != null && isNotJSRPC(item) && typeof item.idFromName === 'function';\n}\n\n/**\n * Duck-type check for Queue producer bindings.\n * Queue has `send` and `sendBatch` async methods.\n */\nexport function isQueue(item: unknown): item is Queue {\n return item != null && isNotJSRPC(item) && typeof item.send === 'function' && typeof item.sendBatch === 'function';\n}\n"],"names":[],"mappings":"AA4CO,SAAS,QAAQ,IAAA,EAAgC;AACtD,EAAA,IAAI;AACF,IAAA,OAAO,CAAC,CAAE,IAAA,CAAiC,0CAA0C,IAAA,CAAK,MAAA,EAAQ,CAAA,CAAE,CAAA;AAAA,EACtG,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;AAEA,MAAM,UAAA,GAAa,CAAC,IAAA,KAAmD,CAAC,QAAQ,IAAI,CAAA;AAM7E,SAAS,yBAAyB,IAAA,EAA+C;AACtF,EAAA,OAAO,QAAQ,IAAA,IAAQ,UAAA,CAAW,IAAI,CAAA,IAAK,OAAO,KAAK,UAAA,KAAe,UAAA;AACxE;AAMO,SAAS,QAAQ,IAAA,EAA8B;AACpD,EAAA,OAAO,IAAA,IAAQ,IAAA,IAAQ,UAAA,CAAW,IAAI,CAAA,IAAK,OAAO,IAAA,CAAK,IAAA,KAAS,UAAA,IAAc,OAAO,IAAA,CAAK,SAAA,KAAc,UAAA;AAC1G;;;;"}
|
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
function isCloudflareClass(value, className) {
|
|
2
|
-
if (!value || typeof value !==
|
|
2
|
+
if (!value || typeof value !== "function") {
|
|
3
3
|
return false;
|
|
4
4
|
}
|
|
5
|
-
|
|
6
5
|
if (value.name === className) {
|
|
7
6
|
return false;
|
|
8
7
|
}
|
|
9
|
-
|
|
10
8
|
let proto = value.prototype;
|
|
11
|
-
|
|
12
9
|
while (proto) {
|
|
13
|
-
const ctor =
|
|
10
|
+
const ctor = proto.constructor;
|
|
14
11
|
const constructorName = ctor?.name;
|
|
15
|
-
|
|
16
12
|
if (constructorName === className) {
|
|
17
13
|
return true;
|
|
18
14
|
}
|
|
19
|
-
|
|
20
15
|
proto = Object.getPrototypeOf(proto);
|
|
21
16
|
}
|
|
22
|
-
|
|
23
17
|
return false;
|
|
24
18
|
}
|
|
25
19
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"isCloudflareClass.js","sources":["../../../src/utils/isCloudflareClass.ts"],"sourcesContent":["import type { DurableObject, WorkflowEntrypoint } from 'cloudflare:workers';\nimport type { WorkerEntrypointConstructor } from '../instrumentations/instrumentWorkerEntrypoint';\ntype CloudflareClassName = 'WorkerEntrypoint' | 'DurableObject' | 'WorkflowEntrypoint';\n\n/**\n * Checks if a class constructor extends a specific Cloudflare base class.\n *\n * Uses prototype chain walking with constructor names rather than instanceof,\n * so it works in Node at build time without requiring the cloudflare:workers\n * module (which only exists in the Workers runtime).\n *\n * This is used to differentiate between different Cloudflare worker types:\n * - WorkerEntrypoint: Class-based workers (used with instrumentWorkerEntrypoint)\n * - DurableObject: Durable Object classes\n * - Workflow: Workflow classes\n *\n * For ExportedHandler (plain objects), this will return false for all types.\n *\n * @param value - The value to check (typically a class constructor)\n * @param className - The Cloudflare base class name to check against\n * @returns true if the value is a class that extends the specified Cloudflare class\n *\n * @example\n * ```ts\n * isCloudflareClass(MyWorker, 'WorkerEntrypoint') // true if MyWorker extends WorkerEntrypoint\n * isCloudflareClass(MyDO, 'DurableObject') // true if MyDO extends DurableObject\n * ```\n */\nexport function isCloudflareClass(value: unknown, className: 'WorkerEntrypoint'): value is WorkerEntrypointConstructor;\nexport function isCloudflareClass(\n value: unknown,\n className: 'DurableObject',\n): value is new (...args: unknown[]) => DurableObject;\nexport function isCloudflareClass(\n value: unknown,\n className: 'WorkflowEntrypoint',\n): value is new (...args: unknown[]) => WorkflowEntrypoint;\nexport function isCloudflareClass(value: unknown, className: CloudflareClassName): boolean {\n if (!value || typeof value !== 'function') {\n return false;\n }\n\n if (value.name === className) {\n return false;\n }\n\n let proto: object | null = value.prototype;\n\n while (proto) {\n const ctor = (proto as { constructor?: { name?: string } }).constructor;\n const constructorName = ctor?.name;\n\n if (constructorName === className) {\n return true;\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n return false;\n}\n"],"names":[],"mappings":"AAqCO,SAAS,
|
|
1
|
+
{"version":3,"file":"isCloudflareClass.js","sources":["../../../src/utils/isCloudflareClass.ts"],"sourcesContent":["import type { DurableObject, WorkflowEntrypoint } from 'cloudflare:workers';\nimport type { WorkerEntrypointConstructor } from '../instrumentations/instrumentWorkerEntrypoint';\ntype CloudflareClassName = 'WorkerEntrypoint' | 'DurableObject' | 'WorkflowEntrypoint';\n\n/**\n * Checks if a class constructor extends a specific Cloudflare base class.\n *\n * Uses prototype chain walking with constructor names rather than instanceof,\n * so it works in Node at build time without requiring the cloudflare:workers\n * module (which only exists in the Workers runtime).\n *\n * This is used to differentiate between different Cloudflare worker types:\n * - WorkerEntrypoint: Class-based workers (used with instrumentWorkerEntrypoint)\n * - DurableObject: Durable Object classes\n * - Workflow: Workflow classes\n *\n * For ExportedHandler (plain objects), this will return false for all types.\n *\n * @param value - The value to check (typically a class constructor)\n * @param className - The Cloudflare base class name to check against\n * @returns true if the value is a class that extends the specified Cloudflare class\n *\n * @example\n * ```ts\n * isCloudflareClass(MyWorker, 'WorkerEntrypoint') // true if MyWorker extends WorkerEntrypoint\n * isCloudflareClass(MyDO, 'DurableObject') // true if MyDO extends DurableObject\n * ```\n */\nexport function isCloudflareClass(value: unknown, className: 'WorkerEntrypoint'): value is WorkerEntrypointConstructor;\nexport function isCloudflareClass(\n value: unknown,\n className: 'DurableObject',\n): value is new (...args: unknown[]) => DurableObject;\nexport function isCloudflareClass(\n value: unknown,\n className: 'WorkflowEntrypoint',\n): value is new (...args: unknown[]) => WorkflowEntrypoint;\nexport function isCloudflareClass(value: unknown, className: CloudflareClassName): boolean {\n if (!value || typeof value !== 'function') {\n return false;\n }\n\n if (value.name === className) {\n return false;\n }\n\n let proto: object | null = value.prototype;\n\n while (proto) {\n const ctor = (proto as { constructor?: { name?: string } }).constructor;\n const constructorName = ctor?.name;\n\n if (constructorName === className) {\n return true;\n }\n\n proto = Object.getPrototypeOf(proto);\n }\n\n return false;\n}\n"],"names":[],"mappings":"AAqCO,SAAS,iBAAA,CAAkB,OAAgB,SAAA,EAAyC;AACzF,EAAA,IAAI,CAAC,KAAA,IAAS,OAAO,KAAA,KAAU,UAAA,EAAY;AACzC,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,KAAA,CAAM,SAAS,SAAA,EAAW;AAC5B,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,QAAuB,KAAA,CAAM,SAAA;AAEjC,EAAA,OAAO,KAAA,EAAO;AACZ,IAAA,MAAM,OAAQ,KAAA,CAA8C,WAAA;AAC5D,IAAA,MAAM,kBAAkB,IAAA,EAAM,IAAA;AAE9B,IAAA,IAAI,oBAAoB,SAAA,EAAW;AACjC,MAAA,OAAO,IAAA;AAAA,IACT;AAEA,IAAA,KAAA,GAAQ,MAAA,CAAO,eAAe,KAAK,CAAA;AAAA,EACrC;AAEA,EAAA,OAAO,KAAA;AACT;;;;"}
|
|
@@ -1,55 +1,31 @@
|
|
|
1
1
|
import { getTraceData } from '@sentry/core';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
* Key used to identify Sentry RPC metadata in a trailing argument.
|
|
5
|
-
* This enables transparent trace propagation across Cloudflare Workers RPC
|
|
6
|
-
* calls (Cap'n Proto), which have no native header/metadata support.
|
|
7
|
-
*/
|
|
8
|
-
const SENTRY_RPC_META_KEY = '__sentry_rpc_meta__';
|
|
9
|
-
|
|
3
|
+
const SENTRY_RPC_META_KEY = "__sentry_rpc_meta__";
|
|
10
4
|
function isSentryRpcMeta(value) {
|
|
11
|
-
if (typeof value !==
|
|
5
|
+
if (typeof value !== "object" || value === null || !(SENTRY_RPC_META_KEY in value)) {
|
|
12
6
|
return false;
|
|
13
7
|
}
|
|
14
|
-
const sentry =
|
|
15
|
-
return typeof sentry ===
|
|
8
|
+
const sentry = value.__sentry_rpc_meta__;
|
|
9
|
+
return typeof sentry === "object" && sentry !== null;
|
|
16
10
|
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Appends Sentry RPC metadata to an args array for trace propagation.
|
|
20
|
-
* If no active trace exists, returns the original args unchanged.
|
|
21
|
-
*/
|
|
22
11
|
function appendRpcMeta(args) {
|
|
23
12
|
const traceData = getTraceData();
|
|
24
|
-
|
|
25
|
-
if (!traceData['sentry-trace']) {
|
|
13
|
+
if (!traceData["sentry-trace"]) {
|
|
26
14
|
return args;
|
|
27
15
|
}
|
|
28
|
-
|
|
29
16
|
return [...args, { [SENTRY_RPC_META_KEY]: traceData }];
|
|
30
17
|
}
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Extracts Sentry RPC metadata from the trailing argument of an args array.
|
|
34
|
-
* Returns cleaned args (without meta) and the extracted trace data if found.
|
|
35
|
-
*/
|
|
36
|
-
function extractRpcMeta(
|
|
37
|
-
args,
|
|
38
|
-
)
|
|
39
|
-
|
|
40
|
-
{
|
|
18
|
+
function extractRpcMeta(args) {
|
|
41
19
|
if (args.length === 0) {
|
|
42
20
|
return { args };
|
|
43
21
|
}
|
|
44
|
-
|
|
45
22
|
const last = args[args.length - 1];
|
|
46
23
|
if (isSentryRpcMeta(last)) {
|
|
47
24
|
return {
|
|
48
|
-
args: args.slice(0, -1)
|
|
49
|
-
rpcMeta: last.__sentry_rpc_meta__
|
|
25
|
+
args: args.slice(0, -1),
|
|
26
|
+
rpcMeta: last.__sentry_rpc_meta__
|
|
50
27
|
};
|
|
51
28
|
}
|
|
52
|
-
|
|
53
29
|
return { args };
|
|
54
30
|
}
|
|
55
31
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpcMeta.js","sources":["../../../src/utils/rpcMeta.ts"],"sourcesContent":["import { getTraceData, type SerializedTraceData } from '@sentry/core';\n\n/**\n * Key used to identify Sentry RPC metadata in a trailing argument.\n * This enables transparent trace propagation across Cloudflare Workers RPC\n * calls (Cap'n Proto), which have no native header/metadata support.\n */\nconst SENTRY_RPC_META_KEY = '__sentry_rpc_meta__';\n\ninterface SentryRpcMeta {\n __sentry_rpc_meta__: SerializedTraceData;\n}\n\nfunction isSentryRpcMeta(value: unknown): value is SentryRpcMeta {\n if (typeof value !== 'object' || value === null || !(SENTRY_RPC_META_KEY in value)) {\n return false;\n }\n const sentry = (value as SentryRpcMeta).__sentry_rpc_meta__;\n return typeof sentry === 'object' && sentry !== null;\n}\n\n/**\n * Appends Sentry RPC metadata to an args array for trace propagation.\n * If no active trace exists, returns the original args unchanged.\n */\nexport function appendRpcMeta(args: unknown[]): unknown[] {\n const traceData = getTraceData();\n\n if (!traceData['sentry-trace']) {\n return args;\n }\n\n return [...args, { [SENTRY_RPC_META_KEY]: traceData }];\n}\n\n/**\n * Extracts Sentry RPC metadata from the trailing argument of an args array.\n * Returns cleaned args (without meta) and the extracted trace data if found.\n */\nexport function extractRpcMeta<T extends unknown[]>(\n args: T,\n): {\n args: T;\n rpcMeta?: SerializedTraceData;\n} {\n if (args.length === 0) {\n return { args };\n }\n\n const last = args[args.length - 1];\n if (isSentryRpcMeta(last)) {\n return {\n args: args.slice(0, -1) as T,\n rpcMeta: last.__sentry_rpc_meta__,\n };\n }\n\n return { args };\n}\n"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"rpcMeta.js","sources":["../../../src/utils/rpcMeta.ts"],"sourcesContent":["import { getTraceData, type SerializedTraceData } from '@sentry/core';\n\n/**\n * Key used to identify Sentry RPC metadata in a trailing argument.\n * This enables transparent trace propagation across Cloudflare Workers RPC\n * calls (Cap'n Proto), which have no native header/metadata support.\n */\nconst SENTRY_RPC_META_KEY = '__sentry_rpc_meta__';\n\ninterface SentryRpcMeta {\n __sentry_rpc_meta__: SerializedTraceData;\n}\n\nfunction isSentryRpcMeta(value: unknown): value is SentryRpcMeta {\n if (typeof value !== 'object' || value === null || !(SENTRY_RPC_META_KEY in value)) {\n return false;\n }\n const sentry = (value as SentryRpcMeta).__sentry_rpc_meta__;\n return typeof sentry === 'object' && sentry !== null;\n}\n\n/**\n * Appends Sentry RPC metadata to an args array for trace propagation.\n * If no active trace exists, returns the original args unchanged.\n */\nexport function appendRpcMeta(args: unknown[]): unknown[] {\n const traceData = getTraceData();\n\n if (!traceData['sentry-trace']) {\n return args;\n }\n\n return [...args, { [SENTRY_RPC_META_KEY]: traceData }];\n}\n\n/**\n * Extracts Sentry RPC metadata from the trailing argument of an args array.\n * Returns cleaned args (without meta) and the extracted trace data if found.\n */\nexport function extractRpcMeta<T extends unknown[]>(\n args: T,\n): {\n args: T;\n rpcMeta?: SerializedTraceData;\n} {\n if (args.length === 0) {\n return { args };\n }\n\n const last = args[args.length - 1];\n if (isSentryRpcMeta(last)) {\n return {\n args: args.slice(0, -1) as T,\n rpcMeta: last.__sentry_rpc_meta__,\n };\n }\n\n return { args };\n}\n"],"names":[],"mappings":";;AAOA,MAAM,mBAAA,GAAsB,qBAAA;AAM5B,SAAS,gBAAgB,KAAA,EAAwC;AAC/D,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,UAAU,IAAA,IAAQ,EAAE,uBAAuB,KAAA,CAAA,EAAQ;AAClF,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,SAAU,KAAA,CAAwB,mBAAA;AACxC,EAAA,OAAO,OAAO,MAAA,KAAW,QAAA,IAAY,MAAA,KAAW,IAAA;AAClD;AAMO,SAAS,cAAc,IAAA,EAA4B;AACxD,EAAA,MAAM,YAAY,YAAA,EAAa;AAE/B,EAAA,IAAI,CAAC,SAAA,CAAU,cAAc,CAAA,EAAG;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,OAAO,CAAC,GAAG,IAAA,EAAM,EAAE,CAAC,mBAAmB,GAAG,WAAW,CAAA;AACvD;AAMO,SAAS,eACd,IAAA,EAIA;AACA,EAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,IAAA,OAAO,EAAE,IAAA,EAAK;AAAA,EAChB;AAEA,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AACjC,EAAA,IAAI,eAAA,CAAgB,IAAI,CAAA,EAAG;AACzB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAAA,MACtB,SAAS,IAAA,CAAK;AAAA,KAChB;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,IAAA,EAAK;AAChB;;;;"}
|
|
@@ -1,45 +1,22 @@
|
|
|
1
1
|
import { debug } from '@sentry/core';
|
|
2
2
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Gets the effective RPC propagation setting, handling deprecation of `instrumentPrototypeMethods`.
|
|
6
|
-
*
|
|
7
|
-
* Priority:
|
|
8
|
-
* 1. If `enableRpcTracePropagation` is set, use it (ignore `instrumentPrototypeMethods`)
|
|
9
|
-
* 2. If only `instrumentPrototypeMethods` is set, use it with deprecation warning
|
|
10
|
-
* 3. If neither is set, return `false`
|
|
11
|
-
*
|
|
12
|
-
* @returns The effective setting for RPC trace propagation
|
|
13
|
-
*/
|
|
14
4
|
function getEffectiveRpcPropagation(options) {
|
|
15
5
|
const { enableRpcTracePropagation, instrumentPrototypeMethods } = options;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
debug.warn(
|
|
22
|
-
'[Sentry] Both `enableRpcTracePropagation` and `instrumentPrototypeMethods` are set. ' +
|
|
23
|
-
'Using `enableRpcTracePropagation` and ignoring `instrumentPrototypeMethods`.',
|
|
24
|
-
);
|
|
6
|
+
if (enableRpcTracePropagation !== void 0) {
|
|
7
|
+
if (instrumentPrototypeMethods !== void 0) {
|
|
8
|
+
DEBUG_BUILD && debug.warn(
|
|
9
|
+
"[Sentry] Both `enableRpcTracePropagation` and `instrumentPrototypeMethods` are set. Using `enableRpcTracePropagation` and ignoring `instrumentPrototypeMethods`."
|
|
10
|
+
);
|
|
25
11
|
}
|
|
26
12
|
return enableRpcTracePropagation;
|
|
27
13
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
DEBUG_BUILD &&
|
|
32
|
-
debug.warn(
|
|
33
|
-
'[Sentry] `instrumentPrototypeMethods` is deprecated and will be removed in a future major version. ' +
|
|
34
|
-
'Please use `enableRpcTracePropagation` instead.',
|
|
35
|
-
);
|
|
36
|
-
// instrumentPrototypeMethods can be boolean or string[], convert to boolean
|
|
37
|
-
return (
|
|
38
|
-
instrumentPrototypeMethods === true ||
|
|
39
|
-
(Array.isArray(instrumentPrototypeMethods) && instrumentPrototypeMethods.length > 0)
|
|
14
|
+
if (instrumentPrototypeMethods !== void 0) {
|
|
15
|
+
DEBUG_BUILD && debug.warn(
|
|
16
|
+
"[Sentry] `instrumentPrototypeMethods` is deprecated and will be removed in a future major version. Please use `enableRpcTracePropagation` instead."
|
|
40
17
|
);
|
|
18
|
+
return instrumentPrototypeMethods === true || Array.isArray(instrumentPrototypeMethods) && instrumentPrototypeMethods.length > 0;
|
|
41
19
|
}
|
|
42
|
-
|
|
43
20
|
return false;
|
|
44
21
|
}
|
|
45
22
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rpcOptions.js","sources":["../../../src/utils/rpcOptions.ts"],"sourcesContent":["import { debug } from '@sentry/core';\nimport type { CloudflareOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Gets the effective RPC propagation setting, handling deprecation of `instrumentPrototypeMethods`.\n *\n * Priority:\n * 1. If `enableRpcTracePropagation` is set, use it (ignore `instrumentPrototypeMethods`)\n * 2. If only `instrumentPrototypeMethods` is set, use it with deprecation warning\n * 3. If neither is set, return `false`\n *\n * @returns The effective setting for RPC trace propagation\n */\nexport function getEffectiveRpcPropagation(options: CloudflareOptions): boolean {\n const { enableRpcTracePropagation, instrumentPrototypeMethods } = options;\n\n // If the new option is explicitly set, use it\n if (enableRpcTracePropagation !== undefined) {\n if (instrumentPrototypeMethods !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Sentry] Both `enableRpcTracePropagation` and `instrumentPrototypeMethods` are set. ' +\n 'Using `enableRpcTracePropagation` and ignoring `instrumentPrototypeMethods`.',\n );\n }\n return enableRpcTracePropagation;\n }\n\n // Fall back to deprecated option with warning\n if (instrumentPrototypeMethods !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Sentry] `instrumentPrototypeMethods` is deprecated and will be removed in a future major version. ' +\n 'Please use `enableRpcTracePropagation` instead.',\n );\n // instrumentPrototypeMethods can be boolean or string[], convert to boolean\n return (\n instrumentPrototypeMethods === true ||\n (Array.isArray(instrumentPrototypeMethods) && instrumentPrototypeMethods.length > 0)\n );\n }\n\n return false;\n}\n"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"rpcOptions.js","sources":["../../../src/utils/rpcOptions.ts"],"sourcesContent":["import { debug } from '@sentry/core';\nimport type { CloudflareOptions } from '../client';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/**\n * Gets the effective RPC propagation setting, handling deprecation of `instrumentPrototypeMethods`.\n *\n * Priority:\n * 1. If `enableRpcTracePropagation` is set, use it (ignore `instrumentPrototypeMethods`)\n * 2. If only `instrumentPrototypeMethods` is set, use it with deprecation warning\n * 3. If neither is set, return `false`\n *\n * @returns The effective setting for RPC trace propagation\n */\nexport function getEffectiveRpcPropagation(options: CloudflareOptions): boolean {\n const { enableRpcTracePropagation, instrumentPrototypeMethods } = options;\n\n // If the new option is explicitly set, use it\n if (enableRpcTracePropagation !== undefined) {\n if (instrumentPrototypeMethods !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Sentry] Both `enableRpcTracePropagation` and `instrumentPrototypeMethods` are set. ' +\n 'Using `enableRpcTracePropagation` and ignoring `instrumentPrototypeMethods`.',\n );\n }\n return enableRpcTracePropagation;\n }\n\n // Fall back to deprecated option with warning\n if (instrumentPrototypeMethods !== undefined) {\n DEBUG_BUILD &&\n debug.warn(\n '[Sentry] `instrumentPrototypeMethods` is deprecated and will be removed in a future major version. ' +\n 'Please use `enableRpcTracePropagation` instead.',\n );\n // instrumentPrototypeMethods can be boolean or string[], convert to boolean\n return (\n instrumentPrototypeMethods === true ||\n (Array.isArray(instrumentPrototypeMethods) && instrumentPrototypeMethods.length > 0)\n );\n }\n\n return false;\n}\n"],"names":[],"mappings":";;;AAcO,SAAS,2BAA2B,OAAA,EAAqC;AAC9E,EAAA,MAAM,EAAE,yBAAA,EAA2B,0BAAA,EAA2B,GAAI,OAAA;AAGlE,EAAA,IAAI,8BAA8B,MAAA,EAAW;AAC3C,IAAA,IAAI,+BAA+B,MAAA,EAAW;AAC5C,MAAA,WAAA,IACE,KAAA,CAAM,IAAA;AAAA,QACJ;AAAA,OAEF;AAAA,IACJ;AACA,IAAA,OAAO,yBAAA;AAAA,EACT;AAGA,EAAA,IAAI,+BAA+B,MAAA,EAAW;AAC5C,IAAA,WAAA,IACE,KAAA,CAAM,IAAA;AAAA,MACJ;AAAA,KAEF;AAEF,IAAA,OACE,+BAA+B,IAAA,IAC9B,KAAA,CAAM,QAAQ,0BAA0B,CAAA,IAAK,2BAA2B,MAAA,GAAS,CAAA;AAAA,EAEtF;AAEA,EAAA,OAAO,KAAA;AACT;;;;"}
|
|
@@ -1,38 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Classifies a Response as streaming or non-streaming.
|
|
3
|
-
*
|
|
4
|
-
* Heuristics:
|
|
5
|
-
* - No body → not streaming
|
|
6
|
-
* - Known streaming Content-Types → streaming (SSE, NDJSON, JSON streaming)
|
|
7
|
-
* - text/plain without Content-Length → streaming (some AI APIs)
|
|
8
|
-
* - Otherwise → not streaming (conservative default, including HTML/SSR)
|
|
9
|
-
*
|
|
10
|
-
* We avoid probing the stream to prevent blocking on transform streams (like injectTraceMetaTags)
|
|
11
|
-
* or SSR streams that may not have data ready immediately.
|
|
12
|
-
*/
|
|
13
1
|
function classifyResponseStreaming(res) {
|
|
14
2
|
if (!res.body) {
|
|
15
3
|
return { isStreaming: false };
|
|
16
4
|
}
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
// Streaming: Known streaming content types
|
|
22
|
-
// - text/event-stream: Server-Sent Events (Vercel AI SDK, real-time APIs)
|
|
23
|
-
// - application/x-ndjson, application/ndjson: Newline-delimited JSON
|
|
24
|
-
// - application/stream+json: JSON streaming
|
|
25
|
-
// - text/plain (without Content-Length): Some AI APIs use this for streaming text
|
|
26
|
-
if (
|
|
27
|
-
/^text\/event-stream\b/i.test(contentType) ||
|
|
28
|
-
/^application\/(x-)?ndjson\b/i.test(contentType) ||
|
|
29
|
-
/^application\/stream\+json\b/i.test(contentType) ||
|
|
30
|
-
(/^text\/plain\b/i.test(contentType) && !contentLength)
|
|
31
|
-
) {
|
|
5
|
+
const contentType = res.headers.get("content-type") ?? "";
|
|
6
|
+
const contentLength = res.headers.get("content-length");
|
|
7
|
+
if (/^text\/event-stream\b/i.test(contentType) || /^application\/(x-)?ndjson\b/i.test(contentType) || /^application\/stream\+json\b/i.test(contentType) || /^text\/plain\b/i.test(contentType) && !contentLength) {
|
|
32
8
|
return { isStreaming: true };
|
|
33
9
|
}
|
|
34
|
-
|
|
35
|
-
// Default: treat as non-streaming
|
|
36
10
|
return { isStreaming: false };
|
|
37
11
|
}
|
|
38
12
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"streaming.js","sources":["../../../src/utils/streaming.ts"],"sourcesContent":["export type StreamingGuess = {\n isStreaming: boolean;\n};\n\n/**\n * Classifies a Response as streaming or non-streaming.\n *\n * Heuristics:\n * - No body → not streaming\n * - Known streaming Content-Types → streaming (SSE, NDJSON, JSON streaming)\n * - text/plain without Content-Length → streaming (some AI APIs)\n * - Otherwise → not streaming (conservative default, including HTML/SSR)\n *\n * We avoid probing the stream to prevent blocking on transform streams (like injectTraceMetaTags)\n * or SSR streams that may not have data ready immediately.\n */\nexport function classifyResponseStreaming(res: Response): StreamingGuess {\n if (!res.body) {\n return { isStreaming: false };\n }\n\n const contentType = res.headers.get('content-type') ?? '';\n const contentLength = res.headers.get('content-length');\n\n // Streaming: Known streaming content types\n // - text/event-stream: Server-Sent Events (Vercel AI SDK, real-time APIs)\n // - application/x-ndjson, application/ndjson: Newline-delimited JSON\n // - application/stream+json: JSON streaming\n // - text/plain (without Content-Length): Some AI APIs use this for streaming text\n if (\n /^text\\/event-stream\\b/i.test(contentType) ||\n /^application\\/(x-)?ndjson\\b/i.test(contentType) ||\n /^application\\/stream\\+json\\b/i.test(contentType) ||\n (/^text\\/plain\\b/i.test(contentType) && !contentLength)\n ) {\n return { isStreaming: true };\n }\n\n // Default: treat as non-streaming\n return { isStreaming: false };\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"streaming.js","sources":["../../../src/utils/streaming.ts"],"sourcesContent":["export type StreamingGuess = {\n isStreaming: boolean;\n};\n\n/**\n * Classifies a Response as streaming or non-streaming.\n *\n * Heuristics:\n * - No body → not streaming\n * - Known streaming Content-Types → streaming (SSE, NDJSON, JSON streaming)\n * - text/plain without Content-Length → streaming (some AI APIs)\n * - Otherwise → not streaming (conservative default, including HTML/SSR)\n *\n * We avoid probing the stream to prevent blocking on transform streams (like injectTraceMetaTags)\n * or SSR streams that may not have data ready immediately.\n */\nexport function classifyResponseStreaming(res: Response): StreamingGuess {\n if (!res.body) {\n return { isStreaming: false };\n }\n\n const contentType = res.headers.get('content-type') ?? '';\n const contentLength = res.headers.get('content-length');\n\n // Streaming: Known streaming content types\n // - text/event-stream: Server-Sent Events (Vercel AI SDK, real-time APIs)\n // - application/x-ndjson, application/ndjson: Newline-delimited JSON\n // - application/stream+json: JSON streaming\n // - text/plain (without Content-Length): Some AI APIs use this for streaming text\n if (\n /^text\\/event-stream\\b/i.test(contentType) ||\n /^application\\/(x-)?ndjson\\b/i.test(contentType) ||\n /^application\\/stream\\+json\\b/i.test(contentType) ||\n (/^text\\/plain\\b/i.test(contentType) && !contentLength)\n ) {\n return { isStreaming: true };\n }\n\n // Default: treat as non-streaming\n return { isStreaming: false };\n}\n"],"names":[],"mappings":"AAgBO,SAAS,0BAA0B,GAAA,EAA+B;AACvE,EAAA,IAAI,CAAC,IAAI,IAAA,EAAM;AACb,IAAA,OAAO,EAAE,aAAa,KAAA,EAAM;AAAA,EAC9B;AAEA,EAAA,MAAM,WAAA,GAAc,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA,IAAK,EAAA;AACvD,EAAA,MAAM,aAAA,GAAgB,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,gBAAgB,CAAA;AAOtD,EAAA,IACE,yBAAyB,IAAA,CAAK,WAAW,CAAA,IACzC,8BAAA,CAA+B,KAAK,WAAW,CAAA,IAC/C,+BAAA,CAAgC,IAAA,CAAK,WAAW,CAAA,IAC/C,iBAAA,CAAkB,KAAK,WAAW,CAAA,IAAK,CAAC,aAAA,EACzC;AACA,IAAA,OAAO,EAAE,aAAa,IAAA,EAAK;AAAA,EAC7B;AAGA,EAAA,OAAO,EAAE,aAAa,KAAA,EAAM;AAC9B;;;;"}
|
|
@@ -2,23 +2,10 @@ import { TraceFlags } from '@opentelemetry/api';
|
|
|
2
2
|
import { getActiveSpan, spanIsSampled, debug, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE } from '@sentry/core';
|
|
3
3
|
import { DEBUG_BUILD } from '../debug-build.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const SENTRY_TRACE_LINK_KEY_PREFIX = '__SENTRY_TRACE_LINK__';
|
|
7
|
-
|
|
8
|
-
/** Stored span context for creating span links */
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Gets the storage key for a specific method's trace link.
|
|
12
|
-
*/
|
|
5
|
+
const SENTRY_TRACE_LINK_KEY_PREFIX = "__SENTRY_TRACE_LINK__";
|
|
13
6
|
function getTraceLinkKey(methodName) {
|
|
14
7
|
return `${SENTRY_TRACE_LINK_KEY_PREFIX}${methodName}`;
|
|
15
8
|
}
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Stores the current span context in Durable Object storage for trace linking.
|
|
19
|
-
* Uses the original uninstrumented storage to avoid creating spans for internal operations.
|
|
20
|
-
* Errors are silently ignored to prevent internal storage failures from propagating to user code.
|
|
21
|
-
*/
|
|
22
9
|
async function storeSpanContext(originalStorage, methodName) {
|
|
23
10
|
try {
|
|
24
11
|
const activeSpan = getActiveSpan();
|
|
@@ -27,45 +14,33 @@ async function storeSpanContext(originalStorage, methodName) {
|
|
|
27
14
|
const storedContext = {
|
|
28
15
|
traceId: spanContext.traceId,
|
|
29
16
|
spanId: spanContext.spanId,
|
|
30
|
-
sampled: spanIsSampled(activeSpan)
|
|
17
|
+
sampled: spanIsSampled(activeSpan)
|
|
31
18
|
};
|
|
32
19
|
await originalStorage.put(getTraceLinkKey(methodName), storedContext);
|
|
33
20
|
}
|
|
34
21
|
} catch (error) {
|
|
35
|
-
// Silently ignore storage errors to prevent internal failures from affecting user code
|
|
36
22
|
DEBUG_BUILD && debug.log(`[CloudflareClient] Error storing span context for method ${methodName}`, error);
|
|
37
23
|
}
|
|
38
24
|
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Retrieves a stored span context from Durable Object storage.
|
|
42
|
-
*/
|
|
43
|
-
async function getStoredSpanContext(
|
|
44
|
-
originalStorage,
|
|
45
|
-
methodName,
|
|
46
|
-
) {
|
|
25
|
+
async function getStoredSpanContext(originalStorage, methodName) {
|
|
47
26
|
try {
|
|
48
27
|
return await originalStorage.get(getTraceLinkKey(methodName));
|
|
49
28
|
} catch {
|
|
50
|
-
return
|
|
29
|
+
return void 0;
|
|
51
30
|
}
|
|
52
31
|
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Builds span links from a stored span context.
|
|
56
|
-
*/
|
|
57
32
|
function buildSpanLinks(storedContext) {
|
|
58
33
|
return [
|
|
59
34
|
{
|
|
60
35
|
context: {
|
|
61
36
|
traceId: storedContext.traceId,
|
|
62
37
|
spanId: storedContext.spanId,
|
|
63
|
-
traceFlags: storedContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE
|
|
38
|
+
traceFlags: storedContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE
|
|
64
39
|
},
|
|
65
40
|
attributes: {
|
|
66
|
-
[SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]:
|
|
67
|
-
}
|
|
68
|
-
}
|
|
41
|
+
[SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: "previous_trace"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
69
44
|
];
|
|
70
45
|
}
|
|
71
46
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traceLinks.js","sources":["../../../src/utils/traceLinks.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport { TraceFlags } from '@opentelemetry/api';\nimport type { SpanLink } from '@sentry/core';\nimport { debug, getActiveSpan, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE, spanIsSampled } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/** Storage key prefix for the span context that links consecutive method invocations */\nconst SENTRY_TRACE_LINK_KEY_PREFIX = '__SENTRY_TRACE_LINK__';\n\n/** Stored span context for creating span links */\nexport interface StoredSpanContext {\n traceId: string;\n spanId: string;\n sampled: boolean;\n}\n\n/**\n * Gets the storage key for a specific method's trace link.\n */\nexport function getTraceLinkKey(methodName: string): string {\n return `${SENTRY_TRACE_LINK_KEY_PREFIX}${methodName}`;\n}\n\n/**\n * Stores the current span context in Durable Object storage for trace linking.\n * Uses the original uninstrumented storage to avoid creating spans for internal operations.\n * Errors are silently ignored to prevent internal storage failures from propagating to user code.\n */\nexport async function storeSpanContext(originalStorage: DurableObjectStorage, methodName: string): Promise<void> {\n try {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n const storedContext: StoredSpanContext = {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n sampled: spanIsSampled(activeSpan),\n };\n await originalStorage.put(getTraceLinkKey(methodName), storedContext);\n }\n } catch (error) {\n // Silently ignore storage errors to prevent internal failures from affecting user code\n DEBUG_BUILD && debug.log(`[CloudflareClient] Error storing span context for method ${methodName}`, error);\n }\n}\n\n/**\n * Retrieves a stored span context from Durable Object storage.\n */\nexport async function getStoredSpanContext(\n originalStorage: DurableObjectStorage,\n methodName: string,\n): Promise<StoredSpanContext | undefined> {\n try {\n return await originalStorage.get<StoredSpanContext>(getTraceLinkKey(methodName));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds span links from a stored span context.\n */\nexport function buildSpanLinks(storedContext: StoredSpanContext): SpanLink[] {\n return [\n {\n context: {\n traceId: storedContext.traceId,\n spanId: storedContext.spanId,\n traceFlags: storedContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,\n },\n attributes: {\n [SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: 'previous_trace',\n },\n },\n ];\n}\n"],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"traceLinks.js","sources":["../../../src/utils/traceLinks.ts"],"sourcesContent":["import type { DurableObjectStorage } from '@cloudflare/workers-types';\nimport { TraceFlags } from '@opentelemetry/api';\nimport type { SpanLink } from '@sentry/core';\nimport { debug, getActiveSpan, SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE, spanIsSampled } from '@sentry/core';\nimport { DEBUG_BUILD } from '../debug-build';\n\n/** Storage key prefix for the span context that links consecutive method invocations */\nconst SENTRY_TRACE_LINK_KEY_PREFIX = '__SENTRY_TRACE_LINK__';\n\n/** Stored span context for creating span links */\nexport interface StoredSpanContext {\n traceId: string;\n spanId: string;\n sampled: boolean;\n}\n\n/**\n * Gets the storage key for a specific method's trace link.\n */\nexport function getTraceLinkKey(methodName: string): string {\n return `${SENTRY_TRACE_LINK_KEY_PREFIX}${methodName}`;\n}\n\n/**\n * Stores the current span context in Durable Object storage for trace linking.\n * Uses the original uninstrumented storage to avoid creating spans for internal operations.\n * Errors are silently ignored to prevent internal storage failures from propagating to user code.\n */\nexport async function storeSpanContext(originalStorage: DurableObjectStorage, methodName: string): Promise<void> {\n try {\n const activeSpan = getActiveSpan();\n if (activeSpan) {\n const spanContext = activeSpan.spanContext();\n const storedContext: StoredSpanContext = {\n traceId: spanContext.traceId,\n spanId: spanContext.spanId,\n sampled: spanIsSampled(activeSpan),\n };\n await originalStorage.put(getTraceLinkKey(methodName), storedContext);\n }\n } catch (error) {\n // Silently ignore storage errors to prevent internal failures from affecting user code\n DEBUG_BUILD && debug.log(`[CloudflareClient] Error storing span context for method ${methodName}`, error);\n }\n}\n\n/**\n * Retrieves a stored span context from Durable Object storage.\n */\nexport async function getStoredSpanContext(\n originalStorage: DurableObjectStorage,\n methodName: string,\n): Promise<StoredSpanContext | undefined> {\n try {\n return await originalStorage.get<StoredSpanContext>(getTraceLinkKey(methodName));\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds span links from a stored span context.\n */\nexport function buildSpanLinks(storedContext: StoredSpanContext): SpanLink[] {\n return [\n {\n context: {\n traceId: storedContext.traceId,\n spanId: storedContext.spanId,\n traceFlags: storedContext.sampled ? TraceFlags.SAMPLED : TraceFlags.NONE,\n },\n attributes: {\n [SEMANTIC_LINK_ATTRIBUTE_LINK_TYPE]: 'previous_trace',\n },\n },\n ];\n}\n"],"names":[],"mappings":";;;;AAOA,MAAM,4BAAA,GAA+B,uBAAA;AAY9B,SAAS,gBAAgB,UAAA,EAA4B;AAC1D,EAAA,OAAO,CAAA,EAAG,4BAA4B,CAAA,EAAG,UAAU,CAAA,CAAA;AACrD;AAOA,eAAsB,gBAAA,CAAiB,iBAAuC,UAAA,EAAmC;AAC/G,EAAA,IAAI;AACF,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,IAAI,UAAA,EAAY;AACd,MAAA,MAAM,WAAA,GAAc,WAAW,WAAA,EAAY;AAC3C,MAAA,MAAM,aAAA,GAAmC;AAAA,QACvC,SAAS,WAAA,CAAY,OAAA;AAAA,QACrB,QAAQ,WAAA,CAAY,MAAA;AAAA,QACpB,OAAA,EAAS,cAAc,UAAU;AAAA,OACnC;AACA,MAAA,MAAM,eAAA,CAAgB,GAAA,CAAI,eAAA,CAAgB,UAAU,GAAG,aAAa,CAAA;AAAA,IACtE;AAAA,EACF,SAAS,KAAA,EAAO;AAEd,IAAA,WAAA,IAAe,KAAA,CAAM,GAAA,CAAI,CAAA,yDAAA,EAA4D,UAAU,IAAI,KAAK,CAAA;AAAA,EAC1G;AACF;AAKA,eAAsB,oBAAA,CACpB,iBACA,UAAA,EACwC;AACxC,EAAA,IAAI;AACF,IAAA,OAAO,MAAM,eAAA,CAAgB,GAAA,CAAuB,eAAA,CAAgB,UAAU,CAAC,CAAA;AAAA,EACjF,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAKO,SAAS,eAAe,aAAA,EAA8C;AAC3E,EAAA,OAAO;AAAA,IACL;AAAA,MACE,OAAA,EAAS;AAAA,QACP,SAAS,aAAA,CAAc,OAAA;AAAA,QACvB,QAAQ,aAAA,CAAc,MAAA;AAAA,QACtB,UAAA,EAAY,aAAA,CAAc,OAAA,GAAU,UAAA,CAAW,UAAU,UAAA,CAAW;AAAA,OACtE;AAAA,MACA,UAAA,EAAY;AAAA,QACV,CAAC,iCAAiC,GAAG;AAAA;AACvC;AACF,GACF;AACF;;;;"}
|