Skip to content

Commit

Permalink
Feat: use node async local storage
Browse files Browse the repository at this point in the history
Related to #2

---

For more details, open the [Copilot Workspace session](https://copilot-workspace.githubnext.com/bluelibs/runner/issues/2?shareId=XXXX-XXXX-XXXX-XXXX).
  • Loading branch information
theodorDiaconu committed Feb 10, 2025
1 parent 5847ae3 commit 2e993ea
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/__tests__/context.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { useContext, withContext } from '../context';

describe('ApplicationContext', () => {
it('should create and use application context', async () => {
const context = { user: { name: 'John Doe' }, roles: ['admin'], isLoggedIn: true };

const result = withContext(context, () => {
const ctx = useContext();
return ctx;
});

expect(result).toEqual(context);
});

it('should handle nested contexts', async () => {
const context1 = { user: { name: 'John Doe' }, roles: ['admin'], isLoggedIn: true };
const context2 = { user: { name: 'Jane Doe' }, roles: ['user'], isLoggedIn: false };

const result = withContext(context1, () => {
const ctx1 = useContext();
expect(ctx1).toEqual(context1);

return withContext(context2, () => {
const ctx2 = useContext();
return ctx2;
});
});

expect(result).toEqual(context2);
});

it('should return undefined when no context is set', async () => {
const result = useContext();
expect(result).toBeUndefined();
});
});
21 changes: 21 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { AsyncLocalStorage } from 'node:async_hooks';

const asyncLocalStorage = new AsyncLocalStorage();

export type IApplicationContext = {
user: User;
roles: string[];
isLoggedIn: boolean;
};

export function useContext(): IApplicationContext | undefined {
return asyncLocalStorage.getStore();
}

export function withContext<T>(
context: IApplicationContext,
fn: (...args: any[]) => T,
...args: any[]
): T {
return asyncLocalStorage.run(context, fn, ...args);
}
8 changes: 8 additions & 0 deletions src/defs.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { AsyncLocalStorage } from 'node:async_hooks';

export const symbolTask: unique symbol = Symbol("runner.task");
export const symbolResource: unique symbol = Symbol("runner.resource");
export const symbolResourceWithConfig: unique symbol = Symbol(
Expand Down Expand Up @@ -326,3 +328,9 @@ export interface IHookDefinition<
dependencies: T extends true ? void : DependencyValuesType<D>
) => Promise<void> | void;
}

export type IApplicationContext = {
user: User;
roles: string[];
isLoggedIn: boolean;
};
1 change: 1 addition & 0 deletions src/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { findCircularDependencies } from "./tools/findCircularDependencies";
import { Errors } from "./errors";
import { globalResources } from "./globalResources";
import { Logger } from "./models/Logger";
import { withContext } from "./context";

export type ResourcesStoreElementType<
C = any,
Expand Down

0 comments on commit 2e993ea

Please sign in to comment.