Skip to content

Commit

Permalink
Adopt for Effector 23 (#401)
Browse files Browse the repository at this point in the history
* Adopt for Effector 23

* Use EventCallable for commands

* Format

* Add migration info

* Migrate some deprecations

* Migrate some deprecations

* Migrate some deprecations

* Migrate some deprecations

* Migrate some deprecations

* Migrate some deprecations

* Migrate some deprecations

* Adopt for Effector 23

* Fix all warnings

* Use stable effector

* Use stable effector

* Adopt Barrier API to effector 23

* Adopt Barrier API to effector 23

* format
  • Loading branch information
igorkamyshev committed Nov 29, 2023
1 parent ec2ab95 commit ffdfffa
Show file tree
Hide file tree
Showing 37 changed files with 277 additions and 141 deletions.
6 changes: 6 additions & 0 deletions .changeset/unlucky-weeks-talk.md
@@ -0,0 +1,6 @@
---
'@farfetched/core': minor
'@farfetched/solid': minor
---

Adopt for Effector 23
5 changes: 5 additions & 0 deletions .changeset/witty-gifts-visit.md
@@ -0,0 +1,5 @@
---
'@farfetched/atomic-router': minor
---

Adopt for Effector 23
6 changes: 6 additions & 0 deletions apps/website/docs/releases/0-11.md
@@ -1,7 +1,13 @@
# v0.11

This release contains a couple of breaking changes, so please read the migration guide carefully.

## Migration guide

### Use Effector v23

To use Farfetched v0.11 you need to use Effector v23 and have all related dependencies (`effector-solid`, `effector-vue`, etc.) updated. Please, refer to Effector v23 migration guide for more details.

### Delete `isAbortError`

Since [v0.10](/releases/0-10) aborted [_Queries_](/api/primitives/query) and [_Mutations_](/api/primitives/mutation) are not treated as failed anymore. So, `isAbortError` is not needed can be safely removed from your codebase.
Expand Down
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -42,7 +42,7 @@
"@vitejs/plugin-react": "3",
"@vitest/ui": "^0.25.8",
"bytes-iec": "^3.1.1",
"effector": "^22.5.0",
"effector": "23.0.0",
"eslint": "~8.15.0",
"fp-ts": "^2.13.1",
"glob": "^8.0.3",
Expand Down Expand Up @@ -71,8 +71,8 @@
"dependencies": {
"atomic-router": "0.6",
"atomic-router-solid": "0.5",
"effector-react": "^22.3.0",
"effector-solid": "0.22.7",
"effector-react": "23.0.0",
"effector-solid": "0.23.0",
"forest": "^0.21.2",
"history": "^5.3.0",
"mermaid": "9.1.7",
Expand Down
10 changes: 5 additions & 5 deletions packages/atomic-router/src/chain.ptorocol.ts
@@ -1,8 +1,8 @@
import { type EventAsReturnType } from 'effector';
import { type RouteParamsAndQuery } from 'atomic-router';
import type { Event, EventCallable } from 'effector';
import type { RouteParamsAndQuery } from 'atomic-router';

export type ChainProtocol<RouteParams extends Record<string, any>> = {
beforeOpen: EventAsReturnType<RouteParamsAndQuery<RouteParams>>;
openOn: EventAsReturnType<any>;
cancelOn: EventAsReturnType<any>;
beforeOpen: EventCallable<RouteParamsAndQuery<RouteParams>>;
openOn: Event<any>;
cancelOn: Event<any>;
};
2 changes: 1 addition & 1 deletion packages/core/package.json
Expand Up @@ -3,6 +3,6 @@
"version": "0.10.6",
"type": "commonjs",
"peerDependencies": {
"effector": "^22.5.0"
"effector": "^23.0.0"
}
}
6 changes: 5 additions & 1 deletion packages/core/src/attach/attach.ts
Expand Up @@ -81,7 +81,11 @@ export function attachOperation<
const { source, mapParams } = config ?? {};

return operation.__.experimentalAPI?.attach({
source: source ?? createStore(null, { serialize: 'ignore' }),
source:
source ??
createStore(null, {
serialize: 'ignore',
}),
mapParams: mapParams ?? ((v: NewParams) => v as unknown as OriginalParams),
});
}
@@ -1,5 +1,10 @@
import { describe, expectTypeOf, test } from 'vitest';
import { createStore, type Effect, type Event } from 'effector';
import {
createStore,
type EventCallable,
type Effect,
type Event,
} from 'effector';

import { type Query } from '../../query/type';
import { type Mutation } from '../../mutation/type';
Expand Down Expand Up @@ -65,7 +70,7 @@ describe('createBarrier', () => {
});

