@@ -257,6 +257,58 @@ Routes.tsx ← 4 routes added inside <Set wrap={ScaffoldLayout} title="Posts" ..
257257| cookie-jar | Typed cookie map. get/set/has/unset/serialize. |
258258| utils | Pluralization wrapper. |
259259
260+ ## ALS WRAPPING & GLOBAL CONTEXT
261+
262+ Cedar provides two related but distinct mechanisms:
263+
264+ - ** ALS wrapping** (` store.run(new Map(), ...) ` ) — ensures the AsyncLocalStorage
265+ store exists for the duration of a request. Needed because serverless
266+ environments (Netlify, Vercel) may reuse the same process across requests —
267+ without a fresh store per request, state from one request could leak into
268+ another. Also prevents the ` context ` proxy from crashing (without an active
269+ store, ` getStore() ` returns ` undefined ` ).
270+ - ** ` context ` ** (auto-imported from ` @cedarjs/context ` ) — a Proxy that
271+ reads/writes from the ALS store. Exists so services deep in the GraphQL
272+ resolver chain can access ` currentUser ` without threading it through every
273+ function parameter.
274+
275+ ` setContext() ` populates the store with the resolved GraphQL context
276+ (including ` currentUser ` ) and is only called by the
277+ ` useRedwoodGlobalContextSetter ` plugin
278+ (` packages/graphql-server/src/plugins/useRedwoodGlobalContextSetter.ts:16 ` ).
279+ It's GraphQL-only because:
280+
281+ 1 . GraphQL has a plugin chain where ` currentUser ` is resolved once by
282+ ` useRedwoodAuthContext ` (from ` ctx.serverAuthState ` ) and then made available
283+ to all downstream resolvers and directive validators via the store.
284+ 2 . Regular functions are single-entry-point: they get the request, do one thing,
285+ return a response. Different function types handle auth differently, but none
286+ need ` setContext() ` for ` currentUser ` :
287+
288+ - ** Auth functions** (login/signup/logout): integral to the auth flow, but
289+ they create/destroy sessions by reading the request body and cookies
290+ directly. On login the user isn't authenticated yet; on logout the session
291+ is already in the cookie. ` currentUser ` is resolved _ after_ these functions
292+ succeed, by the auth decoder on subsequent GraphQL requests.
293+ - ** Webhooks** (Stripe, SendGrid): external POSTs with no Cedar auth context
294+ at all. No way to construct a ` currentUser ` from the request.
295+ - ** Custom API endpoints** : if they need auth they decode the token or read
296+ the cookie themselves. Preferrably with the help of the ` useRequireAuth() `
297+ hook.
298+
299+ | Path | Mechanism | ALS wrapping | ` setContext() ` | ` context.currentUser ` |
300+ | --------------------------------------------------------- | -------------------------- | ------------ | --------------- | --------------------- |
301+ | ** Non-UD dev** — GraphQL | Fastify ` onRequest ` hook | ✅ | ✅ plugin chain | ✅ |
302+ | ** Non-UD dev** — Functions | Fastify ` onRequest ` hook | ✅ | ❌ | ❌ ` undefined ` |
303+ | ** Non-UD serve/deploy** (baremetal/docker) — GraphQL | Fastify ` onRequest ` hook | ✅ | ✅ plugin chain | ✅ |
304+ | ** Non-UD serve/deploy** (baremetal/docker) — Functions | Fastify ` onRequest ` hook | ✅ | ❌ | ❌ ` undefined ` |
305+ | ** Non-UD deploy** (Netlify/Vercel serverless) — GraphQL | Babel safety net in output | ✅ | ✅ plugin chain | ✅ |
306+ | ** Non-UD deploy** (Netlify/Vercel serverless) — Functions | Babel safety net in output | ✅ | ❌ | ❌ ` undefined ` |
307+ | ** UD dev** — GraphQL | Vite Babel transform | ✅ | ✅ plugin chain | ✅ |
308+ | ** UD dev** — Functions | Vite Babel transform | ✅ | ❌ | ❌ ` undefined ` |
309+ | ** UD built/deploy** — GraphQL | Generated ` store.run() ` | ✅ | ✅ plugin chain | ✅ |
310+ | ** UD built/deploy** — Functions | Generated ` store.run() ` | ✅ | ❌ | ❌ ` undefined ` |
311+
260312## CONVENTIONS
261313
262314- Config: ` cedar.toml ` (fallback ` redwood.toml ` )
0 commit comments