diff --git a/CHANGELOG.md b/CHANGELOG.md index 49b869f..b758c4b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.8.0 (2024-07-22) + +- Add: `onBeforeWakeUp` and `onAfterWakeUp` callback options. + ## 0.7.0 (2023-12-17) - Fix: Both `withPersistent()` and `withPersistentMap()`, when `wakeUp` options diff --git a/README.md b/README.md index 4f3b05a..8125462 100644 --- a/README.md +++ b/README.md @@ -146,6 +146,8 @@ interface WithPersistentOptions< | `onFlushFinally` | `EventCallable` | `undefined` | An Event to trigger before flushing to driver. This al always triggering after either `onFlushDone` or `onFlushFail`. An `id` in payload refers to `id` from appropriate `onFlushStart` payload. | | `readOnly` | `EventCallable` | `undefined` | A `filter` Store to disable writes to Driver. | | `wakeUp` | StoreWritable<State> | ((state: State) => void) | `undefined` | Alternative target which will receive initial state read from driver on initialization. When `undefined`, the source StoreWritable will be used. | +| `onBeforeWakeUp` | `() => void` | `undefined` | A callback to be called before "wake up" prodecure. | +| `onAfterWakeUp` | `() => void` | `undefined` | A callback to be called after "wake up" prodecure. | | `serialize` | (input: Value) => Serialized | Promise<Serialized> | `undefined` | Serialization before writing data to driver. | | `unserialize` | (output: Serialized) => Value | Promise<Value> | `undefined` | Unserialization after reading data from driver. | diff --git a/package.json b/package.json index edc0a3a..3efb7fc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cubux/effector-persistent", - "version": "0.7.0", + "version": "0.8.0", "description": "Persist data in effector store.", "keywords": [ "effector", diff --git a/src/internal.ts b/src/internal.ts index adfd213..bc49573 100644 --- a/src/internal.ts +++ b/src/internal.ts @@ -60,6 +60,14 @@ export interface CommonOptions { * A `filter` Store to disable writes to Driver. */ readOnly?: Store; + /** + * A callback to call before the "wake up" procedure. + */ + onBeforeWakeUp?: () => void; + /** + * A callback to call after the "wake up" procedure. + */ + onAfterWakeUp?: () => void; } export interface OptionsWithWakeUp< diff --git a/src/lib/initialize.ts b/src/lib/initialize.ts index 4f41d64..d3dc8de 100644 --- a/src/lib/initialize.ts +++ b/src/lib/initialize.ts @@ -14,40 +14,54 @@ import { noopSerialize } from './noopSerialize'; const isStore = is.store; -function initWakeUp( - driver: Driver, - unserialize: (output: Serialized) => Promise | Value, - wakeUp: StoreWritable | ((state: Value) => void), - read: (driver: Driver) => Promise -) { +function initWakeUp({ + driver, + read, + unserialize, + wakeUp, + onBeforeWakeUp, + onAfterWakeUp, +}: { + driver: Driver; + read: (driver: Driver) => Promise; + unserialize: (output: Serialized) => Promise | Value; + wakeUp: StoreWritable | ((state: Value) => void); + onBeforeWakeUp?: () => void; + onAfterWakeUp?: () => void; +}) { const setWakingUp = createEvent(); const $isWritable = createStore(true).on(setWakingUp, (_, b) => !b); read(driver).then( (s) => { - if (s !== undefined) { - return Promise.resolve(unserialize(s)).then( - (v) => { - setWakingUp(true); - try { - if (isStore(wakeUp)) { - const init = createEvent(); - wakeUp.on(init, (_, v) => v); - init(v); - } else { - wakeUp(v); - } - } finally { - setWakingUp(false); - } - }, - (e) => - console.error( - 'Failed to unserialize output from persistent driver', - e - ) - ); + if (s === undefined) { + onBeforeWakeUp?.(); + onAfterWakeUp?.(); + return; } + return Promise.resolve(unserialize(s)).then( + (v) => { + onBeforeWakeUp?.(); + setWakingUp(true); + try { + if (isStore(wakeUp)) { + const init = createEvent(); + wakeUp.on(init, (_, v) => v); + init(v); + } else { + wakeUp(v); + } + } finally { + setWakingUp(false); + onAfterWakeUp?.(); + } + }, + (e) => + console.error( + 'Failed to unserialize output from persistent driver', + e + ) + ); }, (e) => console.error('Failed to read value from persistent driver', e) ); @@ -115,13 +129,26 @@ export function initialize( readOnly, unserialize = noopSerialize, wakeUp = store, + onBeforeWakeUp, + onAfterWakeUp, }: Omit, 'serialize'>, read: (driver: Driver) => Promise, write: (driver: Driver, value: Value, prev: Value) => Promise ) { function setup(driver: Driver) { addFlush( - initFlush(store, readOnly, initWakeUp(driver, unserialize, wakeUp, read)), + initFlush( + store, + readOnly, + initWakeUp({ + driver, + read, + unserialize, + wakeUp, + onBeforeWakeUp, + onAfterWakeUp, + }) + ), flushDelay, ({ next, prev }) => { const id = Symbol();