UNPKG

@dark-engine/core

Version:

The lightweight and powerful UI rendering engine without dependencies and written in TypeScript (Browser, Node.js, Android, iOS, Windows, Linux, macOS)

160 lines (159 loc) 3.53 kB
import { EFFECT_HOST_MASK, IS_WIP_HOOK_MASK, IS_PORTAL_HOOK_MASK, IS_SUSPENSE_HOOK_MASK, IS_BOUNDARY_HOOK_MASK, IS_PENDING_HOOK_MASK, CLEANUP_HOST_MASK, } from '../constants'; import { detectAreSameComponentTypesWithSameKeys } from '../view'; import { dropEffects } from '../use-effect'; import { detectIsFunction, logError } from '../utils'; import { detectIsComponent } from '../component'; class Fiber { id = 0; cc = 0; cec = 0; idx = 0; eidx = 0; mask = 0; el = null; tag = null; parent = null; child = null; next = null; alt = null; inst = null; hook = null; constructor(idx = 0, hook = null) { this.id = Fiber.incrementId(); this.idx = idx; this.hook = hook; } mutate(fiber) { for (const key in fiber) { this[key] = fiber[key]; } return this; } markHost(mask) { this.mask |= mask; this.parent && !(this.parent.mask & mask) && this.parent.markHost(mask); } increment(count = 1) { if (!this.parent) return; this.parent.cec += count; if (!this.parent.el && !this.parent.hook?.getIsWip()) { this.parent.increment(count); } } setError(err) { if (this.hook?.hasCatch()) { this.hook.catch(err); logError(err); } else if (this.parent) { this.parent.setError(err); } else { throw err; } } static incrementId() { return ++Fiber.nextId; } static setNextId(id) { Fiber.nextId = id; } static nextId = 0; } class Hook { idx = 0; values = []; owner = null; mask = 0; providers = null; cleanups = null; catch = null; pendings = 0; update = null; __getMask(mask) { return Boolean(this.mask & mask); } __mark(mask, x) { x ? (this.mask |= mask) : (this.mask &= ~mask); } getIsWip() { return this.__getMask(IS_WIP_HOOK_MASK); } setIsWip(x) { this.__mark(IS_WIP_HOOK_MASK, x); } getIsPortal() { return this.__getMask(IS_PORTAL_HOOK_MASK); } setIsPortal(x) { this.__mark(IS_PORTAL_HOOK_MASK, x); } getIsSuspense() { return this.__getMask(IS_SUSPENSE_HOOK_MASK); } setIsSuspense(x) { this.__mark(IS_SUSPENSE_HOOK_MASK, x); } getIsBoundary() { return this.__getMask(IS_BOUNDARY_HOOK_MASK); } setIsBoundary(x) { this.__mark(IS_BOUNDARY_HOOK_MASK, x); } getIsPending() { return this.__getMask(IS_PENDING_HOOK_MASK); } setIsPeinding(x) { this.__mark(IS_PENDING_HOOK_MASK, x); } getProviders() { return this.providers; } setProviders(x) { this.providers = x; } hasCatch() { return detectIsFunction(this.catch); } setCatch(x) { this.catch = x; } setUpdate(x) { this.update = x; } createCleanup(key, create) { this.owner.markHost(CLEANUP_HOST_MASK); if (!this.cleanups) this.cleanups = new Map(); this.cleanups.get(key)?.(); this.cleanups.set(key, create()); } incrementPendings() { this.pendings++; } getPendings() { return this.pendings; } drop() { const { values, owner } = this; if (values.length > 0 && owner.mask & EFFECT_HOST_MASK) { dropEffects(this); } if (this.cleanups) { for (const [_, cleanup] of this.cleanups) cleanup(); this.cleanups.clear(); } } } function getHook(alt, prevInst, nextInst) { if (alt && detectAreSameComponentTypesWithSameKeys(prevInst, nextInst)) return alt.hook; if (detectIsComponent(nextInst)) return new Hook(); return null; } export { Fiber, Hook, getHook }; //# sourceMappingURL=fiber.js.map