Skip to content

Commit cf982e8

Browse files
committed
feat(cursors): more cleanuo & migrations from scheduler
1 parent 098ccd9 commit cf982e8

File tree

20 files changed

+114
-193
lines changed

20 files changed

+114
-193
lines changed
Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
import { QError, qError } from '../shared/error/error';
21
import type { QRLInternal } from '../shared/qrl/qrl-class';
3-
import { getChorePromise } from '../shared/scheduler';
4-
import { ChoreType } from '../shared/util-chore-type';
2+
import { retryOnPromise } from '../shared/utils/promises';
53
import type { ValueOrPromise } from '../shared/utils/types';
64
import { getInvokeContext } from '../use/use-core';
75
import { useLexicalScope } from '../use/use-lexical-scope.public';
8-
import { getDomContainer } from './dom-container';
6+
import { VNodeFlags } from './types';
97

108
/**
119
* This is called by qwik-loader to run a QRL. It has to be synchronous.
@@ -17,20 +15,12 @@ export const _run = (...args: unknown[]): ValueOrPromise<unknown> => {
1715
const [runQrl] = useLexicalScope<[QRLInternal<(...args: unknown[]) => unknown>]>();
1816
const context = getInvokeContext();
1917
const hostElement = context.$hostElement$;
18+
return retryOnPromise(() => {
19+
if (!hostElement || hostElement.flags & VNodeFlags.Deleted) {
20+
// silently ignore
21+
return;
22+
}
2023

21-
if (!hostElement) {
22-
// silently ignore if there is no host element, the element might have been removed
23-
return;
24-
}
25-
26-
const container = getDomContainer(context.$element$!);
27-
28-
const scheduler = container.$scheduler$;
29-
if (!scheduler) {
30-
throw qError(QError.schedulerNotFound);
31-
}
32-
33-
// We don't return anything, the scheduler is in charge now
34-
const chore = scheduler(ChoreType.RUN_QRL, hostElement, runQrl, args);
35-
return getChorePromise(chore);
24+
return runQrl(...args);
25+
});
3626
};

packages/qwik/src/core/reactive-primitives/cleanup.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,26 @@
1-
import { ensureMaterialized, vnode_isDomVNode, vnode_isVNode } from '../client/vnode';
2-
import type { Container } from '../shared/types';
3-
import { SignalImpl } from './impl/signal-impl';
4-
import { WrappedSignalImpl } from './impl/wrapped-signal-impl';
5-
import { StoreHandler, getStoreHandler } from './impl/store';
1+
// import { ensureMaterialized, vnode_isElementVNode, vnode_isVNode } from '../client/vnode';
2+
// import type { Container } from '../shared/types';
3+
// import { SignalImpl } from './impl/signal-impl';
4+
// import { WrappedSignalImpl } from './impl/wrapped-signal-impl';
5+
// import { StoreHandler, getStoreHandler } from './impl/store';
6+
// import { AsyncComputedSignalImpl } from './impl/async-computed-signal-impl';
7+
// import { _PROPS_HANDLER } from '../shared/utils/constants';
68
import {
79
EffectSubscriptionProp,
810
_EFFECT_BACK_REF,
911
type Consumer,
1012
type EffectProperty,
1113
type EffectSubscription,
1214
} from './types';
13-
import { AsyncComputedSignalImpl } from './impl/async-computed-signal-impl';
1415
import { isPropsProxy, type PropsProxyHandler } from '../shared/jsx/props-proxy';
15-
import { _PROPS_HANDLER } from '../shared/utils/constants';
1616

1717
/** Class for back reference to the EffectSubscription */
1818
export abstract class BackRef {
1919
[_EFFECT_BACK_REF]: Map<EffectProperty | string, EffectSubscription> | undefined = undefined;
2020
}
2121