test('accept start/end Events as performer', () => {
const voidEvent: Event<void> = {} as any;
const voidEvent: EventCallable<void> = {} as any;
const paramsEvent: Event<{ id: number }> = {} as any;

// void Event as start is allowed
Expand Down
11 changes: 7 additions & 4 deletions packages/core/src/barrier_api/create_barrier.ts
Expand Up @@ -5,6 +5,7 @@ import {
is,
sample,
split,
type EventCallable,
type Effect,
type Event,
type Store,
Expand All @@ -20,10 +21,10 @@ import { get, Mutex } from '../libs/lohyphen';
type Performer =
| RemoteOperation<void, any, any, any>
| Effect<void, any, any>
| { start: Event<void>; end: Event<any> };
| { start: EventCallable<void>; end: Event<any> };

type NormalizedPerformer = {
start: Event<void> | Effect<void, any, any>;
start: EventCallable<void> | Effect<void, any, any>;
end: Event<void>;
$pending: Store<boolean>;
};
Expand Down Expand Up @@ -121,7 +122,7 @@ export function createBarrier({

const performers = normalizePerformers(perform ?? []);

let $active: Store<boolean>;
let $active;
// Overload: active
if (active) {
$active = active;
Expand Down Expand Up @@ -185,7 +186,9 @@ export function createBarrier({
};
}

function startOnlyNotPending(performers: NormalizedPerformer[]): Event<void> {
function startOnlyNotPending(
performers: NormalizedPerformer[]
): EventCallable<void> {
const clock = createEvent();

for (const { start, $pending } of performers) {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/barrier_api/type.ts
@@ -1,6 +1,6 @@
import { type Event, type Store } from 'effector';
import type { EventCallable, Event, Store } from 'effector';

import { Mutex } from '../libs/lohyphen/mutex';
import type { Mutex } from '../libs/lohyphen/mutex';

export type Barrier = {
/**
Expand All @@ -22,15 +22,15 @@ export type Barrier = {
/**
* Call this event every time when operation with applied Barrier tries to start
*/
touch: Event<void>;
touch: EventCallable<void>;
/**
* Call this event every time when operation with applied Barrier fails
*/
operationFailed: Event<{ params: unknown; error: unknown }>;
operationFailed: EventCallable<{ params: unknown; error: unknown }>;
/**
* Call this event every time when operation with applied Barrier succeeds
*/
operationDone: Event<{ params: unknown; result: unknown }>;
operationDone: EventCallable<{ params: unknown; result: unknown }>;
/**
* Barrier ia based on Mutex, this store provides direct access to it
*/
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/cache/adapters/browser_storage.ts
Expand Up @@ -155,7 +155,11 @@ export function browserStorageCache(
}

// -- meta storage
const $meta = createStore<Meta | null>(null, { serialize: 'ignore' });
const $meta = createStore<Meta | null>(null, {
serialize: 'ignore',
name: 'ff.browserStorage.$meta',
sid: 'ff.browserStorage.$meta',
});

const getMetaFx = createEffect(async () => {
const meta = await getItemFx(META_KEY);
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/cache/adapters/instance.ts
Expand Up @@ -7,7 +7,8 @@ export function createCacheAdapter(
): CacheAdapter {
const $instance = createStore(adapter, {
serialize: 'ignore',
sid: 'ff.cache_instance',
name: 'ff.$cacheInstance',
sid: 'ff.$cacheInstance',
});

return { ...adapter, __: { $instance } };
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/cache/adapters/observability.ts
@@ -1,6 +1,6 @@
import { Event, sample } from 'effector';
import { type Event, sample } from 'effector';

import { CacheAdapterInstance, CacheAdapterOptions } from './type';
import type { CacheAdapterInstance, CacheAdapterOptions } from './type';

export function attachObservability({
adapter,
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/cache/adapters/type.ts
@@ -1,22 +1,22 @@
import { Effect, Event, Store } from 'effector';
import type { Effect, Event, EventCallable, Store } from 'effector';

import { Time } from '../../libs/date-nfs';

export interface CacheAdapterInstance {
get: Effect<{ key: string }, { value: unknown; cachedAt: number } | null>;
set: Effect<{ key: string; value: unknown }, void>;
purge: Event<void>;
purge: EventCallable<void>;
unset: Effect<{ key: string }, void>;
}

export interface CacheAdapterOptions {
maxEntries?: number;
maxAge?: Time;
observability?: {
hit?: Event<{ key: string }>;
miss?: Event<{ key: string }>;
expired?: Event<{ key: string }>;
evicted?: Event<{ key: string }>;
hit?: EventCallable<{ key: string }>;
miss?: EventCallable<{ key: string }>;
expired?: EventCallable<{ key: string }>;
evicted?: EventCallable<{ key: string }>;
};
}

Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/fetch/api.ts
Expand Up @@ -163,7 +163,11 @@ export function createApiRequest<

const prepareFx = createEffect(config.response.extract);

const $haveToBeAborted = createStore(false, { serialize: 'ignore' });
const $haveToBeAborted = createStore(false, {
serialize: 'ignore',
name: 'ff.$haveToBeAborted',
sid: 'ff.$haveToBeAborted',
});

const apiRequestFx = createEffect<
DynamicRequestConfig<B> &
Expand Down
16 changes: 12 additions & 4 deletions packages/core/src/libs/patronus/abortable.ts
Expand Up @@ -77,7 +77,11 @@ export function abortable<P = void, D = void, F = Error>(config: {

return result;
});
const $calls = createStore<CurrentCall[]>([], { serialize: 'ignore' });
const $calls = createStore<CurrentCall[]>([], {
serialize: 'ignore',
name: 'ff.$calls',
sid: 'ff.$calls',
});
const callsApi = createApi($calls, {
add(calls, def: CurrentCall) {
return [...calls, def];
Expand All @@ -88,14 +92,18 @@ export function abortable<P = void, D = void, F = Error>(config: {
});

if (abort?.signal) {
const abortTrigger = sample({ clock: abort.signal });

$calls.watch(abortTrigger, (calls) => {
const cancelAllFx = createEffect((calls: CurrentCall[]) => {
calls.forEach((c) => {
c.context?.runAborters?.();
c.reject(abortError());
});
});

sample({
clock: abort.signal,
source: $calls,
target: cancelAllFx,
});
}

// нужно, чтобы поддержать и синхронные эффекты тоже
Expand Down
11 changes: 6 additions & 5 deletions packages/core/src/libs/patronus/delay.ts
Expand Up @@ -2,10 +2,11 @@ import {
createEffect,
createEvent,
sample,
Unit,
Event,
Store,
EventAsReturnType,
type Unit,
type Event,
type Store,
type EventAsReturnType,
type EventCallable,
} from 'effector';

import { normalizeStaticOrReactive } from './sourced';
Expand All @@ -17,7 +18,7 @@ export function delay<T>({
}: {
clock: Unit<T>;
timeout: Store<number> | number;
target?: Event<T>;
target?: EventCallable<T>;
}): EventAsReturnType<T> {
const timerFx = createEffect<{ payload: T; milliseconds: number }, T>(
({ payload, milliseconds }) =>
Expand Down
6 changes: 5 additions & 1 deletion packages/core/src/libs/patronus/postpone.ts
Expand Up @@ -24,7 +24,11 @@ export function postpone<T>({
}): EventAsReturnType<T> {
const target = createEvent<T>();

const $fired = createStore(false, { serialize: 'ignore' })
const $fired = createStore(false, {
serialize: 'ignore',
name: 'ff.$fired',
sid: 'ff.$fired',
})
.on(target, () => true)
.on(clock, () => false);

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/libs/patronus/readonly.ts
Expand Up @@ -6,5 +6,5 @@ export function readonly<T>(event: Event<T>): Event<T>;
export function readonly<T>(
storeOrEvent: Store<T> | Event<T>
): Store<T> | Event<T> {
return storeOrEvent.map((v) => v);
return storeOrEvent.map((v) => v, { skipVoid: false });
}
16 changes: 14 additions & 2 deletions packages/core/src/libs/patronus/sourced.ts
Expand Up @@ -45,7 +45,11 @@ function normalizeSourced<Data, Result, Source>({

if (field === undefined) {
// do nothing
$target = createStore((_: Data) => null as any, { serialize: 'ignore' });
$target = createStore((_: Data) => null as any, {
serialize: 'ignore',
name: 'ff.$target/undefined',
sid: 'ff.$target/undefined',
});
} else if (is.store(field)) {
const $storeField = field as Store<Result>;

Expand All @@ -71,13 +75,17 @@ function normalizeSourced<Data, Result, Source>({
(params: Data): Result | null => callbackField(params) ?? null,
{
serialize: 'ignore',
name: 'ff.$target/callbackField',
sid: 'ff.$target/$callbackField',
}
);
} else {
const valueField = field as Result;

$target = createStore((_: Data): Result | null => valueField ?? null, {
serialize: 'ignore',
name: 'ff.$target/valueField',
sid: 'ff.$target/$valueField',
});
}

Expand Down Expand Up @@ -201,6 +209,8 @@ function normalizeStaticOrReactive<T>(
if (!v) {
return createStore<Exclude<T, undefined> | null>(null, {
serialize: 'ignore',
name: 'ff.$target/undefined',
sid: 'ff.$target/$undefined',
});
}

Expand All @@ -210,14 +220,16 @@ function normalizeStaticOrReactive<T>(

return createStore<Exclude<T, undefined> | null>(v as Exclude<T, undefined>, {
serialize: 'ignore',
name: 'ff.$target/valueField',
sid: 'ff.$target/$valueField',
});
}

// -- Extract source

function extractSource<S>(sourced: SourcedField<any, any, S>): Store<S> | null {
if (is.store(sourced)) {
return sourced;
return sourced as Store<S>;
}

if (sourced?.source) {
Expand Down

0 comments on commit ffdfffa

Please sign in to comment.