@tanstack/react-query-next-experimental 5.20.1 → 5.20.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/build/legacy/HydrationStreamProvider.cjs +5 -4
  2. package/build/legacy/HydrationStreamProvider.cjs.map +1 -1
  3. package/build/legacy/HydrationStreamProvider.d.cts +2 -1
  4. package/build/legacy/HydrationStreamProvider.d.ts +2 -1
  5. package/build/legacy/HydrationStreamProvider.js +5 -4
  6. package/build/legacy/HydrationStreamProvider.js.map +1 -1
  7. package/build/legacy/ReactQueryStreamedHydration.cjs +5 -4
  8. package/build/legacy/ReactQueryStreamedHydration.cjs.map +1 -1
  9. package/build/legacy/ReactQueryStreamedHydration.d.cts +2 -1
  10. package/build/legacy/ReactQueryStreamedHydration.d.ts +2 -1
  11. package/build/legacy/ReactQueryStreamedHydration.js +5 -4
  12. package/build/legacy/ReactQueryStreamedHydration.js.map +1 -1
  13. package/build/legacy/index.d.cts +1 -0
  14. package/build/legacy/index.d.ts +1 -0
  15. package/build/modern/HydrationStreamProvider.cjs +5 -4
  16. package/build/modern/HydrationStreamProvider.cjs.map +1 -1
  17. package/build/modern/HydrationStreamProvider.d.cts +2 -1
  18. package/build/modern/HydrationStreamProvider.d.ts +2 -1
  19. package/build/modern/HydrationStreamProvider.js +5 -4
  20. package/build/modern/HydrationStreamProvider.js.map +1 -1
  21. package/build/modern/ReactQueryStreamedHydration.cjs +5 -4
  22. package/build/modern/ReactQueryStreamedHydration.cjs.map +1 -1
  23. package/build/modern/ReactQueryStreamedHydration.d.cts +2 -1
  24. package/build/modern/ReactQueryStreamedHydration.d.ts +2 -1
  25. package/build/modern/ReactQueryStreamedHydration.js +5 -4
  26. package/build/modern/ReactQueryStreamedHydration.js.map +1 -1
  27. package/build/modern/index.d.cts +1 -0
  28. package/build/modern/index.d.ts +1 -0
  29. package/package.json +4 -4
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(HydrationStreamProvider_exports);
37
37
  var import_navigation = require("next/navigation");
38
38
  var React = __toESM(require("react"), 1);
39
39
  var import_htmlescape = require("./htmlescape.cjs");
40
+ var import_jsx_runtime = require("react/jsx-runtime");
40
41
  var serializedSymbol = Symbol("serialized");
41
42
  function createHydrationStreamProvider() {
42
43
  const context = React.createContext(
@@ -74,14 +75,14 @@ function createHydrationStreamProvider() {
74
75
  `window[${idJSON}] = window[${idJSON}] || [];`,
75
76
  `window[${idJSON}].push(${(0, import_htmlescape.htmlEscapeJsonString)(serializedCacheArgs)});`
76
77
  ];
77
- return /* @__PURE__ */ React.createElement(
78
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
78
79
  "script",
79
80
  {
80
- key: count.current++,
81
81
  dangerouslySetInnerHTML: {
82
82
  __html: html.join("")
83
83
  }
84
- }
84
+ },
85
+ count.current++
85
86
  );
86
87
  });
87
88
  const onEntriesRef = React.useRef(props.onEntries);
@@ -105,7 +106,7 @@ function createHydrationStreamProvider() {
105
106
  win[id] = [];
106
107
  };
107
108
  }, [id, transformer]);
108
- return /* @__PURE__ */ React.createElement(context.Provider, { value: { stream, id } }, props.children);
109
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(context.Provider, { value: { stream, id }, children: props.children });
109
110
  }
110
111
  return {
111
112
  Provider: UseClientHydrationStreamProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAAsC;AACtC,YAAuB;AACvB,wBAAqC;AAErC,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,aAAS,wCAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,iDAAsB,MAAM;AA7GhC;AA+GM,aAAO,KAAK,KAAI,WAAM,YAAN,mCAAqB,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,cAAU,wCAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oCAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,KACnC,MAAM,QACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAAsC;AACtC,YAAuB;AACvB,wBAAqC;AA8H7B;AA5HR,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,aAAS,wCAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,iDAAsB,MAAM;AA7GhC;AA+GM,aAAO,KAAK,KAAI,WAAM,YAAN,mCAAqB,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,cAAU,wCAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,QAHK,MAAM;AAAA,MAIb;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,4CAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,GACnC,gBAAM,UACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
 
3
4
  interface DataTransformer {
@@ -51,7 +52,7 @@ declare function createHydrationStreamProvider<TShape>(): {
51
52
  * onFlush is called on the server when the cache is flushed
52
53
  */
53
54
  onFlush?: (() => Array<TShape>) | undefined;
54
- }) => React.JSX.Element;
55
+ }) => react_jsx_runtime.JSX.Element;
55
56
  context: React.Context<HydrationStreamContext<TShape>>;
56
57
  };
57
58
 
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
 
