# @yadah/subsystem-context

> Yadah domain class mixin to provide a shared context to promise chains

Latest version **0.2.2** (published 2023-06-03) · ISC license · 0 weekly downloads

## Install

```sh
npm install @yadah/subsystem-context
pnpm add @yadah/subsystem-context
yarn add @yadah/subsystem-context
bun add @yadah/subsystem-context
```

## Health

**Score 20/100 (F)** — status: abandoned.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types; pre 1.0.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.2.2 |
| Published | 2023-06-03 |
| First published | 2022-07-12 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | ESM |
| Node | >=18.3.0 |
| Dependencies | 1 |
| Unpacked size | 7.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 1 |
| Author | ttoohey |
| Maintainers | ttoohey |
| Keywords | yadah |

## Links

- npm: https://www.npmjs.com/package/@yadah/subsystem-context
- Repository: https://github.com/ttoohey/yadah
- Homepage: https://github.com/ttoohey/yadah/tree/master/packages/subsystem-context#readme
- Issues: https://github.com/ttoohey/yadah/issues
- npm.io page: https://npm.io/package/@yadah/subsystem-context

## Dependencies (1)

- [@yadah/mixin](https://npm.io/package/@yadah/mixin.md) 0.2.0

## Recent versions

- 0.2.2 (latest) — 2023-06-03
- 0.2.0 — 2023-04-08
- 0.1.1 — 2022-07-12

## README

# Yadah Context subsystem

A [Yadah](https://www.npmjs.com/package/@yadah/yadah) subsystem and Domain class
mixin that provides a way to access shared "context" values in promise chains.

## Basic usage

```js
import createContext, { ContextMixin } from "@yadah/subsystem-context";
import DataManager, { Domain } from "@yadah/data-manager";
import { pipe } from "@yadah/mixin";

class MyDomain extends pipe(Domain, ContextMixin) {
  async foo() {
    const value = this.context.get("foo");
    console.log(value);
  }
  async bar() {
    await this.context(async () => {
      const value = this.context.get("foo");
      this.context.set("foo", value + "!");
      await this.foo();
    });
  }
}

const context = createContext();

const dataManager = new DataManager({ context });
const domains = dataManager.boot({ MyDomain });

await domains.MyDomain.bar();
// logs: "undefined!"

context(async (ctx) => {
  ctx.set("foo", "demo inside context");
  await domains.MyDomain.bar();
  await domains.MyDomain.foo();
});
// logs:
// "demo inside context!"
// "demo inside context"
```

## Nesting contexts

A context callback resolves once all nested context callbacks have resolved.

In this example logging `3` doesn't occur before `2` because the outer context
will await the inner context.

```js
await context(() => {
  context(async () => {
    await new Promise((resolve) => setImmediate(resolve));
    console.log(2);
  });
  console.log(1);
});
console.log(3);
```

This feature allows awaiting async event handlers.

```js
class MyDomain extends pipe(Domain, ContextMixin) {
  registerListeners() {
    this.on("event", () =>
      this.context(async () => {
        await new Promise((resolve) => setImmediate(resolve));
        console.log("event complete");
      })
    );
  }

  doEvent() {
    this.emit("event");
    console.log("before event complete");
  }

  async doEventAsync() {
    await this.context(() => this.emit("event"));
    console.log("after event complete");
  }
}
```

The `.onAsync()` and `.emitAsync()` functions can be used to simplify this
pattern.

```js
class MyDomain extends pipe(Domain, ContextMixin) {
  registerListeners() {
    this.onAsync("event", async () => {
      await new Promise((resolve) => setImmediate(resolve));
      console.log("event complete");
    });
  }

  async doEventAsync() {
    await this.emitAsync("event");
    console.log("after event complete");
  }
}
```

## API

### `createContext()`

- Returns: `<context>`

Creates a promise chain context.

#### `context(callback)`

- `callback` `<AsyncFunction>`
- Returns: `<Promise<any>>`

Executes a callback function in a promise chain context. The `context` object
is passed as the first argument to the callback function.

Returns the result of the callback function.

#### `context.get(key)`

- `key` `<string>` | `<number>` | `<symbol>`
- Returns: `<any>`

Returns the current value stored for the specified `key` from the context.

#### `context.set(key, value)`

- `key` `<string>` | `<number>` | `<symbol>`
- Returns: `<any>`

Sets the current value stored for the specified `key` to `value`.

### `class ContextMixin`

Adds behaviour to `Domain` classes.

A `context` object must be passed as in the `Domain` constructor.

#### `.context()`

Getter to return the context object.

#### `.onAsync(eventName, listener)`

- `eventName` `<string>`|`<symbol>`
- `listener` `<Function>`

Wraps an event listener in a context calback.

#### `.emitAsync(eventName[, ...args])`

- `eventName` `<string>`|`<symbol>`
- `args` `<any>`
- Returns: `<Promise<void>>`

Emits an event in a context callback.

---
_Source: https://npm.io/package/@yadah/subsystem-context · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
