Skip to content

Commit

Permalink
Support enabled for keepFresh (#402)
Browse files Browse the repository at this point in the history
* add enabled param for keepFresh

* update docs

* Support `enabled` in `keepFresh`

* use every, remove extra oveloads, add badge in docs, use createWatch in tests
  • Loading branch information
lordofinterface committed Nov 23, 2023
1 parent 164974d commit ef2d3a5
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 10 deletions.
5 changes: 5 additions & 0 deletions .changeset/light-chefs-applaud.md
@@ -0,0 +1,5 @@
---
'@farfetched/core': patch
---

Support `enabled` in `keepFresh`
1 change: 1 addition & 0 deletions apps/website/docs/api/operators/keep_fresh.md
Expand Up @@ -14,6 +14,7 @@ Config fields:

- `automatically?`: _true_ to refresh the data in a [_Query_](/api/primitives/query) automatically if any [_Store_](https://effector.dev/docs/api/effector/store) that is used in the [_Query_](/api/primitives/query) creation is changed.
- `triggers?`: _Array_ of [_Events_](https://effector.dev/docs/api/effector/event) after which operator starts refreshing the data in the [_Query_](/api/primitives/query).
- `enabled?`: <Badge type="tip" text="since v0.11" /> [_Store_](https://effector.dev/docs/api/effector/store) with the current enabled state. Disabled _keepFresh_ will not execute queries, instead, they will be treated as skipped. Can be `true` or `false`.

```ts
import { keepFresh } from '@farfetched/core';
Expand Down
9 changes: 8 additions & 1 deletion packages/core/src/trigger_api/__test__/keep_fresh.test-d.ts
@@ -1,4 +1,4 @@
import { Event } from 'effector';
import { createStore, Event } from 'effector';
import { describe, test } from 'vitest';

import { Query } from '../../query/type';
Expand All @@ -11,6 +11,13 @@ describe('keepFresh', () => {
keepFresh(q, { automatically: true });
keepFresh(q, { triggers: [] });
keepFresh(q, { automatically: true, triggers: [] });
keepFresh(q, { automatically: true, enabled: createStore(true) });
keepFresh(q, { triggers: [], enabled: createStore(true) });
keepFresh(q, {
automatically: true,
triggers: [],
enabled: createStore(true),
});
});

test('supports any Event as trigger', () => {
Expand Down
52 changes: 52 additions & 0 deletions packages/core/src/trigger_api/__test__/keep_fresh.triggers.test.ts
Expand Up @@ -214,4 +214,56 @@ describe('keepFresh, triggers as TriggerProtocol', () => {
// 1 initial + 1 after enabling
expect(setupListener).toBeCalledTimes(2);
});

test('call teardown after config disabling and call start again after enabling', async () => {
const trigger = {
setup: createEvent(),
teardown: createEvent(),
fired: createEvent(),
};

const scope = fork();

const $enabled = createStore(true);

const teardownListener = vi.fn();

createWatch({
unit: trigger.teardown,
fn: teardownListener,
scope,
});

const setupListener = vi.fn();

createWatch({
unit: trigger.setup,
fn: setupListener,
scope,
});

const query = createQuery({
handler: vi.fn(),
});

keepFresh(query, {
enabled: $enabled,
triggers: [
{
'@@trigger': () => trigger,
},
],
});

await allSettled(query.refresh, { scope });

await allSettled($enabled, { scope, params: false });

expect(teardownListener).toBeCalled();

await allSettled($enabled, { scope, params: true });

// 1 initial + 1 after enabling
expect(setupListener).toBeCalledTimes(2);
});
});
31 changes: 22 additions & 9 deletions packages/core/src/trigger_api/keep_fresh.ts
Expand Up @@ -5,6 +5,7 @@ import {
sample,
is,
createStore,
Store,
} from 'effector';

import { type Query } from '../query/type';
Expand All @@ -15,20 +16,23 @@ import {
syncBatch,
normalizeSourced,
extractSource,
every,
} from '../libs/patronus';
import { type TriggerProtocol } from './trigger_protocol';

export function keepFresh<Params>(
query: Query<Params, any, any, any>,
config: {
automatically: true;
enabled?: Store<boolean>;
}
): void;

export function keepFresh<Params>(
query: Query<Params, any, any, any>,
config: {
triggers: Array<Event<any> | TriggerProtocol>;
enabled?: Store<boolean>;
}
): void;

Expand All @@ -37,6 +41,7 @@ export function keepFresh<Params>(
config: {
automatically: true;
triggers: Array<Event<any> | TriggerProtocol>;
enabled?: Store<boolean>;
}
): void;

Expand All @@ -45,6 +50,7 @@ export function keepFresh<Params>(
config: {
automatically?: true;
triggers?: Array<Event<any> | TriggerProtocol>;
enabled?: Store<boolean>;
}
): void {
const triggers: Array<Event<any>> = [];
Expand All @@ -56,6 +62,16 @@ export function keepFresh<Params>(

triggers.push(...triggerEvents);

const enabledParamStores = [query.$enabled];
if (config.enabled !== undefined) {
enabledParamStores.push(config.enabled);
}

const $enabled = every({
predicate: Boolean,
stores: enabledParamStores,
});

if (protocolCompatibleObjects.length > 0) {
const triggersByProtocol = protocolCompatibleObjects.map((trigger) =>
trigger['@@trigger']()
Expand All @@ -71,15 +87,15 @@ export function keepFresh<Params>(
sample({
clock: [
query.finished.success,
sample({ clock: query.$enabled.updates, filter: query.$enabled }),
sample({ clock: $enabled.updates, filter: $enabled }),
],
filter: not($alreadySetup),
target: [...triggersByProtocol.map(get('setup')), setup],
});

sample({
clock: query.$enabled.updates,
filter: and($alreadySetup, not(query.$enabled)),
clock: $enabled.updates,
filter: and($alreadySetup, not($enabled)),
target: [...triggersByProtocol.map(get('teardown')), teardown],
});

Expand All @@ -103,7 +119,7 @@ export function keepFresh<Params>(
source: $partialSources,
fn: (partialSources, clock) =>
partialSources.map((partialSource) => partialSource(clock)),
filter: query.$enabled,
filter: $enabled,
target: $previousSources,
});

Expand All @@ -124,17 +140,14 @@ export function keepFresh<Params>(

triggers.push(
sample({
clock: [
$nextSources.updates,
query.$enabled.updates.filter({ fn: Boolean }),
],
clock: [$nextSources.updates, $enabled.updates.filter({ fn: Boolean })],
source: [$nextSources, $previousSources] as const,
filter: ([next, prev]) => !isEqual(next, prev),
})
);
}

const forceFresh = sample({ clock: triggers, filter: query.$enabled });
const forceFresh = sample({ clock: triggers, filter: $enabled });

sample({
clock: forceFresh,
Expand Down

0 comments on commit ef2d3a5

Please sign in to comment.