{"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 = Map 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(ctx: T): T {\n if (!ctx) return ctx;\n\n const overrides: OverridesStore = 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(['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} 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(\n store: OverridesStore,\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":["instrumentDurableObjectStorage"],"mappings":"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"}