'use client'; // This allows us to send serialized json from the server to the client using 'useServerInsertedHTML' // We are allowed to send whatever json we want, however it must be triggered at the same time as the client is recieving new html to display // after a suspsense boundary resolves // We do this to send a list of triples and attrs for each query that the server made so they can be pre-filled on the client render. // useServerInsertedHTML is called whenever a suspense boundary resolves, resulting in new html being streamed down to the client. export const isServer = typeof window === 'undefined' || 'Deno' in globalThis; import { useServerInsertedHTML } from 'next/navigation.js'; import * as React from 'react'; import { htmlEscapeJsonString } from './htmlescape.js'; const serializedSymbol = Symbol('serialized'); interface DataTransformer { serialize: (object: any) => any; deserialize: (object: any) => any; } type Serialized = unknown & { [serializedSymbol]: TData; }; interface TypedDataTransformer { serialize: (obj: TData) => Serialized; deserialize: (obj: Serialized) => TData; } interface HydrationStreamContext { id: string; stream: { /** * **Server method** * Push a new entry to the stream * Will be ignored on the client */ push: (...shape: Array) => void; }; } export interface HydrationStreamProviderProps { children: React.ReactNode; /** * Optional transformer to serialize/deserialize the data * Example devalue, superjson et al */ transformer?: DataTransformer; /** * **Client method** * Called in the browser when new entries are received */ onEntries: (entries: Array) => void; /** * **Server method** * onFlush is called on the server when the cache is flushed */ onFlush?: () => Array; /** * A nonce that'll allow the inline script to be executed when Content Security Policy is enforced */ nonce?: string; } export function createHydrationStreamProvider() { const context = React.createContext>( null as any, ); /** * 1. (Happens on server): `useServerInsertedHTML()` is called **on the server** whenever a `Suspense`-boundary completes * - This means that we might have some new entries in the cache that needs to be flushed * - We pass these to the client by inserting a `