2222
export function clearAllEffects(container: Container, consumer: Consumer): void {
23-
if (vnode_isVNode(consumer) && vnode_isDomVNode(consumer)) {
23+
if (vnode_isVNode(consumer) && vnode_isElementVNode(consumer)) {
2424
ensureMaterialized(consumer);
2525
}
2626
const effects = (consumer as BackRef)[_EFFECT_BACK_REF];

packages/qwik/src/core/reactive-primitives/impl/async-computed-signal-impl.ts

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { qwikDebugToString } from '../../debug';
22
import type { NoSerialize } from '../../shared/serdes/verify';
33
import type { Container } from '../../shared/types';
4-
import { ChoreType } from '../../shared/util-chore-type';
54
import { isPromise, retryOnPromise } from '../../shared/utils/promises';
65
import { cleanupDestroyable } from '../../use/utils/destroyable';
76
import { cleanupFn, trackFn } from '../../use/utils/tracker';
@@ -69,12 +68,7 @@ export class AsyncComputedSignalImpl<T>
6968
set untrackedLoading(value: boolean) {
7069
if (value !== this.$untrackedLoading$) {
7170
this.$untrackedLoading$ = value;
72-
this.$container$?.$scheduler$(
73-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
74-
undefined,
75-
this,
76-
this.$loadingEffects$
77-
);
71+
scheduleEffects(this.$container$, this, this.$loadingEffects$);
7872
}
7973
}
8074

@@ -94,12 +88,7 @@ export class AsyncComputedSignalImpl<T>
9488
set untrackedError(value: Error | undefined) {
9589
if (value !== this.$untrackedError$) {
9690
this.$untrackedError$ = value;
97-
this.$container$?.$scheduler$(
98-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
99-
undefined,
100-
this,
101-
this.$errorEffects$
102-
);
91+
scheduleEffects(this.$container$, this, this.$errorEffects$);
10392
}
10493
}
10594

packages/qwik/src/core/reactive-primitives/impl/computed-signal-impl.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ import { qwikDebugToString } from '../../debug';
22
import { assertFalse } from '../../shared/error/assert';
33
import { QError, qError } from '../../shared/error/error';
44
import type { Container } from '../../shared/types';
5-
import { ChoreType } from '../../shared/util-chore-type';
65
import { isPromise } from '../../shared/utils/promises';
76
import { tryGetInvokeContext } from '../../use/use-core';
8-
import { throwIfQRLNotResolved } from '../utils';
7+
import { scheduleEffects, throwIfQRLNotResolved } from '../utils';
98
import type { BackRef } from '../cleanup';
109
import { getSubscriber } from '../subscriber';
1110
import { SerializationSignalFlags, ComputeQRL, EffectSubscription } from '../types';
@@ -53,12 +52,7 @@ export class ComputedSignalImpl<T, S extends QRLInternal = ComputeQRL<T>>
5352

5453
invalidate() {
5554
this.$flags$ |= SignalFlags.INVALID;
56-
this.$container$?.$scheduler$(
57-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
58-
undefined,
59-
this,
60-
this.$effects$
61-
);
55+
scheduleEffects(this.$container$, this, this.$effects$);
6256
}
6357

6458
/**

packages/qwik/src/core/reactive-primitives/impl/signal-impl.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import {
99
addQrlToSerializationCtx,
1010
ensureContainsBackRef,
1111
ensureContainsSubscription,
12+
scheduleEffects,
1213
} from '../utils';
1314
import type { Signal } from '../signal.public';
1415
import { SignalFlags, type EffectSubscription } from '../types';
15-
import { ChoreType } from '../../shared/util-chore-type';
1616
import type { WrappedSignalImpl } from './wrapped-signal-impl';
1717

1818
const DEBUG = false;
@@ -38,12 +38,7 @@ export class SignalImpl<T = any> implements Signal<T> {
3838
* remained the same object
3939
*/
4040
force() {
41-
this.$container$?.$scheduler$(
42-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
43-
undefined,
44-
this,
45-
this.$effects$
46-
);
41+
scheduleEffects(this.$container$, this, this.$effects$);
4742
}
4843

4944
get untrackedValue() {
@@ -68,12 +63,7 @@ export class SignalImpl<T = any> implements Signal<T> {
6863
DEBUG &&
6964
log('Signal.set', this.$untrackedValue$, '->', value, pad('\n' + this.toString(), ' '));
7065
this.$untrackedValue$ = value;
71-
this.$container$?.$scheduler$(
72-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
73-
undefined,
74-
this,
75-
this.$effects$
76-
);
66+
scheduleEffects(this.$container$, this, this.$effects$);
7767
}
7868
}
7969

packages/qwik/src/core/reactive-primitives/impl/store.ts

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
addQrlToSerializationCtx,
88
ensureContainsBackRef,
99
ensureContainsSubscription,
10+
scheduleEffects,
1011
} from '../utils';
1112
import {
1213
STORE_ALL_PROPS,
@@ -16,7 +17,6 @@ import {
1617
type EffectSubscription,
1718
type StoreTarget,
1819
} from '../types';
19-
import { ChoreType } from '../../shared/util-chore-type';
2020
import type { PropsProxy, PropsProxyHandler } from '../../shared/jsx/props-proxy';
2121

2222
const DEBUG = false;
@@ -109,12 +109,7 @@ export class StoreHandler implements ProxyHandler<StoreTarget> {
109109

110110
force(prop: keyof StoreTarget): void {
111111
const target = getStoreTarget(this)!;
112-
this.$container$?.$scheduler$(
113-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
114-
undefined,
115-
this,
116-
getEffects(target, prop, this.$effects$)
117-
);
112+
scheduleEffects(this.$container$, this, getEffects(target, prop, this.$effects$));
118113
}
119114

120115
get(target: StoreTarget, prop: string | symbol) {
@@ -199,12 +194,7 @@ export class StoreHandler implements ProxyHandler<StoreTarget> {
199194
if (!Array.isArray(target)) {
200195
// If the target is an array, we don't need to trigger effects.
201196
// Changing the length property will trigger effects.
202-
this.$container$?.$scheduler$(
203-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
204-
undefined,
205-
this,
206-
getEffects(target, prop, this.$effects$)
207-
);
197+
scheduleEffects(this.$container$, this, getEffects(target, prop, this.$effects$));
208198
}
209199
return true;
210200
}
@@ -292,12 +282,7 @@ function setNewValueAndTriggerEffects<T extends Record<string | symbol, any>>(
292282
(target as any)[prop] = value;
293283
const effects = getEffects(target, prop, currentStore.$effects$);
294284
if (effects) {
295-
currentStore.$container$?.$scheduler$(
296-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
297-
undefined,
298-
currentStore,
299-
effects
300-
);
285+
scheduleEffects(currentStore.$container$, currentStore, effects);
301286
}
302287
}
303288

packages/qwik/src/core/reactive-primitives/impl/wrapped-signal-impl.ts

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { vnode_setProp } from '../../client/vnode';
12
import { assertFalse } from '../../shared/error/assert';
23
import { QError, qError } from '../../shared/error/error';
34
import type { Container, HostElement } from '../../shared/types';
4-
import { ChoreType } from '../../shared/util-chore-type';
5+
import { HOST_EFFECTS } from '../../shared/utils/markers';
6+
import { ChoreBits } from '../../shared/vnode/enums/chore-bits.enum';
57
import { trackSignal } from '../../use/use-core';
68
import type { BackRef } from '../cleanup';
79
import { getValueProp } from '../internal-api';
@@ -15,6 +17,7 @@ import {
1517
} from '../types';
1618
import { isSignal, scheduleEffects } from '../utils';
1719
import { SignalImpl } from './signal-impl';
20+
import { markVNodeDirty } from '../../shared/vnode/vnode-dirty';
1821

1922
export class WrappedSignalImpl<T> extends SignalImpl<T> implements BackRef {
2023
$args$: any[];
@@ -48,12 +51,10 @@ export class WrappedSignalImpl<T> extends SignalImpl<T> implements BackRef {
4851
try {
4952
this.$computeIfNeeded$();
5053
} catch (_) {
51-
this.$container$?.$scheduler$(
52-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
53-
this.$hostElement$,
54-
this,
55-
this.$effects$
56-
);
54+
if (this.$container$ && this.$hostElement$) {
55+
vnode_setProp(this.$hostElement$, HOST_EFFECTS, this.$effects$);
56+
markVNodeDirty(this.$container$, this.$hostElement$, ChoreBits.COMPUTE);
57+
}
5758
}
5859
// if the computation not failed, we can run the effects directly
5960
if (this.$flags$ & SignalFlags.RUN_EFFECTS) {
@@ -68,12 +69,10 @@ export class WrappedSignalImpl<T> extends SignalImpl<T> implements BackRef {
6869
*/
6970
force() {
7071
this.$flags$ |= SignalFlags.RUN_EFFECTS;
71-
this.$container$?.$scheduler$(
72-
ChoreType.RECOMPUTE_AND_SCHEDULE_EFFECTS,
73-
this.$hostElement$,
74-
this,
75-
this.$effects$
76-
);
72+
if (this.$container$ && this.$hostElement$) {
73+
vnode_setProp(this.$hostElement$, HOST_EFFECTS, this.$effects$);
74+
markVNodeDirty(this.$container$, this.$hostElement$, ChoreBits.COMPUTE);
75+
}
7776
}
7877

7978
get untrackedValue() {

packages/qwik/src/core/shared/component-execution.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { isDev } from '@qwik.dev/core/build';
22
import { vnode_isVNode } from '../client/vnode';
33
import { isSignal } from '../reactive-primitives/utils';
44
import { clearAllEffects } from '../reactive-primitives/cleanup';
5-
import { invokeApply, newInvokeContext, untrack } from '../use/use-core';
5+
import { invokeApply, newInvokeContext, untrack, type RenderInvokeContext } from '../use/use-core';
66
import { type EventQRL, type UseOnMap } from '../use/use-on';
77
import { isQwikComponent, type OnRenderFn } from './component.public';
88
import { assertDefined } from './error/assert';
@@ -63,7 +63,7 @@ export const executeComponent = (
6363
subscriptionHost || undefined,
6464
undefined,
6565
RenderEvent
66-
);
66+
) as RenderInvokeContext;
6767
if (subscriptionHost) {
6868
iCtx.$effectSubscriber$ = getSubscriber(subscriptionHost, EffectProperty.COMPONENT);
6969
iCtx.$container$ = container;
@@ -106,7 +106,7 @@ export const executeComponent = (
106106
clearAllEffects(container, renderHost);
107107
}
108108

109-
return componentFn(props);
109+
return maybeThen(componentFn(props), (jsx) => maybeThen(iCtx.$waitOn$, () => jsx));
110110
},
111111
(jsx) => {
112112
const useOnEvents = container.getHostProp<UseOnMap>(renderHost, USE_ON_LOCAL);

0 commit comments

Comments
 (0)