UNPKG

@motion-core/motion-gpu

Version:

Framework-agnostic WebGPU runtime for fullscreen WGSL shaders with explicit Svelte, React, and Vue adapter entrypoints.

85 lines (84 loc) 2.2 kB
//#region src/lib/core/current-value.ts var NO_PENDING_ERROR = Symbol("motiongpu-current-no-error"); /** * Creates a writable value with immediate subscription semantics. * Accepted writes are delivered FIFO to a subscriber snapshot. `onChange` runs * after that snapshot for each value, preserving the original callback order. */ function createCurrentWritable(initialValue, onChange) { let current = initialValue; let currentVersion = 0; const subscribers = /* @__PURE__ */ new Set(); const deliveredVersions = /* @__PURE__ */ new Map(); const pendingValues = []; let pendingIndex = 0; let isFlushing = false; const flush = () => { if (isFlushing) return; isFlushing = true; let firstError = NO_PENDING_ERROR; try { while (pendingIndex < pendingValues.length) { const { value, version } = pendingValues[pendingIndex]; pendingIndex += 1; const snapshot = Array.from(subscribers); for (const run of snapshot) { if (!subscribers.has(run) || (deliveredVersions.get(run) ?? -1) >= version) continue; deliveredVersions.set(run, version); try { run(value); } catch (error) { if (firstError === NO_PENDING_ERROR) firstError = error; } } try { onChange?.(value); } catch (error) { if (firstError === NO_PENDING_ERROR) firstError = error; } } } finally { pendingValues.length = 0; pendingIndex = 0; isFlushing = false; } if (firstError !== NO_PENDING_ERROR) throw firstError; }; const set = (value) => { if (Object.is(current, value)) return; current = value; currentVersion += 1; pendingValues.push({ value, version: currentVersion }); flush(); }; return { get current() { return current; }, subscribe(run) { subscribers.add(run); deliveredVersions.set(run, currentVersion); try { run(current); } catch (error) { subscribers.delete(run); deliveredVersions.delete(run); throw error; } return () => { subscribers.delete(run); deliveredVersions.delete(run); }; }, set, update(updater) { set(updater(current)); } }; } //#endregion export { createCurrentWritable }; //# sourceMappingURL=current-value.js.map