@lowerdeck/execution-context 1.0.0 → 1.0.2
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/README.md +56 -0
- package/dist/execution-context.d.ts +25 -0
- package/dist/execution-context.d.ts.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.module.js +2 -0
- package/dist/index.module.js.map +1 -0
- package/dist/index.umd.js +2 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/with-execution-context.d.ts +14 -0
- package/dist/with-execution-context.d.ts.map +1 -0
- package/package.json +11 -5
- package/.turbo/turbo-build.log +0 -11
- package/.turbo/turbo-test.log +0 -26
- package/tsconfig.json +0 -13
package/README.md
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# `@lowerdeck/execution-context`
|
|
2
|
+
|
|
3
|
+
Track and manage execution context for requests, scheduled jobs, and background tasks. Provides type-safe context objects for different execution environments with support for parent-child relationships.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @lowerdeck/execution-context
|
|
9
|
+
yarn add @lowerdeck/execution-context
|
|
10
|
+
bun add @lowerdeck/execution-context
|
|
11
|
+
pnpm add @lowerdeck/execution-context
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import { createExecutionContext, ExecutionContext } from '@lowerdeck/execution-context';
|
|
18
|
+
|
|
19
|
+
// Create context for an HTTP request
|
|
20
|
+
const requestContext = createExecutionContext({
|
|
21
|
+
type: 'request',
|
|
22
|
+
userId: 'user_123',
|
|
23
|
+
ip: '192.168.1.1',
|
|
24
|
+
userAgent: 'Mozilla/5.0...'
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
// Create context for a scheduled job
|
|
28
|
+
const cronContext = createExecutionContext({
|
|
29
|
+
type: 'scheduled',
|
|
30
|
+
cron: '0 0 * * *',
|
|
31
|
+
name: 'daily-cleanup'
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Create context for a queue job
|
|
35
|
+
const jobContext = createExecutionContext({
|
|
36
|
+
type: 'job',
|
|
37
|
+
queue: 'emails'
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// Nest contexts with parent relationships
|
|
41
|
+
const childContext = createExecutionContext({
|
|
42
|
+
type: 'job',
|
|
43
|
+
queue: 'notifications',
|
|
44
|
+
parent: requestContext
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
console.log(childContext.contextId); // Auto-generated ID
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## License
|
|
51
|
+
|
|
52
|
+
This project is licensed under the Apache License 2.0.
|
|
53
|
+
|
|
54
|
+
<div align="center">
|
|
55
|
+
<sub>Built with ❤️ by <a href="https://metorial.com">Metorial</a></sub>
|
|
56
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export type ExecutionContext = {
|
|
2
|
+
contextId: string;
|
|
3
|
+
parent?: ExecutionContext;
|
|
4
|
+
} & ({
|
|
5
|
+
type: 'request';
|
|
6
|
+
userId?: string;
|
|
7
|
+
memberId?: string;
|
|
8
|
+
apiKeyId?: string;
|
|
9
|
+
machineAccessId?: string;
|
|
10
|
+
ip: string;
|
|
11
|
+
userAgent: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'scheduled';
|
|
14
|
+
cron: string;
|
|
15
|
+
name: string;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'job';
|
|
18
|
+
queue: string;
|
|
19
|
+
} | {
|
|
20
|
+
type: 'unknown';
|
|
21
|
+
});
|
|
22
|
+
export declare let createExecutionContext: (input: ExecutionContext & {
|
|
23
|
+
contextId?: string | undefined;
|
|
24
|
+
}) => ExecutionContext;
|
|
25
|
+
//# sourceMappingURL=execution-context.d.ts.map
|
|
@@ -0,0 +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"}
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +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)}};
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC"}
|
|
@@ -0,0 +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};
|
|
2
|
+
//# sourceMappingURL=index.module.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +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)}}});
|
|
2
|
+
//# sourceMappingURL=index.umd.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'async_hooks';
|
|
2
|
+
import { ExecutionContext } from './execution-context';
|
|
3
|
+
export declare let ctxStorage: AsyncLocalStorage<{
|
|
4
|
+
context: ExecutionContext;
|
|
5
|
+
afterHooks?: Array<() => Promise<void | any>>;
|
|
6
|
+
}>;
|
|
7
|
+
export declare let withExecutionContext: <T>(cb: (ctx: ExecutionContext) => Promise<T>) => Promise<T>;
|
|
8
|
+
export declare let withExecutionContextOptional: <T>(cb: (ctx: ExecutionContext | null) => Promise<T>) => Promise<T>;
|
|
9
|
+
export declare let addAfterHook: (hook: () => Promise<void | any>) => Promise<void>;
|
|
10
|
+
export declare let provideExecutionContext: <T>(ctx: ExecutionContext, cb: () => Promise<T>) => Promise<T>;
|
|
11
|
+
export declare let setExecutionContextSync: (ctx: ExecutionContext) => void;
|
|
12
|
+
export declare let updateExecutionContext: (ctx: Partial<ExecutionContext>) => ExecutionContext;
|
|
13
|
+
export declare let getExecutionContext: () => ExecutionContext;
|
|
14
|
+
//# sourceMappingURL=with-execution-context.d.ts.map
|
|
@@ -0,0 +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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lowerdeck/execution-context",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
7
|
+
"files": [
|
|
8
|
+
"src/**",
|
|
9
|
+
"dist/**",
|
|
10
|
+
"README.md",
|
|
11
|
+
"package.json"
|
|
12
|
+
],
|
|
7
13
|
"author": "Tobias Herber",
|
|
8
14
|
"license": "Apache 2",
|
|
9
15
|
"type": "module",
|
|
@@ -21,15 +27,15 @@
|
|
|
21
27
|
"scripts": {
|
|
22
28
|
"test": "vitest run --passWithNoTests",
|
|
23
29
|
"lint": "prettier src/**/*.ts --check",
|
|
24
|
-
"build": "microbundle"
|
|
30
|
+
"build": "rm -rf ./dist && microbundle"
|
|
25
31
|
},
|
|
26
32
|
"dependencies": {
|
|
27
|
-
"@lowerdeck/id": "^1.0.
|
|
28
|
-
"@lowerdeck/sentry": "^1.0.
|
|
33
|
+
"@lowerdeck/id": "^1.0.5",
|
|
34
|
+
"@lowerdeck/sentry": "^1.0.2"
|
|
29
35
|
},
|
|
30
36
|
"devDependencies": {
|
|
31
37
|
"microbundle": "^0.15.1",
|
|
32
|
-
"@lowerdeck/tsconfig": "^1.0.
|
|
38
|
+
"@lowerdeck/tsconfig": "^1.0.1",
|
|
33
39
|
"typescript": "^5.8.3",
|
|
34
40
|
"vitest": "^3.1.2"
|
|
35
41
|
}
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
[0m[2m[35m$[0m [2m[1mmicrobundle[0m
|
|
3
|
-
[34mBuild "@lowerdeck/unique" to dist:[39m
|
|
4
|
-
[32m77 B[39m: [37mindex.cjs[39m.gz
|
|
5
|
-
[32m58 B[39m: [37mindex.cjs[39m.br
|
|
6
|
-
[32m66 B[39m: [37mindex.module.js[39m.gz
|
|
7
|
-
[32m50 B[39m: [37mindex.module.js[39m.br
|
|
8
|
-
[32m88 B[39m: [37mindex.module.js[39m.gz
|
|
9
|
-
[32m72 B[39m: [37mindex.module.js[39m.br
|
|
10
|
-
[32m170 B[39m: [37mindex.umd.js[39m.gz
|
|
11
|
-
[32m137 B[39m: [37mindex.umd.js[39m.br
|
package/.turbo/turbo-test.log
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
[0m[2m[35m$[0m [2m[1mvitest run --passWithNoTests[0m
|
|
3
|
-
[?25l
|
|
4
|
-
[1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/Users/tobias/code/metorial/metorial-enterprise/oss/src/packages/shared/unique[39m
|
|
5
|
-
|
|
6
|
-
[?2026h
|
|
7
|
-
[1m[33m ❯ [39m[22msrc/index.test.ts[2m [queued][22m
|
|
8
|
-
|
|
9
|
-
[2m Test Files [22m[1m[32m0 passed[39m[22m[90m (1)[39m
|
|
10
|
-
[2m Tests [22m[1m[32m0 passed[39m[22m[90m (0)[39m
|
|
11
|
-
[2m Start at [22m10:23:39
|
|
12
|
-
[2m Duration [22m101ms
|
|
13
|
-
[?2026l[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K[1A[K [32m✓[39m src/index.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 2[2mms[22m[39m
|
|
14
|
-
[32m✓[39m unique[2m > [22mshould return an array with unique elements[32m 1[2mms[22m[39m
|
|
15
|
-
[32m✓[39m unique[2m > [22mshould handle an empty array[32m 0[2mms[22m[39m
|
|
16
|
-
[32m✓[39m unique[2m > [22mshould handle an array with all unique elements[32m 0[2mms[22m[39m
|
|
17
|
-
[32m✓[39m unique[2m > [22mshould handle an array with all duplicate elements[32m 0[2mms[22m[39m
|
|
18
|
-
[32m✓[39m unique[2m > [22mshould work with strings[32m 0[2mms[22m[39m
|
|
19
|
-
[32m✓[39m unique[2m > [22mshould work with mixed types[32m 0[2mms[22m[39m
|
|
20
|
-
|
|
21
|
-
[2m Test Files [22m [1m[32m1 passed[39m[22m[90m (1)[39m
|
|
22
|
-
[2m Tests [22m [1m[32m6 passed[39m[22m[90m (6)[39m
|
|
23
|
-
[2m Start at [22m 10:23:39
|
|
24
|
-
[2m Duration [22m 218ms[2m (transform 29ms, setup 0ms, collect 28ms, tests 2ms, environment 0ms, prepare 40ms)[22m
|
|
25
|
-
|
|
26
|
-
[?25h
|