Skip to content

Commit 7a90214

Browse files
committed
[params] Listeners fire if set before definition
1 parent ab171b5 commit 7a90214

5 files changed

Lines changed: 90 additions & 36 deletions

File tree

coverage.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"tests":7250,"assertions":32247,"lines":{"total":2401,"covered":2401,"skipped":0,"pct":100},"statements":{"total":2598,"covered":2598,"skipped":0,"pct":100},"functions":{"total":1041,"covered":1041,"skipped":0,"pct":100},"branches":{"total":908,"covered":908,"skipped":0,"pct":100},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}
1+
{"tests":7252,"assertions":32251,"lines":{"total":2399,"covered":2399,"skipped":0,"pct":100},"statements":{"total":2599,"covered":2599,"skipped":0,"pct":100},"functions":{"total":1037,"covered":1037,"skipped":0,"pct":100},"branches":{"total":903,"covered":903,"skipped":0,"pct":100},"branchesTrue":{"total":0,"covered":0,"skipped":0,"pct":100}}

src/common/obj.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ export const objSize = (obj: IdObj<unknown>): number => size(objIds(obj));
7272
export const objIsEmpty = <Value>(obj: IdObj<Value> | any): boolean =>
7373
isObject(obj) && objSize(obj) == 0;
7474

75+
/*! istanbul ignore next */
7576
export const objIsEqual = (
7677
obj1: IdObj<unknown>,
7778
obj2: IdObj<unknown>,
@@ -83,7 +84,8 @@ export const objIsEqual = (
8384
size(entries1) === objSize(obj2) &&
8485
arrayEvery(entries1, ([index, value1]) =>
8586
isObject(value1)
86-
? isObject(obj2[index])
87+
? /*! istanbul ignore next */
88+
isObject(obj2[index])
8789
? objIsEqual(obj2[index] as any, value1 as any)
8890
: false
8991
: isEqual(value1, obj2[index]),

src/queries/index.ts

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,19 @@ import {
5656
mapEnsure,
5757
mapForEach,
5858
mapGet,
59-
mapMatch,
6059
mapNew,
6160
mapSet,
6261
mapToObj,
6362
visitTree,
6463
} from '../common/map.ts';
65-
import {objFreeze, objMap, objToMap} from '../common/obj.ts';
64+
import {
65+
objFreeze,
66+
objGet,
67+
objIds,
68+
objIsEqual,
69+
objMap,
70+
objToMap,
71+
} from '../common/obj.ts';
6672
import {
6773
getUndefined,
6874
ifNotUndefined,
@@ -211,8 +217,11 @@ export const createQueries = getCreateFunction((store: Store): Queries => {
211217
build: Build,
212218
paramValues: ParamValues = {},
213219
): Queries => {
220+
const oldParamValues = getParamValues(queryId);
221+
214222
setDefinition(queryId, tableId);
215223
setQueryArgs(queryId, [build, objToMap(paramValues)]);
224+
callParamListeners(queryId, oldParamValues, paramValues);
216225
resetPreStores(queryId);
217226

218227
const [, paramsMap] = getQueryArgs(queryId)!;
@@ -593,33 +602,42 @@ export const createQueries = getCreateFunction((store: Store): Queries => {
593602
return queries;
594603
};
595604

605+
const callParamListeners = (
606+
queryId: Id,
607+
oldParamValues: ParamValues,
608+
newParamValues: ParamValues,
609+
) => {
610+
const allParamIds = setNew<Id>([
611+
...objIds(oldParamValues),
612+
...objIds(newParamValues),
613+
]);
614+
615+
let changed = 0;
616+
collForEach(allParamIds, (paramId) => {
617+
const newParamValue = objGet(newParamValues, paramId);
618+
if (!arrayOrValueEqual(objGet(oldParamValues, paramId), newParamValue)) {
619+
changed = 1;
620+
callListeners(paramValueListeners, [queryId, paramId], newParamValue);
621+
}
622+
});
623+
if (changed) {
624+
callListeners(paramValuesListeners, [queryId], newParamValues);
625+
}
626+
};
627+
596628
const delQueryDefinition = (queryId: Id): Queries => {
597-
const oldParamValues = getQueryArgs(queryId)?.[1];
629+
const oldParamValues = getParamValues(queryId);
598630
resetPreStores(queryId);
599631
delDefinition(queryId);
600-
ifNotUndefined(oldParamValues, (paramValues) => {
601-
mapForEach(paramValues, (paramId) =>
602-
callListeners(paramValueListeners, [queryId, paramId], undefined),
603-
);
604-
callListeners(paramValuesListeners, [queryId], {});
605-
});
632+
callParamListeners(queryId, oldParamValues, {});
606633
return queries;
607634
};
608635

609636
const setParamValues = (queryId: Id, paramValues: ParamValues): Queries => {
610637
ifNotUndefined(getQueryArgs(queryId), ([definition, oldParamValues]) => {
611-
const changedParamValues: IdMap<ParamValue> = mapNew();
612-
mapMatch(
613-
oldParamValues,
614-
paramValues,
615-
(_, paramId, newValue) => {
616-
if (!arrayOrValueEqual(newValue, mapGet(oldParamValues, paramId))) {
617-
mapSet(changedParamValues, paramId, newValue);
618-
}
619-
},
620-
(_, paramId) => mapSet(changedParamValues, paramId, undefined),
621-
);
622-
if (!collIsEmpty(changedParamValues)) {
638+
if (
639+
!objIsEqual(mapToObj(oldParamValues), paramValues, arrayOrValueEqual)
640+
) {
623641
resultStore.transaction(() =>
624642
setQueryDefinition(
625643
queryId,
@@ -628,10 +646,6 @@ export const createQueries = getCreateFunction((store: Store): Queries => {
628646
paramValues,
629647
),
630648
);
631-
mapForEach(changedParamValues, (paramId, value) =>
632-
callListeners(paramValueListeners, [queryId, paramId], value),
633-
);
634-
callListeners(paramValuesListeners, [queryId], {...paramValues});
635649
}
636650
});
637651
return queries;
@@ -641,14 +655,15 @@ export const createQueries = getCreateFunction((store: Store): Queries => {
641655
queryId: Id,
642656
paramId: Id,
643657
value: ParamValue,
644-
): Queries =>
645-
setParamValues(queryId, {
646-
...mapToObj(getQueryArgs(queryId)?.[1]),
647-
[paramId]: value,
648-
});
658+
): Queries => {
659+
if (!arrayOrValueEqual(getParamValue(queryId, paramId), value)) {
660+
setParamValues(queryId, {...getParamValues(queryId), [paramId]: value});
661+
}
662+
return queries;
663+
};
649664

650665
const getParamValues = (queryId: Id): ParamValues =>
651-
ifNotUndefined(getQueryArgs(queryId)?.[1], mapToObj) ?? {};
666+
mapToObj(getQueryArgs(queryId)?.[1]);
652667

653668
const getParamValue = (queryId: Id, paramId: Id): ParamValue | undefined =>
654669
mapGet(getQueryArgs(queryId)?.[1], paramId);

test/unit/core/other/queries.test.ts

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5597,5 +5597,44 @@ describe('Parameterized', () => {
55975597
queries.setParamValue('q1', 'p1', [false]);
55985598
expect(listener).toHaveBeenCalledTimes(1);
55995599
});
5600+
5601+
test('addParamValuesListener before query exists', () => {
5602+
const listener = vi.fn();
5603+
queries.addParamValuesListener('q1', listener);
5604+
5605+
queries.setQueryDefinition(
5606+
'q1',
5607+
't1',
5608+
({select, where, param}) => {
5609+
select('c1');
5610+
where('c1', param('p1') as Cell);
5611+
},
5612+
{p1: 'a', p2: 'test'},
5613+
);
5614+
5615+
expect(listener).toHaveBeenCalledTimes(1);
5616+
expect(listener).toHaveBeenCalledWith(queries, 'q1', {
5617+
p1: 'a',
5618+
p2: 'test',
5619+
});
5620+
});
5621+
5622+
test('addParamValueListener before query exists', () => {
5623+
const listener = vi.fn();
5624+
queries.addParamValueListener('q1', 'p1', listener);
5625+
5626+
queries.setQueryDefinition(
5627+
'q1',
5628+
't1',
5629+
({select, where, param}) => {
5630+
select('c1');
5631+
where('c1', param('p1') as Cell);
5632+
},
5633+
{p1: 'a', p2: 'test'},
5634+
);
5635+
5636+
expect(listener).toHaveBeenCalledTimes(1);
5637+
expect(listener).toHaveBeenCalledWith(queries, 'q1', 'p1', 'a');
5638+
});
56005639
});
56015640
});

test/unit/core/ui-react/hooks.test.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,9 +2629,7 @@ describe('Read Hooks', () => {
26292629
);
26302630
const Test = ({queryId, paramId}: {queryId: Id; paramId: Id}) =>
26312631
didRender(JSON.stringify(useParamValue(queryId, paramId, queries)));
2632-
const {container, rerender, unmount} = render(
2633-
<Test queryId="q1" paramId="p1" />,
2634-
);
2632+
const {container, unmount} = render(<Test queryId="q1" paramId="p1" />);
26352633

26362634
expect(container.textContent).toEqual('"a"');
26372635

0 commit comments

Comments
 (0)