Skip to content

Commit 2646686

Browse files
committed
Fix update sync bug
1 parent f6161ef commit 2646686

File tree

3 files changed

+95
-2
lines changed

3 files changed

+95
-2
lines changed

packages/core/src/__tests__/keyval/edit.test.ts

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { expect, test, describe } from 'vitest';
2-
import { createStore, combine } from 'effector';
2+
import { createStore, combine, createEvent, sample } from 'effector';
33
import { keyval } from '@effector/model';
44

55
function createEntities(fill?: Array<{ id: string }>) {
@@ -158,6 +158,43 @@ describe('edit.update', () => {
158158
{ id: 'foo', count: 0, tag: 'x' },
159159
]);
160160
});
161+
test('sync stores after update', () => {
162+
const entities = keyval(() => {
163+
const $id = createStore('');
164+
const $fieldA = createStore('');
165+
const $count = createStore(0);
166+
const inc = createEvent();
167+
sample({
168+
clock: inc,
169+
source: $count,
170+
fn: (n) => n + 1,
171+
target: $count,
172+
});
173+
return {
174+
key: 'id',
175+
state: {
176+
id: $id,
177+
fieldA: $fieldA,
178+
count: $count,
179+
},
180+
api: {
181+
inc,
182+
},
183+
optional: ['count', 'fieldA'],
184+
};
185+
});
186+
entities.edit.replaceAll([{ id: 'a' }, { id: 'b' }]);
187+
entities.edit.update({ id: 'b', fieldA: 'x' });
188+
expect(entities.$items.getState()).toEqual([
189+
{ id: 'a', fieldA: '', count: 0 },
190+
{ id: 'b', fieldA: 'x', count: 0 },
191+
]);
192+
entities.api.inc({ key: 'b', data: undefined });
193+
expect(entities.$items.getState()).toEqual([
194+
{ id: 'a', fieldA: '', count: 0 },
195+
{ id: 'b', fieldA: 'x', count: 1 },
196+
]);
197+
});
161198
});
162199

163200
describe('edit.replaceAll', () => {
@@ -246,4 +283,44 @@ describe('edit.map', () => {
246283
{ id: 'bar', count: 0, tag: 'y' },
247284
]);
248285
});
286+
test('sync stores after update', () => {
287+
const entities = keyval(() => {
288+
const $id = createStore('');
289+
const $fieldA = createStore('');
290+
const $count = createStore(0);
291+
const inc = createEvent();
292+
sample({
293+
clock: inc,
294+
source: $count,
295+
fn: (n) => n + 1,
296+
target: $count,
297+
});
298+
return {
299+
key: 'id',
300+
state: {
301+
id: $id,
302+
fieldA: $fieldA,
303+
count: $count,
304+
},
305+
api: {
306+
inc,
307+
},
308+
optional: ['count', 'fieldA'],
309+
};
310+
});
311+
entities.edit.replaceAll([{ id: 'a' }, { id: 'b' }]);
312+
entities.edit.map({
313+
keys: 'b',
314+
map: () => ({ fieldA: 'x' }),
315+
});
316+
expect(entities.$items.getState()).toEqual([
317+
{ id: 'a', fieldA: '', count: 0 },
318+
{ id: 'b', fieldA: 'x', count: 0 },
319+
]);
320+
entities.api.inc({ key: 'b', data: undefined });
321+
expect(entities.$items.getState()).toEqual([
322+
{ id: 'a', fieldA: '', count: 0 },
323+
{ id: 'b', fieldA: 'x', count: 1 },
324+
]);
325+
});
249326
});

packages/core/src/keyval.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,19 @@ export function keyval<Input, ModelEnhance, Api, Shape>(
318318
...inputUpdate,
319319
};
320320
freshState.items[idx] = newItem;
321+
const instance = freshState.instances[idx];
322+
const storesToUpdate = [] as any[];
323+
const updates = [] as any[];
324+
for (const key in inputUpdate) {
325+
const store = instance.props[key as any as keyof ModelEnhance];
326+
storesToUpdate.push(store);
327+
updates.push(inputUpdate[key]);
328+
}
329+
launch({
330+
target: storesToUpdate,
331+
params: updates,
332+
defer: true,
333+
});
321334
}
322335

323336
const addFx = attach({

packages/core/vite.config.mts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import { defineConfig } from 'vitest/config';
22
import tsconfigPaths from 'vite-tsconfig-paths';
33

44
export default defineConfig({
5-
test: { typecheck: { ignoreSourceErrors: true } },
5+
test: {
6+
reporters: 'default',
7+
typecheck: { ignoreSourceErrors: true },
8+
},
69
plugins: [tsconfigPaths()],
710
});

0 commit comments

Comments
 (0)