Skip to content

Commit

Permalink
feat: add cut operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Lonli-Lokli authored and sergeysova committed Oct 6, 2022
1 parent b298405 commit 2af6b0f
Show file tree
Hide file tree
Showing 5 changed files with 576 additions and 0 deletions.
42 changes: 42 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,48 @@ Patronum had 3 breaking changes: 1) from `0.14` to `0.100`, 2) from `0.100` to `

We have [migration guide](https://patronum.effector.dev/docs/migration-guide).

## Cut

[Method documentation & API](/src/cut)

```ts
import { createEvent } from 'effector';
import { cut } from 'patronum/cut';

type WSInitEvent = { type: 'init'; key: string };
type WSIncrementEvent = { type: 'increment'; count: number; name: string };
type WSResetEvent = { type: 'reset'; name: string };
type WSEvent =
| WSInitEvent
| WSIncrementEvent
| WSResetEvent

export const websocketEventReceived = createEvent<WSEvent[]>();

const { init, increment, reset, __ } = cut({
source: websocketEventReceived,
cases: {
init: (events) => events.filter((wsEvent: WSEvent): wsEvent is WSInitEvent => wsEvent.type === 'init'),
increment: (events) => events.filter((wsEvent: WSEvent): wsEvent is WSIncrementEvent => wsEvent.type === 'increment'),
reset: (events) => events.filter((wsEvent: WSEvent): wsEvent is WSResetEvent => wsEvent.type === 'reset'),
},
});

init.watch(initEvents => {
console.info(`inited for ${initEvents.length}`);
});

increment.watch(incrementEvents => {
console.info('should be incremented', incrementEvents.map(wsEvent => wsEvent.count).reduce((a, b) => a + b));
});

websocketEventReceived([{ type: 'increment', name: 'demo', count: 5 }, { type: 'increment', name: 'demo', count: 15 }]);
// => inited for 0
// => should be incremented 20
```

[Try it]()

# Development

You can review [CONTRIBUTING.md](./CONTRIBUTING.md)
Expand Down
113 changes: 113 additions & 0 deletions src/cut/cut.fork.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import 'regenerator-runtime/runtime';
import { createDomain, fork, serialize, allSettled } from 'effector';

import { cut } from './index';

test('works in forked scope', async () => {
const app = createDomain();
const source = app.createEvent<{ first?: number; another?: boolean }>();
const out = cut({
source,
cases: {
first: (payload) => payload.first,
},
});

const $data = app.createStore(0);

$data
.on(out.first, (state, payload) => state + payload)
.on(out.__, (state, payload) => (payload ? -state : 0));

const scope = fork(app);

await allSettled(source, {
scope,
params: { first: 15 },
});
expect(serialize(scope)).toMatchInlineSnapshot(`
Object {
"-4r0u7g": 15,
}
`);

await allSettled(source, {
scope,
params: { another: true },
});
expect(serialize(scope)).toMatchInlineSnapshot(`
Object {
"-4r0u7g": -15,
}
`);
});

test('do not affect another fork', async () => {
const app = createDomain();
const source = app.createEvent<{ first?: number; another?: boolean }>();
const out = cut({
source,
cases: {
first: (payload) => payload.first,
},
});

const $data = app.createStore(0);

$data
.on(out.first, (state, payload) => state + payload)
.on(out.__, (state, payload) => (payload ? -state : 0));

const scopeA = fork(app);
const scopeB = fork(app);

await allSettled(source, {
scope: scopeA,
params: { first: 200 },
});
expect(serialize(scopeA)).toMatchInlineSnapshot(`
Object {
"-hjldon": 200,
}
`);

await allSettled(source, {
scope: scopeB,
params: { first: -5 },
});
expect(serialize(scopeB)).toMatchInlineSnapshot(`
Object {
"-hjldon": -5,
}
`);
});

test('do not affect original store value', async () => {
const app = createDomain();
const source = app.createEvent<{ first?: number; another?: boolean }>();
const out = cut({
source,
cases: {
first: (payload) => payload.first,
},
});

const $data = app.createStore(0);

$data
.on(out.first, (state, payload) => state + payload)
.on(out.__, (state, payload) => (payload ? -state : 0));

const scope = fork(app);

await allSettled(source, {
scope,
params: { first: 15 },
});
expect(serialize(scope)).toMatchInlineSnapshot(`
Object {
"-tv4arn": 15,
}
`);
expect($data.getState()).toBe($data.defaultState);
});
Loading

0 comments on commit 2af6b0f

Please sign in to comment.