3
4
  interface DataTransformer {
@@ -51,7 +52,7 @@ declare function createHydrationStreamProvider<TShape>(): {
51
52
  * onFlush is called on the server when the cache is flushed
52
53
  */
53
54
  onFlush?: (() => Array<TShape>) | undefined;
54
- }) => React.JSX.Element;
55
+ }) => react_jsx_runtime.JSX.Element;
55
56
  context: React.Context<HydrationStreamContext<TShape>>;
56
57
  };
57
58
 
@@ -4,6 +4,7 @@
4
4
  import { useServerInsertedHTML } from "next/navigation";
5
5
  import * as React from "react";
6
6
  import { htmlEscapeJsonString } from "./htmlescape.js";
7
+ import { jsx } from "react/jsx-runtime";
7
8
  var serializedSymbol = Symbol("serialized");
8
9
  function createHydrationStreamProvider() {
9
10
  const context = React.createContext(
@@ -41,14 +42,14 @@ function createHydrationStreamProvider() {
41
42
  `window[${idJSON}] = window[${idJSON}] || [];`,
42
43
  `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`
43
44
  ];
44
- return /* @__PURE__ */ React.createElement(
45
+ return /* @__PURE__ */ jsx(
45
46
  "script",
46
47
  {
47
- key: count.current++,
48
48
  dangerouslySetInnerHTML: {
49
49
  __html: html.join("")
50
50
  }
51
- }
51
+ },
52
+ count.current++
52
53
  );
53
54
  });
54
55
  const onEntriesRef = React.useRef(props.onEntries);
@@ -72,7 +73,7 @@ function createHydrationStreamProvider() {
72
73
  win[id] = [];
73
74
  };
74
75
  }, [id, transformer]);
75
- return /* @__PURE__ */ React.createElement(context.Provider, { value: { stream, id } }, props.children);
76
+ return /* @__PURE__ */ jsx(context.Provider, { value: { stream, id }, children: props.children });
76
77
  }
77
78
  return {
78
79
  Provider: UseClientHydrationStreamProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;AAEA,SAAS,6BAA6B;AACtC,YAAY,WAAW;AACvB,SAAS,4BAA4B;AAErC,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,SAAS,qBAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,0BAAsB,MAAM;AA7GhC;AA+GM,aAAO,KAAK,KAAI,WAAM,YAAN,mCAAqB,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,UAAU,qBAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oCAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,KACnC,MAAM,QACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;AAEA,SAAS,6BAA6B;AACtC,YAAY,WAAW;AACvB,SAAS,4BAA4B;AA8H7B;AA5HR,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,SAAS,qBAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,0BAAsB,MAAM;AA7GhC;AA+GM,aAAO,KAAK,KAAI,WAAM,YAAN,mCAAqB,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,UAAU,qBAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,QAHK,MAAM;AAAA,MAIb;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oBAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,GACnC,gBAAM,UACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(ReactQueryStreamedHydration_exports);
37
37
  var import_react_query = require("@tanstack/react-query");
38
38
  var React = __toESM(require("react"), 1);
39
39
  var import_HydrationStreamProvider = require("./HydrationStreamProvider.cjs");
40
+ var import_jsx_runtime = require("react/jsx-runtime");
40
41
  var stream = (0, import_HydrationStreamProvider.createHydrationStreamProvider)();
41
42
  function ReactQueryStreamedHydration(props) {
42
43
  const queryClient = (0, import_react_query.useQueryClient)(props.queryClient);
@@ -50,7 +51,7 @@ function ReactQueryStreamedHydration(props) {
50
51
  }
51
52
  });
52
53
  }
53
- return /* @__PURE__ */ React.createElement(
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
55
  stream.Provider,
55
56
  {
56
57
  onFlush: () => {
@@ -74,9 +75,9 @@ function ReactQueryStreamedHydration(props) {
74
75
  (0, import_react_query.hydrate)(queryClient, hydratedState, (_a = props.options) == null ? void 0 : _a.hydrate);
75
76
  }
76
77
  },
77
- transformer: props.transformer
78
- },
79
- props.children
78
+ transformer: props.transformer,
79
+ children: props.children
80
+ }
80
81
  );
81
82
  }
82
83
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAKO;AACP,YAAuB;AACvB,qCAA8C;AAS9C,IAAM,aAAS,8DAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,kBAAc,mCAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AA1DrB;AA8DQ,cAAM,oBACJ,iBAAM,YAAN,mBAAe,cAAf,mBAA0B,yBAC1B;AAEF,cAAM,sBAAkB,8BAAU,aAAa;AAAA,UAC7C,IAAG,WAAM,YAAN,mBAAe;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AAjF9B;AAkFQ,mBAAW,iBAAiB,SAAS;AACnC,0CAAQ,aAAa,gBAAe,WAAM,YAAN,mBAAe,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA;AAAA,IAElB,MAAM;AAAA,EACT;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAKO;AACP,YAAuB;AACvB,qCAA8C;AA+C1C;AAtCJ,IAAM,aAAS,8DAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,kBAAc,mCAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AA1DrB;AA8DQ,cAAM,oBACJ,iBAAM,YAAN,mBAAe,cAAf,mBAA0B,yBAC1B;AAEF,cAAM,sBAAkB,8BAAU,aAAa;AAAA,UAC7C,IAAG,WAAM,YAAN,mBAAe;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AAjF9B;AAkFQ,mBAAW,iBAAiB,SAAS;AACnC,0CAAQ,aAAa,gBAAe,WAAM,YAAN,mBAAe,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA,MAElB,gBAAM;AAAA;AAAA,EACT;AAEJ;","names":[]}
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
  import { HydrationStreamProviderProps } from './HydrationStreamProvider.cjs';
