Skip to content

Commit

Permalink
add a refresh function to subscribe
Browse files Browse the repository at this point in the history
  • Loading branch information
jmeistrich committed Oct 27, 2023
1 parent e873de5 commit 5d305c3
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 19 deletions.
12 changes: 7 additions & 5 deletions src/ObservableObject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import type {
TrackingType,
UpdateFn,
RetryOptions,
ObservablePersistStateInternal,
} from './observableInterfaces';
import { observe } from './observe';
import { onChange } from './onChange';
Expand Down Expand Up @@ -891,6 +892,7 @@ function activateNodeFunction(node: NodeValue, lazyFn: () => void) {
let curTarget$: ObservableObject<any>;
const activator = (isFunction(node) ? node : lazyFn) as (value: ActivateProxyParams) => any;
let wasPromise: Promise<any> | undefined;
const refresh = () => (node.state as ObservableObject<ObservablePersistStateInternal>).refreshNum.set((v) => v + 1);
observe(
() => {
const params = createNodeActivationParams(node);
Expand Down Expand Up @@ -927,9 +929,11 @@ function activateNodeFunction(node: NodeValue, lazyFn: () => void) {
if (!node.activated) {
node.activated = true;
const activateNodeFn = wasPromise ? globalState.activateNode : activateNodeBase;
activateNodeFn(node, value).update!;
activateNodeFn(node, refresh, value);
}

(node.state as ObservableObject<ObservablePersistStateInternal>).refreshNum.get();

return value;
},
({ value }) => {
Expand All @@ -953,7 +957,7 @@ function activateNodeFunction(node: NodeValue, lazyFn: () => void) {
);
}

const activateNodeBase = (globalState.activateNode = function activateNodeBase(node: NodeValue): { update: UpdateFn } {
const activateNodeBase = (globalState.activateNode = function activateNodeBase(node: NodeValue, refresh: () => void) {
const { onSetFn, subscriber } = node.activationState!;
let isSetting = false;
if (!node.state) {
Expand Down Expand Up @@ -1001,8 +1005,6 @@ const activateNodeBase = (globalState.activateNode = function activateNodeBase(n
};

if (subscriber) {
subscriber({ update });
subscriber({ update, refresh });
}

return { update };
});
7 changes: 1 addition & 6 deletions src/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ export const globalState = {
isLoadingLocal: false,
isMerging: false,
isLoadingRemote$: undefined as unknown as ObservablePrimitive<boolean>,
activateNode: undefined as unknown as (
node: NodeValue,
newValue: any,
) => {
update?: UpdateFn;
},
activateNode: undefined as unknown as (node: NodeValue, refresh: () => void, newValue: any) => void,
};

export function isObservable(obs: any): obs is ObservableObject {
Expand Down
8 changes: 6 additions & 2 deletions src/observableInterfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ export interface ObservablePersistStateBase {
isEnabledLocal: boolean;
isEnabledRemote: boolean;
dateModified?: number;
syncCount?: number;
clearLocal: () => Promise<void>;
sync: () => Promise<void>;
getPendingChanges: () =>
Expand All @@ -340,6 +341,9 @@ export interface ObservablePersistStateBase {
| undefined;
}
export type ObservablePersistState = ObservableState & ObservablePersistStateBase;
export type ObservablePersistStateInternal = ObservablePersistState & {
refreshNum: number;
};
export interface WithPersistState {
state?: ObservablePersistState; // TODOV3: remove this
_state?: ObservablePersistState;
Expand Down Expand Up @@ -480,7 +484,7 @@ interface BaseNodeValue {
activationState?: {
onSetFn?: (value: ListenerParams<any>) => void;
update?: UpdateFn;
subscriber?: (params: { update: UpdateFn }) => void;
subscriber?: (params: { update: UpdateFn; refresh: () => void }) => void;
retryOptions?: RetryOptions;
lastSync: { value?: number };
cacheOptions?: CacheOptions;
Expand Down Expand Up @@ -540,7 +544,7 @@ export interface CacheOptions<T = any> {
}
export interface ActivateParams<T = any> {
onSet: (fn: (params: ListenerParams<T>) => void) => void;
subscribe: (fn: (params: { update: (props: ObservableOnChangeParams) => void }) => void) => void;
subscribe: (fn: (params: { update: UpdateFn; refresh: () => void }) => void) => void;
}
export interface ActivateProxyParams<T = any> extends ActivateParams {
proxy: (fn: (key: string, params: ActivateParams<T>) => T | Promise<T>) => void;
Expand Down
9 changes: 5 additions & 4 deletions src/persist/persistObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {
ObservablePersistRemoteSetParams,
ObservablePersistState,
ObservablePersistStateBase,
ObservablePersistStateInternal,
ObservableReadable,
ObservableWriteable,
PersistMetadata,
Expand Down Expand Up @@ -654,11 +655,12 @@ export function persistObservable<T extends WithoutState>(
const localState: LocalState = {};
let sync: () => Promise<void>;

const syncState = (node.state = observable<ObservablePersistState>({
const syncState = (node.state = observable<ObservablePersistStateInternal>({
isLoadedLocal: false,
isLoaded: false,
isEnabledLocal: true,
isEnabledRemote: true,
refreshNum: 0,
clearLocal: undefined as unknown as () => Promise<void>,
sync: () => Promise.resolve(),
getPendingChanges: () => localState.pendingChanges,
Expand Down Expand Up @@ -866,7 +868,7 @@ export function persistObservable<T extends WithoutState>(
return obs as any;
}

globalState.activateNode = function activateNodePersist(node: NodeValue, newValue: any): { update?: UpdateFn } {
globalState.activateNode = function activateNodePersist(node: NodeValue, refresh: () => void, newValue: any) {
const { onSetFn, subscriber, lastSync, cacheOptions, retryOptions } = node.activationState!;

let onChange: UpdateFn | undefined = undefined;
Expand Down Expand Up @@ -896,6 +898,7 @@ globalState.activateNode = function activateNodePersist(node: NodeValue, newValu
onChange(params);
}
},
refresh,
});
}
persistObservable(getProxy(node), {
Expand All @@ -905,8 +908,6 @@ globalState.activateNode = function activateNodePersist(node: NodeValue, newValu
retry: retryOptions,
},
});

return { update: onChange };
};

declare module '@legendapp/state' {
Expand Down
22 changes: 20 additions & 2 deletions tests/computedtests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1001,7 +1001,7 @@ export const run = (isPersist: boolean) => {
});
});
describe('subscribing to computeds', () => {
test('basic subscription', async () => {
test('subscription with update', async () => {
const obs = observable(({ subscribe }: ActivateParams) => {
subscribe(({ update }) => {
setTimeout(() => {
Expand All @@ -1015,9 +1015,27 @@ export const run = (isPersist: boolean) => {
expect(obs.get()).toEqual(undefined);
await promiseTimeout(0);
expect(obs.get()).toEqual('hi there');
await promiseTimeout(5);
await promiseTimeout(10);
expect(obs.get()).toEqual('hi there again');
});
test('subscription with refresh', async () => {
let num = 0;
const obs = observable(({ subscribe }: ActivateParams) => {
subscribe(({ refresh }) => {
setTimeout(() => {
refresh();
}, 5);
});
return new Promise((resolve) => {
setTimeout(() => resolve('hi there ' + num++), 0);
});
});
expect(obs.get()).toEqual(undefined);
await promiseTimeout(0);
expect(obs.get()).toEqual('hi there 0');
await promiseTimeout(10);
expect(obs.get()).toEqual('hi there 1');
});
});
describe('loading', () => {
test('isLoaded', async () => {
Expand Down

0 comments on commit 5d305c3

Please sign in to comment.