Skip to content

Commit

Permalink
init prev value
Browse files Browse the repository at this point in the history
  • Loading branch information
pavel-nikitin-2022 committed Jan 14, 2025
1 parent bebf5da commit 00eaed1
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 24 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v1.7.3
-
- Устранены проблемы при исползовании хука useParams c жестом SwipeBack.

v1.7.2
-
- Устранены проблемы, связанные с работой runSync при использовании большого количества переходов в одной транзакции.
Expand Down
16 changes: 9 additions & 7 deletions src/hooks/useThrottledContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import { EventBus } from '../services/EventBus';

export function useThrottledContext<T>(context: Context<T>): [T, T | null] {
const contextValue = useContext(context);
const contextName = context.displayName;
const [prevValue, setPrevValue] = useState<T>(contextValue);
const [throttledValue, setThrottledValue] = useState<T>(contextValue);
const contextName = context.displayName ?? '';
const initialContextData = ContextThrottleService.retrieveContextInfo(contextName, contextValue);

if (!contextName) {
console.error('No context display name found');
return [contextValue, null];
}
const [prevValue, setPrevValue] = useState<T | null>(initialContextData.prevValue);
const [throttledValue, setThrottledValue] = useState<T>(initialContextData.throttledValue);

useEffect(() => {
const unsubscribe = EventBus.subscribe<(throttleValue: T, prevValue: T) => void>(
Expand All @@ -29,5 +26,10 @@ export function useThrottledContext<T>(context: Context<T>): [T, T | null] {
ContextThrottleService.triggerContextUpdate(contextName, contextValue);
}, [contextValue, contextName]);

if (!contextName) {
console.error('No context display name found');
return [contextValue, null];
}

return [throttledValue, prevValue];
}
77 changes: 60 additions & 17 deletions src/services/ContextThrottleService.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { areKeysEqual } from '../utils';
import { EventBus } from './EventBus';
import { TransactionExecutor } from './TransactionExecutor';

interface ContextThrottleInfo {
prevValue: unknown;
interface ContextThrottleInfo<T = unknown> {
prevValue: T | null;
updateTimerId: number;
throttledValue: unknown;
throttledValue: T;
lastUpdateTimestamp: number;
}

Expand All @@ -17,7 +18,7 @@ export class ContextThrottleService {
private static instance?: ContextThrottleService;
private interval = 0;
private throttled = true;
private contextThrottleMap: Record<string, ContextThrottleInfo> = {};
private contextThrottleMap: Map<string, ContextThrottleInfo> = new Map();

// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {}
Expand All @@ -30,20 +31,44 @@ export class ContextThrottleService {
return ContextThrottleService.instance;
}

private getContextThrottleInfoByName(contextName: string) {
if (!(contextName in this.contextThrottleMap)) {
this.contextThrottleMap[contextName] = {
prevValue: null,
throttledValue: null,
lastUpdateTimestamp: 0,
updateTimerId: 0,
};
private validateContextInfo<T>(
value: ContextThrottleInfo | undefined,
contextValue: T,
): value is ContextThrottleInfo<T> {
if (typeof value !== 'object' || typeof value.throttledValue !== typeof contextValue) {
return false;
}
return this.contextThrottleMap[contextName];

if (typeof contextValue === 'object' && contextValue !== null) {
return areKeysEqual(value.throttledValue as object, contextValue);
}

return true;
}

private getContextThrottleInfoByName<T>(
contextName: string,
contextValue: T,
): ContextThrottleInfo<T> {
const existingData = this.contextThrottleMap.get(contextName);

if (this.validateContextInfo<T>(existingData, contextValue)) {
return existingData;
}

const newData: ContextThrottleInfo<T> = {
prevValue: null,
throttledValue: contextValue,
lastUpdateTimestamp: 0,
updateTimerId: 0,
};

this.contextThrottleMap.set(contextName, newData);
return newData;
}

private isContextChange<T>(contextName: string, newValue: T) {
const contextData = this.getContextThrottleInfoByName(contextName);
const contextData = this.getContextThrottleInfoByName(contextName, newValue);
return !(newValue === contextData.throttledValue);
}

Expand All @@ -54,17 +79,25 @@ export class ContextThrottleService {
}

private updateContextValue<T>(contextName: string, newValue: T) {
const contextData = this.getContextThrottleInfoByName(contextName);
const contextData = this.getContextThrottleInfoByName(contextName, newValue);

if (!this.isContextChange(contextName, newValue)) {
return;
}

contextData.prevValue = contextData.throttledValue;
contextData.lastUpdateTimestamp = Date.now();
contextData.throttledValue = newValue;
EventBus.broadcast(contextName, [contextData.throttledValue, contextData.prevValue]);
}

private throttleUpdateContextValue<T>(contextName: string, newValue: T) {
const contextData = this.getContextThrottleInfoByName(contextName);
const contextData = this.getContextThrottleInfoByName(contextName, newValue);
clearTimeout(contextData.updateTimerId);
if (this.isRunSyncActive()) return;

if (this.isRunSyncActive()) {
return;
}

const lastUpdateTimestamp = contextData.lastUpdateTimestamp;
const timeUntilNextUpdate = this.getTimeUntilNextUpdate(lastUpdateTimestamp);
Expand Down Expand Up @@ -96,6 +129,16 @@ export class ContextThrottleService {
}
}

public static retrieveContextInfo<T>(contextName: string, contextValue: T) {
const throttledService = ContextThrottleService.getInstance();
const { prevValue, throttledValue } = throttledService.getContextThrottleInfoByName(
contextName,
contextValue,
);

return { prevValue, throttledValue };
}

public static updateThrottledServiceSettings(settings: ContextThrottleServiceSettings) {
const throttledService = ContextThrottleService.getInstance();
throttledService.interval = settings.interval;
Expand Down
11 changes: 11 additions & 0 deletions src/utils/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ export const isPageObject = (path: NavigationTarget): path is Page | PageWithPar
return typeof path === 'object' && 'path' in path;
};

export const areKeysEqual = <T extends object, U extends object>(obj1: T, obj2: U): boolean => {
const keys1 = Object.keys(obj1);
const keys2 = Object.keys(obj2);

if (keys1.length !== keys2.length) {
return false;
}

return keys1.every((key) => keys2.includes(key));
};

export const isPageWithOptionsPath = (
path: NavigationTarget,
): path is Partial<Path> | ExtendedPathWithParams<string> | ExtendedPath => {
Expand Down

0 comments on commit 00eaed1

Please sign in to comment.