@lowerdeck/execution-context 1.0.3 → 1.0.4

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.
@@ -1,6 +1,12 @@
1
+ export type ExecutionTraceCarrier = {
2
+ traceparent?: string;
3
+ tracestate?: string;
4
+ baggage?: string;
5
+ };
1
6
  export type ExecutionContext = {
2
7
  contextId: string;
3
8
  parent?: ExecutionContext;
9
+ trace?: ExecutionTraceCarrier;
4
10
  } & ({
5
11
  type: 'request';
6
12
  userId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../src/execution-context.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,GAAG,CACA;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CACtB,CAAC;AAEF,eAAO,IAAI,sBAAsB,GAC/B,OAAO,gBAAgB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KAI5C,gBACjB,CAAC"}
1
+ {"version":3,"file":"execution-context.d.ts","sourceRoot":"","sources":["../src/execution-context.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,qBAAqB,GAAG;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,KAAK,CAAC,EAAE,qBAAqB,CAAC;CAC/B,GAAG,CACA;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GACD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CACtB,CAAC;AAEF,eAAO,IAAI,sBAAsB,GAC/B,OAAO,gBAAgB,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KAsB5C,gBACjB,CAAC"}
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- var e=require("@lowerdeck/id"),t=require("@lowerdeck/sentry"),r=require("async_hooks"),o=t.getSentry(),n=new r.AsyncLocalStorage,c=function(){var e=n.getStore();if(!e)throw new Error("No execution context found");return e.context};exports.addAfterHook=function(e){try{var t=n.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(e),Promise.resolve()}catch(e){return Promise.reject(e)}},exports.createExecutionContext=function(t){return t.contextId||(t.contextId=e.generateId("ctx_")),t},exports.ctxStorage=n,exports.getExecutionContext=c,exports.provideExecutionContext=function(e,t){try{var r=[];return o.setContext("executionContext",e),Promise.resolve(n.run({context:e,afterHooks:r},function(){try{return Promise.resolve(t())}catch(e){return Promise.reject(e)}})).then(function(t){for(var n=0,c=r;n<c.length;n++)(0,c[n])().catch(function(t){o.captureException(t),console.error("Error in after hook",{err:t,context:e})});return t})}catch(e){return Promise.reject(e)}},exports.setExecutionContextSync=function(e){n.enterWith({context:e})},exports.updateExecutionContext=function(e){var t=c();return Object.assign(t,e),t},exports.withExecutionContext=function(e){try{var t=n.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(e(t.context))}catch(e){return Promise.reject(e)}},exports.withExecutionContextOptional=function(e){try{var t,r=n.getStore();return Promise.resolve(e(null!=(t=null==r?void 0:r.context)?t:null))}catch(e){return Promise.reject(e)}};
1
+ var e=require("@opentelemetry/api"),t=require("@lowerdeck/id"),r=require("@lowerdeck/sentry"),o=require("async_hooks"),n=r.getSentry(),c=function(t,r){try{var o,n,c,a,i=function(t){if(a)return t;var o=e.propagation.extract(e.context.active(),u);return Promise.resolve(e.context.with(o,r))},u={};null!=(o=t.trace)&&o.traceparent&&(u.traceparent=t.trace.traceparent),null!=(n=t.trace)&&n.tracestate&&(u.tracestate=t.trace.tracestate),null!=(c=t.trace)&&c.baggage&&(u.baggage=t.trace.baggage);var s=function(){if(!Object.keys(u).length)return Promise.resolve(r()).then(function(e){return a=1,e})}();return Promise.resolve(s&&s.then?s.then(i):i(s))}catch(e){return Promise.reject(e)}},a=new o.AsyncLocalStorage,i=function(){var e=a.getStore();if(!e)throw new Error("No execution context found");return e.context};exports.addAfterHook=function(e){try{var t=a.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(e),Promise.resolve()}catch(e){return Promise.reject(e)}},exports.createExecutionContext=function(r){if(r.contextId||(r.contextId=t.generateId("ctx_")),!r.trace){var o={};try{e.propagation.inject(e.context.active(),o)}catch(e){o={}}(o.traceparent||o.tracestate||o.baggage)&&(r.trace={traceparent:o.traceparent,tracestate:o.tracestate,baggage:o.baggage})}return r},exports.ctxStorage=a,exports.getExecutionContext=i,exports.provideExecutionContext=function(e,t){try{var r=[];return n.setContext("executionContext",e),Promise.resolve(c(e,function(){try{return Promise.resolve(a.run({context:e,afterHooks:r},function(){try{return Promise.resolve(t())}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})).then(function(t){for(var o=0,c=r;o<c.length;o++)(0,c[o])().catch(function(t){n.captureException(t),console.error("Error in after hook",{err:t,context:e})});return t})}catch(e){return Promise.reject(e)}},exports.setExecutionContextSync=function(e){a.enterWith({context:e})},exports.updateExecutionContext=function(e){var t=i();return Object.assign(t,e),t},exports.withExecutionContext=function(e){try{var t=a.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(e(t.context))}catch(e){return Promise.reject(e)}},exports.withExecutionContextOptional=function(e){try{var t,r=a.getStore();return Promise.resolve(e(null!=(t=null==r?void 0:r.context)?t:null))}catch(e){return Promise.reject(e)}},exports.withExecutionTraceContext=c;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/with-execution-context.ts","../src/execution-context.ts"],"sourcesContent":["import { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n","import { generateId } from '@lowerdeck/id';\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n return input as ExecutionContext;\n};\n"],"names":["Sentry","getSentry","ctxStorage","AsyncLocalStorage","getExecutionContext","ctx","getStore","Error","context","hook","afterHooks","push","Promise","resolve","e","reject","input","contextId","generateId","cb","setContext","run","then","res","_i","_afterHooks","length","err","captureException","console","error","enterWith","currentCtx","Object","assign","_ctx$context"],"mappings":"uFAIIA,EAASC,EAAAA,YAEFC,EAAa,IAAIC,EAAAA,kBAgFjBC,EAAsB,WAC/B,IAAIC,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAElB,OAAOF,EAAIG,OACb,uBA/DW,SAAsBC,GAA+B,IAC9D,IAAIJ,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAGlB,IAAKF,EAAIK,WACP,MAAM,IAAIH,MAAM,sDAGQ,OAA1BF,EAAIK,WAAWC,KAAKF,GAAMG,QAAAC,SAC5B,CAAC,MAAAC,UAAAF,QAAAG,OAAAD,EAAA,CAAA,iCCpBmC,SAClCE,GAIA,OAFKA,EAAMC,YAAWD,EAAMC,UAAYC,EAAAA,WAAW,SAE5CF,CACT,qFDgBkC,SAChCX,EACAc,GACc,IACd,IAAIT,EAA+C,GAER,OAA3CV,EAAOoB,WAAW,mBAAoBf,GAAKO,QAAAC,QAE3BX,EAAWmB,IACzB,CACEb,QAASH,EACTK,WAAAA,GACDE,WAAAA,IAAAA,OAAAA,QAAAC,QACiBM,IAAI,CAAA,MAAAL,GAAA,OAAAF,QAAAG,OAAAD,EACvB,CAAA,IAAAQ,KANGC,SAAAA,GAQJ,IAAA,IAAAC,EAAA,EAAAC,EAAiBf,EAAUc,EAAAC,EAAAC,OAAAF,KACzBf,EADWgB,EAAAD,MACC,MAAC,SAAAG,GACX3B,EAAO4B,iBAAiBD,GAExBE,QAAQC,MAAM,sBAAuB,CACnCH,IAAAA,EACAnB,QAASH,GAEb,GAGF,OAAOkB,CAAI,EACb,CAAC,MAAAT,UAAAF,QAAAG,OAAAD,EAAA,CAAA,kCAEoC,SAACT,GACpCH,EAAW6B,UAAU,CACnBvB,QAASH,GAEb,iCAEoC,SAACA,GACnC,IAAI2B,EAAa5B,IAIjB,OAFA6B,OAAOC,OAAOF,EAAY3B,GAEnB2B,CACT,+BAzE+B,SAC7Bb,GAAyC,IAEzC,IAAId,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAM,IAAIE,MAAM,8BACjB,OAAAK,QAAAC,QAEYM,EAAGd,EAAIG,SACtB,CAAC,MAAAM,UAAAF,QAAAG,OAAAD,EAAA,CAAA,uCAEsC,SACrCK,GAAgD,IAClCgB,IAAAA,EACV9B,EAAMH,EAAWI,WAAW,OAAAM,QAAAC,QACnBM,EAAe,OAAbgB,EAAC9B,MAAAA,OAAAA,EAAAA,EAAKG,SAAO2B,EAAI,MAClC,CAAC,MAAArB,GAAA,OAAAF,QAAAG,OAAAD,EAED,CAAA"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/with-execution-context.ts","../src/execution-context.ts"],"sourcesContent":["import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let withExecutionTraceContext = async <T>(\n executionContext: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let carrier: Record<string, string> = {};\n\n if (executionContext.trace?.traceparent) {\n carrier.traceparent = executionContext.trace.traceparent;\n }\n if (executionContext.trace?.tracestate) {\n carrier.tracestate = executionContext.trace.tracestate;\n }\n if (executionContext.trace?.baggage) {\n carrier.baggage = executionContext.trace.baggage;\n }\n\n if (!Object.keys(carrier).length) {\n return await cb();\n }\n\n let extractedContext = propagation.extract(otelContext.active(), carrier);\n\n return await otelContext.with(extractedContext, cb);\n};\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await withExecutionTraceContext(\n ctx,\n async () =>\n await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n )\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n","import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { generateId } from '@lowerdeck/id';\n\nexport type ExecutionTraceCarrier = {\n traceparent?: string;\n tracestate?: string;\n baggage?: string;\n};\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n trace?: ExecutionTraceCarrier;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n if (!input.trace) {\n let carrier: Record<string, string> = {};\n\n try {\n propagation.inject(otelContext.active(), carrier);\n } catch {\n carrier = {};\n }\n\n if (carrier.traceparent || carrier.tracestate || carrier.baggage) {\n input.trace = {\n traceparent: carrier.traceparent,\n tracestate: carrier.tracestate,\n baggage: carrier.baggage\n };\n }\n }\n\n return input as ExecutionContext;\n};\n"],"names":["Sentry","getSentry","withExecutionTraceContext","executionContext","cb","_executionContext$tra","_executionContext$tra2","_executionContext$tra3","_exit","_temp2","_result","extractedContext","propagation","extract","otelContext","active","carrier","Promise","resolve","trace","traceparent","tracestate","baggage","_temp","Object","keys","length","then","_await$cb","e","reject","ctxStorage","AsyncLocalStorage","getExecutionContext","ctx","getStore","Error","context","hook","afterHooks","push","input","contextId","generateId","inject","_unused","setContext","run","res","_i","_afterHooks","err","captureException","console","error","enterWith","currentCtx","assign","_ctx$context"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{generateId as r}from"@lowerdeck/id";import{getSentry as t}from"@lowerdeck/sentry";import{AsyncLocalStorage as e}from"async_hooks";var o=function(t){return t.contextId||(t.contextId=r("ctx_")),t},n=t(),c=new e,i=function(r){try{var t=c.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(r(t.context))}catch(r){return Promise.reject(r)}},u=function(r){try{var t,e=c.getStore();return Promise.resolve(r(null!=(t=null==e?void 0:e.context)?t:null))}catch(r){return Promise.reject(r)}},f=function(r){try{var t=c.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(r),Promise.resolve()}catch(r){return Promise.reject(r)}},s=function(r,t){try{var e=[];return n.setContext("executionContext",r),Promise.resolve(c.run({context:r,afterHooks:e},function(){try{return Promise.resolve(t())}catch(r){return Promise.reject(r)}})).then(function(t){for(var o=0,c=e;o<c.length;o++)(0,c[o])().catch(function(t){n.captureException(t),console.error("Error in after hook",{err:t,context:r})});return t})}catch(r){return Promise.reject(r)}},a=function(r){c.enterWith({context:r})},x=function(r){var t=h();return Object.assign(t,r),t},h=function(){var r=c.getStore();if(!r)throw new Error("No execution context found");return r.context};export{f as addAfterHook,o as createExecutionContext,c as ctxStorage,h as getExecutionContext,s as provideExecutionContext,a as setExecutionContextSync,x as updateExecutionContext,i as withExecutionContext,u as withExecutionContextOptional};
1
+ import{propagation as e,context as t}from"@opentelemetry/api";import{generateId as r}from"@lowerdeck/id";import{getSentry as n}from"@lowerdeck/sentry";import{AsyncLocalStorage as o}from"async_hooks";var c=function(n){if(n.contextId||(n.contextId=r("ctx_")),!n.trace){var o={};try{e.inject(t.active(),o)}catch(e){o={}}(o.traceparent||o.tracestate||o.baggage)&&(n.trace={traceparent:o.traceparent,tracestate:o.tracestate,baggage:o.baggage})}return n},a=n(),i=function(r,n){try{var o,c,a,i,u=function(r){if(i)return r;var o=e.extract(t.active(),s);return Promise.resolve(t.with(o,n))},s={};null!=(o=r.trace)&&o.traceparent&&(s.traceparent=r.trace.traceparent),null!=(c=r.trace)&&c.tracestate&&(s.tracestate=r.trace.tracestate),null!=(a=r.trace)&&a.baggage&&(s.baggage=r.trace.baggage);var f=function(){if(!Object.keys(s).length)return Promise.resolve(n()).then(function(e){return i=1,e})}();return Promise.resolve(f&&f.then?f.then(u):u(f))}catch(e){return Promise.reject(e)}},u=new o,s=function(e){try{var t=u.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(e(t.context))}catch(e){return Promise.reject(e)}},f=function(e){try{var t,r=u.getStore();return Promise.resolve(e(null!=(t=null==r?void 0:r.context)?t:null))}catch(e){return Promise.reject(e)}},l=function(e){try{var t=u.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(e),Promise.resolve()}catch(e){return Promise.reject(e)}},h=function(e,t){try{var r=[];return a.setContext("executionContext",e),Promise.resolve(i(e,function(){try{return Promise.resolve(u.run({context:e,afterHooks:r},function(){try{return Promise.resolve(t())}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})).then(function(t){for(var n=0,o=r;n<o.length;n++)(0,o[n])().catch(function(t){a.captureException(t),console.error("Error in after hook",{err:t,context:e})});return t})}catch(e){return Promise.reject(e)}},g=function(e){u.enterWith({context:e})},m=function(e){var t=v();return Object.assign(t,e),t},v=function(){var e=u.getStore();if(!e)throw new Error("No execution context found");return e.context};export{l as addAfterHook,c as createExecutionContext,u as ctxStorage,v as getExecutionContext,h as provideExecutionContext,g as setExecutionContextSync,m as updateExecutionContext,s as withExecutionContext,f as withExecutionContextOptional,i as withExecutionTraceContext};
2
2
  //# sourceMappingURL=index.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.module.js","sources":["../src/execution-context.ts","../src/with-execution-context.ts"],"sourcesContent":["import { generateId } from '@lowerdeck/id';\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n return input as ExecutionContext;\n};\n","import { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n"],"names":["createExecutionContext","input","contextId","generateId","Sentry","getSentry","ctxStorage","AsyncLocalStorage","withExecutionContext","cb","ctx","getStore","Error","Promise","resolve","context","e","reject","withExecutionContextOptional","_ctx$context","addAfterHook","hook","afterHooks","push","provideExecutionContext","setContext","run","then","res","_i","_afterHooks","length","err","captureException","console","error","setExecutionContextSync","enterWith","updateExecutionContext","currentCtx","getExecutionContext","Object","assign"],"mappings":"yIAoBW,IAAAA,EAAyB,SAClCC,GAIA,OAFKA,EAAMC,YAAWD,EAAMC,UAAYC,EAAW,SAE5CF,CACT,ECtBIG,EAASC,IAEFC,EAAa,IAAIC,EAKjBC,EAAoB,SAC7BC,GAAyC,IAEzC,IAAIC,EAAMJ,EAAWK,WACrB,IAAKD,EACH,MAAM,IAAIE,MAAM,8BACjB,OAAAC,QAAAC,QAEYL,EAAGC,EAAIK,SACtB,CAAC,MAAAC,UAAAH,QAAAI,OAAAD,EAAA,CAAA,EAEUE,EAA4B,SACrCT,GAAgD,IAClCU,IAAAA,EACVT,EAAMJ,EAAWK,WAAW,OAAAE,QAAAC,QACnBL,EAAe,OAAbU,EAACT,MAAAA,OAAAA,EAAAA,EAAKK,SAAOI,EAAI,MAClC,CAAC,MAAAH,GAAA,OAAAH,QAAAI,OAAAD,EAED,CAAA,EAAWI,EAAA,SAAsBC,GAA+B,IAC9D,IAAIX,EAAMJ,EAAWK,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAGlB,IAAKF,EAAIY,WACP,MAAM,IAAIV,MAAM,sDAGQ,OAA1BF,EAAIY,WAAWC,KAAKF,GAAMR,QAAAC,SAC5B,CAAC,MAAAE,UAAAH,QAAAI,OAAAD,EAAA,CAAA,EAEUQ,EAAuB,SAChCd,EACAD,GACc,IACd,IAAIa,EAA+C,GAER,OAA3ClB,EAAOqB,WAAW,mBAAoBf,GAAKG,QAAAC,QAE3BR,EAAWoB,IACzB,CACEX,QAASL,EACTY,WAAAA,GACDT,WAAAA,IAAAA,OAAAA,QAAAC,QACiBL,IAAI,CAAA,MAAAO,GAAA,OAAAH,QAAAI,OAAAD,EACvB,CAAA,IAAAW,KANGC,SAAAA,GAQJ,IAAA,IAAAC,EAAA,EAAAC,EAAiBR,EAAUO,EAAAC,EAAAC,OAAAF,KACzBR,EADWS,EAAAD,MACC,MAAC,SAAAG,GACX5B,EAAO6B,iBAAiBD,GAExBE,QAAQC,MAAM,sBAAuB,CACnCH,IAAAA,EACAjB,QAASL,GAEb,GAGF,OAAOkB,CAAI,EACb,CAAC,MAAAZ,UAAAH,QAAAI,OAAAD,EAAA,CAAA,EAEUoB,EAA0B,SAAC1B,GACpCJ,EAAW+B,UAAU,CACnBtB,QAASL,GAEb,EAEW4B,EAAyB,SAAC5B,GACnC,IAAI6B,EAAaC,IAIjB,OAFAC,OAAOC,OAAOH,EAAY7B,GAEnB6B,CACT,EAEWC,EAAsB,WAC/B,IAAI9B,EAAMJ,EAAWK,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAElB,OAAOF,EAAIK,OACb"}
1
+ {"version":3,"file":"index.module.js","sources":["../src/execution-context.ts","../src/with-execution-context.ts"],"sourcesContent":["import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { generateId } from '@lowerdeck/id';\n\nexport type ExecutionTraceCarrier = {\n traceparent?: string;\n tracestate?: string;\n baggage?: string;\n};\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n trace?: ExecutionTraceCarrier;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n if (!input.trace) {\n let carrier: Record<string, string> = {};\n\n try {\n propagation.inject(otelContext.active(), carrier);\n } catch {\n carrier = {};\n }\n\n if (carrier.traceparent || carrier.tracestate || carrier.baggage) {\n input.trace = {\n traceparent: carrier.traceparent,\n tracestate: carrier.tracestate,\n baggage: carrier.baggage\n };\n }\n }\n\n return input as ExecutionContext;\n};\n","import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let withExecutionTraceContext = async <T>(\n executionContext: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let carrier: Record<string, string> = {};\n\n if (executionContext.trace?.traceparent) {\n carrier.traceparent = executionContext.trace.traceparent;\n }\n if (executionContext.trace?.tracestate) {\n carrier.tracestate = executionContext.trace.tracestate;\n }\n if (executionContext.trace?.baggage) {\n carrier.baggage = executionContext.trace.baggage;\n }\n\n if (!Object.keys(carrier).length) {\n return await cb();\n }\n\n let extractedContext = propagation.extract(otelContext.active(), carrier);\n\n return await otelContext.with(extractedContext, cb);\n};\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await withExecutionTraceContext(\n ctx,\n async () =>\n await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n )\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n"],"names":["createExecutionContext","input","contextId","generateId","trace","carrier","propagation","inject","otelContext","active","_unused","traceparent","tracestate","baggage","Sentry","getSentry","withExecutionTraceContext","executionContext","cb","_executionContext$tra","_executionContext$tra2","_executionContext$tra3","_exit","_temp2","_result","extractedContext","extract","Promise","resolve","_temp","Object","keys","length","then","_await$cb","e","reject","ctxStorage","AsyncLocalStorage","withExecutionContext","ctx","getStore","Error","context","withExecutionContextOptional","_ctx$context","addAfterHook","hook","afterHooks","push","provideExecutionContext","setContext","run","res","_i","_afterHooks","err","captureException","console","error","setExecutionContextSync","enterWith","updateExecutionContext","currentCtx","getExecutionContext","assign"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@lowerdeck/id"),require("@lowerdeck/sentry"),require("async_hooks")):"function"==typeof define&&define.amd?define(["exports","@lowerdeck/id","@lowerdeck/sentry","async_hooks"],t):t((e||self).executionContext={},e.id,e.sentry,e.async_hooks)}(this,function(e,t,o,r){var n=o.getSentry(),c=new r.AsyncLocalStorage,i=function(){var e=c.getStore();if(!e)throw new Error("No execution context found");return e.context};e.addAfterHook=function(e){try{var t=c.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(e),Promise.resolve()}catch(e){return Promise.reject(e)}},e.createExecutionContext=function(e){return e.contextId||(e.contextId=t.generateId("ctx_")),e},e.ctxStorage=c,e.getExecutionContext=i,e.provideExecutionContext=function(e,t){try{var o=[];return n.setContext("executionContext",e),Promise.resolve(c.run({context:e,afterHooks:o},function(){try{return Promise.resolve(t())}catch(e){return Promise.reject(e)}})).then(function(t){for(var r=0,c=o;r<c.length;r++)(0,c[r])().catch(function(t){n.captureException(t),console.error("Error in after hook",{err:t,context:e})});return t})}catch(e){return Promise.reject(e)}},e.setExecutionContextSync=function(e){c.enterWith({context:e})},e.updateExecutionContext=function(e){var t=i();return Object.assign(t,e),t},e.withExecutionContext=function(e){try{var t=c.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(e(t.context))}catch(e){return Promise.reject(e)}},e.withExecutionContextOptional=function(e){try{var t,o=c.getStore();return Promise.resolve(e(null!=(t=null==o?void 0:o.context)?t:null))}catch(e){return Promise.reject(e)}}});
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@opentelemetry/api"),require("@lowerdeck/id"),require("@lowerdeck/sentry"),require("async_hooks")):"function"==typeof define&&define.amd?define(["exports","@opentelemetry/api","@lowerdeck/id","@lowerdeck/sentry","async_hooks"],t):t((e||self).executionContext={},e.api,e.id,e.sentry,e.async_hooks)}(this,function(e,t,r,n,o){var c=n.getSentry(),a=function(e,r){try{var n,o,c,a,i=function(e){if(a)return e;var n=t.propagation.extract(t.context.active(),u);return Promise.resolve(t.context.with(n,r))},u={};null!=(n=e.trace)&&n.traceparent&&(u.traceparent=e.trace.traceparent),null!=(o=e.trace)&&o.tracestate&&(u.tracestate=e.trace.tracestate),null!=(c=e.trace)&&c.baggage&&(u.baggage=e.trace.baggage);var s=function(){if(!Object.keys(u).length)return Promise.resolve(r()).then(function(e){return a=1,e})}();return Promise.resolve(s&&s.then?s.then(i):i(s))}catch(e){return Promise.reject(e)}},i=new o.AsyncLocalStorage,u=function(){var e=i.getStore();if(!e)throw new Error("No execution context found");return e.context};e.addAfterHook=function(e){try{var t=i.getStore();if(!t)throw new Error("No execution context found");if(!t.afterHooks)throw new Error("After hooks not enabled for this execution context");return t.afterHooks.push(e),Promise.resolve()}catch(e){return Promise.reject(e)}},e.createExecutionContext=function(e){if(e.contextId||(e.contextId=r.generateId("ctx_")),!e.trace){var n={};try{t.propagation.inject(t.context.active(),n)}catch(e){n={}}(n.traceparent||n.tracestate||n.baggage)&&(e.trace={traceparent:n.traceparent,tracestate:n.tracestate,baggage:n.baggage})}return e},e.ctxStorage=i,e.getExecutionContext=u,e.provideExecutionContext=function(e,t){try{var r=[];return c.setContext("executionContext",e),Promise.resolve(a(e,function(){try{return Promise.resolve(i.run({context:e,afterHooks:r},function(){try{return Promise.resolve(t())}catch(e){return Promise.reject(e)}}))}catch(e){return Promise.reject(e)}})).then(function(t){for(var n=0,o=r;n<o.length;n++)(0,o[n])().catch(function(t){c.captureException(t),console.error("Error in after hook",{err:t,context:e})});return t})}catch(e){return Promise.reject(e)}},e.setExecutionContextSync=function(e){i.enterWith({context:e})},e.updateExecutionContext=function(e){var t=u();return Object.assign(t,e),t},e.withExecutionContext=function(e){try{var t=i.getStore();if(!t)throw new Error("No execution context found");return Promise.resolve(e(t.context))}catch(e){return Promise.reject(e)}},e.withExecutionContextOptional=function(e){try{var t,r=i.getStore();return Promise.resolve(e(null!=(t=null==r?void 0:r.context)?t:null))}catch(e){return Promise.reject(e)}},e.withExecutionTraceContext=a});
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/execution-context.ts","../src/with-execution-context.ts"],"sourcesContent":["import { generateId } from '@lowerdeck/id';\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n return input as ExecutionContext;\n};\n","import { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n"],"names":["createExecutionContext","Sentry","getSentry","ctxStorage","AsyncLocalStorage","getExecutionContext","ctx","getStore","Error","context","hook","afterHooks","push","Promise","resolve","e","reject","input","contextId","generateId","cb","setContext","run","then","res","_i","_afterHooks","length","err","captureException","console","error","enterWith","currentCtx","Object","assign","_ctx$context"],"mappings":"2YAoBWA,IChBPC,EAASC,EAAAA,YAEFC,EAAa,IAAIC,EAAAA,kBAgFjBC,EAAsB,WAC/B,IAAIC,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAElB,OAAOF,EAAIG,OACb,iBA/DW,SAAsBC,GAA+B,IAC9D,IAAIJ,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAU,IAAAE,MAAM,8BAGlB,IAAKF,EAAIK,WACP,MAAM,IAAIH,MAAM,sDAGQ,OAA1BF,EAAIK,WAAWC,KAAKF,GAAMG,QAAAC,SAC5B,CAAC,MAAAC,UAAAF,QAAAG,OAAAD,EAAA,CAAA,2BDpBmC,SAClCE,GAIA,OAFKA,EAAMC,YAAWD,EAAMC,UAAYC,EAAAA,WAAW,SAE5CF,CACT,mECgBkC,SAChCX,EACAc,GACc,IACd,IAAIT,EAA+C,GAER,OAA3CV,EAAOoB,WAAW,mBAAoBf,GAAKO,QAAAC,QAE3BX,EAAWmB,IACzB,CACEb,QAASH,EACTK,WAAAA,GACDE,WAAAA,IAAAA,OAAAA,QAAAC,QACiBM,IAAI,CAAA,MAAAL,GAAA,OAAAF,QAAAG,OAAAD,EACvB,CAAA,IAAAQ,KANGC,SAAAA,GAQJ,IAAA,IAAAC,EAAA,EAAAC,EAAiBf,EAAUc,EAAAC,EAAAC,OAAAF,KACzBf,EADWgB,EAAAD,MACC,MAAC,SAAAG,GACX3B,EAAO4B,iBAAiBD,GAExBE,QAAQC,MAAM,sBAAuB,CACnCH,IAAAA,EACAnB,QAASH,GAEb,GAGF,OAAOkB,CAAI,EACb,CAAC,MAAAT,UAAAF,QAAAG,OAAAD,EAAA,CAAA,4BAEoC,SAACT,GACpCH,EAAW6B,UAAU,CACnBvB,QAASH,GAEb,2BAEoC,SAACA,GACnC,IAAI2B,EAAa5B,IAIjB,OAFA6B,OAAOC,OAAOF,EAAY3B,GAEnB2B,CACT,yBAzE+B,SAC7Bb,GAAyC,IAEzC,IAAId,EAAMH,EAAWI,WACrB,IAAKD,EACH,MAAM,IAAIE,MAAM,8BACjB,OAAAK,QAAAC,QAEYM,EAAGd,EAAIG,SACtB,CAAC,MAAAM,UAAAF,QAAAG,OAAAD,EAAA,CAAA,iCAEsC,SACrCK,GAAgD,IAClCgB,IAAAA,EACV9B,EAAMH,EAAWI,WAAW,OAAAM,QAAAC,QACnBM,EAAe,OAAbgB,EAAC9B,MAAAA,OAAAA,EAAAA,EAAKG,SAAO2B,EAAI,MAClC,CAAC,MAAArB,GAAA,OAAAF,QAAAG,OAAAD,EAED,CAAA"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/execution-context.ts","../src/with-execution-context.ts"],"sourcesContent":["import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { generateId } from '@lowerdeck/id';\n\nexport type ExecutionTraceCarrier = {\n traceparent?: string;\n tracestate?: string;\n baggage?: string;\n};\n\nexport type ExecutionContext = {\n contextId: string;\n parent?: ExecutionContext;\n trace?: ExecutionTraceCarrier;\n} & (\n | {\n type: 'request';\n userId?: string;\n memberId?: string;\n apiKeyId?: string;\n machineAccessId?: string;\n ip: string;\n userAgent: string;\n }\n | { type: 'scheduled'; cron: string; name: string }\n | { type: 'job'; queue: string }\n | { type: 'unknown' }\n);\n\nexport let createExecutionContext = (\n input: ExecutionContext & { contextId?: string | undefined }\n) => {\n if (!input.contextId) input.contextId = generateId('ctx_');\n\n if (!input.trace) {\n let carrier: Record<string, string> = {};\n\n try {\n propagation.inject(otelContext.active(), carrier);\n } catch {\n carrier = {};\n }\n\n if (carrier.traceparent || carrier.tracestate || carrier.baggage) {\n input.trace = {\n traceparent: carrier.traceparent,\n tracestate: carrier.tracestate,\n baggage: carrier.baggage\n };\n }\n }\n\n return input as ExecutionContext;\n};\n","import { context as otelContext, propagation } from '@opentelemetry/api';\nimport { getSentry } from '@lowerdeck/sentry';\nimport { AsyncLocalStorage } from 'async_hooks';\nimport { ExecutionContext } from './execution-context';\n\nlet Sentry = getSentry();\n\nexport let withExecutionTraceContext = async <T>(\n executionContext: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let carrier: Record<string, string> = {};\n\n if (executionContext.trace?.traceparent) {\n carrier.traceparent = executionContext.trace.traceparent;\n }\n if (executionContext.trace?.tracestate) {\n carrier.tracestate = executionContext.trace.tracestate;\n }\n if (executionContext.trace?.baggage) {\n carrier.baggage = executionContext.trace.baggage;\n }\n\n if (!Object.keys(carrier).length) {\n return await cb();\n }\n\n let extractedContext = propagation.extract(otelContext.active(), carrier);\n\n return await otelContext.with(extractedContext, cb);\n};\n\nexport let ctxStorage = new AsyncLocalStorage<{\n context: ExecutionContext;\n afterHooks?: Array<() => Promise<void | any>>;\n}>();\n\nexport let withExecutionContext = async <T>(\n cb: (ctx: ExecutionContext) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n return await cb(ctx.context);\n};\n\nexport let withExecutionContextOptional = async <T>(\n cb: (ctx: ExecutionContext | null) => Promise<T>\n): Promise<T> => {\n let ctx = ctxStorage.getStore();\n return await cb(ctx?.context ?? null);\n};\n\nexport let addAfterHook = async (hook: () => Promise<void | any>) => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n\n if (!ctx.afterHooks) {\n throw new Error('After hooks not enabled for this execution context');\n }\n\n ctx.afterHooks.push(hook);\n};\n\nexport let provideExecutionContext = async <T>(\n ctx: ExecutionContext,\n cb: () => Promise<T>\n): Promise<T> => {\n let afterHooks: Array<() => Promise<void | any>> = [];\n\n Sentry.setContext('executionContext', ctx);\n\n let res = await withExecutionTraceContext(\n ctx,\n async () =>\n await ctxStorage.run(\n {\n context: ctx,\n afterHooks\n },\n async () => await cb()\n )\n );\n\n for (let hook of afterHooks) {\n hook().catch(err => {\n Sentry.captureException(err);\n\n console.error('Error in after hook', {\n err,\n context: ctx\n });\n });\n }\n\n return res;\n};\n\nexport let setExecutionContextSync = (ctx: ExecutionContext) => {\n ctxStorage.enterWith({\n context: ctx\n });\n};\n\nexport let updateExecutionContext = (ctx: Partial<ExecutionContext>) => {\n let currentCtx = getExecutionContext();\n\n Object.assign(currentCtx, ctx);\n\n return currentCtx;\n};\n\nexport let getExecutionContext = () => {\n let ctx = ctxStorage.getStore();\n if (!ctx) {\n throw new Error('No execution context found');\n }\n return ctx.context;\n};\n"],"names":["createExecutionContext","Sentry","getSentry","withExecutionTraceContext","executionContext","cb","_executionContext$tra","_executionContext$tra2","_executionContext$tra3","_exit","_temp2","_result","extractedContext","propagation","extract","otelContext","active","carrier","Promise","resolve","trace","traceparent","tracestate","baggage","_temp","Object","keys","length","then","_await$cb","e","reject","ctxStorage","AsyncLocalStorage","getExecutionContext","ctx","getStore","Error","context","hook","afterHooks","push","input","contextId","generateId","inject","_unused","setContext","run","res","_i","_afterHooks","err","captureException","console","error","enterWith","currentCtx","assign","_ctx$context"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { AsyncLocalStorage } from 'async_hooks';
2
2
  import { ExecutionContext } from './execution-context';
3
+ export declare let withExecutionTraceContext: <T>(executionContext: ExecutionContext, cb: () => Promise<T>) => Promise<T>;
3
4
  export declare let ctxStorage: AsyncLocalStorage<{
4
5
  context: ExecutionContext;
5
6
  afterHooks?: Array<() => Promise<void | any>>;
@@ -1 +1 @@
1
- {"version":3,"file":"with-execution-context.d.ts","sourceRoot":"","sources":["../src/with-execution-context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIvD,eAAO,IAAI,UAAU;aACV,gBAAgB;iBACZ,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;EAC3C,CAAC;AAEL,eAAO,IAAI,oBAAoB,GAAU,CAAC,EACxC,IAAI,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxC,OAAO,CAAC,CAAC,CAOX,CAAC;AAEF,eAAO,IAAI,4BAA4B,GAAU,CAAC,EAChD,IAAI,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAC/C,OAAO,CAAC,CAAC,CAGX,CAAC;AAEF,eAAO,IAAI,YAAY,GAAU,MAAM,MAAM,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,kBAW/D,CAAC;AAEF,eAAO,IAAI,uBAAuB,GAAU,CAAC,EAC3C,KAAK,gBAAgB,EACrB,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KACnB,OAAO,CAAC,CAAC,CAyBX,CAAC;AAEF,eAAO,IAAI,uBAAuB,GAAI,KAAK,gBAAgB,SAI1D,CAAC;AAEF,eAAO,IAAI,sBAAsB,GAAI,KAAK,OAAO,CAAC,gBAAgB,CAAC,qBAMlE,CAAC;AAEF,eAAO,IAAI,mBAAmB,wBAM7B,CAAC"}
1
+ {"version":3,"file":"with-execution-context.d.ts","sourceRoot":"","sources":["../src/with-execution-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAIvD,eAAO,IAAI,yBAAyB,GAAU,CAAC,EAC7C,kBAAkB,gBAAgB,EAClC,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KACnB,OAAO,CAAC,CAAC,CAoBX,CAAC;AAEF,eAAO,IAAI,UAAU;aACV,gBAAgB;iBACZ,KAAK,CAAC,MAAM,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;EAC3C,CAAC;AAEL,eAAO,IAAI,oBAAoB,GAAU,CAAC,EACxC,IAAI,CAAC,GAAG,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,KACxC,OAAO,CAAC,CAAC,CAOX,CAAC;AAEF,eAAO,IAAI,4BAA4B,GAAU,CAAC,EAChD,IAAI,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,KAC/C,OAAO,CAAC,CAAC,CAGX,CAAC;AAEF,eAAO,IAAI,YAAY,GAAU,MAAM,MAAM,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,kBAW/D,CAAC;AAEF,eAAO,IAAI,uBAAuB,GAAU,CAAC,EAC3C,KAAK,gBAAgB,EACrB,IAAI,MAAM,OAAO,CAAC,CAAC,CAAC,KACnB,OAAO,CAAC,CAAC,CA6BX,CAAC;AAEF,eAAO,IAAI,uBAAuB,GAAI,KAAK,gBAAgB,SAI1D,CAAC;AAEF,eAAO,IAAI,sBAAsB,GAAI,KAAK,OAAO,CAAC,gBAAgB,CAAC,qBAMlE,CAAC;AAEF,eAAO,IAAI,mBAAmB,wBAM7B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lowerdeck/execution-context",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -30,6 +30,7 @@
30
30
  "build": "rm -rf ./dist && microbundle"
31
31
  },
32
32
  "dependencies": {
33
+ "@opentelemetry/api": "^1.9.0",
33
34
  "@lowerdeck/id": "^1.0.6",
34
35
  "@lowerdeck/sentry": "^1.0.2"
35
36
  },
@@ -1,8 +1,16 @@
1
+ import { context as otelContext, propagation } from '@opentelemetry/api';
1
2
  import { generateId } from '@lowerdeck/id';
2
3
 
4
+ export type ExecutionTraceCarrier = {
5
+ traceparent?: string;
6
+ tracestate?: string;
7
+ baggage?: string;
8
+ };
9
+
3
10
  export type ExecutionContext = {
4
11
  contextId: string;
5
12
  parent?: ExecutionContext;
13
+ trace?: ExecutionTraceCarrier;
6
14
  } & (
7
15
  | {
8
16
  type: 'request';
@@ -23,5 +31,23 @@ export let createExecutionContext = (
23
31
  ) => {
24
32
  if (!input.contextId) input.contextId = generateId('ctx_');
25
33
 
34
+ if (!input.trace) {
35
+ let carrier: Record<string, string> = {};
36
+
37
+ try {
38
+ propagation.inject(otelContext.active(), carrier);
39
+ } catch {
40
+ carrier = {};
41
+ }
42
+
43
+ if (carrier.traceparent || carrier.tracestate || carrier.baggage) {
44
+ input.trace = {
45
+ traceparent: carrier.traceparent,
46
+ tracestate: carrier.tracestate,
47
+ baggage: carrier.baggage
48
+ };
49
+ }
50
+ }
51
+
26
52
  return input as ExecutionContext;
27
53
  };
@@ -1,9 +1,35 @@
1
+ import { context as otelContext, propagation } from '@opentelemetry/api';
1
2
  import { getSentry } from '@lowerdeck/sentry';
2
3
  import { AsyncLocalStorage } from 'async_hooks';
3
4
  import { ExecutionContext } from './execution-context';
4
5
 
5
6
  let Sentry = getSentry();
6
7
 
8
+ export let withExecutionTraceContext = async <T>(
9
+ executionContext: ExecutionContext,
10
+ cb: () => Promise<T>
11
+ ): Promise<T> => {
12
+ let carrier: Record<string, string> = {};
13
+
14
+ if (executionContext.trace?.traceparent) {
15
+ carrier.traceparent = executionContext.trace.traceparent;
16
+ }
17
+ if (executionContext.trace?.tracestate) {
18
+ carrier.tracestate = executionContext.trace.tracestate;
19
+ }
20
+ if (executionContext.trace?.baggage) {
21
+ carrier.baggage = executionContext.trace.baggage;
22
+ }
23
+
24
+ if (!Object.keys(carrier).length) {
25
+ return await cb();
26
+ }
27
+
28
+ let extractedContext = propagation.extract(otelContext.active(), carrier);
29
+
30
+ return await otelContext.with(extractedContext, cb);
31
+ };
32
+
7
33
  export let ctxStorage = new AsyncLocalStorage<{
8
34
  context: ExecutionContext;
9
35
  afterHooks?: Array<() => Promise<void | any>>;
@@ -48,12 +74,16 @@ export let provideExecutionContext = async <T>(
48
74
 
49
75
  Sentry.setContext('executionContext', ctx);
50
76
 
51
- let res = await ctxStorage.run(
52
- {
53
- context: ctx,
54
- afterHooks
55
- },
56
- async () => await cb()
77
+ let res = await withExecutionTraceContext(
78
+ ctx,
79
+ async () =>
80
+ await ctxStorage.run(
81
+ {
82
+ context: ctx,
83
+ afterHooks
84
+ },
85
+ async () => await cb()
86
+ )
57
87
  );
58
88
 
59
89
  for (let hook of afterHooks) {