darky / effector-async-local-storage

Effector Domain based on AsyncLocalStorage

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

effector-async-local-storage

Effector Domain based on Node.js AsyncLocalStorage

Example

import { attach, createEffect, createEvent, createStore } from 'effector';
import { effectorAsyncLocalStorageFactory, effectorAsyncLocalStorageInit } from 'effector-async-local-storage';
import Koa from 'koa';
import Router from 'koa-router';
import Redis from 'ioredis';

const eff = effectorAsyncLocalStorageFactory({
  onCreateEffect(sid, effect) {
    effect.watch((val) => {
      console.log(`Effect "${sid}" call with value: ${val}`);
    });
    effect.doneData.watch((val) => {
      console.log(`Effect "${sid}" done with value: ${val}`);
    });
    effect.failData.watch((val) => {
      console.log(`Effect "${sid}" fail with value: ${val}`);
    });
  },
  onCreateEvent(sid, event) {
    event.watch((val) => {
      console.log(`Event "${sid}" call with value: ${val}`);
    });
  },
  onCreateStore(sid, store) {
    store.watch((state, val) => {
      console.log(`Store "${sid}" mutation with value: ${val}`);
      console.log(`Store "${sid}" mutation, current state: ${state}`);
    });
  },
});

const increment = eff('increment', () => createEvent());
const decrement = eff('decrement', () => createEvent());
const reset = eff('reset', () => createEvent());

const pullCounterFx = eff('pullCounterFx', () =>
  createEffect<void, number>(async () => {
    const count = await redis.get('counter');
    return Number(count ?? 0);
  })
);

const pushCounterFx = eff('pushCounterFx', () =>
  attach({
    source: $counter(),
    effect: createEffect<number, number>(async (count) => {
      await redis.set('counter', count);
      return count;
    }),
  })
);

const $counter = eff(
  '$counter',
  () =>
    createStore(0)
      .on(increment(), (state) => state + 1)
      .on(decrement(), (state) => state - 1)
      .on(pullCounterFx().doneData, (_, value) => value)
      .reset(reset())
);

const app = new Koa();
const router = new Router();
const redis = new Redis();

app.use(async (_, next) => {
  await effectorAsyncLocalStorageInit(async () => {
    await next();
  });
});

router.post('/increment', async (ctx) => {
  $counter();
  await pullCounterFx()();
  increment()();
  ctx.body = await pushCounterFx()();
});

router.post('/decrement', async (ctx) => {
  $counter();
  await pullCounterFx()();
  decrement()();
  ctx.body = await pushCounterFx()();
});

router.post('/reset', async (ctx) => {
  $counter();
  await pullCounterFx()();
  reset()();
  ctx.body = await pushCounterFx()();
});

app.use(router.routes());

app.listen(4000);

Related

  • effector-storify - Effector utils for storify Effect/Event

  • ts-fp-di - Tiny TypeScript functional dependency injection, based on Node.js AsyncLocalStorage

About

Effector Domain based on AsyncLocalStorage

License:MIT License


Languages

Language:TypeScript 100.0%