3
4
  import { QueryClient, HydrateOptions, DehydrateOptions, DehydratedState } from '@tanstack/react-query';
@@ -15,6 +16,6 @@ declare function ReactQueryStreamedHydration(props: {
15
16
  dehydrate?: DehydrateOptions;
16
17
  };
17
18
  transformer?: HydrationStreamProviderProps<DehydratedState>['transformer'];
18
- }): React.JSX.Element;
19
+ }): react_jsx_runtime.JSX.Element;
19
20
 
20
21
  export { ReactQueryStreamedHydration };
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
  import { HydrationStreamProviderProps } from './HydrationStreamProvider.js';
3
4
  import { QueryClient, HydrateOptions, DehydrateOptions, DehydratedState } from '@tanstack/react-query';
@@ -15,6 +16,6 @@ declare function ReactQueryStreamedHydration(props: {
15
16
  dehydrate?: DehydrateOptions;
16
17
  };
17
18
  transformer?: HydrationStreamProviderProps<DehydratedState>['transformer'];
18
- }): React.JSX.Element;
19
+ }): react_jsx_runtime.JSX.Element;
19
20
 
20
21
  export { ReactQueryStreamedHydration };
@@ -9,6 +9,7 @@ import {
9
9
  } from "@tanstack/react-query";
10
10
  import * as React from "react";
11
11
  import { createHydrationStreamProvider } from "./HydrationStreamProvider.js";
12
+ import { jsx } from "react/jsx-runtime";
12
13
  var stream = createHydrationStreamProvider();
13
14
  function ReactQueryStreamedHydration(props) {
14
15
  const queryClient = useQueryClient(props.queryClient);
@@ -22,7 +23,7 @@ function ReactQueryStreamedHydration(props) {
22
23
  }
23
24
  });
24
25
  }
25
- return /* @__PURE__ */ React.createElement(
26
+ return /* @__PURE__ */ jsx(
26
27
  stream.Provider,
27
28
  {
28
29
  onFlush: () => {
@@ -46,9 +47,9 @@ function ReactQueryStreamedHydration(props) {
46
47
  hydrate(queryClient, hydratedState, (_a = props.options) == null ? void 0 : _a.hydrate);
47
48
  }
48
49
  },
49
- transformer: props.transformer
50
- },
51
- props.children
50
+ transformer: props.transformer,
51
+ children: props.children
52
+ }
52
53
  );
53
54
  }
54
55
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,WAAW;AACvB,SAAS,qCAAqC;AAS9C,IAAM,SAAS,8BAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,cAAc,eAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AA1DrB;AA8DQ,cAAM,oBACJ,iBAAM,YAAN,mBAAe,cAAf,mBAA0B,yBAC1B;AAEF,cAAM,kBAAkB,UAAU,aAAa;AAAA,UAC7C,IAAG,WAAM,YAAN,mBAAe;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AAjF9B;AAkFQ,mBAAW,iBAAiB,SAAS;AACnC,kBAAQ,aAAa,gBAAe,WAAM,YAAN,mBAAe,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA;AAAA,IAElB,MAAM;AAAA,EACT;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,WAAW;AACvB,SAAS,qCAAqC;AA+C1C;AAtCJ,IAAM,SAAS,8BAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,cAAc,eAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AA1DrB;AA8DQ,cAAM,oBACJ,iBAAM,YAAN,mBAAe,cAAf,mBAA0B,yBAC1B;AAEF,cAAM,kBAAkB,UAAU,aAAa;AAAA,UAC7C,IAAG,WAAM,YAAN,mBAAe;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AAjF9B;AAkFQ,mBAAW,iBAAiB,SAAS;AACnC,kBAAQ,aAAa,gBAAe,WAAM,YAAN,mBAAe,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA,MAElB,gBAAM;AAAA;AAAA,EACT;AAEJ;","names":[]}
@@ -1,4 +1,5 @@
1
1
  export { ReactQueryStreamedHydration } from './ReactQueryStreamedHydration.cjs';
2
+ import 'react/jsx-runtime';
2
3
  import 'react';
3
4
  import './HydrationStreamProvider.cjs';
4
5
  import '@tanstack/react-query';
@@ -1,4 +1,5 @@
1
1
  export { ReactQueryStreamedHydration } from './ReactQueryStreamedHydration.js';
2
+ import 'react/jsx-runtime';
2
3
  import 'react';
3
4
  import './HydrationStreamProvider.js';
4
5
  import '@tanstack/react-query';
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(HydrationStreamProvider_exports);
37
37
  var import_navigation = require("next/navigation");
38
38
  var React = __toESM(require("react"), 1);
39
39
  var import_htmlescape = require("./htmlescape.cjs");
