Skip to content

Commit

Permalink
Add onBeforeWakeUp and onAfterWakeUp callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
Vovan-VE committed Jul 22, 2024
1 parent 830980a commit 3971f41
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ interface WithPersistentOptions<
| `onFlushFinally` | `EventCallable<WithPersistentFlushEvent>` | `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<boolean>` | `undefined` | A `filter` Store to disable writes to Driver. |
| `wakeUp` | <code>StoreWritable&lt;State&gt; &#124; ((state: State) =&gt; void)</code> | `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` | <code>(input: Value) =&gt; Serialized &#124; Promise&lt;Serialized&gt;</code> | `undefined` | Serialization before writing data to driver. |
| `unserialize` | <code>(output: Serialized) =&gt; Value &#124; Promise&lt;Value&gt;</code> | `undefined` | Unserialization after reading data from driver. |
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@cubux/effector-persistent",
"version": "0.7.0",
"version": "0.8.0",
"description": "Persist data in effector store.",
"keywords": [
"effector",
Expand Down
8 changes: 8 additions & 0 deletions src/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ export interface CommonOptions<State = any, Value = State, Serialized = Value> {
* A `filter` Store to disable writes to Driver.
*/
readOnly?: Store<boolean>;
/**
* 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<
Expand Down
85 changes: 56 additions & 29 deletions src/lib/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,40 +14,54 @@ import { noopSerialize } from './noopSerialize';

const isStore = is.store;

function initWakeUp<Driver, Value, Serialized>(
driver: Driver,
unserialize: (output: Serialized) => Promise<Value> | Value,
wakeUp: StoreWritable<Value> | ((state: Value) => void),
read: (driver: Driver) => Promise<Serialized | undefined>
) {
function initWakeUp<Driver, Value, Serialized>({
driver,
read,
unserialize,
wakeUp,
onBeforeWakeUp,
onAfterWakeUp,
}: {
driver: Driver;
read: (driver: Driver) => Promise<Serialized | undefined>;
unserialize: (output: Serialized) => Promise<Value> | Value;
wakeUp: StoreWritable<Value> | ((state: Value) => void);
onBeforeWakeUp?: () => void;
onAfterWakeUp?: () => void;
}) {
const setWakingUp = createEvent<boolean>();
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<Value>();
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<Value>();
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)
);
Expand Down Expand Up @@ -115,13 +129,26 @@ export function initialize<Driver, Value, Serialized = Value>(
readOnly,
unserialize = noopSerialize,
wakeUp = store,
onBeforeWakeUp,
onAfterWakeUp,
}: Omit<WithPersistentOptions<Value, Value, Serialized>, 'serialize'>,
read: (driver: Driver) => Promise<Serialized | undefined>,
write: (driver: Driver, value: Value, prev: Value) => Promise<void>
) {
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();
Expand Down

0 comments on commit 3971f41

Please sign in to comment.