UNPKG

rvx

Version:

A signal based rendering library

95 lines 2.86 kB
import { $, capture, isolate, teardown } from "../signals.js"; export function createMapArrayState() { const state = []; teardown(() => { for (let i = 0; i < state.length; i++) { state[i].d(); } }); return state; } function createEntry(value, index, fn) { const signal = $(index); let output; const dispose = isolate(capture, () => { output = fn(value, () => signal.value); }); return { i: value, o: output, s: signal, d: dispose, r: false, }; } export function mapArrayUpdate(state, rawInput, fn) { const inputs = Array.isArray(rawInput) ? rawInput : Array.from(rawInput); let start = 0; const maxStart = Math.min(state.length, inputs.length); while (start < maxStart && Object.is(inputs[start], state[start].i)) { start++; } if (start === inputs.length && inputs.length === state.length) { return null; } const minEnd = inputs.length - maxStart + start; const lenDiff = inputs.length - state.length; let end = inputs.length - 1; while (end >= minEnd && Object.is(inputs[end], state[end - lenDiff].i)) { end--; } end++; const stateEnd = end - lenDiff; const nextState = []; if ((end - lenDiff - start) === 0) { for (let i = start; i < end; i++) { nextState[i - start] = createEntry(inputs[i], i, fn); } } else { const indexByValue = new Map(); const nextIndexByIndex = []; for (let i = end - 1; i >= start; i--) { const value = inputs[i]; const next = indexByValue.get(value); if (next !== undefined) { nextIndexByIndex[i] = next; } indexByValue.set(value, i); } for (let i = start; i < stateEnd; i++) { const instance = state[i]; const index = indexByValue.get(instance.i); if (index === undefined) { instance.d(); instance.r = true; } else { nextState[index - start] = instance; indexByValue.set(instance.i, nextIndexByIndex[index]); } } for (let i = start; i < end; i++) { const old = nextState[i - start]; if (old) { old.s.value = i; } else { nextState[i - start] = createEntry(inputs[i], i, fn); } } } const prevState = state.splice(start, stateEnd - start, ...nextState); if (stateEnd !== end) { for (let i = end; i < state.length; i++) { state[i].s.value = i; } } return { s: start, e: end, p: prevState, n: nextState, }; } //# sourceMappingURL=map-array.js.map