40
+ var import_jsx_runtime = require("react/jsx-runtime");
40
41
  var serializedSymbol = Symbol("serialized");
41
42
  function createHydrationStreamProvider() {
42
43
  const context = React.createContext(
@@ -73,14 +74,14 @@ function createHydrationStreamProvider() {
73
74
  `window[${idJSON}] = window[${idJSON}] || [];`,
74
75
  `window[${idJSON}].push(${(0, import_htmlescape.htmlEscapeJsonString)(serializedCacheArgs)});`
75
76
  ];
76
- return /* @__PURE__ */ React.createElement(
77
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
77
78
  "script",
78
79
  {
79
- key: count.current++,
80
80
  dangerouslySetInnerHTML: {
81
81
  __html: html.join("")
82
82
  }
83
- }
83
+ },
84
+ count.current++
84
85
  );
85
86
  });
86
87
  const onEntriesRef = React.useRef(props.onEntries);
@@ -104,7 +105,7 @@ function createHydrationStreamProvider() {
104
105
  win[id] = [];
105
106
  };
106
107
  }, [id, transformer]);
107
- return /* @__PURE__ */ React.createElement(context.Provider, { value: { stream, id } }, props.children);
108
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(context.Provider, { value: { stream, id }, children: props.children });
108
109
  }
109
110
  return {
110
111
  Provider: UseClientHydrationStreamProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAAsC;AACtC,YAAuB;AACvB,wBAAqC;AAErC,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,aAAS,wCAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,iDAAsB,MAAM;AAE1B,aAAO,KAAK,GAAI,MAAM,UAAU,KAAK,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,cAAU,wCAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oCAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,KACnC,MAAM,QACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,wBAAsC;AACtC,YAAuB;AACvB,wBAAqC;AA8H7B;AA5HR,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,aAAS,wCAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,iDAAsB,MAAM;AAE1B,aAAO,KAAK,GAAI,MAAM,UAAU,KAAK,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,cAAU,wCAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,QAHK,MAAM;AAAA,MAIb;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,4CAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,GACnC,gBAAM,UACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
 
3
4
  interface DataTransformer {
@@ -51,7 +52,7 @@ declare function createHydrationStreamProvider<TShape>(): {
51
52
  * onFlush is called on the server when the cache is flushed
52
53
  */
53
54
  onFlush?: (() => Array<TShape>) | undefined;
54
- }) => React.JSX.Element;
55
+ }) => react_jsx_runtime.JSX.Element;
55
56
  context: React.Context<HydrationStreamContext<TShape>>;
56
57
  };
57
58
 
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
 
3
4
  interface DataTransformer {
@@ -51,7 +52,7 @@ declare function createHydrationStreamProvider<TShape>(): {
51
52
  * onFlush is called on the server when the cache is flushed
52
53
  */
53
54
  onFlush?: (() => Array<TShape>) | undefined;
54
- }) => React.JSX.Element;
55
+ }) => react_jsx_runtime.JSX.Element;
55
56
  context: React.Context<HydrationStreamContext<TShape>>;
56
57
  };
57
58
 
@@ -4,6 +4,7 @@
4
4
  import { useServerInsertedHTML } from "next/navigation";
5
5
  import * as React from "react";
6
6
  import { htmlEscapeJsonString } from "./htmlescape.js";
7
+ import { jsx } from "react/jsx-runtime";
7
8
  var serializedSymbol = Symbol("serialized");
8
9
  function createHydrationStreamProvider() {
9
10
  const context = React.createContext(
@@ -40,14 +41,14 @@ function createHydrationStreamProvider() {
40
41
  `window[${idJSON}] = window[${idJSON}] || [];`,
41
42
  `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`
42
43
  ];
43
- return /* @__PURE__ */ React.createElement(
44
+ return /* @__PURE__ */ jsx(
44
45
  "script",
45
46
  {
46
- key: count.current++,
47
47
  dangerouslySetInnerHTML: {
48
48
  __html: html.join("")
49
49
  }
50
- }
50
+ },
51
+ count.current++
51
52
  );
52
53
  });
53
54
  const onEntriesRef = React.useRef(props.onEntries);
@@ -71,7 +72,7 @@ function createHydrationStreamProvider() {
71
72
  win[id] = [];
72
73
  };
73
74
  }, [id, transformer]);
74
- return /* @__PURE__ */ React.createElement(context.Provider, { value: { stream, id } }, props.children);
75
+ return /* @__PURE__ */ jsx(context.Provider, { value: { stream, id }, children: props.children });
75
76
  }
