diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:26:46 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:43:56 -0700 |
| commit | e4fa1e69e7ebfb627c7198fd1a9881e9327ec4d4 (patch) | |
| tree | 06284a538a6008eca75051399e47db4e5d50301c /node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts | |
initial commit: scaffolding
Diffstat (limited to 'node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts')
| -rw-r--r-- | node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts b/node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts new file mode 100644 index 0000000..70fec02 --- /dev/null +++ b/node_modules/rxjs/src/internal/scheduler/VirtualTimeScheduler.ts @@ -0,0 +1,128 @@ +import { AsyncAction } from './AsyncAction'; +import { Subscription } from '../Subscription'; +import { AsyncScheduler } from './AsyncScheduler'; +import { SchedulerAction } from '../types'; +import { TimerHandle } from './timerHandle'; + +export class VirtualTimeScheduler extends AsyncScheduler { + /** @deprecated Not used in VirtualTimeScheduler directly. Will be removed in v8. */ + static frameTimeFactor = 10; + + /** + * The current frame for the state of the virtual scheduler instance. The difference + * between two "frames" is synonymous with the passage of "virtual time units". So if + * you record `scheduler.frame` to be `1`, then later, observe `scheduler.frame` to be at `11`, + * that means `10` virtual time units have passed. + */ + public frame: number = 0; + + /** + * Used internally to examine the current virtual action index being processed. + * @deprecated Internal implementation detail, do not use directly. Will be made internal in v8. + */ + public index: number = -1; + + /** + * This creates an instance of a `VirtualTimeScheduler`. Experts only. The signature of + * this constructor is likely to change in the long run. + * + * @param schedulerActionCtor The type of Action to initialize when initializing actions during scheduling. + * @param maxFrames The maximum number of frames to process before stopping. Used to prevent endless flush cycles. + */ + constructor(schedulerActionCtor: typeof AsyncAction = VirtualAction as any, public maxFrames: number = Infinity) { + super(schedulerActionCtor, () => this.frame); + } + + /** + * Prompt the Scheduler to execute all of its queued actions, therefore + * clearing its queue. + */ + public flush(): void { + const { actions, maxFrames } = this; + let error: any; + let action: AsyncAction<any> | undefined; + + while ((action = actions[0]) && action.delay <= maxFrames) { + actions.shift(); + this.frame = action.delay; + + if ((error = action.execute(action.state, action.delay))) { + break; + } + } + + if (error) { + while ((action = actions.shift())) { + action.unsubscribe(); + } + throw error; + } + } +} + +export class VirtualAction<T> extends AsyncAction<T> { + protected active: boolean = true; + + constructor( + protected scheduler: VirtualTimeScheduler, + protected work: (this: SchedulerAction<T>, state?: T) => void, + protected index: number = (scheduler.index += 1) + ) { + super(scheduler, work); + this.index = scheduler.index = index; + } + + public schedule(state?: T, delay: number = 0): Subscription { + if (Number.isFinite(delay)) { + if (!this.id) { + return super.schedule(state, delay); + } + this.active = false; + // If an action is rescheduled, we save allocations by mutating its state, + // pushing it to the end of the scheduler queue, and recycling the action. + // But since the VirtualTimeScheduler is used for testing, VirtualActions + // must be immutable so they can be inspected later. + const action = new VirtualAction(this.scheduler, this.work); + this.add(action); + return action.schedule(state, delay); + } else { + // If someone schedules something with Infinity, it'll never happen. So we + // don't even schedule it. + return Subscription.EMPTY; + } + } + + protected requestAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): TimerHandle { + this.delay = scheduler.frame + delay; + const { actions } = scheduler; + actions.push(this); + (actions as Array<VirtualAction<T>>).sort(VirtualAction.sortActions); + return 1; + } + + protected recycleAsyncId(scheduler: VirtualTimeScheduler, id?: any, delay: number = 0): TimerHandle | undefined { + return undefined; + } + + protected _execute(state: T, delay: number): any { + if (this.active === true) { + return super._execute(state, delay); + } + } + + private static sortActions<T>(a: VirtualAction<T>, b: VirtualAction<T>) { + if (a.delay === b.delay) { + if (a.index === b.index) { + return 0; + } else if (a.index > b.index) { + return 1; + } else { + return -1; + } + } else if (a.delay > b.delay) { + return 1; + } else { + return -1; + } + } +} |
