-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontext.ts
More file actions
92 lines (87 loc) · 2.36 KB
/
context.ts
File metadata and controls
92 lines (87 loc) · 2.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/**
* Keep track of information for each web request, like the URL and session.
* This lets you easily get the current request's details from anywhere.
* @module
*/
import { AsyncLocalStorage } from 'node:async_hooks'
import { startTime } from '@01edu/time'
import type {
GetContext,
NewContext,
RequestContext,
RunContext,
} from '@01edu/types/context'
export type { GetContext, NewContext, RequestContext, RunContext }
/**
* Creates a new request context. Useful for testing or running background jobs.
*
* @param urlInit - The URL for the new context.
* @param extra - Optional additional properties to add to the context.
* @returns A new request context object.
*
* @example
* ```ts
* import { newContext } from '@01edu/context';
*
* const context = newContext('/users/123');
* console.log(context.url.pathname);
* // => "/users/123"
* ```
*/
export const newContext: NewContext = (
urlInit: string | URL,
extra?: Partial<RequestContext>,
) => {
const url = new URL(urlInit, 'http://locahost')
const req = new Request(url)
return {
trace: startTime,
cookies: {},
span: undefined,
url,
req,
...extra,
}
}
const defaultContext = newContext('/')
const requestContext = new AsyncLocalStorage<RequestContext>()
/**
* Returns the current request's context.
* If no context is found, it returns a default context.
*
* @returns The current request context.
*
* @example
* ```ts
* import { getContext } from '@01edu/context';
*
* function logPath() {
* const { url } = getContext();
* console.log(url.pathname);
* }
* ```
*/
export const getContext: GetContext = () =>
requestContext.getStore() || defaultContext
/**
* Runs a callback within a specific request context, making it available via `getContext`.
* This is essential for ensuring that context is not lost in asynchronous operations.
*
* @param store - The request context to run the callback in.
* @param cb - The callback to execute.
* @returns The return value of the callback.
*
* @example
* ```ts
* import { runContext, newContext, getContext } from '@01edu/context';
*
* const context = newContext('/about');
*
* runContext(context, () => {
* const currentContext = getContext();
* console.log(currentContext.url.pathname); // => "/about"
* });
* ```
*/
export const runContext: RunContext = (store, cb) =>
requestContext.run(store, cb, store)