Skip to content

Commit

Permalink
fix: ReplicationStore
Browse files Browse the repository at this point in the history
  • Loading branch information
dineug committed Dec 30, 2023
1 parent fcd4dad commit 7fcba11
Showing 1 changed file with 46 additions and 11 deletions.
57 changes: 46 additions & 11 deletions packages/erd-editor/src/engine/replication-store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { toJson } from '@dineug/erd-editor-schema';
import { AnyAction } from '@dineug/r-html';
import { asap } from '@dineug/shared';
import { asap, safeCallback } from '@dineug/shared';
import { isEmpty, omit } from 'lodash-es';
import { debounceTime, map, Observable, Subject, Subscription } from 'rxjs';

Expand All @@ -10,11 +10,24 @@ import { initialLoadJsonAction$ } from '@/engine/modules/editor/generator.action
import { actionsFilter } from '@/engine/rx-operators';
import { createStore } from '@/engine/store';
import { createHooks } from '@/engine/store-hooks';
import { Unsubscribe, ValuesType } from '@/internal-types';
import { toSafeString } from '@/utils/validation';

type ReducerRecord = {
[P in keyof InternalActionMap]: (payload: InternalActionMap[P]) => void;
};

const InternalActionType = {
change: 'change',
} as const;
type InternalActionType = ValuesType<typeof InternalActionType>;
type InternalActionMap = {
[InternalActionType.change]: void;
};

export type ReplicationStore = {
readonly value: string;
change$: Observable<Array<AnyAction>>;
on: (reducers: Partial<ReducerRecord>) => Unsubscribe;
setInitialValue: (value: string) => void;
dispatch: (actions: Array<AnyAction> | AnyAction) => void;
dispatchSync: (actions: Array<AnyAction> | AnyAction) => void;
Expand All @@ -31,6 +44,25 @@ export function createReplicationStore(
const change$ = new Observable<Array<AnyAction>>(subscriber =>
store.subscribe(actions => subscriber.next(actions))
).pipe(actionsFilter(ChangeActionTypes), debounceTime(200));
const observers = new Set<Partial<ReducerRecord>>();

const on = (reducers: Partial<ReducerRecord>): Unsubscribe => {
observers.has(reducers) || observers.add(reducers);

return () => {
observers.delete(reducers);
};
};

const emit = <T extends InternalActionType>(
type: T,
payload: InternalActionMap[T]
) => {
observers.forEach(reducers => {
const reducer = Reflect.get(reducers, type);
safeCallback(reducer, payload);
});
};

const setInitialValue = (value: string) => {
const safeValue = toSafeString(value);
Expand All @@ -50,24 +82,27 @@ export function createReplicationStore(
const destroy = () => {
Array.from(subscriptionSet).forEach(sub => sub.unsubscribe());
subscriptionSet.clear();
observers.clear();
store.destroy();
hooks.destroy();
};

subscriptionSet.add(
dispatch$
.pipe(
actionsFilter(ChangeActionTypes),
map(actions => actions.map(action => omit(action, 'tags')))
)
.subscribe(store.dispatchSync)
);
subscriptionSet
.add(change$.subscribe(() => emit(InternalActionType.change, undefined)))
.add(
dispatch$
.pipe(
actionsFilter(ChangeActionTypes),
map(actions => actions.map(action => omit(action, 'tags')))
)
.subscribe(store.dispatchSync)
);

return Object.freeze({
get value() {
return toJson(store.state);
},
change$,
on,
setInitialValue,
dispatch,
dispatchSync,
Expand Down

0 comments on commit 7fcba11

Please sign in to comment.