UNPKG

@apollo/client-integration-tanstack-start

Version:

This package provides integrations between Apollo Client and TanStack Start to support modern streaming SSR.

246 lines (238 loc) 7.74 kB
'use strict'; var clientReactStreaming = require('@apollo/client-react-streaming'); var react = require('@apollo/client/react'); var React2 = require('react'); var invariant = require('@apollo/client/utilities/invariant'); var routerCore = require('@tanstack/router-core'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var React2__default = /*#__PURE__*/_interopDefault(React2); // src/routerWithApolloClient.tsx // src/bundleInfo.ts var bundle = { pkg: "@apollo/client-integration-tanstack-start", client: "ApolloClient", cache: "InMemoryCache" }; // src/ApolloProvider.tsx var ApolloProvider = ({ client, context, children }) => { return /* @__PURE__ */ React2__default.default.createElement(WrappedApolloProvider, { makeClient: () => client, context }, children); }; var WrappedApolloProvider = clientReactStreaming.WrapApolloProvider((props) => { const transport = props.context.transport; invariant.invariant(transport, "No apolloClientTransport defined"); if ("dispatchRequestStarted" in transport) { invariant.invariant( props.registerDispatchRequestStarted, "Browser bundle loaded in SSR" ); props.registerDispatchRequestStarted(transport.dispatchRequestStarted); } else { invariant.invariant( props.onQueryEvent && props.rerunSimulatedQueries, "SSR bundle loaded in Browser" ); transport.onQueryEvent = props.onQueryEvent; transport.rerunSimulatedQueries = props.rerunSimulatedQueries; } return /* @__PURE__ */ React2__default.default.createElement(clientReactStreaming.DataTransportContext.Provider, { value: transport }, props.children); }); WrappedApolloProvider.info = bundle; var getQueryRefSerializationAdapter = (apolloClient) => routerCore.createSerializationAdapter({ key: "apollo-query-ref", test: clientReactStreaming.isTransportedQueryRef, fromSerializable(value) { const queryRef = { $__apollo_queryRef: value }; clientReactStreaming.reviveTransportedQueryRef(queryRef, apolloClient); return queryRef; }, toSerializable(queryRef) { return queryRef.$__apollo_queryRef; } }); var transportSerializationAdapter = routerCore.createSerializationAdapter({ key: "apollo-transport", test(value) { return value instanceof ServerTransport; }, toSerializable(value) { return value.stream; }, fromSerializable(value) { return new ClientTransport(value); } }); var ServerTransport = class { stream; controller; ongoingStreams = /* @__PURE__ */ new Set(); constructor() { this.stream = new ReadableStream({ start: (controller) => { this.controller = controller; } }); } shouldClose = false; closeOnceFinished() { this.shouldClose = true; this.closeIfFinished(); } closed = false; closeIfFinished() { if (this.shouldClose && this.ongoingStreams.size === 0 && !this.closed) { this.controller.close(); this.closed = true; } } dispatchRequestStarted = ({ event, observable }) => { this.controller.enqueue(event); this.ongoingStreams.add(event); const finalize = () => { this.ongoingStreams.delete(event); this.closeIfFinished(); }; observable.subscribe({ next: (event2) => { if (!this.closed) this.controller.enqueue(event2); }, error: finalize, complete: finalize }); }; streamValue(id, value) { this.controller.enqueue({ type: "value", id, value }); } useStaticValueRef = (value) => { const id = React2__default.default.useId(); this.streamValue(id, value); return React2__default.default.useRef(value); }; }; var ClientTransport = class { bufferedEvents = []; receivedValues = {}; constructor(incomingStream) { this.consume(incomingStream); } async consume(stream) { for await (const event of stream) { if (event.type === "value") { this.receivedValues[event.id] = event.value; } else { this.bufferedEvents.push(event); } } this.rerunSimulatedQueries?.(); } // this will be set from the `WrapApolloProvider` data transport set onQueryEvent(callback) { let event; while (event = this.bufferedEvents.shift()) { callback(event); } this.bufferedEvents.push = (...events) => { for (const event2 of events) { callback(event2); } return 0; }; } // this will be set from the `WrapApolloProvider` data transport rerunSimulatedQueries; getStreamedValue(id) { return this.receivedValues[id]; } deleteStreamedValue(id) { delete this.receivedValues[id]; } useStaticValueRef = (value) => { const id = React2__default.default.useId(); const streamedValue = this.getStreamedValue(id); const dataValue = streamedValue !== undefined ? streamedValue : value; React2__default.default.useEffect(() => { this.deleteStreamedValue(id); }, [id]); return React2__default.default.useRef(dataValue); }; }; // src/routerWithApolloClient.tsx function routerWithApolloClient(router, apolloClient) { router.options.context ??= {}; router.options.context.apolloClient = apolloClient; router.options.context.preloadQuery = router.isServer ? clientReactStreaming.createTransportedQueryPreloader(apolloClient, { prepareForReuse: true }) : react.createQueryPreloader( apolloClient ); const providerContext = {}; const ogHydrate = router.options.hydrate; const ogDehydrate = router.options.dehydrate; if (router.isServer) { const apolloClientTransport = new ServerTransport(); providerContext.transport = apolloClientTransport; router.options.dehydrate = async () => { router.serverSsr.onRenderFinished( () => apolloClientTransport.closeOnceFinished() ); return { ...await ogDehydrate?.(), apolloClientTransport }; }; } else { router.options.hydrate = (dehydratedState) => { providerContext.transport = dehydratedState.apolloClientTransport; return ogHydrate?.(dehydratedState); }; } router.options.serializationAdapters = [ ...router.options.serializationAdapters ?? [], getQueryRefSerializationAdapter(apolloClient), transportSerializationAdapter ]; const PreviousInnerWrap = router.options.InnerWrap || React2__default.default.Fragment; router.options.InnerWrap = ({ children }) => /* @__PURE__ */ React2__default.default.createElement(ApolloProvider, { client: apolloClient, context: providerContext }, /* @__PURE__ */ React2__default.default.createElement(PreviousInnerWrap, null, children)); return router; } routerWithApolloClient.defaultContext = { apolloClient: new Proxy({}, { get: contextAccess }), preloadQuery: new Proxy(contextAccess, { get: contextAccess }) }; function contextAccess() { throw new Error( ` Could not find Apollo Client in router context. Did you forget to wrap your router in a \`routerWithApolloClient\` call before returning it from \`getRouter\`? `.trim() ); } var ApolloClient = class extends clientReactStreaming.ApolloClient { /** * Information about the current package and it's export names, for use in error messages. * * @internal */ static info = bundle; }; var InMemoryCache = class extends clientReactStreaming.InMemoryCache { /** * Information about the current package and it's export names, for use in error messages. * * @internal */ static info = bundle; }; exports.built_for_browser = true; exports.ApolloClient = ApolloClient; exports.InMemoryCache = InMemoryCache; exports.routerWithApolloClient = routerWithApolloClient; //# sourceMappingURL=out.js.map //# sourceMappingURL=index.cjs.map