UNPKG

6.85 kBSource Map (JSON)View Raw
1{"version":3,"file":"useSyncExternalStore.js","sourceRoot":"","sources":["../../../src/react/hooks/useSyncExternalStore.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,IAAI,0BAA0B,GAAG,KAAK,CAAC;AAYvC,IAAM,OAAO,GAAG,sBAA4C,CAAC;AAC7D,IAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAmC,CAAC;AAMlE,MAAM,CAAC,IAAM,oBAAoB,GAAuB,QAAQ,IAAI,CAAC,UACnE,SAAS,EACT,WAAW,EACX,iBAAiB;IAMjB,IAAM,KAAK,GAAG,WAAW,EAAE,CAAC;IAC5B,IAEE,OAAO;QACP,CAAC,0BAA0B;QAG3B,KAAK,KAAK,WAAW,EAAE,EACvB;QACA,0BAA0B,GAAG,IAAI,CAAC;QAElC,SAAS,CAAC,KAAK,CACb,sEAAsE,CACvE,CAAC;KACH;IAgBK,IAAA,KAAwB,KAAK,CAAC,QAAQ,CAAC,EAAC,IAAI,EAAE,EAAC,KAAK,OAAA,EAAE,WAAW,aAAA,EAAC,EAAC,CAAC,EAAlE,IAAI,aAAA,EAAG,WAAW,QAAgD,CAAC;IAK3E,IAAI,kBAAkB,EAAE;QAKtB,KAAK,CAAC,eAAe,CAAC;YACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,OAAA,EAAE,WAAW,aAAA,EAAE,CAAC,CAAC;YAK5C,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE;gBAEhC,WAAW,CAAC,EAAC,IAAI,MAAA,EAAC,CAAC,CAAC;aACrB;QACH,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;KACrC;SAAM;QACL,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,KAAK,OAAA,EAAE,WAAW,aAAA,EAAE,CAAC,CAAC;KAC7C;IAED,KAAK,CAAC,SAAS,CAAC;QAGd,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE;YAEhC,WAAW,CAAC,EAAC,IAAI,MAAA,EAAC,CAAC,CAAC;SACrB;QAGD,OAAO,SAAS,CAAC,SAAS,iBAAiB;YAQzC,IAAI,sBAAsB,CAAC,IAAI,CAAC,EAAE;gBAEhC,WAAW,CAAC,EAAC,IAAI,MAAA,EAAC,CAAC,CAAC;aACrB;QACH,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;IAEhB,OAAO,KAAK,CAAC;AACf,CAAC,CAAC,CAAC;AAEH,SAAS,sBAAsB,CAAW,EAMzC;QALC,KAAK,WAAA,EACL,WAAW,iBAAA;IAKX,IAAI;QACF,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;KAChC;IAAC,WAAM;QACN,OAAO,IAAI,CAAC;KACb;AACH,CAAC","sourcesContent":["import { invariant } from '../../utilities/globals';\nimport * as React from 'react';\n\nimport { canUseLayoutEffect } from '../../utilities';\n\nlet didWarnUncachedGetSnapshot = false;\n\ntype RealUseSESHookType =\n // This import depends only on the @types/use-sync-external-store package, not\n // the actual use-sync-external-store package, which is not installed. It\n // might be nice to get this type from React 18, but it still needs to work\n // when only React 17 or earlier is installed.\n typeof import(\"use-sync-external-store\").useSyncExternalStore;\n\n// Prevent webpack from complaining about our feature detection of the\n// useSyncExternalStore property of the React namespace, which is expected not\n// to exist when using React 17 and earlier, and that's fine.\nconst uSESKey = \"useSyncExternalStore\" as keyof typeof React;\nconst realHook = React[uSESKey] as RealUseSESHookType | undefined;\n\n// Adapted from https://www.npmjs.com/package/use-sync-external-store, with\n// Apollo Client deviations called out by \"// DEVIATION ...\" comments.\n\n// When/if React.useSyncExternalStore is defined, delegate fully to it.\nexport const useSyncExternalStore: RealUseSESHookType = realHook || ((\n subscribe,\n getSnapshot,\n getServerSnapshot,\n) => {\n // Read the current snapshot from the store on every render. Again, this\n // breaks the rules of React, and only works here because of specific\n // implementation details, most importantly that updates are\n // always synchronous.\n const value = getSnapshot();\n if (\n // DEVIATION: Using our own __DEV__ polyfill (from ../../utilities/globals).\n __DEV__ &&\n !didWarnUncachedGetSnapshot &&\n // DEVIATION: Not using Object.is because we know our snapshots will never\n // be exotic primitive values like NaN, which is !== itself.\n value !== getSnapshot()\n ) {\n didWarnUncachedGetSnapshot = true;\n // DEVIATION: Using invariant.error instead of console.error directly.\n invariant.error(\n 'The result of getSnapshot should be cached to avoid an infinite loop',\n );\n }\n\n // Because updates are synchronous, we don't queue them. Instead we force a\n // re-render whenever the subscribed state changes by updating an some\n // arbitrary useState hook. Then, during render, we call getSnapshot to read\n // the current value.\n //\n // Because we don't actually use the state returned by the useState hook, we\n // can save a bit of memory by storing other stuff in that slot.\n //\n // To implement the early bailout, we need to track some things on a mutable\n // object. Usually, we would put that in a useRef hook, but we can stash it in\n // our useState hook instead.\n //\n // To force a re-render, we call forceUpdate({inst}). That works because the\n // new object always fails an equality check.\n const [{inst}, forceUpdate] = React.useState({inst: {value, getSnapshot}});\n\n // Track the latest getSnapshot function with a ref. This needs to be updated\n // in the layout phase so we can access it during the tearing check that\n // happens on subscribe.\n if (canUseLayoutEffect) {\n // DEVIATION: We avoid calling useLayoutEffect when !canUseLayoutEffect,\n // which may seem like a conditional hook, but this code ends up behaving\n // unconditionally (one way or the other) because canUseLayoutEffect is\n // constant.\n React.useLayoutEffect(() => {\n Object.assign(inst, { value, getSnapshot });\n // Whenever getSnapshot or subscribe changes, we need to check in the\n // commit phase if there was an interleaved mutation. In concurrent mode\n // this can happen all the time, but even in synchronous mode, an earlier\n // effect may have mutated the store.\n if (checkIfSnapshotChanged(inst)) {\n // Force a re-render.\n forceUpdate({inst});\n }\n }, [subscribe, value, getSnapshot]);\n } else {\n Object.assign(inst, { value, getSnapshot });\n }\n\n React.useEffect(() => {\n // Check for changes right before subscribing. Subsequent changes will be\n // detected in the subscription handler.\n if (checkIfSnapshotChanged(inst)) {\n // Force a re-render.\n forceUpdate({inst});\n }\n\n // Subscribe to the store and return a clean-up function.\n return subscribe(function handleStoreChange() {\n // TODO: Because there is no cross-renderer API for batching updates, it's\n // up to the consumer of this library to wrap their subscription event\n // with unstable_batchedUpdates. Should we try to detect when this isn't\n // the case and print a warning in development?\n\n // The store changed. Check if the snapshot changed since the last time we\n // read from the store.\n if (checkIfSnapshotChanged(inst)) {\n // Force a re-render.\n forceUpdate({inst});\n }\n });\n }, [subscribe]);\n\n return value;\n});\n\nfunction checkIfSnapshotChanged<Snapshot>({\n value,\n getSnapshot,\n}: {\n value: Snapshot;\n getSnapshot: () => Snapshot;\n}): boolean {\n try {\n return value !== getSnapshot();\n } catch {\n return true;\n }\n}\n"]}
\No newline at end of file