76
77
  return {
77
78
  Provider: UseClientHydrationStreamProvider,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;AAEA,SAAS,6BAA6B;AACtC,YAAY,WAAW;AACvB,SAAS,4BAA4B;AAErC,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,SAAS,qBAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,0BAAsB,MAAM;AAE1B,aAAO,KAAK,GAAI,MAAM,UAAU,KAAK,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,UAAU,qBAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UACC,KAAK,MAAM;AAAA,UACX,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,MACF;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oCAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,KACnC,MAAM,QACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
1
+ {"version":3,"sources":["../../src/HydrationStreamProvider.tsx"],"sourcesContent":["'use client'\n\nimport { useServerInsertedHTML } from 'next/navigation'\nimport * as React from 'react'\nimport { htmlEscapeJsonString } from './htmlescape'\n\nconst serializedSymbol = Symbol('serialized')\n\ninterface DataTransformer {\n serialize: (object: any) => any\n deserialize: (object: any) => any\n}\n\ntype Serialized<TData> = unknown & {\n [serializedSymbol]: TData\n}\n\ninterface TypedDataTransformer<TData> {\n serialize: (obj: TData) => Serialized<TData>\n deserialize: (obj: Serialized<TData>) => TData\n}\n\ninterface HydrationStreamContext<TShape> {\n id: string\n stream: {\n /**\n * **Server method**\n * Push a new entry to the stream\n * Will be ignored on the client\n */\n push: (...shape: Array<TShape>) => void\n }\n}\n\nexport interface HydrationStreamProviderProps<TShape> {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n}\n\nexport function createHydrationStreamProvider<TShape>() {\n const context = React.createContext<HydrationStreamContext<TShape>>(\n null as any,\n )\n /**\n\n * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes\n * - This means that we might have some new entries in the cache that needs to be flushed\n * - We pass these to the client by inserting a `<script>`-tag where we do `window[id].push(serializedVersionOfCache)`\n * 2. (Happens in browser) In `useEffect()`:\n * - We check if `window[id]` is set to an array and call `push()` on all the entries which will call `onEntries()` with the new entries\n * - We replace `window[id]` with a `push()`-method that will be called whenever new entries are received\n **/\n function UseClientHydrationStreamProvider(props: {\n children: React.ReactNode\n /**\n * Optional transformer to serialize/deserialize the data\n * Example devalue, superjson et al\n */\n transformer?: DataTransformer\n /**\n * **Client method**\n * Called in the browser when new entries are received\n */\n onEntries: (entries: Array<TShape>) => void\n /**\n * **Server method**\n * onFlush is called on the server when the cache is flushed\n */\n onFlush?: () => Array<TShape>\n }) {\n // unique id for the cache provider\n const id = `__RQ${React.useId()}`\n const idJSON = htmlEscapeJsonString(JSON.stringify(id))\n\n const [transformer] = React.useState(\n () =>\n (props.transformer ?? {\n // noop\n serialize: (obj: any) => obj,\n deserialize: (obj: any) => obj,\n }) as unknown as TypedDataTransformer<TShape>,\n )\n\n // <server stuff>\n const [stream] = React.useState<Array<TShape>>(() => {\n if (typeof window !== 'undefined') {\n return {\n push() {\n // no-op on the client\n },\n } as unknown as Array<TShape>\n }\n return []\n })\n const count = React.useRef(0)\n useServerInsertedHTML(() => {\n // This only happens on the server\n stream.push(...(props.onFlush?.() ?? []))\n\n if (!stream.length) {\n return null\n }\n // console.log(`pushing ${stream.length} entries`)\n const serializedCacheArgs = stream\n .map((entry) => transformer.serialize(entry))\n .map((entry) => JSON.stringify(entry))\n .join(',')\n\n // Flush stream\n stream.length = 0\n\n const html: Array<string> = [\n `window[${idJSON}] = window[${idJSON}] || [];`,\n `window[${idJSON}].push(${htmlEscapeJsonString(serializedCacheArgs)});`,\n ]\n return (\n <script\n key={count.current++}\n dangerouslySetInnerHTML={{\n __html: html.join(''),\n }}\n />\n )\n })\n // </server stuff>\n\n // <client stuff>\n const onEntriesRef = React.useRef(props.onEntries)\n React.useEffect(() => {\n onEntriesRef.current = props.onEntries\n })\n\n React.useEffect(() => {\n // Client: consume cache:\n const onEntries = (...serializedEntries: Array<Serialized<TShape>>) => {\n const entries = serializedEntries.map((serialized) =>\n transformer.deserialize(serialized),\n )\n onEntriesRef.current(entries)\n }\n\n const win = window as any\n // Register cache consumer\n const winStream: Array<Serialized<TShape>> = win[id] ?? []\n\n onEntries(...winStream)\n\n // Register our own consumer\n win[id] = {\n push: onEntries,\n }\n\n return () => {\n // Cleanup after unmount\n win[id] = []\n }\n }, [id, transformer])\n // </client stuff>\n\n return (\n <context.Provider value={{ stream, id }}>\n {props.children}\n </context.Provider>\n )\n }\n\n return {\n Provider: UseClientHydrationStreamProvider,\n context,\n }\n}\n"],"mappings":";;;AAEA,SAAS,6BAA6B;AACtC,YAAY,WAAW;AACvB,SAAS,4BAA4B;AA8H7B;AA5HR,IAAM,mBAAmB,OAAO,YAAY;AA+CrC,SAAS,gCAAwC;AACtD,QAAM,UAAgB;AAAA,IACpB;AAAA,EACF;AAUA,WAAS,iCAAiC,OAiBvC;AAED,UAAM,KAAK,OAAa,YAAM,CAAC;AAC/B,UAAM,SAAS,qBAAqB,KAAK,UAAU,EAAE,CAAC;AAEtD,UAAM,CAAC,WAAW,IAAU;AAAA,MAC1B,MACG,MAAM,eAAe;AAAA;AAAA,QAEpB,WAAW,CAAC,QAAa;AAAA,QACzB,aAAa,CAAC,QAAa;AAAA,MAC7B;AAAA,IACJ;AAGA,UAAM,CAAC,MAAM,IAAU,eAAwB,MAAM;AACnD,UAAI,OAAO,WAAW,aAAa;AACjC,eAAO;AAAA,UACL,OAAO;AAAA,UAEP;AAAA,QACF;AAAA,MACF;AACA,aAAO,CAAC;AAAA,IACV,CAAC;AACD,UAAM,QAAc,aAAO,CAAC;AAC5B,0BAAsB,MAAM;AAE1B,aAAO,KAAK,GAAI,MAAM,UAAU,KAAK,CAAC,CAAE;AAExC,UAAI,CAAC,OAAO,QAAQ;AAClB,eAAO;AAAA,MACT;AAEA,YAAM,sBAAsB,OACzB,IAAI,CAAC,UAAU,YAAY,UAAU,KAAK,CAAC,EAC3C,IAAI,CAAC,UAAU,KAAK,UAAU,KAAK,CAAC,EACpC,KAAK,GAAG;AAGX,aAAO,SAAS;AAEhB,YAAM,OAAsB;AAAA,QAC1B,UAAU,MAAM,cAAc,MAAM;AAAA,QACpC,UAAU,MAAM,UAAU,qBAAqB,mBAAmB,CAAC;AAAA,MACrE;AACA,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,yBAAyB;AAAA,YACvB,QAAQ,KAAK,KAAK,EAAE;AAAA,UACtB;AAAA;AAAA,QAHK,MAAM;AAAA,MAIb;AAAA,IAEJ,CAAC;AAID,UAAM,eAAqB,aAAO,MAAM,SAAS;AACjD,IAAM,gBAAU,MAAM;AACpB,mBAAa,UAAU,MAAM;AAAA,IAC/B,CAAC;AAED,IAAM,gBAAU,MAAM;AAEpB,YAAM,YAAY,IAAI,sBAAiD;AACrE,cAAM,UAAU,kBAAkB;AAAA,UAAI,CAAC,eACrC,YAAY,YAAY,UAAU;AAAA,QACpC;AACA,qBAAa,QAAQ,OAAO;AAAA,MAC9B;AAEA,YAAM,MAAM;AAEZ,YAAM,YAAuC,IAAI,EAAE,KAAK,CAAC;AAEzD,gBAAU,GAAG,SAAS;AAGtB,UAAI,EAAE,IAAI;AAAA,QACR,MAAM;AAAA,MACR;AAEA,aAAO,MAAM;AAEX,YAAI,EAAE,IAAI,CAAC;AAAA,MACb;AAAA,IACF,GAAG,CAAC,IAAI,WAAW,CAAC;AAGpB,WACE,oBAAC,QAAQ,UAAR,EAAiB,OAAO,EAAE,QAAQ,GAAG,GACnC,gBAAM,UACT;AAAA,EAEJ;AAEA,SAAO;AAAA,IACL,UAAU;AAAA,IACV;AAAA,EACF;AACF;","names":[]}
@@ -37,6 +37,7 @@ module.exports = __toCommonJS(ReactQueryStreamedHydration_exports);
37
37
  var import_react_query = require("@tanstack/react-query");
38
38
  var React = __toESM(require("react"), 1);
39
39
  var import_HydrationStreamProvider = require("./HydrationStreamProvider.cjs");
40
+ var import_jsx_runtime = require("react/jsx-runtime");
40
41
  var stream = (0, import_HydrationStreamProvider.createHydrationStreamProvider)();
41
42
  function ReactQueryStreamedHydration(props) {
42
43
  const queryClient = (0, import_react_query.useQueryClient)(props.queryClient);
@@ -50,7 +51,7 @@ function ReactQueryStreamedHydration(props) {
50
51
  }
51
52
  });
