Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | 2x 2x 2x 62x 62x 62x 62x 62x 136x 136x 136x 130x 130x 130x 134x 136x 62x 46x 46x 46x 46x 46x 46x 62x 16x 16x 16x 16x 16x 16x 2x 2x 2x 2x 16x 62x 108x 9x 9x 9x 9x 108x 1x 1x 106x 106x 106x 106x 106x 108x 5x 5x 5x 108x 106x 2x 2x 106x 106x 106x 106x 106x 108x 62x 62x 62x 62x | import { batch, batchFlush, batchStart, tasks } from "./batch"; import { type Disposer, type Get, type Readable, type ReadableLike } from "./typings"; import { getReadable, unsubscribe } from "./utils"; export interface WatchEffect { (get: Get, dispose: Disposer): (() => void) | undefined | void; } export const watch = (effect: WatchEffect): Disposer => { let running: boolean | undefined; let disposed: boolean | undefined; let collectedDeps: Set<Readable> | undefined; let cleanupEffect: Disposer | null | undefined | void; const get: Get = ($?: ReadableLike): unknown => { const readable = getReadable($); if (!readable) return $; if (!collectedDeps?.has(readable)) { (collectedDeps ??= new Set()).add(readable); readable.onReaction_(subscription); } return readable.get(); }; const subscription = () => { if (!running) { unsubscribe(collectedDeps, subscription); collectedDeps?.clear(); } tasks.add(runner); }; const dispose = () => { disposed = true; tasks.delete(runner); effect = null as any; // enable gc unsubscribe(collectedDeps, subscription); collectedDeps = undefined; if (cleanupEffect) { const cleanup = cleanupEffect; cleanupEffect = null; batch(cleanup); } }; const runner = () => { if (cleanupEffect) { const cleanup = cleanupEffect; cleanupEffect = null; batch(cleanup); } if (disposed) { return; } const isTopRunner = !running; running = true; const isBatchTop = batchStart(); try { cleanupEffect = effect(get, dispose); } catch (e) { unsubscribe(collectedDeps, subscription); collectedDeps?.clear(); throw e; } finally { if (disposed) { dispose(); } if (isTopRunner) { running = false; } isBatchTop && batchFlush(); } }; runner.task_ = runner; runner(); return dispose; }; |