Skip to content

Commit aea1db3

Browse files
authored
Merge pull request #7367 from QwikDev/v2-track-whole-store
fix: tracking whole store
2 parents 2ec1a82 + 5eebd79 commit aea1db3

File tree

6 files changed

+67
-14
lines changed

6 files changed

+67
-14
lines changed

.changeset/young-cameras-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@qwik.dev/core': patch
3+
---
4+
5+
fix: tracking whole store

packages/qwik/src/core/shared/shared-serialization.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
getStoreHandler,
2323
getStoreTarget,
2424
isStore,
25-
STORE_ARRAY_PROP,
25+
STORE_ALL_PROPS,
2626
} from '../signal/store';
2727
import type { ISsrNode, SsrAttrs, SymbolToChunkResolver } from '../ssr/ssr-types';
2828
import { untrack } from '../use/use-core';
@@ -401,7 +401,7 @@ export const _constants = [
401401
EMPTY_ARRAY,
402402
EMPTY_OBJ,
403403
NEEDS_COMPUTATION,
404-
STORE_ARRAY_PROP,
404+
STORE_ALL_PROPS,
405405
Slot,
406406
Fragment,
407407
NaN,
@@ -420,7 +420,7 @@ const _constantNames = [
420420
'EMPTY_ARRAY',
421421
'EMPTY_OBJ',
422422
'NEEDS_COMPUTATION',
423-
'STORE_ARRAY_PROP',
423+
'STORE_ALL_PROPS',
424424
'Slot',
425425
'Fragment',
426426
'NaN',
@@ -1084,8 +1084,8 @@ function serialize(serializationContext: SerializationContext): void {
10841084
output(TypeIds.Constant, Constants.Undefined);
10851085
} else if (value === NEEDS_COMPUTATION) {
10861086
output(TypeIds.Constant, Constants.NEEDS_COMPUTATION);
1087-
} else if (value === STORE_ARRAY_PROP) {
1088-
output(TypeIds.Constant, Constants.STORE_ARRAY_PROP);
1087+
} else if (value === STORE_ALL_PROPS) {
1088+
output(TypeIds.Constant, Constants.STORE_ALL_PROPS);
10891089
} else {
10901090
throw qError(QError.serializeErrorUnknownType, [typeof value]);
10911091
}
@@ -1712,7 +1712,7 @@ export const enum Constants {
17121712
EMPTY_ARRAY,
17131713
EMPTY_OBJ,
17141714
NEEDS_COMPUTATION,
1715-
STORE_ARRAY_PROP,
1715+
STORE_ALL_PROPS,
17161716
Slot,
17171717
Fragment,
17181718
NaN,

packages/qwik/src/core/shared/shared-serialization.unit.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ describe('shared-serialization', () => {
5656
5 Constant EMPTY_ARRAY
5757
6 Constant EMPTY_OBJ
5858
7 Constant NEEDS_COMPUTATION
59-
8 Constant STORE_ARRAY_PROP
59+
8 Constant STORE_ALL_PROPS
6060
9 Constant Slot
6161
10 Constant Fragment
6262
11 Constant NaN

packages/qwik/src/core/signal/store.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const log = (...args: any[]) => console.log('STORE', ...args.map(qwikDebugToStri
1818

1919
const STORE_TARGET = Symbol('store.target');
2020
const STORE_HANDLER = Symbol('store.handler');
21-
export const STORE_ARRAY_PROP = Symbol('store.array');
21+
export const STORE_ALL_PROPS = Symbol('store.all');
2222

2323
export type TargetType = Record<string | symbol, any>;
2424

@@ -113,7 +113,12 @@ export class StoreHandler implements ProxyHandler<TargetType> {
113113
}
114114
const effectSubscriber = ctx.$effectSubscriber$;
115115
if (effectSubscriber) {
116-
addEffect(target, Array.isArray(target) ? STORE_ARRAY_PROP : prop, this, effectSubscriber);
116+
addStoreEffect(
117+
target,
118+
Array.isArray(target) ? STORE_ALL_PROPS : prop,
119+
this,
120+
effectSubscriber
121+
);
117122
}
118123
}
119124

@@ -173,9 +178,9 @@ export class StoreHandler implements ProxyHandler<TargetType> {
173178
if (ctx) {
174179
const effectSubscriber = ctx.$effectSubscriber$;
175180
if (effectSubscriber) {
176-
addEffect(
181+
addStoreEffect(
177182
target,
178-
Array.isArray(target) ? STORE_ARRAY_PROP : prop,
183+
Array.isArray(target) ? STORE_ALL_PROPS : prop,
179184
this,
180185
effectSubscriber
181186
);
@@ -189,7 +194,7 @@ export class StoreHandler implements ProxyHandler<TargetType> {
189194
const ctx = tryGetInvokeContext();
190195
const effectSubscriber = ctx?.$effectSubscriber$;
191196
if (effectSubscriber) {
192-
addEffect(target, STORE_ARRAY_PROP, this, effectSubscriber);
197+
addStoreEffect(target, STORE_ALL_PROPS, this, effectSubscriber);
193198
}
194199
return Reflect.ownKeys(target);
195200
}
@@ -212,7 +217,7 @@ export class StoreHandler implements ProxyHandler<TargetType> {
212217
}
213218
}
214219

215-
function addEffect(
220+
export function addStoreEffect(
216221
target: TargetType,
217222
prop: string | symbol,
218223
store: StoreHandler,
@@ -271,7 +276,7 @@ function getEffects<T extends Record<string | symbol, any>>(
271276
}
272277
}
273278

274-
const storeArrayValue = storeEffects?.get(STORE_ARRAY_PROP);
279+
const storeArrayValue = storeEffects?.get(STORE_ALL_PROPS);
275280
if (storeArrayValue) {
276281
effectsToTrigger ||= new Set();
277282
for (const effect of storeArrayValue) {

packages/qwik/src/core/tests/use-task.spec.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,33 @@ describe.each([
238238
</Component>
239239
);
240240
});
241+
it('should track store', async () => {
242+
const Counter = component$(() => {
243+
const store = useStore({ count: 1, double: 0 });
244+
useTask$(({ track }) => {
245+
const storeCounter = track(store);
246+
store.double = 2 * storeCounter.count;
247+
});
248+
return <button onClick$={() => store.count++}>{store.double}</button>;
249+
});
250+
251+
const { vNode, document } = await render(<Counter />, { debug });
252+
expect(vNode).toMatchVDOM(
253+
<Component>
254+
<button>
255+
<Signal ssr-required>2</Signal>
256+
</button>
257+
</Component>
258+
);
259+
await trigger(document.body, 'button', 'click');
260+
expect(vNode).toMatchVDOM(
261+
<Component>
262+
<button>
263+
<Signal ssr-required>4</Signal>
264+
</button>
265+
</Component>
266+
);
267+
});
241268

242269
it('should unsubscribe from removed component', async () => {
243270
(global as any).logs = [] as string[];

packages/qwik/src/core/use/use-task.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ import { useLexicalScope } from './use-lexical-scope.public';
1818
import type { ResourceReturnInternal } from './use-resource';
1919
import { useSequentialScope } from './use-sequential-scope';
2020
import { getSubscriber } from '../signal/subscriber';
21+
import {
22+
STORE_ALL_PROPS,
23+
addStoreEffect,
24+
getStoreHandler,
25+
getStoreTarget,
26+
isStore,
27+
} from '../signal/store';
2128

2229
export const enum TaskFlags {
2330
VISIBLE_TASK = 1 << 0,
@@ -188,6 +195,15 @@ export const runTask = (
188195
return (obj as Record<string, unknown>)[prop];
189196
} else if (isSignal(obj)) {
190197
return obj.value;
198+
} else if (isStore(obj)) {
199+
// track whole store
200+
addStoreEffect(
201+
getStoreTarget(obj)!,
202+
STORE_ALL_PROPS,
203+
getStoreHandler(obj)!,
204+
ctx.$effectSubscriber$!
205+
);
206+
return obj;
191207
} else {
192208
throw qError(QError.trackObjectWithoutProp);
193209
}

0 commit comments

Comments
 (0)