52
53
  }
53
- return /* @__PURE__ */ React.createElement(
54
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
54
55
  stream.Provider,
55
56
  {
56
57
  onFlush: () => {
@@ -72,9 +73,9 @@ function ReactQueryStreamedHydration(props) {
72
73
  (0, import_react_query.hydrate)(queryClient, hydratedState, props.options?.hydrate);
73
74
  }
74
75
  },
75
- transformer: props.transformer
76
- },
77
- props.children
76
+ transformer: props.transformer,
77
+ children: props.children
78
+ }
78
79
  );
79
80
  }
80
81
  // Annotate the CommonJS export names for ESM import in node:
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAKO;AACP,YAAuB;AACvB,qCAA8C;AAS9C,IAAM,aAAS,8DAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,kBAAc,mCAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AAIb,cAAM,kBACJ,MAAM,SAAS,WAAW,wBAC1B;AAEF,cAAM,sBAAkB,8BAAU,aAAa;AAAA,UAC7C,GAAG,MAAM,SAAS;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AACtB,mBAAW,iBAAiB,SAAS;AACnC,0CAAQ,aAAa,eAAe,MAAM,SAAS,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA;AAAA,IAElB,MAAM;AAAA,EACT;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,yBAKO;AACP,YAAuB;AACvB,qCAA8C;AA+C1C;AAtCJ,IAAM,aAAS,8DAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,kBAAc,mCAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AAIb,cAAM,kBACJ,MAAM,SAAS,WAAW,wBAC1B;AAEF,cAAM,sBAAkB,8BAAU,aAAa;AAAA,UAC7C,GAAG,MAAM,SAAS;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AACtB,mBAAW,iBAAiB,SAAS;AACnC,0CAAQ,aAAa,eAAe,MAAM,SAAS,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA,MAElB,gBAAM;AAAA;AAAA,EACT;AAEJ;","names":[]}
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
  import { HydrationStreamProviderProps } from './HydrationStreamProvider.cjs';
