UNPKG

rvx

Version:

A signal based rendering library

87 lines 2.56 kB
import { CONTEXT_WINDOWS } from "./internals/stacks.js"; const _capture = (context) => { return { context: context, value: context.current, }; }; export class Context { constructor(defaultValue) { this.default = defaultValue; } #stack = []; #windowId = 0; default; get current() { if (this.#windowId === CONTEXT_WINDOWS.length) { const stack = this.#stack; return stack[stack.length - 1] ?? this.default; } return this.default; } inject(value, fn, ...args) { const window = CONTEXT_WINDOWS[CONTEXT_WINDOWS.length - 1]; const stack = this.#stack; const parent = this.#windowId; try { this.#windowId = CONTEXT_WINDOWS.length; window.push(this); stack.push(value); return fn(...args); } finally { stack.pop(); window.pop(); this.#windowId = parent; } } with(value) { return { context: this, value }; } static window(states, fn, ...args) { try { CONTEXT_WINDOWS.push([]); return Context.inject(states, fn, ...args); } finally { CONTEXT_WINDOWS.pop(); } } static inject(states, fn, ...args) { const active = []; const windowId = CONTEXT_WINDOWS.length; const window = CONTEXT_WINDOWS[windowId - 1]; for (let i = 0; i < states.length; i++) { const { context, value } = states[i]; active.push({ c: context, p: context.#windowId }); context.#windowId = windowId; context.#stack.push(value); window.push(context); } try { return fn(...args); } finally { for (let i = active.length - 1; i >= 0; i--) { const { c: context, p: parent } = active[i]; context.#windowId = parent; context.#stack.pop(); window.pop(); } } } static capture() { return CONTEXT_WINDOWS[CONTEXT_WINDOWS.length - 1].map(_capture); } static wrap(fn) { const states = Context.capture(); return ((...args) => Context.window(states, fn, ...args)); } } export function Inject(props) { if ("context" in props) { return props.context.inject(props.value, props.children); } return Context.inject(props.states, props.children); } //# sourceMappingURL=context.js.map