{"version":3,"file":"stores.cjs","names":[],"sources":["../../src/stores.ts"],"sourcesContent":["import { arraysEqual, functionalUpdate } from './utils'\n\nimport type { AnyRoute } from './route'\nimport type { RouterState } from './router'\nimport type { FullSearchSchema } from './routeInfo'\nimport type { ParsedLocation } from './location'\nimport type { AnyRouteMatch } from './Matches'\n\nexport interface RouterReadableStore<TValue> {\n  get: () => TValue\n}\n\nexport interface RouterWritableStore<\n  TValue,\n> extends RouterReadableStore<TValue> {\n  set: ((updater: (prev: TValue) => TValue) => void) & ((value: TValue) => void)\n}\n\nexport type RouterBatchFn = (fn: () => void) => void\n\nexport type MutableStoreFactory = <TValue>(\n  initialValue: TValue,\n) => RouterWritableStore<TValue>\n\nexport type ReadonlyStoreFactory = <TValue>(\n  read: () => TValue,\n) => RouterReadableStore<TValue>\n\nexport type GetStoreConfig = (opts: { isServer?: boolean }) => StoreConfig\n\nexport type StoreConfig = {\n  createMutableStore: MutableStoreFactory\n  createReadonlyStore: ReadonlyStoreFactory\n  batch: RouterBatchFn\n}\n\ntype MatchStore = RouterWritableStore<AnyRouteMatch | undefined>\ntype ReadableStore<TValue> = RouterReadableStore<TValue>\n\n/** SSR non-reactive createMutableStore */\nexport function createNonReactiveMutableStore<TValue>(\n  initialValue: TValue,\n): RouterWritableStore<TValue> {\n  let value = initialValue\n\n  return {\n    get() {\n      return value\n    },\n    set(nextOrUpdater: TValue | ((prev: TValue) => TValue)) {\n      value = functionalUpdate(nextOrUpdater, value)\n    },\n  }\n}\n\n/** SSR non-reactive createReadonlyStore */\nexport function createNonReactiveReadonlyStore<TValue>(\n  read: () => TValue,\n): RouterReadableStore<TValue> {\n  return {\n    get() {\n      return read()\n    },\n  }\n}\n\nexport interface RouterStores<in out TRouteTree extends AnyRoute> {\n  status: RouterWritableStore<RouterState<TRouteTree>['status']>\n  location: RouterWritableStore<ParsedLocation<FullSearchSchema<TRouteTree>>>\n  resolvedLocation: RouterWritableStore<\n    ParsedLocation<FullSearchSchema<TRouteTree>> | undefined\n  >\n  ids: RouterWritableStore<Array<string>>\n  matches: ReadableStore<Array<AnyRouteMatch>>\n  __store: RouterReadableStore<RouterState<TRouteTree>>\n\n  byRoute: Map<string, MatchStore>\n\n  /**\n   * Get the stable atom for a route's presented match. The atom remains in the\n   * pool when the route leaves and contains `undefined` until it re-enters.\n   */\n  getMatchStore: (\n    routeId: string,\n  ) => RouterReadableStore<AnyRouteMatch | undefined>\n\n  setMatches: (nextMatches: Array<AnyRouteMatch>) => void\n}\n\nexport function createRouterStores<TRouteTree extends AnyRoute>(\n  initialLocation: RouterState<TRouteTree>['location'],\n  config: StoreConfig,\n): RouterStores<TRouteTree> {\n  const { createMutableStore, createReadonlyStore, batch } = config\n\n  // non reactive utilities\n  const byRoute = new Map<string, MatchStore>()\n\n  // atoms\n  const status = createMutableStore<RouterState<TRouteTree>['status']>('idle')\n  const location = createMutableStore(initialLocation)\n  const resolvedLocation =\n    createMutableStore<RouterState<TRouteTree>['resolvedLocation']>(undefined)\n  const ids = createMutableStore<Array<string>>([])\n\n  // 1st order derived stores\n  const matches = createReadonlyStore(() =>\n    ids.get().map((id) => byRoute.get(id)!.get()!),\n  )\n\n  // compatibility \"big\" state store\n  const __store = createReadonlyStore(() => ({\n    status: status.get(),\n    isLoading: status.get() === 'pending',\n    matches: matches.get(),\n    location: location.get(),\n    resolvedLocation: resolvedLocation.get(),\n  }))\n\n  function getMatchStore(routeId: string): MatchStore {\n    let matchStore = byRoute.get(routeId)\n    if (!matchStore) {\n      matchStore = createMutableStore<AnyRouteMatch | undefined>(undefined)\n      byRoute.set(routeId, matchStore)\n    }\n    return matchStore\n  }\n\n  const store = {\n    // atoms\n    status,\n    location,\n    resolvedLocation,\n    ids,\n\n    // derived\n    matches,\n\n    // non-reactive state\n    byRoute,\n\n    // compatibility \"big\" state\n    __store,\n\n    // stable per-route presentation atoms\n    getMatchStore,\n\n    // methods\n    setMatches,\n  }\n\n  // setters to update non-reactive utilities in sync with the reactive stores\n  function setMatches(nextMatches: Array<AnyRouteMatch>) {\n    const previousIds = ids.get()\n    const nextIds = nextMatches.map((match) => match.routeId)\n\n    batch(() => {\n      // Publish lane membership first so framework trees reconcile departures\n      // before observers of a leaving route receive its tombstone.\n      if (!arraysEqual(previousIds, nextIds)) {\n        ids.set(nextIds)\n      }\n\n      for (const id of previousIds) {\n        if (!nextIds.includes(id)) {\n          byRoute.get(id)!.set(() => undefined)\n        }\n      }\n\n      for (const nextMatch of nextMatches) {\n        const matchStore = getMatchStore(nextMatch.routeId)\n        if (matchStore.get() !== nextMatch) {\n          matchStore.set(nextMatch)\n        }\n      }\n    })\n  }\n\n  return store\n}\n"],"mappings":";;;AAwCA,SAAgB,8BACd,cAC6B;CAC7B,IAAI,QAAQ;CAEZ,OAAO;EACL,MAAM;GACJ,OAAO;EACT;EACA,IAAI,eAAoD;GACtD,QAAQ,cAAA,iBAAiB,eAAe,KAAK;EAC/C;CACF;AACF;;AAGA,SAAgB,+BACd,MAC6B;CAC7B,OAAO,EACL,MAAM;EACJ,OAAO,KAAK;CACd,EACF;AACF;AAyBA,SAAgB,mBACd,iBACA,QAC0B;CAC1B,MAAM,EAAE,oBAAoB,qBAAqB,UAAU;CAG3D,MAAM,0BAAU,IAAI,IAAwB;CAG5C,MAAM,SAAS,mBAAsD,MAAM;CAC3E,MAAM,WAAW,mBAAmB,eAAe;CACnD,MAAM,mBACJ,mBAAgE,KAAA,CAAS;CAC3E,MAAM,MAAM,mBAAkC,CAAC,CAAC;CAGhD,MAAM,UAAU,0BACd,IAAI,IAAI,EAAE,KAAK,OAAO,QAAQ,IAAI,EAAE,EAAG,IAAI,CAAE,CAC/C;CAGA,MAAM,UAAU,2BAA2B;EACzC,QAAQ,OAAO,IAAI;EACnB,WAAW,OAAO,IAAI,MAAM;EAC5B,SAAS,QAAQ,IAAI;EACrB,UAAU,SAAS,IAAI;EACvB,kBAAkB,iBAAiB,IAAI;CACzC,EAAE;CAEF,SAAS,cAAc,SAA6B;EAClD,IAAI,aAAa,QAAQ,IAAI,OAAO;EACpC,IAAI,CAAC,YAAY;GACf,aAAa,mBAA8C,KAAA,CAAS;GACpE,QAAQ,IAAI,SAAS,UAAU;EACjC;EACA,OAAO;CACT;CAEA,MAAM,QAAQ;EAEZ;EACA;EACA;EACA;EAGA;EAGA;EAGA;EAGA;EAGA;CACF;CAGA,SAAS,WAAW,aAAmC;EACrD,MAAM,cAAc,IAAI,IAAI;EAC5B,MAAM,UAAU,YAAY,KAAK,UAAU,MAAM,OAAO;EAExD,YAAY;GAGV,IAAI,CAAC,cAAA,YAAY,aAAa,OAAO,GACnC,IAAI,IAAI,OAAO;GAGjB,KAAK,MAAM,MAAM,aACf,IAAI,CAAC,QAAQ,SAAS,EAAE,GACtB,QAAQ,IAAI,EAAE,EAAG,UAAU,KAAA,CAAS;GAIxC,KAAK,MAAM,aAAa,aAAa;IACnC,MAAM,aAAa,cAAc,UAAU,OAAO;IAClD,IAAI,WAAW,IAAI,MAAM,WACvB,WAAW,IAAI,SAAS;GAE5B;EACF,CAAC;CACH;CAEA,OAAO;AACT"}