3
4
  import { QueryClient, HydrateOptions, DehydrateOptions, DehydratedState } from '@tanstack/react-query';
@@ -15,6 +16,6 @@ declare function ReactQueryStreamedHydration(props: {
15
16
  dehydrate?: DehydrateOptions;
16
17
  };
17
18
  transformer?: HydrationStreamProviderProps<DehydratedState>['transformer'];
18
- }): React.JSX.Element;
19
+ }): react_jsx_runtime.JSX.Element;
19
20
 
20
21
  export { ReactQueryStreamedHydration };
@@ -1,3 +1,4 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
1
2
  import * as React from 'react';
2
3
  import { HydrationStreamProviderProps } from './HydrationStreamProvider.js';
3
4
  import { QueryClient, HydrateOptions, DehydrateOptions, DehydratedState } from '@tanstack/react-query';
@@ -15,6 +16,6 @@ declare function ReactQueryStreamedHydration(props: {
15
16
  dehydrate?: DehydrateOptions;
16
17
  };
17
18
  transformer?: HydrationStreamProviderProps<DehydratedState>['transformer'];
18
- }): React.JSX.Element;
19
+ }): react_jsx_runtime.JSX.Element;
19
20
 
20
21
  export { ReactQueryStreamedHydration };
@@ -9,6 +9,7 @@ import {
9
9
  } from "@tanstack/react-query";
10
10
  import * as React from "react";
11
11
  import { createHydrationStreamProvider } from "./HydrationStreamProvider.js";
12
+ import { jsx } from "react/jsx-runtime";
12
13
  var stream = createHydrationStreamProvider();
13
14
  function ReactQueryStreamedHydration(props) {
14
15
  const queryClient = useQueryClient(props.queryClient);
@@ -22,7 +23,7 @@ function ReactQueryStreamedHydration(props) {
22
23
  }
23
24
  });
24
25
  }
25
- return /* @__PURE__ */ React.createElement(
26
+ return /* @__PURE__ */ jsx(
26
27
  stream.Provider,
27
28
  {
28
29
  onFlush: () => {
@@ -44,9 +45,9 @@ function ReactQueryStreamedHydration(props) {
44
45
  hydrate(queryClient, hydratedState, props.options?.hydrate);
45
46
  }
46
47
  },
47
- transformer: props.transformer
48
- },
49
- props.children
48
+ transformer: props.transformer,
49
+ children: props.children
50
+ }
50
51
  );
51
52
  }
