UNPKG

@tanstack/solid-router

Version:

Modern and scalable routing for Solid applications

1 lines 3.68 kB
{"version":3,"file":"routerStores.cjs","names":[],"sources":["../../src/routerStores.ts"],"sourcesContent":["import * as Solid from 'solid-js'\nimport {\n createNonReactiveMutableStore,\n createNonReactiveReadonlyStore,\n} from '@tanstack/router-core'\nimport { isServer } from '@tanstack/router-core/isServer'\nimport type {\n GetStoreConfig,\n RouterReadableStore,\n RouterWritableStore,\n} from '@tanstack/router-core'\n\nexport const getStoreFactory: GetStoreConfig = (opts) => {\n if (isServer ?? opts.isServer) {\n return {\n createMutableStore: createNonReactiveMutableStore,\n createReadonlyStore: createNonReactiveReadonlyStore,\n batch: (fn) => fn(),\n }\n }\n\n // router-core writes stores and re-reads them synchronously mid-pipeline,\n // but Solid 2 defers signal commits to its scheduler. Rather than forcing a\n // full synchronous flush after every core batch (which runs all effects,\n // including renders, several times per navigation), each store keeps a\n // synchronous shadow of its eventual settled value and serves it until the\n // scheduler catches up. The reactive graph settles on its own schedule; the\n // one explicit flush per navigation is the settle point in `startTransition`.\n let writeEpoch = 0\n\n function createSolidMutableStore<TValue>(\n initialValue: TValue,\n ): RouterWritableStore<TValue> {\n const [signal, setSignal] = Solid.createSignal(initialValue as any)\n let current = initialValue\n let dirty = false\n\n return {\n get: () => {\n const settled = signal()\n // `current` is always the post-flush value, so once the signal\n // catches up the shadow can retire until the next write.\n if (dirty && settled === current) dirty = false\n return dirty ? current : settled\n },\n set: (next: TValue | ((prev: TValue) => TValue)) => {\n current =\n typeof next === 'function'\n ? (next as (prev: TValue) => TValue)(current)\n : next\n dirty = true\n writeEpoch++\n setSignal(() => current)\n },\n }\n }\n\n function createSolidReadonlyStore<TValue>(\n read: () => TValue,\n ): RouterReadableStore<TValue> {\n const memo = Solid.createRoot(() => Solid.createMemo(read))\n let cache: TValue\n let cachedAt = -1\n\n return {\n get: () => {\n // The memo carries reactive subscriptions; the served value comes\n // from the epoch cache so it is fresh before the scheduler settles\n // and identity-stable across flushes that change nothing.\n memo()\n if (cachedAt !== writeEpoch) {\n cache = Solid.untrack(read)\n cachedAt = writeEpoch\n }\n return cache\n },\n }\n }\n\n return {\n createMutableStore: createSolidMutableStore,\n createReadonlyStore: createSolidReadonlyStore,\n batch: (fn) => fn(),\n }\n}\n"],"mappings":";;;;;;AAYA,IAAa,mBAAmC,SAAS;CACvD,IAAI,+BAAA,YAAY,KAAK,UACnB,OAAO;EACL,oBAAoB,sBAAA;EACpB,qBAAqB,sBAAA;EACrB,QAAQ,OAAO,GAAG;CACpB;CAUF,IAAI,aAAa;CAEjB,SAAS,wBACP,cAC6B;EAC7B,MAAM,CAAC,QAAQ,aAAa,SAAM,aAAa,YAAmB;EAClE,IAAI,UAAU;EACd,IAAI,QAAQ;EAEZ,OAAO;GACL,WAAW;IACT,MAAM,UAAU,OAAO;IAGvB,IAAI,SAAS,YAAY,SAAS,QAAQ;IAC1C,OAAO,QAAQ,UAAU;GAC3B;GACA,MAAM,SAA8C;IAClD,UACE,OAAO,SAAS,aACX,KAAkC,OAAO,IAC1C;IACN,QAAQ;IACR;IACA,gBAAgB,OAAO;GACzB;EACF;CACF;CAEA,SAAS,yBACP,MAC6B;EAC7B,MAAM,OAAO,SAAM,iBAAiB,SAAM,WAAW,IAAI,CAAC;EAC1D,IAAI;EACJ,IAAI,WAAW;EAEf,OAAO,EACL,WAAW;GAIT,KAAK;GACL,IAAI,aAAa,YAAY;IAC3B,QAAQ,SAAM,QAAQ,IAAI;IAC1B,WAAW;GACb;GACA,OAAO;EACT,EACF;CACF;CAEA,OAAO;EACL,oBAAoB;EACpB,qBAAqB;EACrB,QAAQ,OAAO,GAAG;CACpB;AACF"}