{"version":3,"file":"suspendingReader.cjs","names":["React"],"sources":["../../../src/server/suspendingReader.ts"],"sourcesContent":["import React from 'react';\n\ntype AsyncRungStore<T> = {\n  status: 'pending' | 'resolved' | 'rejected';\n  value?: T;\n  error?: unknown;\n  promise?: Promise<void>;\n};\n\n/**\n * Turns an async loader into a synchronous reader that suspends until the\n * value is available, without going through `React.use`.\n *\n * `React.use` matches its per-component state positionally across suspense\n * retries, so a `use()` call whose condition can change between attempts\n * (here: the server context is seeded by the provider concurrently with the\n * page render) shifts the index and hands a later `use()` — such as the\n * dynamic dictionary chunk loader — the wrong promise's value. Throwing the\n * promise ourselves and caching the settlement in a request-scoped store\n * keeps the suspension mechanics without touching React's positional state,\n * which makes the ambient chain safe to run conditionally.\n *\n * Requires `React.cache` for per-request isolation; without it (React < 19)\n * the reader reports `undefined` so callers fall back to the default locale,\n * matching the previous behavior.\n */\nexport const createSuspendingReader = <T>(\n  load: () => Promise<T | undefined>\n): (() => T | undefined) => {\n  if (typeof React.cache !== 'function') return () => undefined;\n\n  const getStore = React.cache(\n    (): AsyncRungStore<T | undefined> => ({ status: 'pending' })\n  );\n\n  return (): T | undefined => {\n    const store = getStore();\n\n    // Suspending is only safe when the store survives the retry: React replays\n    // the component from the top, so a cache that hands back a fresh store\n    // every call would restart the load and throw a new promise forever. That\n    // is what `React.cache` degrades to outside a request scope — notably in\n    // the SSR pass of client components, where it is a passthrough. Reporting\n    // no value there lets the caller fall back instead of hanging the render.\n    if (getStore() !== store) return undefined;\n\n    if (store.status === 'resolved') return store.value;\n    if (store.status === 'rejected') throw store.error;\n\n    if (!store.promise) {\n      store.promise = load().then(\n        (value) => {\n          store.value = value;\n          store.status = 'resolved';\n        },\n        (error) => {\n          store.error = error;\n          store.status = 'rejected';\n        }\n      );\n    }\n\n    // Suspend: React retries the component once the promise settles.\n    throw store.promise;\n  };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,MAAa,0BACX,SAC0B;CAC1B,IAAI,OAAOA,cAAM,UAAU,YAAY,aAAa;CAEpD,MAAM,WAAWA,cAAM,aACiB,EAAE,QAAQ,UAAU,EAC5D;CAEA,aAA4B;EAC1B,MAAM,QAAQ,SAAS;EAQvB,IAAI,SAAS,MAAM,OAAO,OAAO;EAEjC,IAAI,MAAM,WAAW,YAAY,OAAO,MAAM;EAC9C,IAAI,MAAM,WAAW,YAAY,MAAM,MAAM;EAE7C,IAAI,CAAC,MAAM,SACT,MAAM,UAAU,KAAK,CAAC,CAAC,MACpB,UAAU;GACT,MAAM,QAAQ;GACd,MAAM,SAAS;EACjB,IACC,UAAU;GACT,MAAM,QAAQ;GACd,MAAM,SAAS;EACjB,CACF;EAIF,MAAM,MAAM;CACd;AACF"}