{"version":3,"file":"store.mjs","sources":["../../../../src/clients/feed/store.ts"],"sourcesContent":["import { GenericData } from \"@knocklabs/types\";\nimport { Store } from \"@tanstack/store\";\n\nimport { NetworkStatus } from \"../../networkStatus\";\n\nimport { FeedItem, FeedMetadata, FeedResponse } from \"./interfaces\";\nimport { FeedStoreState, StoreFeedResultOptions } from \"./types\";\nimport { deduplicateItems, sortItems } from \"./utils\";\n\nfunction processItems(items: FeedItem[]) {\n  const deduped = deduplicateItems(items);\n  const sorted = sortItems(deduped);\n\n  return sorted;\n}\n\nconst defaultSetResultOptions = {\n  shouldSetPage: true,\n  shouldAppend: false,\n};\n\nexport const initialStoreState: FeedStoreState = {\n  items: [],\n  metadata: {\n    total_count: 0,\n    unread_count: 0,\n    unseen_count: 0,\n  },\n  pageInfo: {\n    before: null,\n    after: null,\n    page_size: 50,\n  },\n  loading: false,\n  networkStatus: NetworkStatus.ready,\n  setResult: () => {},\n  setMetadata: () => {},\n  setNetworkStatus: () => {},\n  resetStore: () => {},\n  setItemAttrs: () => {},\n};\n\n/**\n * Initalize the store with tanstack store so it can be used within our\n * FeedStore class. We do this seperately so that we have the ability to\n * change which store library we use in the future if need be.\n */\nconst initalizeStore = () => {\n  const store = new Store(initialStoreState);\n\n  store.setState((state) => ({\n    ...state,\n    // The network status indicates what's happening with the request\n    networkStatus: NetworkStatus.ready,\n    loading: false,\n    setNetworkStatus: (networkStatus: NetworkStatus) =>\n      store.setState((state) => ({\n        ...state,\n        networkStatus,\n        loading: networkStatus === NetworkStatus.loading,\n      })),\n\n    setResult: (\n      { entries, meta, page_info }: FeedResponse,\n      options: StoreFeedResultOptions = defaultSetResultOptions,\n    ) =>\n      store.setState((state) => {\n        // We resort the list on set, so concating everything is fine (if a bit suboptimal)\n        const items = options.shouldAppend\n          ? processItems(state.items.concat(entries as FeedItem<GenericData>[]))\n          : entries;\n\n        return {\n          ...state,\n          items,\n          metadata: meta,\n          pageInfo: options.shouldSetPage ? page_info : state.pageInfo,\n          loading: false,\n          networkStatus: NetworkStatus.ready,\n        };\n      }),\n\n    setMetadata: (metadata: FeedMetadata) =>\n      store.setState((state) => ({ ...state, metadata })),\n\n    resetStore: (metadata = initialStoreState.metadata) =>\n      store.setState(() => ({\n        ...initialStoreState,\n        setResult: store.state.setResult,\n        setMetadata: store.state.setMetadata,\n        setNetworkStatus: store.state.setNetworkStatus,\n        resetStore: store.state.resetStore,\n        setItemAttrs: store.state.setItemAttrs,\n        metadata,\n      })),\n\n    setItemAttrs: (itemIds: Array<string>, attrs: object) => {\n      // Create a map for the items to the updates to be made\n      const itemUpdatesMap: { [id: string]: object } = itemIds.reduce(\n        (acc, itemId) => ({ ...acc, [itemId]: attrs }),\n        {},\n      );\n\n      return store.setState((state) => {\n        const items = state.items.map((item) => {\n          if (itemUpdatesMap[item.id]) {\n            return { ...item, ...itemUpdatesMap[item.id] };\n          }\n\n          return item;\n        });\n\n        return { ...state, items };\n      });\n    },\n  }));\n\n  return store;\n};\n\n/**\n * The FeedStore class is a wrapper for our store solution that's\n * based on the same shape as zustand. This wrapping class allows\n * us to maintain backwards compatibility with the zustand model\n * while still allowing us to utilize tanstack store for the\n * underlying store solution.\n */\nexport class FeedStore {\n  store: Store<FeedStoreState>;\n\n  constructor(store: Store<FeedStoreState>) {\n    this.store = store;\n  }\n\n  getState() {\n    return this.store.state;\n  }\n\n  setState(\n    updater: ((state: FeedStoreState) => FeedStoreState) | FeedStoreState,\n  ) {\n    this.store.setState(\n      typeof updater === \"function\" ? updater : () => updater,\n    );\n  }\n\n  getInitialState() {\n    return initialStoreState;\n  }\n\n  subscribe(listener: (state: FeedStoreState) => void) {\n    return this.store.subscribe((state) => listener(state.currentVal));\n  }\n}\n\nexport default function createStore() {\n  const store = initalizeStore();\n  return new FeedStore(store);\n}\n"],"names":["processItems","items","deduped","deduplicateItems","sortItems","defaultSetResultOptions","initialStoreState","NetworkStatus","initalizeStore","store","Store","state","networkStatus","entries","meta","page_info","options","metadata","itemIds","attrs","itemUpdatesMap","acc","itemId","item","FeedStore","__publicField","updater","listener","createStore"],"mappings":"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"}