UNPKG

@oxyhq/services

Version:

Reusable OxyHQ module to handle authentication, user management, karma system, device-based session management and more 🚀

153 lines (149 loc) • 4.11 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.useUploading = exports.useUploadAggregateProgress = exports.useFiles = exports.useFileStore = exports.useDeleting = void 0; var _zustand = require("zustand"); // Shallow compare two file metadata objects by keys/values function shallowEqualFile(a, b) { if (a === b) return true; if (!a || !b) return false; const aKeys = Object.keys(a); const bKeys = Object.keys(b); if (aKeys.length !== bKeys.length) return false; for (const k of aKeys) { // treat metadata/variants shallowly by reference if (a[k] !== b[k]) return false; } return true; } // Basic upload progress type for aggregate tracking const initialState = { files: {}, order: [], uploading: false, deleting: null, uploadProgress: null }; const useFileStore = exports.useFileStore = (0, _zustand.create)((set, get) => ({ ...initialState, setFiles: (files, opts) => set(state => { const merge = opts?.merge !== false; // default true if (!merge) { const map = {}; const order = []; files.forEach(f => { map[f.id] = f; order.push(f.id); }); // detect if identical to avoid redundant updates const sameOrder = order.length === state.order.length && order.every((id, i) => id === state.order[i]); let sameFiles = sameOrder; if (sameOrder) { sameFiles = order.every(id => state.files[id] && shallowEqualFile(state.files[id], map[id])); } if (sameOrder && sameFiles) return {}; return { files: map, order }; } const newFiles = { ...state.files }; const newOrder = [...state.order]; let changed = false; files.forEach(f => { const prev = state.files[f.id]; const merged = { ...(prev || {}), ...f }; if (!prev || !shallowEqualFile(prev, merged)) { newFiles[f.id] = merged; changed = true; } if (!newOrder.includes(f.id)) { newOrder.unshift(f.id); changed = true; } }); if (!changed) return {}; return { files: newFiles, order: newOrder }; }), addFile: (file, opts) => set(state => { const prepend = opts?.prepend !== false; // default true if (state.files[file.id]) { if (shallowEqualFile(state.files[file.id], file)) return {}; return { files: { ...state.files, [file.id]: file } }; } return { files: { ...state.files, [file.id]: file }, order: prepend ? [file.id, ...state.order] : [...state.order, file.id] }; }), updateFile: (id, patch) => set(state => { const existing = state.files[id]; if (!existing) return {}; const updated = { ...existing, ...patch }; if (shallowEqualFile(existing, updated)) return {}; return { files: { ...state.files, [id]: updated } }; }), removeFile: id => set(state => { if (!state.files[id]) return {}; const { [id]: _removed, ...rest } = state.files; const newOrder = state.order.filter(fid => fid !== id); return { files: rest, order: newOrder }; }), setUploading: val => set({ uploading: val }), setDeleting: id => set({ deleting: id }), setUploadProgress: p => set({ uploadProgress: p }), reset: () => set(initialState) })); // selectors const useFiles = () => { const files = useFileStore(s => s.files); const order = useFileStore(s => s.order); // Return stable array when contents unchanged const out = order.map(id => files[id]); return out; }; exports.useFiles = useFiles; const useUploading = () => useFileStore(s => s.uploading); exports.useUploading = useUploading; const useUploadAggregateProgress = () => useFileStore(s => s.uploadProgress); exports.useUploadAggregateProgress = useUploadAggregateProgress; const useDeleting = () => useFileStore(s => s.deleting); exports.useDeleting = useDeleting; //# sourceMappingURL=fileStore.js.map