Skip to content

Commit

Permalink
WIP: hook up scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
mhevery committed Jun 2, 2024
1 parent 3b22893 commit bee49ed
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 15 deletions.
11 changes: 10 additions & 1 deletion packages/qwik/src/core/v2/shared/scheduler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ export const enum ChoreType {
/* order of elements (not encoded here) */
MICRO /* ***************** */ = 0b000_111,

/** Ensure tha the QRL promise is resolved before processing next chores in the queue */
QRL_RESOLVE /* *********** */ = 0b000_000,
// TODO(mhevery): COMPUTED should be deleted because it is handled synchronously.
COMPUTED /* ************** */ = 0b000_001,
RESOURCE /* ************** */ = 0b000_010,
TASK /* ****************** */ = 0b000_011,
Expand Down Expand Up @@ -150,6 +153,12 @@ export const createScheduler = (
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

function schedule(
type: ChoreType.QRL_RESOLVE,
ignore0: null,
ignore1: null,
promise: Promise<any>
): ValueOrPromise<void>;
function schedule(type: ChoreType.JOURNAL_FLUSH): ValueOrPromise<void>;
function schedule(type: ChoreType.WAIT_FOR_ALL): ValueOrPromise<void>;
function schedule(type: ChoreType.WAIT_FOR_COMPONENTS): ValueOrPromise<void>;
Expand Down Expand Up @@ -186,7 +195,7 @@ export const createScheduler = (
///// IMPLEMENTATION /////
function schedule(
type: ChoreType,
hostOrTask: HostElement | Task = null!,
hostOrTask: HostElement | Task | null = null,
targetOrQrl: HostElement | QRL<(...args: any[]) => any> | null = null,
payload: any = null
): ValueOrPromise<any> {
Expand Down
32 changes: 25 additions & 7 deletions packages/qwik/src/core/v2/signal-v2/v2-signal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,32 @@ class Signal2<T = any> implements ISignal2<T> {
*
* An effect is work which needs to be done when the signal changes.
*
* 1. `Task` - A task which needs to be re-run.
* 1. `Task` - A task which needs to be re-run. For example a `useTask` or `useResource`, etc...
* 2. `VNode` - A component or Direct DOM update. (Look at the VNode attributes to determine if it is
* a Component or VNode signal target)
* 3. `Signal2` - A derived signal which needs to be re-computed. A derived signal gets marked as
* dirty synchronously, but the computation is lazy.
*
* `Task` and `VNode` are leaves in a tree, where as `Signal2` is a node in a tree. When
* processing a change in a signal, the leaves (`Task` and `VNode`) are scheduled for execution,
* where as the Nodes (`Signal2`) are synchronously recursed into and marked as dirty.
*/
private $effects$: null | Array<Task | VNode | Signal2> = null;

/** If this signal is computed, then compute function is stored here. */
/**
* If this signal is computed, then compute function is stored here.
*
* The computed functions must be executed synchronously (because of this we need to eagerly
* resolve the QRL during the mark dirty phase so that any call to it will be synchronous). )
*/
private $computeQrl$: null | QRLInternal<() => T>;

/**
* The execution context when the signal was being created.
*
* The context contains the scheduler and the subscriber, and is used by the derived signal to
* capture dependencies.
*/
private $context$: InvokeContext | undefined;

constructor(value: T, computeTask: QRLInternal<() => T> | null) {
Expand Down Expand Up @@ -113,12 +131,12 @@ class Signal2<T = any> implements ISignal2<T> {
assertDefined(subscriber.$computeQrl$, 'Expecting ComputedSignal');
// Special case of a computed signal.
subscriber.$untrackedValue$ = NEEDS_COMPUTATION;
const resolved = subscriber.$computeQrl$.getFn();
// TODO(mhevery): This needs to be added to the scheduler to make sure
// that we don't try to read the computed signal until it has been resolved.
// scheduler(ChoreType.QRL_RESOLVE, resolved);
const qrl = subscriber.$computeQrl$!;
if (!qrl.resolved) {
const resolved = subscriber.$computeQrl$.resolve();
this.$context$?.$container2$?.$scheduler$(ChoreType.QRL_RESOLVE, null, null, resolved);
}
target = subscriber;
DEBUG && log('Should schedule', resolved);
} else {
target = subscriber[1] as Task;
assertTrue(isTask(target), 'Invalid subscriber.');
Expand Down
9 changes: 2 additions & 7 deletions packages/qwik/src/core/v2/signal-v2/v2-signal.unit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,15 +51,10 @@ describe('v2-signal', () => {
const a = createSignal2(2);
const b = createSignal2(10);
await retry(() => {
const signal = createComputed2$(() => {
return a.value + b.value;
});
const signal = createComputed2$(() => a.value + b.value);
expect((signal as any).$untrackedValue$).toEqual(12);
expect(signal.value).toEqual(12);
effect$(() => {
console.log('TEST effect.signal', signal.value);
log.push(signal.value);
});
effect$(() => log.push(signal.value));
expect(log).toEqual([12]);
a.value++;
b.value += 10;
Expand Down

0 comments on commit bee49ed

Please sign in to comment.