From 076686fd466c0deba7621aceb107741a58b0d31f Mon Sep 17 00:00:00 2001 From: Jay Meistrich Date: Sun, 8 Oct 2023 17:29:48 +0200 Subject: [PATCH] change: persistObservable to use the same concept as Promises and return an observable with state in it --- src/observableInterfaces.ts | 3 +++ src/persist/persistObservable.ts | 15 +++++++++------ tests/persist-indexeddb.test.ts | 16 ++++++++-------- tests/persist-remote-fn.test.ts | 6 +++--- tests/persist.test.ts | 4 ++-- 5 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/observableInterfaces.ts b/src/observableInterfaces.ts index 27a947776..ed17e2660 100644 --- a/src/observableInterfaces.ts +++ b/src/observableInterfaces.ts @@ -316,6 +316,9 @@ export interface ObservablePersistState extends ObservableState { > | undefined; } +export interface WithPersistState { + state?: ObservablePersistState; +} export type RecordValue = T extends Record ? t : never; export type ArrayValue = T extends Array ? t : never; export type ObservableValue = T extends Observable ? t : never; diff --git a/src/persist/persistObservable.ts b/src/persist/persistObservable.ts index d44aa7a60..28c68f242 100644 --- a/src/persist/persistObservable.ts +++ b/src/persist/persistObservable.ts @@ -17,11 +17,13 @@ import type { PersistOptionsRemote, PersistTransform, TypeAtPath, + WithPersistState, } from '@legendapp/state'; import { batch, constructObjectWithPath, deconstructObjectWithPath, + getNode, internal, isEmpty, isFunction, @@ -611,20 +613,21 @@ async function loadLocal( export function persistObservable( observable: ObservableWriteable, persistOptions: PersistOptions, -): [Observable, ObservableObject]; +): Observable; export function persistObservable( initial: T | (() => T) | (() => Promise), persistOptions: PersistOptions, -): [Observable, ObservableObject]; +): Observable; export function persistObservable( initialOrObservable: ObservableWriteable | T | (() => T) | (() => Promise), persistOptions: PersistOptions, -): [Observable, ObservableObject] { +): Observable { const obs = ( isObservable(initialOrObservable) ? initialOrObservable : observable(isFunction(initialOrObservable) ? initialOrObservable() : initialOrObservable) ) as Observable; + const node = getNode(obs); // Merge remote persist options with clobal options if (persistOptions.remote) { @@ -635,7 +638,7 @@ export function persistObservable( const remotePersistence = persistOptions.pluginRemote! || observablePersistConfiguration?.pluginRemote; const localState: LocalState = {}; - const syncState = observable({ + const syncState = (node.state = observable({ isLoadedLocal: false, isLoaded: false, isEnabledLocal: true, @@ -643,7 +646,7 @@ export function persistObservable( clearLocal: undefined as unknown as () => Promise, sync: () => Promise.resolve(), getPendingChanges: () => localState.pendingChanges, - }); + })); if (local) { loadLocal(obs, persistOptions, syncState, localState); @@ -793,5 +796,5 @@ export function persistObservable( ); }); - return [obs, syncState as any]; + return obs as any; } diff --git a/tests/persist-indexeddb.test.ts b/tests/persist-indexeddb.test.ts index 54529ea95..b4bc8fe30 100644 --- a/tests/persist-indexeddb.test.ts +++ b/tests/persist-indexeddb.test.ts @@ -56,7 +56,7 @@ describe('Persist IDB', () => { test('Persist IDB save', async () => { const obs = observable>({}); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { local: TableName, }); @@ -69,7 +69,7 @@ describe('Persist IDB', () => { test('Persist IDB save deep', async () => { const obs = observable>({}); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { local: TableName, }); @@ -82,7 +82,7 @@ describe('Persist IDB', () => { test('Persist IDB get after save', async () => { const obs = observable>({}); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { local: TableName, }); @@ -95,7 +95,7 @@ describe('Persist IDB', () => { const obs2 = observable>({}); - const [, state2] = persistObservable(obs2, { + const { state: state2 } = persistObservable(obs2, { local: TableName, }); @@ -106,7 +106,7 @@ describe('Persist IDB', () => { test('Persist IDB save root', async () => { const obs = observable>({}); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { local: TableName, }); @@ -120,7 +120,7 @@ describe('Persist IDB', () => { await persist.initialize!(persistLocalOptions); const obs2 = observable>({}); - const [, state2] = persistObservable(obs2, { + const { state: state2 } = persistObservable(obs2, { local: TableName, }); @@ -133,7 +133,7 @@ describe('Persist IDB', () => { const obs = observable>({}); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { local: TableName, }); @@ -146,7 +146,7 @@ describe('Persist IDB', () => { await persist.initialize!(persistLocalOptions); const obs2 = observable>({}); - const [, state2] = persistObservable(obs2, { + const { state: state2 } = persistObservable(obs2, { local: TableName, }); diff --git a/tests/persist-remote-fn.test.ts b/tests/persist-remote-fn.test.ts index 4cd44b61b..fa2fec4f1 100644 --- a/tests/persist-remote-fn.test.ts +++ b/tests/persist-remote-fn.test.ts @@ -11,7 +11,7 @@ jest.setTimeout(50); describe('Persist remote with functions', () => { test('Persist remote fns basic', async () => { const obs = observable({ test: { x: 'hi' } }); - const [, state] = persistObservable(obs, { + const { state } = persistObservable(obs, { pluginRemote: { async get() { // Emulate a network request with a timeout @@ -33,7 +33,7 @@ describe('Persist remote with functions', () => { test('Persist remote fns with set', async () => { let setTo: { dateModified: number; value: any } | undefined = undefined; const obs$ = observable({ test: { x: 'hi' } }); - const [, state] = persistObservable(obs$, { + const { state } = persistObservable(obs$, { pluginRemote: { async get() { // Emulate a network request with a timeout @@ -72,7 +72,7 @@ describe('Persist remote with functions', () => { let setTo: { dateModified: number; value: any } | undefined = undefined; const obs$ = observable({ test: { x: 'hi' } }); const didSave$ = observable(false); - const [, state] = persistObservable(obs$, { + const { state } = persistObservable(obs$, { pluginRemote: { async get() { // Emulate a network request with a timeout diff --git a/tests/persist.test.ts b/tests/persist.test.ts index 69d05dc5d..987dea43b 100644 --- a/tests/persist.test.ts +++ b/tests/persist.test.ts @@ -8,7 +8,7 @@ function promiseTimeout(time?: number) { describe('Creating', () => { test('Create with object', () => { - const [obs$, state$] = persistObservable( + const obs$ = persistObservable( { test: 'hi' }, { pluginLocal: ObservablePersistLocalStorage, @@ -18,7 +18,7 @@ describe('Creating', () => { expect(obs$.get()).toEqual({ test: 'hi' }); - expect(state$.isLoadedLocal.get()).toEqual(true); + expect(obs$.state.isLoadedLocal.get()).toEqual(true); }); });