From bd0ae3b1a0349d53e8c7a70fc382a18419cedbaf Mon Sep 17 00:00:00 2001 From: smikhalevski Date: Mon, 29 Apr 2024 23:11:45 +0300 Subject: [PATCH] Updated README.md --- README.md | 41 ++++++++++++++++------------- src/main/plugin/abortDeactivated.ts | 4 +-- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ed60b31..abbae1b 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ npm install --save-prod react-executor - [`invalidateByPeers`](#invalidatebypeers) - [`invalidatePeers`](#invalidatepeers) - [`retryFocused`](#retryfocused) +- [`retryFulfilled`](#retryfulfilled) - [`retryRejected`](#retryrejected) - [`retryStale`](#retrystale) - [`synchronizeStorage`](#synchronizestorage) @@ -447,7 +448,7 @@ The [task was aborted](#abort-a-task). If executor is still [pending](https://smikhalevski.github.io/react-executor/interfaces/react_executor.Executor.html#isPending) when -an `'aborted'` event is published then the currently pending task is being replaced with a new task. +an `'aborted'` event is published then the currently pending task is being [replaced](#replace-a-task) with a new task. Calling [`Executor.execute`](https://smikhalevski.github.io/react-executor/interfaces/react_executor.Executor.html#execute) when handling an abort event may lead to stack overflow. If you need to do this anyway, execute a new task from async @@ -586,7 +587,8 @@ const disposePlugin: ExecutorPlugin = executor => { ``` To apply a plugin, pass it to the -[`ExecutorManager.getOrCreate`](https://smikhalevski.github.io/react-executor/classes/react_executor.ExecutorManager.html#getOrCreate): +[`ExecutorManager.getOrCreate`](https://smikhalevski.github.io/react-executor/classes/react_executor.ExecutorManager.html#getOrCreate) +or to the [`useExecutor`](https://smikhalevski.github.io/react-executor/functions/react_executor.useExecutor.html) hook: ```ts const executor = executorManager.getOrCreate('test', undefined, [disposePlugin]); @@ -602,7 +604,7 @@ executorManager.get('test'); ## `abortDeactivated` -Aborts the pending task after the timeout when the executor is deactivated. +Aborts the pending task after the timeout if the executor is deactivated. ```ts import abortDeactivated from 'react-executor/plugin/abortDeactivated'; @@ -625,20 +627,15 @@ Binds all executor methods to the instance. ```ts import bindAll from 'react-executor/plugin/bindAll'; -const executor = useExecutor('test', 'Bye', [bindAll()]); - -// 🟡 Method can now be detached from the executor -const resolve = executor.resolve; +// 🟡 Methods can now be detached from the executor instance +const { resolve } = useExecutor('test', 'Bye', [bindAll()]); resolve('Hello'); - -executor.value; -// ⮕ 'Hello' ``` ## `disposeDeactivated` -Aborts the pending task after the timeout when the executor is deactivated. +Aborts the pending task after the timeout if the executor is deactivated. ```ts import disposeDeactivated from 'react-executor/plugin/disposeDeactivated'; @@ -654,8 +651,8 @@ executor.deactivate(); `disposeDeactivated` has a single argument: the delay after which the executor should be disposed. If an executor is re-activated during this delay, the executor won't be disposed. -Both an executor manager and this plugin don't abort the pending task during the executor disposal. -Use [`abortDeactivated`] to abort the pending task: +Both an executor manager and this plugin don't abort the pending task when executor is disposed. +Use [`abortDeactivated`](#abortdeactivated) to do the job: ```ts import abortDeactivated from 'react-executor/plugin/abortDeactivated'; @@ -728,7 +725,7 @@ const executor = useExecutor('test', 42, [retryFocused()]); This plugin is no-op in the server environment. -# `retryFulfilled` +## `retryFulfilled` Repeats the last task after the execution was fulfilled. @@ -818,6 +815,7 @@ import { ExecutorTask, useExecutor } from 'react-executor'; import invalidateByPeers from 'react-executor/plugin/invalidateByPeers'; const fetchCheese: ExecutorTask = async (signal, executor) => { + // Wait for the breadExecutor to be created const breadExecutor = await executor.manager.waitFor('bread'); @@ -825,6 +823,7 @@ const fetchCheese: ExecutorTask = async (signal, executor) => { const bread = await breadExecutor.toPromise(); // Choose the best cheese for this bread + return bread === 'Ciabatta' ? 'Mozzarella' : 'Burrata'; }; const cheeseExecutor = useExecutor('cheese', fetchCheese, [ @@ -852,10 +851,14 @@ const executor = useExecutor('test', 42, [synchronizeStorage(localStorage)]); executor.activate(); ``` +With this plugin, you can synchronize the executor state +[across multiple browser tabs](https://codesandbox.io/p/sandbox/react-executor-example-ltflgy?file=%2Fsrc%2FApp.tsx%3A25%2C1) +in just one line. + > [!WARNING]\ > If executor is [disposed](#dispose-an-executor), then the corresponding item is removed from the storage. -By default, executor state is serialized using +By default, an executor state is serialized using [`JSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON). If your executor stores a value that may contain circular references, or non-serializable data like `BigInt`, use a custom serializer: @@ -874,7 +877,7 @@ away: ```tsx import { useExecutor } from 'react-executor'; -function User(props: { userId: string }) { +const User = (props: { userId: string }) => { const executor = useExecutor(`user-${props.userId}`, async signal => { // Fetch the user from the server }); @@ -938,7 +941,7 @@ const User = (props: { userId: string }) => { useEffect(() => { executor.execute(async signal => getUserById(props.userId, signal)); }, [props.userId]); -} +}; ``` If the task itself doesn't depend on a rendered value, but must be re-executed anyway when a rendered value is changed, @@ -958,7 +961,7 @@ hook: ```tsx import { useExecutorSuspense } from 'react-executor'; -function Account() { +const Account = () => { const executor = useExecutorSuspense( useExecutor('account', signal => { // Fetch the account from the server @@ -966,7 +969,7 @@ function Account() { ); // Render the account from the executor.value -} +}; ``` An executor returned from the `useExecutorSuspense` hook is never pending. diff --git a/src/main/plugin/abortDeactivated.ts b/src/main/plugin/abortDeactivated.ts index f9dfcde..bfe680e 100644 --- a/src/main/plugin/abortDeactivated.ts +++ b/src/main/plugin/abortDeactivated.ts @@ -1,5 +1,5 @@ /** - * The plugin that aborts the pending task after the timeout when the executor is deactivated. + * The plugin that aborts the pending task after the timeout if the executor is deactivated. * * ```ts * import abortDeactivated from 'react-executor/plugin/abortDeactivated'; @@ -13,7 +13,7 @@ import type { ExecutorPlugin } from '../types'; /** - * Aborts the pending task after the timeout when the executor is deactivated. + * Aborts the pending task after the timeout if the executor is deactivated. * * @param ms The timeout in milliseconds after which the task is aborted. */