Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 | 1x 39x 39x 39x 39x 55x | import type { IAsyncLocalStorage } from './async-local-storage.types.mjs'
/**
* A synchronous-only polyfill for AsyncLocalStorage.
*
* This provides the same API as Node's AsyncLocalStorage but only works
* for synchronous code paths. It uses a simple stack-based approach.
*
* Limitations:
* - Context does NOT propagate across async boundaries (setTimeout, promises, etc.)
* - Only suitable for environments where DI resolution is synchronous
*
* This is acceptable for browser environments where:
* 1. Constructors are typically synchronous
* 2. Circular dependency detection mainly needs sync tracking
*/
export class SyncLocalStorage<T> implements IAsyncLocalStorage<T> {
private stack: T[] = []
/**
* Runs a function within the given store context.
* The context is only available synchronously within the function.
*/
run<R>(store: T, fn: () => R): R {
this.stack.push(store)
try {
return fn()
} finally {
this.stack.pop()
}
}
/**
* Gets the current store value, or undefined if not in a context.
*/
getStore(): T | undefined {
return this.stack.length > 0 ? this.stack[this.stack.length - 1] : undefined
}
/**
* Exits the current context and runs the function without any store.
* This matches AsyncLocalStorage.exit() behavior.
*/
exit<R>(fn: () => R): R {
const savedStack = this.stack
this.stack = []
try {
return fn()
} finally {
this.stack = savedStack
}
}
}
|