UNPKG

@replyke/core

Version:

Replyke: Build interactive apps with social features like comments, votes, feeds, user lists, notifications, and more.

290 lines 13 kB
var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var _a; import { createSlice, createSelector } from "@reduxjs/toolkit"; // Default state for a new entity list var createDefaultEntityListState = function () { return ({ entities: [], page: 1, loading: true, hasMore: true, error: null, lastFetched: null, // Default configuration sourceId: null, limit: 10, // Default filters (user-controlled only) sortBy: "hot", sortDir: null, sortType: "auto", timeFrame: null, userId: null, followedOnly: false, keywordsFilters: null, titleFilters: null, contentFilters: null, attachmentsFilters: null, locationFilters: null, metadataFilters: null, }); }; // Initial state var initialState = { lists: {}, }; // Create the slice export var entityListsSlice = createSlice({ name: "entityLists", initialState: initialState, reducers: { // Initialize or get existing list initializeList: function (state, action) { var listId = action.payload.listId; if (!state.lists[listId]) { state.lists[listId] = createDefaultEntityListState(); } }, // Update filters and sort (unified function) updateFiltersAndSort: function (state, action) { var _a = action.payload, listId = _a.listId, filters = _a.filters, options = _a.options; // Ensure list exists if (!state.lists[listId]) { state.lists[listId] = createDefaultEntityListState(); } var list = state.lists[listId]; // If resetUnspecified is true, reset to defaults first if (options === null || options === void 0 ? void 0 : options.resetUnspecified) { var defaultState = createDefaultEntityListState(); // Reset all filter properties to defaults list.sortBy = defaultState.sortBy; list.sortDir = defaultState.sortDir; list.sortType = defaultState.sortType; list.timeFrame = defaultState.timeFrame; list.userId = defaultState.userId; list.followedOnly = defaultState.followedOnly; list.keywordsFilters = defaultState.keywordsFilters; list.titleFilters = defaultState.titleFilters; list.contentFilters = defaultState.contentFilters; list.attachmentsFilters = defaultState.attachmentsFilters; list.locationFilters = defaultState.locationFilters; list.metadataFilters = defaultState.metadataFilters; } // Update specified filters Object.keys(filters).forEach(function (key) { if (filters[key] !== undefined) { list[key] = filters[key]; } }); // Update config if provided if (action.payload.config) { if (action.payload.config.sourceId !== undefined) { list.sourceId = action.payload.config.sourceId; } if (action.payload.config.limit !== undefined) { list.limit = action.payload.config.limit; } } // Reset pagination when filters change list.page = 1; list.hasMore = true; list.error = null; }, // Set loading state for entity list setEntityListLoading: function (state, action) { var _a = action.payload, listId = _a.listId, loading = _a.loading; if (state.lists[listId]) { state.lists[listId].loading = loading; } }, // Set entities for entity list setEntityListEntities: function (state, action) { var _a = action.payload, listId = _a.listId, entities = _a.entities, _b = _a.append, append = _b === void 0 ? false : _b; if (!state.lists[listId]) { state.lists[listId] = createDefaultEntityListState(); } var list = state.lists[listId]; if (append) { // Filter out duplicates when appending var existingIds_1 = new Set(list.entities.map(function (e) { return e.id; })); var newEntities = entities.filter(function (e) { return !existingIds_1.has(e.id); }); list.entities = __spreadArray(__spreadArray([], list.entities, true), newEntities, true); } else { list.entities = entities; } list.loading = false; list.lastFetched = Date.now(); // Note: hasMore is set explicitly by the caller based on limit from hook props }, // Increment page for load more incrementPage: function (state, action) { var listId = action.payload; if (state.lists[listId]) { state.lists[listId].page += 1; } }, // Set hasMore for entity list setEntityListHasMore: function (state, action) { var _a = action.payload, listId = _a.listId, hasMore = _a.hasMore; if (state.lists[listId]) { state.lists[listId].hasMore = hasMore; } }, // Set error for entity list setEntityListError: function (state, action) { var _a = action.payload, listId = _a.listId, error = _a.error; if (state.lists[listId]) { state.lists[listId].error = error; state.lists[listId].loading = false; } }, // Add entity addEntity: function (state, action) { var _a = action.payload, listId = _a.listId, entity = _a.entity, _b = _a.insertPosition, insertPosition = _b === void 0 ? "first" : _b; if (!state.lists[listId]) return; var list = state.lists[listId]; if (insertPosition === "last") { list.entities.push(entity); } else { list.entities.unshift(entity); } }, // Remove entity removeEntity: function (state, action) { var _a = action.payload, listId = _a.listId, entityId = _a.entityId; if (!state.lists[listId]) return; var list = state.lists[listId]; list.entities = list.entities.filter(function (e) { return e.id !== entityId; }); }, // Update keywords filters (special case due to complexity) updateKeywordsFilters: function (state, action) { var _a, _b, _c, _d; var _e = action.payload, listId = _e.listId, type = _e.type, key = _e.key, value = _e.value; if (!state.lists[listId]) { state.lists[listId] = createDefaultEntityListState(); } var list = state.lists[listId]; var items = Array.isArray(value) ? value : value ? [value] : []; var newFilters = list.keywordsFilters || {}; switch (type) { case "add": { if (key === "both") break; // Invalid to add to both newFilters = __assign(__assign({}, newFilters), (_a = {}, _a[key] = Array.from(new Set(__spreadArray(__spreadArray([], (newFilters[key] || []), true), items, true))), _a)); break; } case "remove": { if (key === "both") { newFilters = { includes: (newFilters.includes || []).filter(function (item) { return !items.includes(item); }), doesNotInclude: (newFilters.doesNotInclude || []).filter(function (item) { return !items.includes(item); }), }; } else { newFilters = __assign(__assign({}, newFilters), (_b = {}, _b[key] = (newFilters[key] || []).filter(function (item) { return !items.includes(item); }), _b)); } break; } case "reset": { if (key === "both") { newFilters = {}; } else { newFilters = __assign(__assign({}, newFilters), (_c = {}, _c[key] = undefined, _c)); } break; } case "replace": { if (key === "both") break; // Replace does not apply to both newFilters = __assign(__assign({}, newFilters), (_d = {}, _d[key] = items, _d)); break; } } list.keywordsFilters = Object.keys(newFilters).length > 0 ? newFilters : null; // Reset pagination when filters change list.page = 1; list.hasMore = true; list.error = null; }, // Clean up unused lists (for memory management) cleanupList: function (state, action) { var listId = action.payload; delete state.lists[listId]; }, // Clean up old lists (older than TTL) cleanupOldLists: function (state, action) { var ttl = action.payload; // TTL in milliseconds var now = Date.now(); Object.keys(state.lists).forEach(function (listId) { var list = state.lists[listId]; if (list.lastFetched && now - list.lastFetched > ttl) { delete state.lists[listId]; } }); }, }, }); // Export actions export var initializeList = (_a = entityListsSlice.actions, _a.initializeList), updateFiltersAndSort = _a.updateFiltersAndSort, setEntityListLoading = _a.setEntityListLoading, setEntityListEntities = _a.setEntityListEntities, incrementPage = _a.incrementPage, setEntityListHasMore = _a.setEntityListHasMore, setEntityListError = _a.setEntityListError, addEntity = _a.addEntity, removeEntity = _a.removeEntity, updateKeywordsFilters = _a.updateKeywordsFilters, cleanupList = _a.cleanupList, cleanupOldLists = _a.cleanupOldLists; // Base selectors var selectEntityListsState = function (state) { return state.entityLists; }; var selectListId = function (_, listId) { return listId; }; // Memoized selectors using createSelector export var selectEntityList = createSelector([selectEntityListsState, selectListId], function (entityListsState, listId) { return entityListsState.lists[listId]; }); export var selectEntityListEntities = createSelector([selectEntityList], function (entityList) { return (entityList === null || entityList === void 0 ? void 0 : entityList.entities) || []; }); export var selectEntityListLoading = createSelector([selectEntityList], function (entityList) { return (entityList === null || entityList === void 0 ? void 0 : entityList.loading) || false; }); export var selectEntityListHasMore = createSelector([selectEntityList], function (entityList) { return (entityList === null || entityList === void 0 ? void 0 : entityList.hasMore) || false; }); export var selectEntityListFilters = createSelector([selectEntityList], function (entityList) { if (!entityList) return null; return { sortBy: entityList.sortBy, sortDir: entityList.sortDir, sortType: entityList.sortType, timeFrame: entityList.timeFrame, userId: entityList.userId, followedOnly: entityList.followedOnly, keywordsFilters: entityList.keywordsFilters, titleFilters: entityList.titleFilters, contentFilters: entityList.contentFilters, attachmentsFilters: entityList.attachmentsFilters, locationFilters: entityList.locationFilters, metadataFilters: entityList.metadataFilters, }; }); export var selectEntityListConfig = createSelector([selectEntityList], function (entityList) { if (!entityList) return null; return { sourceId: entityList.sourceId, limit: entityList.limit, }; }); export default entityListsSlice.reducer; //# sourceMappingURL=entityListsSlice.js.map