refactor(store): remove partial slice state updates (#296)

This commit is contained in:
rahim
2026-01-06 14:23:00 +11:00
committed by GitHub
parent 0354e3ef9c
commit bb2b54e86f
12 changed files with 56 additions and 89 deletions
+4 -6
View File
@@ -35,16 +35,14 @@ export interface SliceGetSnapshotContext<Target, State> {
export type SliceSubscribe<Target, State extends object> = (ctx: SliceSubscribeContext<Target, State>) => void;
export interface SliceSubscribeContext<Target, State extends object> {
export interface SliceSubscribeContext<Target, _State extends object> {
target: Target;
update: SliceUpdate<State>;
update: SliceUpdate;
signal: AbortSignal;
}
export interface SliceUpdate<State extends object> {
(): void;
(state: Partial<State>): void;
}
/** Sync slice state from target via getSnapshot. */
export type SliceUpdate = () => void;
export interface SliceConfig<
Target,
+11 -14
View File
@@ -1,6 +1,13 @@
import type { PendingTask, Task, TaskContext } from './queue';
import type { RequestMeta, RequestMetaInit, ResolvedRequestConfig } from './request';
import type { AnySlice, Slice, UnionSliceRequests, UnionSliceState, UnionSliceTarget, UnionSliceTasks } from './slice';
import type {
AnySlice,
SliceUpdate,
UnionSliceRequests,
UnionSliceState,
UnionSliceTarget,
UnionSliceTasks,
} from './slice';
import type { StateFactory } from './state';
import { getSelectorKeys } from '@videojs/utils/object';
@@ -115,20 +122,10 @@ export class Store<Target, Slices extends AnySlice<Target>[] = AnySlice<Target>[
return () => this.#detach();
}
#createUpdate<State extends object>(slice: Slice<Target, State, any>) {
return (partial?: Partial<State>) => {
#createUpdate(slice: AnySlice<Target>): SliceUpdate {
return () => {
const target = this.#target;
if (!target) return;
try {
if (partial === undefined) {
this.#syncSlice(slice, target);
} else {
this.#state.patch(partial as Partial<UnionSliceState<Slices>>);
}
} catch (error) {
this.#handleError({ error });
}
if (target) this.#syncSlice(slice, target);
};
}
@@ -15,7 +15,7 @@ describe('store lifecycle integration', () => {
getSnapshot: ({ target }) => ({ count: target.value }),
subscribe: ({ target, update, signal }) => {
events.push('subscribe');
target.addEventListener('change', () => update(), { signal });
target.addEventListener('change', update, { signal });
signal.addEventListener('abort', () => events.push('unsubscribe'));
},
request: {
@@ -231,7 +231,7 @@ describe('request coordination', () => {
});
describe('state syncing', () => {
it('partial updates only trigger relevant subscriptions', async () => {
it('updates only trigger subscriptions for changed keys', async () => {
const volumeUpdates: number[] = [];
const mutedUpdates: boolean[] = [];
@@ -250,21 +250,8 @@ describe('state syncing', () => {
muted: target.muted,
}),
subscribe: ({ target, update, signal }) => {
target.addEventListener(
'volumechange',
() => {
update({ volume: target.volume });
},
{ signal },
);
target.addEventListener(
'mutechange',
() => {
update({ muted: target.muted });
},
{ signal },
);
target.addEventListener('volumechange', update, { signal });
target.addEventListener('mutechange', update, { signal });
},
request: {
setVolume: (volume: number, { target }) => {
+2 -3
View File
@@ -21,10 +21,9 @@ describe('store', () => {
muted: target.muted,
}),
subscribe: ({ target, update, signal }) => {
const handler = () => update();
target.addEventListener('volumechange', handler);
target.addEventListener('volumechange', update);
signal.addEventListener('abort', () => {
target.removeEventListener('volumechange', handler);
target.removeEventListener('volumechange', update);
});
},
request: {