UNPKG

react-native-sortables

Version:

Powerful Sortable Components for Flexible Content Reordering in React Native

79 lines (74 loc) 2.34 kB
"use strict"; const shallowEq = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]); export function createItemsStore(initialItems, initialRenderItem) { let keys = []; const nodes = new Map(); const meta = new Map(); const keyListeners = new Set(); const itemListeners = new Map(); // Track the renderer to detect changes let currentRenderer = initialRenderItem; const getKeys = () => keys; const getNode = key => nodes.get(key); const subscribeKeys = listener => { keyListeners.add(listener); return () => keyListeners.delete(listener); }; const subscribeItem = (key, listener) => { let set = itemListeners.get(key); if (!set) itemListeners.set(key, set = new Set()); set.add(listener); return () => { set.delete(listener); if (!set.size) itemListeners.delete(key); }; }; // Core logic for init + updates function apply(entries, renderItem, notify = true) { const nextKeys = entries.map(([k]) => k); const keysChanged = !shallowEq(keys, nextKeys); // If renderer changed, we’ll force-recompute all items const rendererChanged = renderItem !== currentRenderer; currentRenderer = renderItem; if (keysChanged) { const nextSet = new Set(nextKeys); for (const k of keys) { if (!nextSet.has(k)) { meta.delete(k); nodes.delete(k); } } keys = nextKeys; } const touched = new Set(); entries.forEach(([k, item], index) => { const prev = meta.get(k); const changed = rendererChanged || !prev || prev.item !== item || prev.index !== index; if (!changed) return; const info = { index, item }; meta.set(k, info); nodes.set(k, renderItem ? renderItem(info) : item); touched.add(k); }); if (!notify) return; if (keysChanged) keyListeners.forEach(fn => fn()); touched.forEach(k => { const subs = itemListeners.get(k); if (subs) subs.forEach(fn => fn()); }); } // Initial snapshot (sync), no notifications if (initialItems) apply(initialItems, initialRenderItem, false); const update = (entries, renderItem) => apply(entries, renderItem, true); return { getKeys, getNode, subscribeItem, subscribeKeys, update }; } //# sourceMappingURL=store.js.map