@warlock.js/context 5.34.1 → 5.34.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/CHANGELOG.md +6 -0
- package/llms-full.txt +59 -72
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/skills/index.md +34 -1
- package/skills/overview/SKILL.md +0 -68
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,12 @@ All notable changes to `@warlock.js/context` are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). `@warlock.js/*` packages are released in lockstep — every package shares the same version number, so a version below may list only the changes that affected this package.
|
|
6
6
|
|
|
7
|
+
## 5.34.2 - 2026-10-19
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Merge package orientation into the grouped skill index and remove the duplicate overview topic; preserve that orientation in generated LLM projections.
|
|
12
|
+
|
|
7
13
|
## 5.32.0 - 2026-10-18
|
|
8
14
|
|
|
9
15
|
### Changed
|
package/llms-full.txt
CHANGED
|
@@ -4,6 +4,65 @@
|
|
|
4
4
|
|
|
5
5
|
> Generated artifact. Concatenates every SKILL.md and reference file under `@warlock.js/context/skills/`. Re-run `node scripts/generate-llms.mjs` after any change.
|
|
6
6
|
|
|
7
|
+
## Package orientation
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
description: 'Typed request-scoped context on Node AsyncLocalStorage, so data (user, tenant, trace id, transaction) flows through awaits without parameter threading. Exports `Context`, `contextManager`, `ContextManager`. Use for: "share the current user or tenant across async calls", "request-scoped storage", "AsyncLocalStorage wrapper", "run several contexts together", "avoid passing data through every function". Not this package: cross-request state → @warlock.js/cache or a database; HTTP request/response objects → @warlock.js/core.'
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# @warlock.js/context
|
|
14
|
+
|
|
15
|
+
A thin typed wrapper over `AsyncLocalStorage`. Each `Context<TStore>` subclass declares its store shape and how `buildStore` creates it; the store lives for the scope and propagates through every `await` inside. `contextManager` runs several contexts together. Zero dependencies; the framework uses it internally for request, user and tenant.
|
|
16
|
+
|
|
17
|
+
## The 80% path
|
|
18
|
+
|
|
19
|
+
1. Use this index for orientation and choose a task below.
|
|
20
|
+
2. Subclass `Context`, implement `buildStore`, read with `get` / `set` anywhere down the call tree: `define-context.md`.
|
|
21
|
+
3. Wrap work with `run(store, callback)`, or `enter(store)` for middleware that cannot wrap a callback: `define-context.md`.
|
|
22
|
+
4. With two or more active contexts, register them on `contextManager` and use `runAll` / `enterAll`: `orchestrate-contexts.md`.
|
|
23
|
+
|
|
24
|
+
## Conventions and pitfalls
|
|
25
|
+
|
|
26
|
+
- Outside a `run`/`enter` scope there is no store; guard with `hasContext` when code may run unscoped.
|
|
27
|
+
- `enter` leaks until cleared; pair `enterAll` with `clearAll` at the end of the request.
|
|
28
|
+
- Worker threads do not share the store; serialize data across and re-enter.
|
|
29
|
+
- Context is not shared state: it vanishes with the scope.
|
|
30
|
+
- One context in a cooperative framework needs no manager; use plain `run`.
|
|
31
|
+
|
|
32
|
+
## When to reach for it
|
|
33
|
+
|
|
34
|
+
- You have request-scoped data (user, tenant, trace id, db transaction) that you'd otherwise thread through every function as a parameter. One `userContext.get("userId")` anywhere down the call tree replaces five layers of plumbing.
|
|
35
|
+
- You're inside a `@warlock.js/*` project and want consistent context handling across modules. The framework already uses this package internally for request + user + tenant contexts.
|
|
36
|
+
- You'd reach for **cls-hooked**, **nest-context**, or a bare `AsyncLocalStorage<T>` and want a typed wrapper with `run` / `enter` / `update` / `get` / `set` semantics out of the box.
|
|
37
|
+
|
|
38
|
+
Skip if your call chain is a single function with no `await` boundaries — just pass the data as a parameter. Skip if you need cross-request shared state — that's a cache or database, not a context.
|
|
39
|
+
|
|
40
|
+
## What it is in one sentence
|
|
41
|
+
|
|
42
|
+
Each `Context<TStore>` subclass declares a typed store shape and what payload builds it; the framework uses Node's `AsyncLocalStorage` under the hood so the store propagates through every `await` inside the scope and disappears when the scope ends.
|
|
43
|
+
|
|
44
|
+
## Two operating modes — when to pick which
|
|
45
|
+
|
|
46
|
+
| Situation | Reach for |
|
|
47
|
+
| ----------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
48
|
+
| Framework gives you a callback to wrap | `context.run(store, callback)` |
|
|
49
|
+
| Framework expects middleware that returns synchronously (Express, etc.) | `context.enter(store)` |
|
|
50
|
+
| You have 2+ contexts active for the same request | `contextManager.runAll(stores, callback)` |
|
|
51
|
+
| Middleware-style with 2+ contexts | `contextManager.enterAll(stores)` then `clearAll()` at end |
|
|
52
|
+
| You only have one context and the framework cooperates | Single `context.run(...)`. Skip the manager. |
|
|
53
|
+
|
|
54
|
+
## What this package deliberately doesn't do
|
|
55
|
+
|
|
56
|
+
- **Persist data across requests.** AsyncLocalStorage dies with the scope. For cross-request state, reach for `@warlock.js/cache` or a database.
|
|
57
|
+
- **Cross-thread context.** Worker threads don't share AsyncLocalStorage with the main thread. Serialize the data you need across the boundary and re-enter on the other side.
|
|
58
|
+
- **Browser context.** Server-side only. The browser equivalent is React Context or a state library.
|
|
59
|
+
- **Implicit context for non-async code.** If your call stack has no `await`, the storage works but there's no propagation benefit — just pass the value as a parameter.
|
|
60
|
+
|
|
61
|
+
## See also
|
|
62
|
+
|
|
63
|
+
- The `warlock-js-core` skill index — the parent framework; `context` is one of its foundation packages.
|
|
64
|
+
|
|
65
|
+
|
|
7
66
|
## define-context `@warlock.js/context/define-context/SKILL.md`
|
|
8
67
|
|
|
9
68
|
---
|
|
@@ -328,75 +387,3 @@ async function handleRequest(req: any, res: any) {
|
|
|
328
387
|
- Don't expect `enterAll()` to auto-clean. It's a one-way setup — pair with `clearAll()` at the end of the request, or just use `runAll` when you can.
|
|
329
388
|
|
|
330
389
|
|
|
331
|
-
## overview `@warlock.js/context/overview/SKILL.md`
|
|
332
|
-
|
|
333
|
-
---
|
|
334
|
-
name: overview
|
|
335
|
-
description: "@warlock.js/context overview for orientation and choosing the focused skill for the task."
|
|
336
|
-
---
|
|
337
|
-
|
|
338
|
-
# `@warlock.js/context` — overview
|
|
339
|
-
|
|
340
|
-
Two-file package: a typed wrapper over Node's `AsyncLocalStorage` and a singleton that runs several of them together. That's it. The entire surface fits in two skills below — most callers only need the first one.
|
|
341
|
-
|
|
342
|
-
## When to reach for it
|
|
343
|
-
|
|
344
|
-
- You have request-scoped data (user, tenant, trace id, db transaction) that you'd otherwise thread through every function as a parameter. One `userContext.get("userId")` anywhere down the call tree replaces five layers of plumbing.
|
|
345
|
-
- You're inside a `@warlock.js/*` project and want consistent context handling across modules. The framework already uses this package internally for request + user + tenant contexts.
|
|
346
|
-
- You'd reach for `cls-hooked`, `nest-context`, or a bare `AsyncLocalStorage<T>` and want a typed wrapper with `run` / `enter` / `update` / `get` / `set` semantics out of the box.
|
|
347
|
-
|
|
348
|
-
Skip if your call chain is a single function with no `await` boundaries — just pass the data as a parameter. Skip if you need cross-request shared state — that's a cache or database, not a context.
|
|
349
|
-
|
|
350
|
-
## What it is in one sentence
|
|
351
|
-
|
|
352
|
-
Each `Context<TStore>` subclass declares a typed store shape and what payload builds it; the framework uses Node's `AsyncLocalStorage` under the hood so the store propagates through every `await` inside the scope and disappears when the scope ends.
|
|
353
|
-
|
|
354
|
-
## Skills index
|
|
355
|
-
|
|
356
|
-
Two task skills cover everything. The first one is the daily-use one; the second is for when you have multiple contexts active at the same time.
|
|
357
|
-
|
|
358
|
-
### `define-context`
|
|
359
|
-
|
|
360
|
-
Extend `Context<TStore>` to declare what your context stores and how it's
|
|
361
|
-
built. Implement `buildStore(payload?)`; use `run` / `enter` / `update` /
|
|
362
|
-
`get` / `set` / `getStore` / `clear` / `hasContext` to interact with the
|
|
363
|
-
store from anywhere in the async scope.
|
|
364
|
-
|
|
365
|
-
Load when sharing data (user, tenant, trace id) across async calls
|
|
366
|
-
without threading it through every function — i.e. ~90% of the time you
|
|
367
|
-
use this package.
|
|
368
|
-
|
|
369
|
-
### `orchestrate-contexts`
|
|
370
|
-
|
|
371
|
-
Register multiple `Context<TStore>` instances on the `contextManager`
|
|
372
|
-
singleton and run them all together with a single call. Covers
|
|
373
|
-
`register` / `unregister`, `buildStores`, `runAll` / `enterAll`,
|
|
374
|
-
`clearAll`, `getContext` / `hasContext`.
|
|
375
|
-
|
|
376
|
-
Load when several contexts apply to the same scope (request + database
|
|
377
|
-
|
|
378
|
-
- trace + tenant) and you'd otherwise nest `run()` calls by hand.
|
|
379
|
-
|
|
380
|
-
## Two operating modes — when to pick which
|
|
381
|
-
|
|
382
|
-
| Situation | Reach for |
|
|
383
|
-
| ----------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
384
|
-
| Framework gives you a callback to wrap | `context.run(store, callback)` |
|
|
385
|
-
| Framework expects middleware that returns synchronously (Express, etc.) | `context.enter(store)` |
|
|
386
|
-
| You have 2+ contexts active for the same request | `contextManager.runAll(stores, callback)` |
|
|
387
|
-
| Middleware-style with 2+ contexts | `contextManager.enterAll(stores)` then `clearAll()` at end |
|
|
388
|
-
| You only have one context and the framework cooperates | Single `context.run(...)`. Skip the manager. |
|
|
389
|
-
|
|
390
|
-
## What this package deliberately doesn't do
|
|
391
|
-
|
|
392
|
-
- **Persist data across requests.** AsyncLocalStorage dies with the scope. For cross-request state, reach for `@warlock.js/cache` or a database.
|
|
393
|
-
- **Cross-thread context.** Worker threads don't share AsyncLocalStorage with the main thread. Serialize the data you need across the boundary and re-enter on the other side.
|
|
394
|
-
- **Browser context.** Server-side only. The browser equivalent is React Context or a state library.
|
|
395
|
-
- **Implicit context for non-async code.** If your call stack has no `await`, the storage works but there's no propagation benefit — just pass the value as a parameter.
|
|
396
|
-
|
|
397
|
-
## See also
|
|
398
|
-
|
|
399
|
-
- The `overview` topic of the `warlock-js-core` skill — the parent framework; `context` is one of its foundation packages.
|
|
400
|
-
- `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.
|
|
401
|
-
|
|
402
|
-
|
package/llms.txt
CHANGED
|
@@ -6,6 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
## Skills
|
|
8
8
|
|
|
9
|
+
- [Package orientation](@warlock.js/context/skills/index.md): Typed request-scoped context on Node AsyncLocalStorage, so data (user, tenant, trace id, transaction) flows through awaits without parameter threading. Exports `Context`, `contextManager`, `ContextManager`. Use for: "share the current user or tenant across async calls", "request-scoped storage", "AsyncLocalStorage wrapper", "run several contexts together", "avoid passing data through every function". Not this package: cross-request state → @warlock.js/cache or a database; HTTP request/response objects → @warlock.js/core.
|
|
9
10
|
- [define-context](@warlock.js/context/define-context/SKILL.md): Extend Context<TStore> to define an AsyncLocalStorage-backed typed context — implement buildStore, use run / enter / update / get / set / getStore / clear / hasContext. Triggers: `Context`, `Context<TStore>`, `buildStore`, `run`, `enter`, `update`, `get`, `set`, `getStore`, `clear`, `hasContext`; "share user/tenant/trace id across async calls", "AsyncLocalStorage typed wrapper", "request-scoped store without thread-through"; typical import `import { Context } from "@warlock.js/context"`. Skip: orchestrating multiple contexts — the `orchestrate-contexts` topic; native `AsyncLocalStorage`, `cls-hooked`, `nest-context`, React Context.
|
|
10
11
|
- [orchestrate-contexts](@warlock.js/context/orchestrate-contexts/SKILL.md): Orchestrate multiple Context<TStore> instances via the contextManager singleton — register, buildStores, runAll, enterAll, clearAll. Triggers: `contextManager`, `register`, `buildStores`, `runAll`, `enterAll`, `clearAll`, `unregister`, `getContext`, `hasContext`; "run multiple contexts active for the same scope", "register contexts at boot", "avoid nested run() calls for request + database + tenant"; typical import `import { contextManager } from "@warlock.js/context"`. Skip: defining a single context class — the `define-context` topic; native `AsyncLocalStorage` nesting, `cls-hooked` namespaces.
|
|
11
|
-
- [overview](@warlock.js/context/overview/SKILL.md): @warlock.js/context overview for orientation and choosing the focused skill for the task.
|
package/package.json
CHANGED
package/skills/index.md
CHANGED
|
@@ -8,7 +8,7 @@ A thin typed wrapper over `AsyncLocalStorage`. Each `Context<TStore>` subclass d
|
|
|
8
8
|
|
|
9
9
|
## The 80% path
|
|
10
10
|
|
|
11
|
-
1.
|
|
11
|
+
1. Use this index for orientation and choose a task below.
|
|
12
12
|
2. Subclass `Context`, implement `buildStore`, read with `get` / `set` anywhere down the call tree: `define-context.md`.
|
|
13
13
|
3. Wrap work with `run(store, callback)`, or `enter(store)` for middleware that cannot wrap a callback: `define-context.md`.
|
|
14
14
|
4. With two or more active contexts, register them on `contextManager` and use `runAll` / `enterAll`: `orchestrate-contexts.md`.
|
|
@@ -20,3 +20,36 @@ A thin typed wrapper over `AsyncLocalStorage`. Each `Context<TStore>` subclass d
|
|
|
20
20
|
- Worker threads do not share the store; serialize data across and re-enter.
|
|
21
21
|
- Context is not shared state: it vanishes with the scope.
|
|
22
22
|
- One context in a cooperative framework needs no manager; use plain `run`.
|
|
23
|
+
|
|
24
|
+
## When to reach for it
|
|
25
|
+
|
|
26
|
+
- You have request-scoped data (user, tenant, trace id, db transaction) that you'd otherwise thread through every function as a parameter. One `userContext.get("userId")` anywhere down the call tree replaces five layers of plumbing.
|
|
27
|
+
- You're inside a `@warlock.js/*` project and want consistent context handling across modules. The framework already uses this package internally for request + user + tenant contexts.
|
|
28
|
+
- You'd reach for **cls-hooked**, **nest-context**, or a bare `AsyncLocalStorage<T>` and want a typed wrapper with `run` / `enter` / `update` / `get` / `set` semantics out of the box.
|
|
29
|
+
|
|
30
|
+
Skip if your call chain is a single function with no `await` boundaries — just pass the data as a parameter. Skip if you need cross-request shared state — that's a cache or database, not a context.
|
|
31
|
+
|
|
32
|
+
## What it is in one sentence
|
|
33
|
+
|
|
34
|
+
Each `Context<TStore>` subclass declares a typed store shape and what payload builds it; the framework uses Node's `AsyncLocalStorage` under the hood so the store propagates through every `await` inside the scope and disappears when the scope ends.
|
|
35
|
+
|
|
36
|
+
## Two operating modes — when to pick which
|
|
37
|
+
|
|
38
|
+
| Situation | Reach for |
|
|
39
|
+
| ----------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
40
|
+
| Framework gives you a callback to wrap | `context.run(store, callback)` |
|
|
41
|
+
| Framework expects middleware that returns synchronously (Express, etc.) | `context.enter(store)` |
|
|
42
|
+
| You have 2+ contexts active for the same request | `contextManager.runAll(stores, callback)` |
|
|
43
|
+
| Middleware-style with 2+ contexts | `contextManager.enterAll(stores)` then `clearAll()` at end |
|
|
44
|
+
| You only have one context and the framework cooperates | Single `context.run(...)`. Skip the manager. |
|
|
45
|
+
|
|
46
|
+
## What this package deliberately doesn't do
|
|
47
|
+
|
|
48
|
+
- **Persist data across requests.** AsyncLocalStorage dies with the scope. For cross-request state, reach for `@warlock.js/cache` or a database.
|
|
49
|
+
- **Cross-thread context.** Worker threads don't share AsyncLocalStorage with the main thread. Serialize the data you need across the boundary and re-enter on the other side.
|
|
50
|
+
- **Browser context.** Server-side only. The browser equivalent is React Context or a state library.
|
|
51
|
+
- **Implicit context for non-async code.** If your call stack has no `await`, the storage works but there's no propagation benefit — just pass the value as a parameter.
|
|
52
|
+
|
|
53
|
+
## See also
|
|
54
|
+
|
|
55
|
+
- The `warlock-js-core` skill index — the parent framework; `context` is one of its foundation packages.
|
package/skills/overview/SKILL.md
DELETED
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: overview
|
|
3
|
-
description: "@warlock.js/context overview for orientation and choosing the focused skill for the task."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# `@warlock.js/context` — overview
|
|
7
|
-
|
|
8
|
-
Two-file package: a typed wrapper over Node's `AsyncLocalStorage` and a singleton that runs several of them together. That's it. The entire surface fits in two skills below — most callers only need the first one.
|
|
9
|
-
|
|
10
|
-
## When to reach for it
|
|
11
|
-
|
|
12
|
-
- You have request-scoped data (user, tenant, trace id, db transaction) that you'd otherwise thread through every function as a parameter. One `userContext.get("userId")` anywhere down the call tree replaces five layers of plumbing.
|
|
13
|
-
- You're inside a `@warlock.js/*` project and want consistent context handling across modules. The framework already uses this package internally for request + user + tenant contexts.
|
|
14
|
-
- You'd reach for `cls-hooked`, `nest-context`, or a bare `AsyncLocalStorage<T>` and want a typed wrapper with `run` / `enter` / `update` / `get` / `set` semantics out of the box.
|
|
15
|
-
|
|
16
|
-
Skip if your call chain is a single function with no `await` boundaries — just pass the data as a parameter. Skip if you need cross-request shared state — that's a cache or database, not a context.
|
|
17
|
-
|
|
18
|
-
## What it is in one sentence
|
|
19
|
-
|
|
20
|
-
Each `Context<TStore>` subclass declares a typed store shape and what payload builds it; the framework uses Node's `AsyncLocalStorage` under the hood so the store propagates through every `await` inside the scope and disappears when the scope ends.
|
|
21
|
-
|
|
22
|
-
## Skills index
|
|
23
|
-
|
|
24
|
-
Two task skills cover everything. The first one is the daily-use one; the second is for when you have multiple contexts active at the same time.
|
|
25
|
-
|
|
26
|
-
### `define-context`
|
|
27
|
-
|
|
28
|
-
Extend `Context<TStore>` to declare what your context stores and how it's
|
|
29
|
-
built. Implement `buildStore(payload?)`; use `run` / `enter` / `update` /
|
|
30
|
-
`get` / `set` / `getStore` / `clear` / `hasContext` to interact with the
|
|
31
|
-
store from anywhere in the async scope.
|
|
32
|
-
|
|
33
|
-
Load when sharing data (user, tenant, trace id) across async calls
|
|
34
|
-
without threading it through every function — i.e. ~90% of the time you
|
|
35
|
-
use this package.
|
|
36
|
-
|
|
37
|
-
### `orchestrate-contexts`
|
|
38
|
-
|
|
39
|
-
Register multiple `Context<TStore>` instances on the `contextManager`
|
|
40
|
-
singleton and run them all together with a single call. Covers
|
|
41
|
-
`register` / `unregister`, `buildStores`, `runAll` / `enterAll`,
|
|
42
|
-
`clearAll`, `getContext` / `hasContext`.
|
|
43
|
-
|
|
44
|
-
Load when several contexts apply to the same scope (request + database
|
|
45
|
-
|
|
46
|
-
- trace + tenant) and you'd otherwise nest `run()` calls by hand.
|
|
47
|
-
|
|
48
|
-
## Two operating modes — when to pick which
|
|
49
|
-
|
|
50
|
-
| Situation | Reach for |
|
|
51
|
-
| ----------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
52
|
-
| Framework gives you a callback to wrap | `context.run(store, callback)` |
|
|
53
|
-
| Framework expects middleware that returns synchronously (Express, etc.) | `context.enter(store)` |
|
|
54
|
-
| You have 2+ contexts active for the same request | `contextManager.runAll(stores, callback)` |
|
|
55
|
-
| Middleware-style with 2+ contexts | `contextManager.enterAll(stores)` then `clearAll()` at end |
|
|
56
|
-
| You only have one context and the framework cooperates | Single `context.run(...)`. Skip the manager. |
|
|
57
|
-
|
|
58
|
-
## What this package deliberately doesn't do
|
|
59
|
-
|
|
60
|
-
- **Persist data across requests.** AsyncLocalStorage dies with the scope. For cross-request state, reach for `@warlock.js/cache` or a database.
|
|
61
|
-
- **Cross-thread context.** Worker threads don't share AsyncLocalStorage with the main thread. Serialize the data you need across the boundary and re-enter on the other side.
|
|
62
|
-
- **Browser context.** Server-side only. The browser equivalent is React Context or a state library.
|
|
63
|
-
- **Implicit context for non-async code.** If your call stack has no `await`, the storage works but there's no propagation benefit — just pass the value as a parameter.
|
|
64
|
-
|
|
65
|
-
## See also
|
|
66
|
-
|
|
67
|
-
- The `overview` topic of the `warlock-js-core` skill — the parent framework; `context` is one of its foundation packages.
|
|
68
|
-
- `mongez-agent-kit-authoring-skills` (load via agent-kit sync) — how this `overview` topic becomes the front-door skill in `.claude/skills/warlock-js-context-overview/`.
|