Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions apps/website/docs/api/operators/apply_barrier.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,31 @@ Applies the [_Barrier_](/api/primitives/barrier) to the [_Query_](/api/primitive

## Formulae

### `applyBarrier(operation, { barrier })`
### `applyBarrier(operation, config)`

```ts
import { applyBarrier } from '@farfetched/core';

applyBarrier(operation, { barrier });
applyBarrier(operation, config);
```

#### Arguments
Operation could be a [_Query_](/api/primitives/query) or a [_Mutation_](/api/primitives/mutation) to apply the [_Barrier_](/api/primitives/barrier) to.

- `operation` - [_Query_](/api/primitives/query) or [_Mutation_](/api/primitives/mutation) to apply the [_Barrier_](/api/primitives/barrier) to
- `barrier` - [_Barrier_](/api/primitives/barrier) to apply
Config fields:

### `applyBarrier(operations, { barrier })` <Badge type="tip" text="since v0.12" />
- `barrier` - [_Barrier_](/api/primitives/barrier) to apply.
- `suppressIntermediateFailures?` - _boolean_ whether to suppress intermediate failures or not, defaults to `false`. If `true`, then the operation will be marked as failed after the first fail.

### `applyBarrier(operations, config)` <Badge type="tip" text="since v0.12" />

```ts
import { applyBarrier } from '@farfetched/core';

applyBarrier([operation1, operation2], { barrier });
applyBarrier([operation1, operation2], config);
```

#### Arguments
Operations is an array of [_Queries_](/api/primitives/query) or [_Mutations_](/api/primitives/mutation) to apply the [_Barrier_](/api/primitives/barrier) to.

Config fields:

- `operations` - Array of [_Queries_](/api/primitives/query) or [_Mutations_](/api/primitives/mutation) to apply the [_Barrier_](/api/primitives/barrier) to
- `barrier` - [_Barrier_](/api/primitives/barrier) to apply
- same as [previous formula](/api/operators/apply_barrier#applybarrier-operation-config).
45 changes: 45 additions & 0 deletions packages/core/src/barrier_api/__tests__/apply_barrier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,4 +132,49 @@ describe('applyBarrier', () => {

expect(performer).toBeCalledTimes(1);
});

test.concurrent(
'suppress intermediate failure on operation fail',
async () => {
const defer = createDefer();

const renewTokenFx = createEffect(() => defer.promise);

const authBarrier = createBarrier({
activateOn: { failure: isHttpErrorCode(401) },
perform: [renewTokenFx],
});

const query = createQuery({
handler: vi
.fn()
.mockRejectedValueOnce(
httpError({ status: 401, statusText: 'Nooo', response: null })
)
.mockResolvedValueOnce('OK'),
});

applyBarrier(query, {
barrier: authBarrier,
suppressIntermediateFailures: true,
});

const scope = fork();

const { listeners } = watchRemoteOperation(query, scope);

allSettled(query.refresh, { scope });
await setTimeout(1);
expect(scope.getState(authBarrier.$active)).toBeTruthy();

defer.resolve(null);
await allSettled(scope);
expect(scope.getState(authBarrier.$active)).toBeFalsy();
expect(listeners.onFailure).toBeCalledTimes(0);
expect(listeners.onSuccess).toBeCalledTimes(1);
expect(listeners.onSuccess).toBeCalledWith(
expect.objectContaining({ result: 'OK' })
);
}
);
});
17 changes: 14 additions & 3 deletions packages/core/src/barrier_api/apply_barrier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,39 @@ import { type Barrier } from './type';
*
* @param operation Query or Mutation to apply Barrier to
* @param config.barrier Barrier to apply
* @param config.suppressIntermediateFailures Whether to suppress intermediate failures or not, defaults to `false`
*/
export function applyBarrier(
operation: RemoteOperation<any, any, any, any, any>,
{ barrier }: { barrier: Barrier }
{
barrier,
suppressIntermediateFailures,
}: { barrier: Barrier; suppressIntermediateFailures?: boolean }
): void;

/**
* Applies the Barrier to the Query or Mutation. After operation start it checks the Barrier .$active status and postpones the execution if the Barrier is active. After the Barrier is deactivated, it resumes the execution of the operation.
*
* @param operations Query or Mutation to apply Barrier to
* @param config.barrier Barrier to apply
* @param config.suppressIntermediateFailures Whether to suppress intermediate failures or not, defaults to `false`
*/
export function applyBarrier(
operations: RemoteOperation<any, any, any, any, any>[],
{ barrier }: { barrier: Barrier }
{
barrier,
suppressIntermediateFailures,
}: { barrier: Barrier; suppressIntermediateFailures?: boolean }
): void;

export function applyBarrier(
operation:
| RemoteOperation<any, any, any, any, any>
| RemoteOperation<any, any, any, any, any>[],
{ barrier }: { barrier: Barrier }
{
barrier,
suppressIntermediateFailures = false,
}: { barrier: Barrier; suppressIntermediateFailures?: boolean }
): void {
if (Array.isArray(operation)) {
for (const op of operation) {
Expand Down