Skip to content

Commit

Permalink
change: persistObservable to use the same concept as Promises and ret…
Browse files Browse the repository at this point in the history
…urn an observable with state in it
  • Loading branch information
jmeistrich committed Oct 8, 2023
1 parent 135911e commit 076686f
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 19 deletions.
3 changes: 3 additions & 0 deletions src/observableInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,9 @@ export interface ObservablePersistState extends ObservableState {
>
| undefined;
}
export interface WithPersistState {
state?: ObservablePersistState;
}
export type RecordValue<T> = T extends Record<string, infer t> ? t : never;
export type ArrayValue<T> = T extends Array<infer t> ? t : never;
export type ObservableValue<T> = T extends Observable<infer t> ? t : never;
Expand Down
15 changes: 9 additions & 6 deletions src/persist/persistObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ import type {
PersistOptionsRemote,
PersistTransform,
TypeAtPath,
WithPersistState,
} from '@legendapp/state';
import {
batch,
constructObjectWithPath,
deconstructObjectWithPath,
getNode,
internal,
isEmpty,
isFunction,
Expand Down Expand Up @@ -611,20 +613,21 @@ async function loadLocal<T>(
export function persistObservable<T, TState = {}>(
observable: ObservableWriteable<T>,
persistOptions: PersistOptions<T, TState>,
): [Observable<T>, ObservableObject<ObservablePersistState & TState>];
): Observable<WithPersistState & T>;
export function persistObservable<T, TState = {}>(
initial: T | (() => T) | (() => Promise<T>),
persistOptions: PersistOptions<T, TState>,
): [Observable<T>, ObservableObject<ObservablePersistState & TState>];
): Observable<WithPersistState & T>;
export function persistObservable<T, TState = {}>(
initialOrObservable: ObservableWriteable<T> | T | (() => T) | (() => Promise<T>),
persistOptions: PersistOptions<T, TState>,
): [Observable<T>, ObservableObject<ObservablePersistState & TState>] {
): Observable<WithPersistState & T> {
const obs = (
isObservable(initialOrObservable)
? initialOrObservable
: observable(isFunction(initialOrObservable) ? initialOrObservable() : initialOrObservable)
) as Observable<T>;
const node = getNode(obs);

// Merge remote persist options with clobal options
if (persistOptions.remote) {
Expand All @@ -635,15 +638,15 @@ export function persistObservable<T, TState = {}>(
const remotePersistence = persistOptions.pluginRemote! || observablePersistConfiguration?.pluginRemote;
const localState: LocalState = {};

const syncState = observable<ObservablePersistState>({
const syncState = (node.state = observable<ObservablePersistState>({
isLoadedLocal: false,
isLoaded: false,
isEnabledLocal: true,
isEnabledRemote: true,
clearLocal: undefined as unknown as () => Promise<void>,
sync: () => Promise.resolve(),
getPendingChanges: () => localState.pendingChanges,
});
}));

if (local) {
loadLocal(obs, persistOptions, syncState, localState);
Expand Down Expand Up @@ -793,5 +796,5 @@ export function persistObservable<T, TState = {}>(
);
});

return [obs, syncState as any];
return obs as any;
}
16 changes: 8 additions & 8 deletions tests/persist-indexeddb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe('Persist IDB', () => {
test('Persist IDB save', async () => {
const obs = observable<Record<string, any>>({});

const [, state] = persistObservable(obs, {
const { state } = persistObservable(obs, {
local: TableName,
});

Expand All @@ -69,7 +69,7 @@ describe('Persist IDB', () => {
test('Persist IDB save deep', async () => {
const obs = observable<Record<string, any>>({});

const [, state] = persistObservable(obs, {
const { state } = persistObservable(obs, {
local: TableName,
});

Expand All @@ -82,7 +82,7 @@ describe('Persist IDB', () => {
test('Persist IDB get after save', async () => {
const obs = observable<Record<string, any>>({});

const [, state] = persistObservable(obs, {
const { state } = persistObservable(obs, {
local: TableName,
});

Expand All @@ -95,7 +95,7 @@ describe('Persist IDB', () => {

const obs2 = observable<Record<string, any>>({});

const [, state2] = persistObservable(obs2, {
const { state: state2 } = persistObservable(obs2, {
local: TableName,
});

Expand All @@ -106,7 +106,7 @@ describe('Persist IDB', () => {
test('Persist IDB save root', async () => {
const obs = observable<Record<string, any>>({});

const [, state] = persistObservable(obs, {
const { state } = persistObservable(obs, {
local: TableName,
});

Expand All @@ -120,7 +120,7 @@ describe('Persist IDB', () => {
await persist.initialize!(persistLocalOptions);

const obs2 = observable<Record<string, any>>({});
const [, state2] = persistObservable(obs2, {
const { state: state2 } = persistObservable(obs2, {
local: TableName,
});

Expand All @@ -133,7 +133,7 @@ describe('Persist IDB', () => {

const obs = observable<Record<string, any>>({});

const [, state] = persistObservable(obs, {
const { state } = persistObservable(obs, {
local: TableName,
});

Expand All @@ -146,7 +146,7 @@ describe('Persist IDB', () => {
await persist.initialize!(persistLocalOptions);

const obs2 = observable<Record<string, any>>({});
const [, state2] = persistObservable(obs2, {
const { state: state2 } = persistObservable(obs2, {
local: TableName,
});

Expand Down
6 changes: 3 additions & 3 deletions tests/persist-remote-fn.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions tests/persist.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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);
});
});

Expand Down

0 comments on commit 076686f

Please sign in to comment.