@b9g/async-context 0.1.2 → 0.1.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.
- package/README.md +46 -26
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ The TC39 AsyncContext proposal aims to standardize async context propagation in
|
|
|
12
12
|
|
|
13
13
|
This package provides a **lightweight, maintainable polyfill** that:
|
|
14
14
|
|
|
15
|
-
✅ Implements the TC39 `AsyncContext.Variable`
|
|
15
|
+
✅ Implements the TC39 `AsyncContext.Variable` and `AsyncContext.Snapshot` APIs
|
|
16
16
|
✅ Uses battle-tested `AsyncLocalStorage` under the hood
|
|
17
17
|
✅ Zero dependencies (beyond Node.js built-ins)
|
|
18
18
|
✅ Full TypeScript support
|
|
@@ -121,19 +121,17 @@ console.log(themeContext.get()); // "light"
|
|
|
121
121
|
### Classes
|
|
122
122
|
|
|
123
123
|
- `AsyncVariable<T>` - Main class for creating async context variables
|
|
124
|
-
- `
|
|
124
|
+
- `AsyncSnapshot` - Captures and restores context state
|
|
125
|
+
- `AsyncContext.Variable<T>` - Alias for AsyncVariable (TC39 API)
|
|
126
|
+
- `AsyncContext.Snapshot` - Alias for AsyncSnapshot (TC39 API)
|
|
125
127
|
|
|
126
128
|
### Types
|
|
127
129
|
|
|
128
130
|
- `AsyncVariableOptions<T>` - Options for AsyncVariable constructor (defaultValue, name)
|
|
129
131
|
|
|
130
|
-
### Namespaces
|
|
131
|
-
|
|
132
|
-
- `AsyncContext` - Namespace containing Variable class (TC39 API)
|
|
133
|
-
|
|
134
132
|
### Default Export
|
|
135
133
|
|
|
136
|
-
- `AsyncContext` -
|
|
134
|
+
- `AsyncContext` - Object containing Variable and Snapshot classes
|
|
137
135
|
|
|
138
136
|
## API
|
|
139
137
|
|
|
@@ -147,13 +145,14 @@ Options:
|
|
|
147
145
|
- `defaultValue?: T` - Default value when no context is set
|
|
148
146
|
- `name?: string` - Optional name for debugging
|
|
149
147
|
|
|
150
|
-
#### `run<R>(value: T, fn: () => R): R`
|
|
148
|
+
#### `run<R>(value: T, fn: (...args) => R, ...args): R`
|
|
151
149
|
|
|
152
150
|
Execute a function with a context value. The value is available via `get()` throughout the entire async execution of `fn`.
|
|
153
151
|
|
|
154
152
|
**Parameters:**
|
|
155
153
|
- `value: T` - The context value to set
|
|
156
|
-
- `fn: () => R` - Function to execute (can be sync or async)
|
|
154
|
+
- `fn: (...args) => R` - Function to execute (can be sync or async)
|
|
155
|
+
- `...args` - Additional arguments to pass to fn
|
|
157
156
|
|
|
158
157
|
**Returns:** The return value of `fn`
|
|
159
158
|
|
|
@@ -165,14 +164,39 @@ Get the current context value. Returns `defaultValue` if no context is set.
|
|
|
165
164
|
|
|
166
165
|
Get the name of this variable (for debugging).
|
|
167
166
|
|
|
168
|
-
### `
|
|
167
|
+
### `AsyncSnapshot`
|
|
168
|
+
|
|
169
|
+
Captures the current values of all Variables at construction time. Use `run()` to restore that state later.
|
|
170
|
+
|
|
171
|
+
#### `constructor()`
|
|
172
|
+
|
|
173
|
+
Creates a snapshot of all current Variable values.
|
|
169
174
|
|
|
170
|
-
|
|
175
|
+
#### `run<R>(fn: (...args) => R, ...args): R`
|
|
176
|
+
|
|
177
|
+
Execute a function with the captured context values restored.
|
|
178
|
+
|
|
179
|
+
**Parameters:**
|
|
180
|
+
- `fn: (...args) => R` - Function to execute
|
|
181
|
+
- `...args` - Additional arguments to pass to fn
|
|
182
|
+
|
|
183
|
+
**Returns:** The return value of `fn`
|
|
184
|
+
|
|
185
|
+
#### `static wrap<F>(fn: F): F`
|
|
186
|
+
|
|
187
|
+
Wrap a function to preserve the current context. When the wrapped function is called later, it will execute with the context values that were active when `wrap()` was called.
|
|
171
188
|
|
|
172
189
|
```typescript
|
|
173
|
-
|
|
190
|
+
const userVar = new AsyncContext.Variable<string>();
|
|
174
191
|
|
|
175
|
-
const
|
|
192
|
+
const wrappedFn = userVar.run("alice", () => {
|
|
193
|
+
return AsyncContext.Snapshot.wrap(() => {
|
|
194
|
+
return userVar.get();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
// Later, even outside the run() context:
|
|
199
|
+
wrappedFn(); // returns "alice"
|
|
176
200
|
```
|
|
177
201
|
|
|
178
202
|
## How It Works
|
|
@@ -203,25 +227,21 @@ The polyfill provides:
|
|
|
203
227
|
|
|
204
228
|
This package works in any JavaScript runtime that supports `AsyncLocalStorage`:
|
|
205
229
|
|
|
206
|
-
- ✅ Node.js 12.17+
|
|
207
|
-
- ✅ Bun
|
|
208
|
-
- ✅
|
|
209
|
-
-
|
|
230
|
+
- ✅ Node.js 12.17+
|
|
231
|
+
- ✅ Bun
|
|
232
|
+
- ✅ Deno
|
|
233
|
+
- ✅ Cloudflare Workers
|
|
210
234
|
|
|
211
235
|
## Differences from TC39 Proposal
|
|
212
236
|
|
|
213
|
-
This polyfill
|
|
214
|
-
|
|
215
|
-
- ✅ `AsyncContext.Variable`
|
|
216
|
-
- ✅ `.run(value, fn)` method
|
|
217
|
-
- ✅ `.get()` method
|
|
237
|
+
This polyfill implements the core TC39 AsyncContext API:
|
|
218
238
|
|
|
219
|
-
|
|
239
|
+
- ✅ `AsyncContext.Variable` - context variables with `run()` and `get()`
|
|
240
|
+
- ✅ `AsyncContext.Snapshot` - context capture with `run()` and `wrap()`
|
|
220
241
|
|
|
221
|
-
-
|
|
222
|
-
- ⏳ `AsyncContext.Mapping`
|
|
242
|
+
The implementation uses Node.js `AsyncLocalStorage` rather than the pure-JS reference implementation, which means async context propagation works natively without monkey-patching `Promise.prototype.then`.
|
|
223
243
|
|
|
224
|
-
|
|
244
|
+
Test suite adapted from the [TC39 proposal repository](https://github.com/tc39/proposal-async-context).
|
|
225
245
|
|
|
226
246
|
## Migration Path
|
|
227
247
|
|
package/package.json
CHANGED