# @nextwrappers/async-local-storage

> Middleware wrapper for Next.js Route Handlers that executes requests within an AsyncLocalStorage context.

Latest version **1.0.1** (published 2023-07-06) · MIT license · 0 weekly downloads

## Install

```sh
npm install @nextwrappers/async-local-storage
pnpm add @nextwrappers/async-local-storage
yarn add @nextwrappers/async-local-storage
bun add @nextwrappers/async-local-storage
```

## Health

**Score 35/100 (D)** — status: abandoned.

Positive: has types; no vulnerabilities; high quality score.

Warnings: low downloads; no esm support.

Negative: abandoned.

## Facts

| | |
|---|---|
| Version | 1.0.1 |
| Published | 2023-07-06 |
| First published | 2023-07-06 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 1 |
| Unpacked size | 12.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 30 |
| Author | Rexford Essilfie |
| Maintainers | rexfordessilfie |
| Keywords | next, route, handler, wrapper, middleware, api |

## Links

- npm: https://www.npmjs.com/package/@nextwrappers/async-local-storage
- Repository: https://github.com/rexfordessilfie/nextwrappers
- Homepage: https://github.com/rexfordessilfie/nextwrappers#readme
- Issues: https://github.com/rexfordessilfie/nextwrappers/issues
- npm.io page: https://npm.io/package/@nextwrappers/async-local-storage

## Dependencies (1)

- [path-to-regexp](https://npm.io/package/path-to-regexp.md) ^6.2.1

## Alternatives

- [express-promise-router](https://npm.io/package/express-promise-router.md) — 736.1K weekly downloads
- [next-usequerystate](https://npm.io/package/next-usequerystate.md) — 29.8K weekly downloads
- [@bitkyc08/opencodex](https://npm.io/package/@bitkyc08/opencodex.md) — 4.6K weekly downloads
- [lynkr](https://npm.io/package/lynkr.md) — 575 weekly downloads
- [baremetal.js](https://npm.io/package/baremetal.js.md) — 42 weekly downloads

## Recent versions

- 1.0.1 (latest) — 2023-07-06
- 1.0.2-rc1 (next) — 2023-07-06
- 1.0.1-rc3 — 2023-07-06
- 1.0.1-rc2 — 2023-07-06

## README

# Next.js AsyncLocalStorage Route Handler
Middleware wrapper for Next.js Route Handlers that executes requests within an AsyncLocalStorage context.

## Installation
```bash
npm install @nextwrappers/async-local-storage # npm
yarn add @nextwrappers/async-local-storage # yarn
pnpm add @nextwrappers/async-local-storage # pnpm
```

## Usage
```ts
// app/api/hello/route.ts
import { asyncLocalStorage } from "@nextwrappers/async-local-storage";

export const { wrapper: asyncLocalStorageWrapped, getStore } =
  asyncLocalStorage({
    initialize: () => "Hello from AsyncLocalStorage!"
  });

export const GET = asyncLocalStorageWrapped(() => {
  console.log(getStore()); // "Hello from AsyncLocalStorage!"
  return new Response("OK");
});
```

By wrapping the route handler with `asyncLocalStorageWrapped`, we can access the AsyncLocalStorage store from anywhere within the callback execution with a call to `getStore()`.



# Use-Cases 📝

## Request Tracing
### `traced` wrapper
Together with `uuid`, we can trace a request through through execution and log throughout.

First we create a wrapper that initializes the store with a `traceId`:

```ts
// utils.ts
import { asyncLocalStorage } from "@nextwrappers/async-local-storage";
import { v4 as uuid } from "uuid";
import { NextRequest } from "next/server";

export const { wrapper: asyncLocalStorageWrapped, getStore } =
  asyncLocalStorage({
    initialize: (request: NextRequest) => ({
      traceId: uuid(),
      pathname: request.nextUrl.pathname
    })
  });
```

Now we define a simple logger that logs the `traceId` and the message:

```ts
// lib/logger.ts
import { getStore } from "./utils";

export const logger = (prefix: string, message: string) => {
  const { traceId, pathname } = getStore() || {};
  console.log(`[${traceId}] (${pathname}) ${prefix}: ${message}`);
};
```

Finally, we can use the logger in our route handler:

```ts
// app/api/hello/route.ts
import { asyncLocalStorageWrapped, logger } from "lib";

const doSomething = async () => {
  logger("doSomething", "Doing something!");
  return new Promise((resolve) => setTimeout(()=>{
    logger("doSomething", "Done!");
    resolve("OK");
  }, 1000));
};

export const GET = asyncLocalStorageWrapped((request: NextRequest) => {
  logger("GET", "Request started!");
  const response = new Response(doSomething());
  logger("GET", "Request finished!");
  return response;
});
```

This will log something like this:
  
```text
[1b9c0b0a-7b5a-4b9f-8f9c-8b0c0b0a7b5a] (/api/hello) GET: Request started!
[1b9c0b0a-7b5a-4b9f-8f9c-8b0c0b0a7b5a] (/api/hello) doSomething: Doing something!
[1b9c0b0a-7b5a-4b9f-8f9c-8b0c0b0a7b5a] (/api/hello) doSomething: Done!
[1b9c0b0a-7b5a-4b9f-8f9c-8b0c0b0a7b5a] (/api/hello) GET: Request finished!
```

---
_Source: https://npm.io/package/@nextwrappers/async-local-storage · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
