Skip to content

Commit 40413d4

Browse files
committed
Updated README.md
1 parent c318462 commit 40413d4

2 files changed

Lines changed: 52 additions & 25 deletions

File tree

README.md

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ npm install --save-prod react-executor
7777
- [`retryInvalidated`](#retryinvalidated)
7878
- [`retryRejected`](#retryrejected)
7979
- [`retryWhen`](#retrywhen)
80-
- [`syncStorage`](#syncstorage)
80+
- [`syncBrowserStorage`](#syncbrowserstorage)
81+
- [`syncExternalStore`](#syncsxternalstore)
8182

8283
<span class="toc-icon">⚛️&ensp;</span>[**React integration**](#react-integration)
8384

@@ -1411,17 +1412,14 @@ const executor = useExecutor('test', heavyTask, [
14111412
]);
14121413
```
14131414

1414-
## `syncStorage`
1415+
## `syncBrowserStorage`
14151416

1416-
Persists the executor value in the synchronous storage.
1417+
Synchronizes the executor state with a browser storage item. No-op in a non-browser environment.
14171418

1418-
<!-- prettier-ignore -->
14191419
```ts
1420-
import syncStorage from 'react-executor/plugin/syncStorage';
1420+
import syncBrowserStorage from 'react-executor/plugin/syncBrowserStorage';
14211421

1422-
const executor = useExecutor('test', 42, [
1423-
syncStorage(localStorage),
1424-
]);
1422+
const executor = useExecutor('test', 42, [syncBrowserStorage()]);
14251423
```
14261424

14271425
With this plugin, you can synchronize the executor state
@@ -1442,7 +1440,7 @@ Here's how you can enable serialization of objects with circular references:
14421440
import JSONMarshal from 'json-marshal';
14431441

14441442
const executor = useExecutor('test', 42, [
1445-
syncStorage(localStorage, {
1443+
syncBrowserStorage({
14461444
serializer: JSONMarshal,
14471445
}),
14481446
]);
@@ -1452,22 +1450,52 @@ const executor = useExecutor('test', 42, [
14521450
> With additional configuration, [json-marshal&#8239;<sup>↗</sup>](https://github.com/smikhalevski/json-marshal#readme)
14531451
> can stringify and parse any data structure.
14541452
1455-
By default, `syncStorage` plugin uses a [serialized executor key](#executor-keys) as a storage key. You can provide a
1456-
custom key
1457-
via [`storageKey`&#8239;<sup>↗</sup>](https://smikhalevski.github.io/react-executor/interfaces/plugin_syncStorage.SyncStorageOptions.html#storagekey)
1453+
By default, `syncBrowserStorage` plugin uses a [serialized executor key](#executor-keys) as a storage key. You can
1454+
provide a custom key
1455+
via [`storageKey`&#8239;<sup>↗</sup>](https://smikhalevski.github.io/react-executor/interfaces/plugin_syncBrowserStorage.SyncBrowserStorageOptions.html#storagekey)
14581456
option:
14591457

14601458
```ts
1461-
useExecutor('test', 42, [syncStorage(localStorage, { storageKey: 'hello' })]);
1459+
useExecutor('test', 42, [syncBrowserStorage({ storageKey: 'hello' })]);
14621460
```
14631461

1464-
In the environment where storage is unavailable (for example, [during SSR](#server-side-rendering)), you can
1465-
conditionally disable the plugin:
1462+
## `syncExternalStore`
1463+
1464+
Persists the executor state in the observable external store.
1465+
1466+
Here's the minimal external store example:
14661467

14671468
```ts
1468-
useExecutor('test', 42, [typeof localStorage !== 'undefined' ? syncStorage(localStorage) : null]);
1469+
import { useExecutor, ExecutorState } from 'react-executor';
1470+
import syncExternalStore, { ExternalStore } from 'react-executor/plugin/syncExternalStore';
1471+
1472+
let myStoredState: ExecutorState | null = null;
1473+
1474+
const myStore: ExternalStore<ExecutorState> = {
1475+
get() {
1476+
return myStoredState;
1477+
},
1478+
1479+
subscribe(listener) {
1480+
// Place subscription login here
1481+
return () => {};
1482+
},
1483+
};
1484+
1485+
const myExecutor = useExecutor('test', 42, [syncExternalStore(myStore)]);
14691486
```
14701487

1488+
When executor is [settled](#settle-an-executor), [cleared](#clear-an-executor), [invalidated](#invalidate-results) or
1489+
annotated then the plugin calls
1490+
the [`ExternalStore.set`&#8239;<sup>↗</sup>](https://smikhalevski.github.io/react-executor/interfaces/plugin_syncExternalStore.ExternalStore.html#set)
1491+
method on the store.
1492+
1493+
When executor is [detached](#detach-an-executor) then the plugin calls
1494+
the [`ExternalStore.delete`&#8239;<sup>↗</sup>](https://smikhalevski.github.io/react-executor/interfaces/plugin_syncExternalStore.ExternalStore.html#delete)
1495+
method on the store.
1496+
1497+
Prefer [`syncBrowserStorage`](#syncbrowserstorage) if you want to persist the executor state in a `localStorage`.
1498+
14711499
# React integration
14721500

14731501
In the basic scenario, to use executors in your React app, you don't need any additional configuration, just use
@@ -2091,21 +2119,21 @@ const App = () => <ExecutorManagerProvider value={manager}>{/* Render you app he
20912119

20922120
## Storage state versioning
20932121

2094-
You can store an executor state in a `localStorage` using the [`syncStorage`](#syncstorage) plugin:
2122+
You can store an executor state in a `localStorage` using the [`syncBrowserStorage`](#syncbrowserstorage) plugin:
20952123

20962124
```ts
20972125
import { useExecutor } from 'react-executor';
2098-
import syncStorage from 'react-executor/plugin/syncStorage';
2126+
import syncBrowserStorage from 'react-executor/plugin/syncBrowserStorage';
20992127

2100-
const playerExecutor = useExecutor('player', { health: '50%' }, [syncStorage(localStorage)]);
2128+
const playerExecutor = useExecutor('player', { health: '50%' }, [syncBrowserStorage()]);
21012129
// ⮕ Executor<{ health: string }>
21022130
```
21032131

21042132
But what if over time you'd like to change the structure of the value stored in the `playerExecutor`? For example,
21052133
make `health` property a number:
21062134

21072135
```ts
2108-
const playerExecutor = useExecutor('player', { health: 0.5 }, [syncStorage(localStorage)]);
2136+
const playerExecutor = useExecutor('player', { health: 0.5 }, [syncBrowserStorage()]);
21092137
```
21102138

21112139
After users have used the previous version of the app where `health` was a string, they would still receive a string
@@ -2139,10 +2167,10 @@ export function requireVersion(version: number): ExecutorPlugin {
21392167
Add the plugin to the executor:
21402168

21412169
```ts
2142-
const playerExecutor = useExecutor('player', { health: 0.5 }, [syncStorage(localStorage), requireVersion(1)]);
2170+
const playerExecutor = useExecutor('player', { health: 0.5 }, [syncBrowserStorage(), requireVersion(1)]);
21432171
```
21442172

2145-
After the `syncStorage` plugin reads the data from the `localStorage`, the `requireVersion` plugin ensures that
2173+
After the `syncBrowserStorage` plugin reads the data from the `localStorage`, the `requireVersion` plugin ensures that
21462174
the `version` annotation read from the `localStorage` matches the required version. On mismatch the executor is cleared
21472175
and the initial value `{ health: 0.5 }` is written to the storage.
21482176

@@ -2176,7 +2204,7 @@ Now `requireVersion` would apply the migration on the state version mismatch:
21762204

21772205
```ts
21782206
const playerExecutor = useExecutor('player', { health: 0.5 }, [
2179-
syncStorage(localStorage),
2207+
syncBrowserStorage(),
21802208

21812209
requireVersion(1, executor => {
21822210
executor.resolve({

typedoc.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,16 @@
1010
"inherited": true,
1111
"protected": false
1212
},
13-
"sortEntryPoints": false,
1413
"readme": "none",
1514
"tsconfig": "./tsconfig.json",
1615
"entryPoints": [
1716
"./src/main/index.ts",
1817
"./src/main/core.ts",
1918
"./src/main/ssr/index.ts",
20-
"./src/main/ssr/node/index.ts",
2119
"./src/main/plugin/*.ts",
2220
"./src/main/observable/*.ts"
2321
],
22+
"sortEntryPoints": false,
2423
"intentionallyNotExported": ["ExecutorImpl", "NoInfer"],
2524
"plugin": ["typedoc-plugin-mdn-links"],
2625
"externalSymbolLinkMappings": {

0 commit comments

Comments
 (0)