52
53
  export {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,WAAW;AACvB,SAAS,qCAAqC;AAS9C,IAAM,SAAS,8BAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,cAAc,eAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AAIb,cAAM,kBACJ,MAAM,SAAS,WAAW,wBAC1B;AAEF,cAAM,kBAAkB,UAAU,aAAa;AAAA,UAC7C,GAAG,MAAM,SAAS;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AACtB,mBAAW,iBAAiB,SAAS;AACnC,kBAAQ,aAAa,eAAe,MAAM,SAAS,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA;AAAA,IAElB,MAAM;AAAA,EACT;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../src/ReactQueryStreamedHydration.tsx"],"sourcesContent":["'use client'\n\nimport {\n defaultShouldDehydrateQuery,\n dehydrate,\n hydrate,\n useQueryClient,\n} from '@tanstack/react-query'\nimport * as React from 'react'\nimport { createHydrationStreamProvider } from './HydrationStreamProvider'\nimport type { HydrationStreamProviderProps } from './HydrationStreamProvider'\nimport type {\n DehydrateOptions,\n DehydratedState,\n HydrateOptions,\n QueryClient,\n} from '@tanstack/react-query'\n\nconst stream = createHydrationStreamProvider<DehydratedState>()\n\n/**\n * This component is responsible for:\n * - hydrating the query client on the server\n * - dehydrating the query client on the server\n */\nexport function ReactQueryStreamedHydration(props: {\n children: React.ReactNode\n queryClient?: QueryClient\n options?: {\n hydrate?: HydrateOptions\n dehydrate?: DehydrateOptions\n }\n transformer?: HydrationStreamProviderProps<DehydratedState>['transformer']\n}) {\n const queryClient = useQueryClient(props.queryClient)\n\n /**\n * We need to track which queries were added/updated during the render\n */\n const [trackedKeys] = React.useState(() => new Set<string>())\n\n // <server only>\n if (typeof window === 'undefined') {\n // Do we need to care about unsubscribing? I don't think so to be honest\n queryClient.getQueryCache().subscribe((event) => {\n switch (event.type) {\n case 'added':\n case 'updated':\n // console.log('tracking', event.query.queryHash, 'b/c of a', event.type)\n trackedKeys.add(event.query.queryHash)\n }\n })\n }\n // </server only>\n\n return (\n <stream.Provider\n // Happens on server:\n onFlush={() => {\n /**\n * Dehydrated state of the client where we only include the queries that were added/updated since the last flush\n */\n const shouldDehydrate =\n props.options?.dehydrate?.shouldDehydrateQuery ??\n defaultShouldDehydrateQuery\n\n const dehydratedState = dehydrate(queryClient, {\n ...props.options?.dehydrate,\n shouldDehydrateQuery(query) {\n return trackedKeys.has(query.queryHash) && shouldDehydrate(query)\n },\n })\n trackedKeys.clear()\n\n if (!dehydratedState.queries.length) {\n return []\n }\n\n return [dehydratedState]\n }}\n // Happens in browser:\n onEntries={(entries) => {\n for (const hydratedState of entries) {\n hydrate(queryClient, hydratedState, props.options?.hydrate)\n }\n }}\n // Handle BigInts etc using superjson\n transformer={props.transformer}\n >\n {props.children}\n </stream.Provider>\n )\n}\n"],"mappings":";;;AAEA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,YAAY,WAAW;AACvB,SAAS,qCAAqC;AA+C1C;AAtCJ,IAAM,SAAS,8BAA+C;AAOvD,SAAS,4BAA4B,OAQzC;AACD,QAAM,cAAc,eAAe,MAAM,WAAW;AAKpD,QAAM,CAAC,WAAW,IAAU,eAAS,MAAM,oBAAI,IAAY,CAAC;AAG5D,MAAI,OAAO,WAAW,aAAa;AAEjC,gBAAY,cAAc,EAAE,UAAU,CAAC,UAAU;AAC/C,cAAQ,MAAM,MAAM;AAAA,QAClB,KAAK;AAAA,QACL,KAAK;AAEH,sBAAY,IAAI,MAAM,MAAM,SAAS;AAAA,MACzC;AAAA,IACF,CAAC;AAAA,EACH;AAGA,SACE;AAAA,IAAC,OAAO;AAAA,IAAP;AAAA,MAEC,SAAS,MAAM;AAIb,cAAM,kBACJ,MAAM,SAAS,WAAW,wBAC1B;AAEF,cAAM,kBAAkB,UAAU,aAAa;AAAA,UAC7C,GAAG,MAAM,SAAS;AAAA,UAClB,qBAAqB,OAAO;AAC1B,mBAAO,YAAY,IAAI,MAAM,SAAS,KAAK,gBAAgB,KAAK;AAAA,UAClE;AAAA,QACF,CAAC;AACD,oBAAY,MAAM;AAElB,YAAI,CAAC,gBAAgB,QAAQ,QAAQ;AACnC,iBAAO,CAAC;AAAA,QACV;AAEA,eAAO,CAAC,eAAe;AAAA,MACzB;AAAA,MAEA,WAAW,CAAC,YAAY;AACtB,mBAAW,iBAAiB,SAAS;AACnC,kBAAQ,aAAa,eAAe,MAAM,SAAS,OAAO;AAAA,QAC5D;AAAA,MACF;AAAA,MAEA,aAAa,MAAM;AAAA,MAElB,gBAAM;AAAA;AAAA,EACT;AAEJ;","names":[]}
@@ -1,4 +1,5 @@
1
1
  export { ReactQueryStreamedHydration } from './ReactQueryStreamedHydration.cjs';
2
+ import 'react/jsx-runtime';
2
3
  import 'react';
3
4
  import './HydrationStreamProvider.cjs';
4
5
  import '@tanstack/react-query';
@@ -1,4 +1,5 @@
1
1
  export { ReactQueryStreamedHydration } from './ReactQueryStreamedHydration.js';
2
+ import 'react/jsx-runtime';
2
3
  import 'react';
3
4
  import './HydrationStreamProvider.js';
4
5
  import '@tanstack/react-query';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-query-next-experimental",
3
- "version": "5.20.1",
3
+ "version": "5.20.2",
4
4
  "description": "Hydration utils for React Query in the NextJs app directory",
5
5
  "author": "tannerlinsley",
6
6
  "license": "MIT",
@@ -33,16 +33,16 @@
33
33
  "src"
34
34
  ],
35
35
  "devDependencies": {
36
- "@types/react": "^18.2.45",
36
+ "@types/react": "^18.2.55",
37
37
  "@vitejs/plugin-react": "^4.2.1",
38
38
  "next": "^14.0.0",
39
39
  "react": "^18.2.0",
40
- "@tanstack/react-query": "5.20.1"
40
+ "@tanstack/react-query": "5.20.2"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "next": "^13 || ^14",
44
44
  "react": "^18.0.0",
45
- "@tanstack/react-query": "^5.20.1"
45
+ "@tanstack/react-query": "^5.20.2"
46
46
  },
47
47
  "scripts": {
48
48
  "clean": "rimraf ./build && rimraf ./coverage",