effective-rsc 0.1.3 → 0.1.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"client/flight-client.js","sources":["../../src/client/flight-client.ts"],"sourcesContent":["// oxlint-disable effecttsgo/process-env-in-effect -- Rspack replaces NODE_ENV at compile time.\nimport { Context, Deferred, Effect, Exit, Layer, Schema, Scope, Stream } from 'effect';\nimport { HttpBody, HttpClient, HttpClientRequest } from 'effect/unstable/http';\nimport {\n createFromReadableStream,\n type TemporaryReferenceSet,\n} from 'react-server-dom-rspack/client.browser';\n\nimport { FlightMediaType, ServerFnIdHeader, type FlightPayload } from '../rsc/flight';\nimport { InitialFlightStream } from './initial-flight-stream';\n\nexport class FlightLoadError extends Schema.TaggedError<FlightLoadError>()('FlightLoadError', {\n cause: Schema.Defect(),\n reason: Schema.Literals(['RequestFailed', 'UnexpectedResponse', 'DecodeFailed']),\n}) {}\n\nexport type FlightRequest =\n | {\n readonly _tag: 'Navigation';\n readonly destination: URL;\n }\n | {\n readonly _tag: 'ServerFunction';\n readonly body: BodyInit;\n readonly destination: URL;\n readonly id: string;\n readonly temporaryReferences: TemporaryReferenceSet;\n };\n\ntype DecodedFlight = {\n readonly completed: Effect.Effect<void, FlightLoadError>;\n readonly payload: FlightPayload;\n};\n\ntype FlightResource = DecodedFlight & {\n readonly _tag: 'Flight';\n readonly release: Effect.Effect<void>;\n readonly resolvedUrl: URL;\n};\n\ntype DocumentResource = {\n readonly _tag: 'Document';\n readonly release: Effect.Effect<void>;\n};\n\nexport class FlightClient extends Context.Service<FlightClient>()('ersc/client/FlightClient', {\n make: Effect.gen(function* () {\n const httpClient = yield* HttpClient.HttpClient;\n const initialFlight = yield* InitialFlightStream;\n\n const loadInitial = Effect.gen(function* () {\n const completed = Promise.withResolvers<void>();\n const stream = initialFlight.stream.pipeThrough(\n new TransformStream({\n flush: () => completed.resolve(),\n transform: (chunk, controller) => controller.enqueue(chunk),\n }),\n );\n const payload = yield* Effect.tryPromise({\n try: () =>\n createFromReadableStream<FlightPayload>(\n stream,\n process.env.NODE_ENV === 'development' ? { startTime: 0 } : undefined,\n ),\n catch: (cause) => new FlightLoadError({ cause, reason: 'DecodeFailed' }),\n });\n\n return {\n completed: Effect.promise(() => completed.promise),\n payload,\n } satisfies DecodedFlight;\n });\n\n const load = Effect.fnUntraced(function* (flightRequest: FlightRequest) {\n const parentScope = yield* Effect.scope;\n const responseScope = yield* Scope.fork(parentScope);\n const release = Scope.close(responseScope, Exit.void);\n\n return yield* Effect.gen(function* () {\n const client = httpClient.pipe(HttpClient.withScope);\n const request =\n flightRequest._tag === 'Navigation'\n ? HttpClientRequest.get(flightRequest.destination).pipe(\n HttpClientRequest.setHeader('accept', FlightMediaType),\n )\n : HttpClientRequest.post(flightRequest.destination).pipe(\n HttpClientRequest.setHeaders({\n accept: FlightMediaType,\n [ServerFnIdHeader]: flightRequest.id,\n }),\n HttpClientRequest.setBody(HttpBody.raw(flightRequest.body)),\n );\n const requestStartTime = process.env.NODE_ENV === 'development' ? performance.now() : 0;\n const response = yield* client.execute(request).pipe(\n Scope.provide(responseScope),\n Effect.mapError(\n (cause) =>\n new FlightLoadError({\n cause,\n reason: 'RequestFailed',\n }),\n ),\n );\n if (response.status < 200 || response.status >= 300) {\n if (flightRequest._tag === 'Navigation') {\n return { _tag: 'Document', release } satisfies DocumentResource;\n }\n return yield* new FlightLoadError({\n cause: new Error(`Flight request failed with status ${response.status}.`),\n reason: 'RequestFailed',\n });\n }\n const contentType = response.headers['content-type']\n ?.split(';', 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== FlightMediaType) {\n if (flightRequest._tag === 'Navigation') {\n return { _tag: 'Document', release } satisfies DocumentResource;\n }\n return yield* new FlightLoadError({\n cause: new Error(\n `Expected a ${FlightMediaType} response, received ${response.headers['content-type'] ?? 'no content type'}.`,\n ),\n reason: 'UnexpectedResponse',\n });\n }\n\n const contentLocation = response.headers['content-location'];\n if (contentLocation === undefined) {\n return yield* new FlightLoadError({\n cause: new Error('Expected the Flight response to include a Content-Location header.'),\n reason: 'UnexpectedResponse',\n });\n }\n const resolvedUrl = yield* Effect.try({\n try: () => new URL(contentLocation, flightRequest.destination),\n catch: (cause) =>\n new FlightLoadError({\n cause,\n reason: 'UnexpectedResponse',\n }),\n });\n\n const completed = yield* Deferred.make<void, FlightLoadError>();\n const responseBody = yield* Stream.toReadableStreamEffect(\n response.stream.pipe(\n Stream.onExit((exit) =>\n Deferred.done(\n completed,\n exit.pipe(\n Exit.mapError(\n (cause) =>\n new FlightLoadError({\n cause,\n reason: 'RequestFailed',\n }),\n ),\n Exit.asVoid,\n ),\n ),\n ),\n Stream.ensuring(release),\n ),\n );\n const decodeOptions =\n flightRequest._tag === 'ServerFunction'\n ? process.env.NODE_ENV === 'development'\n ? {\n startTime: requestStartTime,\n temporaryReferences: flightRequest.temporaryReferences,\n }\n : { temporaryReferences: flightRequest.temporaryReferences }\n : process.env.NODE_ENV === 'development'\n ? {\n startTime: requestStartTime,\n }\n : undefined;\n const payload = yield* Effect.tryPromise({\n try: () => createFromReadableStream<FlightPayload>(responseBody, decodeOptions),\n catch: (cause) =>\n new FlightLoadError({\n cause,\n reason: 'DecodeFailed',\n }),\n });\n\n return {\n _tag: 'Flight',\n completed: Deferred.await(completed),\n payload,\n release,\n resolvedUrl,\n } satisfies FlightResource;\n }).pipe(Effect.onError(() => release));\n });\n\n return { load, loadInitial };\n }),\n}) {\n static readonly layer = Layer.effect(this, this.make);\n\n static readonly layerTest = Layer.mock(this);\n}\n"],"names":["Context","Deferred","Effect","Exit","Layer","Schema","Scope","Stream","HttpBody","HttpClient","HttpClientRequest","createFromReadableStream","FlightMediaType","ServerFnIdHeader","InitialFlightStream","FlightLoadError","FlightClient","httpClient","initialFlight","loadInitial","completed","Promise","stream","TransformStream","chunk","controller","payload","process","undefined","cause","load","flightRequest","parentScope","responseScope","release","client","request","requestStartTime","performance","response","Error","contentType","contentLocation","resolvedUrl","URL","responseBody","exit","decodeOptions"],"mappings":"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"}
1
+ {"version":3,"file":"client/flight-client.js","sources":["../../src/client/flight-client.ts"],"sourcesContent":["// oxlint-disable effecttsgo/process-env-in-effect -- Rspack replaces NODE_ENV at compile time.\nimport { Context, Deferred, Effect, Exit, Layer, Schema, Scope, Stream } from 'effect';\nimport { HttpBody, HttpClient, HttpClientRequest } from 'effect/unstable/http';\nimport {\n createFromReadableStream,\n type TemporaryReferenceSet,\n} from 'react-server-dom-rspack/client.browser';\n\nimport { FlightMediaType, ServerFnIdHeader, type FlightPayload } from '../rsc/flight';\nimport { InitialFlightStream } from './initial-flight-stream';\n\nexport class FlightLoadError extends Schema.TaggedError<FlightLoadError>()('FlightLoadError', {\n cause: Schema.Defect(),\n reason: Schema.Literals(['RequestFailed', 'UnexpectedResponse', 'DecodeFailed']),\n}) {}\n\nexport type FlightRequest =\n | {\n readonly _tag: 'Navigation';\n readonly destination: URL;\n }\n | {\n readonly _tag: 'ServerFunction';\n readonly body: BodyInit;\n readonly destination: URL;\n readonly id: string;\n readonly temporaryReferences: TemporaryReferenceSet;\n };\n\ntype DecodedFlight = {\n readonly completed: Effect.Effect<void, FlightLoadError>;\n readonly payload: FlightPayload;\n};\n\ntype FlightResource = DecodedFlight & {\n readonly _tag: 'Flight';\n readonly release: Effect.Effect<void>;\n readonly resolvedUrl: URL;\n};\n\ntype DocumentResource = {\n readonly _tag: 'Document';\n readonly release: Effect.Effect<void>;\n};\n\nexport class FlightClient extends Context.Service<FlightClient>()('ersc/client/FlightClient', {\n make: Effect.gen(function* () {\n const httpClient = yield* HttpClient.HttpClient;\n const initialFlight = yield* InitialFlightStream;\n\n const loadInitial = Effect.gen(function* () {\n const completed = Promise.withResolvers<void>();\n const stream = initialFlight.stream.pipeThrough(\n new TransformStream({\n flush: () => completed.resolve(),\n transform: (chunk, controller) => controller.enqueue(chunk),\n }),\n );\n const payload = yield* Effect.tryPromise({\n try: () =>\n createFromReadableStream<FlightPayload>(\n stream,\n process.env.NODE_ENV === 'development' ? { startTime: 0 } : undefined,\n ),\n catch: (cause) => new FlightLoadError({ cause, reason: 'DecodeFailed' }),\n });\n\n return {\n completed: Effect.promise(() => completed.promise),\n payload,\n } satisfies DecodedFlight;\n });\n\n const load = Effect.fnUntraced(function* (flightRequest: FlightRequest) {\n const parentScope = yield* Effect.scope;\n const responseScope = yield* Scope.fork(parentScope);\n const release = Scope.close(responseScope, Exit.void);\n\n return yield* Effect.gen(function* () {\n const client = httpClient.pipe(HttpClient.withScope);\n const request =\n flightRequest._tag === 'Navigation'\n ? HttpClientRequest.get(flightRequest.destination).pipe(\n HttpClientRequest.setHeader('accept', FlightMediaType),\n )\n : HttpClientRequest.post(flightRequest.destination).pipe(\n HttpClientRequest.setHeaders({\n accept: FlightMediaType,\n [ServerFnIdHeader]: flightRequest.id,\n }),\n HttpClientRequest.setBody(HttpBody.raw(flightRequest.body)),\n );\n const requestStartTime = process.env.NODE_ENV === 'development' ? performance.now() : 0;\n const response = yield* client.execute(request).pipe(\n Scope.provide(responseScope),\n Effect.mapError(\n (cause) =>\n new FlightLoadError({\n cause,\n reason: 'RequestFailed',\n }),\n ),\n );\n if (response.status < 200 || response.status >= 300) {\n if (flightRequest._tag === 'Navigation') {\n return { _tag: 'Document', release } satisfies DocumentResource;\n }\n return yield* new FlightLoadError({\n cause: new Error(`Flight request failed with status ${response.status}.`),\n reason: 'RequestFailed',\n });\n }\n const contentType = response.headers['content-type']\n ?.split(';', 1)[0]\n ?.trim()\n .toLowerCase();\n if (contentType !== FlightMediaType) {\n if (flightRequest._tag === 'Navigation') {\n return { _tag: 'Document', release } satisfies DocumentResource;\n }\n return yield* new FlightLoadError({\n cause: new Error(\n `Expected a ${FlightMediaType} response, received ${response.headers['content-type'] ?? 'no content type'}.`,\n ),\n reason: 'UnexpectedResponse',\n });\n }\n\n if (response.url === '') {\n return yield* new FlightLoadError({\n cause: new Error('Expected the Flight response to include a resolved URL.'),\n reason: 'UnexpectedResponse',\n });\n }\n const resolvedUrl = yield* Effect.try({\n try: () => new URL(response.url),\n catch: (cause) =>\n new FlightLoadError({\n cause,\n reason: 'UnexpectedResponse',\n }),\n });\n\n const completed = yield* Deferred.make<void, FlightLoadError>();\n const responseBody = yield* Stream.toReadableStreamEffect(\n response.stream.pipe(\n Stream.onExit((exit) =>\n Deferred.done(\n completed,\n exit.pipe(\n Exit.mapError(\n (cause) =>\n new FlightLoadError({\n cause,\n reason: 'RequestFailed',\n }),\n ),\n Exit.asVoid,\n ),\n ),\n ),\n Stream.ensuring(release),\n ),\n );\n const decodeOptions =\n flightRequest._tag === 'ServerFunction'\n ? process.env.NODE_ENV === 'development'\n ? {\n startTime: requestStartTime,\n temporaryReferences: flightRequest.temporaryReferences,\n }\n : { temporaryReferences: flightRequest.temporaryReferences }\n : process.env.NODE_ENV === 'development'\n ? {\n startTime: requestStartTime,\n }\n : undefined;\n const payload = yield* Effect.tryPromise({\n try: () => createFromReadableStream<FlightPayload>(responseBody, decodeOptions),\n catch: (cause) =>\n new FlightLoadError({\n cause,\n reason: 'DecodeFailed',\n }),\n });\n\n return {\n _tag: 'Flight',\n completed: Deferred.await(completed),\n payload,\n release,\n resolvedUrl,\n } satisfies FlightResource;\n }).pipe(Effect.onError(() => release));\n });\n\n return { load, loadInitial };\n }),\n}) {\n static readonly layer = Layer.effect(this, this.make);\n\n static readonly layerTest = Layer.mock(this);\n}\n"],"names":["Context","Deferred","Effect","Exit","Layer","Schema","Scope","Stream","HttpBody","HttpClient","HttpClientRequest","createFromReadableStream","FlightMediaType","ServerFnIdHeader","InitialFlightStream","FlightLoadError","FlightClient","httpClient","initialFlight","loadInitial","completed","Promise","stream","TransformStream","chunk","controller","payload","process","undefined","cause","load","flightRequest","parentScope","responseScope","release","client","request","requestStartTime","performance","response","Error","contentType","resolvedUrl","URL","responseBody","exit","decodeOptions"],"mappings":"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"}
@@ -108,12 +108,13 @@ class ReactDOMRenderer extends Context.Service()('ersc/client/ReactDOMRenderer',
108
108
  }, [
109
109
  render
110
110
  ]);
111
+ const routeTree = render._tag === 'Discard' ? render.restore.routeTree : render.routeTree;
111
112
  return /*#__PURE__*/ jsx(BrowserErrorBoundary, {
112
113
  onError: reportError,
113
114
  onRendered: reportRendered,
114
115
  render: render,
115
116
  children: /*#__PURE__*/ jsx(RouteTree, {
116
- root: render.routeTree
117
+ root: routeTree
117
118
  })
118
119
  });
119
120
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client/react-dom-renderer.js","sources":["../../src/client/react-dom-renderer.tsx"],"sourcesContent":["import { Context, Effect, Layer, Schema } from 'effect';\nimport {\n Component,\n type ErrorInfo,\n type ReactNode,\n StrictMode,\n useLayoutEffect,\n useState,\n} from 'react';\nimport { hydrateRoot } from 'react-dom/client';\n\nimport type { FlightPayload } from '../rsc/flight';\nimport { BrowserEffectRunner } from './browser-effect-runner';\nimport { BrowserRenderStatus } from './browser-render-status';\nimport { type BrowserRender, BrowserRenderer } from './browser-renderer';\nimport { BrowserFailureScreen } from './browser-screen';\nimport { RouteTree } from './route-tree';\n\nexport class ReactDOMHydrationError extends Schema.TaggedError<ReactDOMHydrationError>()(\n 'ReactDOMHydrationError',\n { cause: Schema.Defect() },\n) {}\n\ntype BrowserErrorBoundaryState =\n | { readonly _tag: 'Uninitialized' }\n | { readonly _tag: 'Ready'; readonly render: BrowserRender }\n | { readonly _tag: 'Failed'; readonly render: BrowserRender };\ntype BrowserErrorBoundaryProps = {\n readonly children: ReactNode;\n readonly onError: (error: unknown, info: ErrorInfo) => void;\n readonly onRendered: () => void;\n readonly render: BrowserRender;\n};\n\nclass BrowserErrorBoundary extends Component<BrowserErrorBoundaryProps, BrowserErrorBoundaryState> {\n override readonly state: BrowserErrorBoundaryState = { _tag: 'Uninitialized' };\n\n static getDerivedStateFromError() {\n return { _tag: 'Failed' } as const;\n }\n\n static getDerivedStateFromProps(\n props: BrowserErrorBoundaryProps,\n state: BrowserErrorBoundaryState,\n ): BrowserErrorBoundaryState | null {\n if (state._tag !== 'Uninitialized' && props.render === state.render) {\n return null;\n }\n // Discard acknowledges a cancelled candidate, not a request to retry the failed tree.\n return state._tag === 'Failed' && props.render._tag === 'Discard'\n ? { _tag: 'Failed', render: props.render }\n : { _tag: 'Ready', render: props.render };\n }\n\n override componentDidCatch(error: unknown, info: ErrorInfo) {\n this.props.onError(error, info);\n }\n\n override componentDidMount() {\n if (this.state._tag === 'Ready') {\n this.props.onRendered();\n }\n }\n\n override componentDidUpdate() {\n if (this.state._tag === 'Ready') {\n this.props.onRendered();\n }\n }\n\n override render() {\n if (this.state._tag === 'Failed') {\n return <BrowserFailureScreen />;\n }\n\n return this.props.children;\n }\n}\n\nexport class ReactDOMRenderer extends Context.Service<ReactDOMRenderer>()(\n 'ersc/client/ReactDOMRenderer',\n {\n make: Effect.gen(function* () {\n const browserRenderer = yield* BrowserRenderer;\n const run = yield* BrowserEffectRunner;\n const renderStatus = yield* BrowserRenderStatus;\n\n const hydrate = Effect.fnUntraced(function* (\n container: Element | Document,\n initialPayload: FlightPayload,\n ) {\n const browserRendererReady = Promise.withResolvers<void>();\n const reportError = (error: unknown, info: ErrorInfo) => {\n void run(\n Effect.gen(function* () {\n yield* renderStatus.report({\n _tag: 'Failed',\n error,\n componentStack: info.componentStack ?? null,\n });\n yield* Effect.logError('Uncaught client render error.', error, info.componentStack);\n }),\n );\n };\n\n const reportRendered = () => {\n void run(renderStatus.report({ _tag: 'Rendered' }));\n };\n\n function Root() {\n const [render, setRender] = useState<BrowserRender>(() => ({\n _tag: 'Initial',\n routeTree: initialPayload.routeTree,\n }));\n\n useLayoutEffect(() => {\n browserRenderer.initialize(initialPayload.routeTree, setRender);\n browserRendererReady.resolve();\n }, []);\n\n useLayoutEffect(() => {\n browserRenderer.commit(render);\n }, [render]);\n\n return (\n <BrowserErrorBoundary onError={reportError} onRendered={reportRendered} render={render}>\n <RouteTree root={render.routeTree} />\n </BrowserErrorBoundary>\n );\n }\n\n yield* Effect.acquireRelease(\n Effect.try({\n try: () =>\n hydrateRoot(\n container,\n <StrictMode>\n <Root />\n </StrictMode>,\n { formState: initialPayload.formState },\n ),\n catch: (cause) => new ReactDOMHydrationError({ cause }),\n }),\n (root) => Effect.sync(() => root.unmount()),\n );\n yield* Effect.promise(() => browserRendererReady.promise);\n });\n\n return { hydrate };\n }),\n },\n) {\n static readonly layer = Layer.effect(this, this.make);\n}\n"],"names":["Context","Effect","Layer","Schema","Component","StrictMode","useLayoutEffect","useState","hydrateRoot","BrowserEffectRunner","BrowserRenderStatus","BrowserRenderer","BrowserFailureScreen","RouteTree","ReactDOMHydrationError","BrowserErrorBoundary","props","state","error","info","ReactDOMRenderer","browserRenderer","run","renderStatus","hydrate","container","initialPayload","browserRendererReady","Promise","reportError","reportRendered","Root","render","setRender","cause","root"],"mappings":"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"}
1
+ {"version":3,"file":"client/react-dom-renderer.js","sources":["../../src/client/react-dom-renderer.tsx"],"sourcesContent":["import { Context, Effect, Layer, Schema } from 'effect';\nimport {\n Component,\n type ErrorInfo,\n type ReactNode,\n StrictMode,\n useLayoutEffect,\n useState,\n} from 'react';\nimport { hydrateRoot } from 'react-dom/client';\n\nimport type { FlightPayload } from '../rsc/flight';\nimport { BrowserEffectRunner } from './browser-effect-runner';\nimport { BrowserRenderStatus } from './browser-render-status';\nimport { type BrowserRender, BrowserRenderer } from './browser-renderer';\nimport { BrowserFailureScreen } from './browser-screen';\nimport { RouteTree } from './route-tree';\n\nexport class ReactDOMHydrationError extends Schema.TaggedError<ReactDOMHydrationError>()(\n 'ReactDOMHydrationError',\n { cause: Schema.Defect() },\n) {}\n\ntype BrowserErrorBoundaryState =\n | { readonly _tag: 'Uninitialized' }\n | { readonly _tag: 'Ready'; readonly render: BrowserRender }\n | { readonly _tag: 'Failed'; readonly render: BrowserRender };\ntype BrowserErrorBoundaryProps = {\n readonly children: ReactNode;\n readonly onError: (error: unknown, info: ErrorInfo) => void;\n readonly onRendered: () => void;\n readonly render: BrowserRender;\n};\n\nclass BrowserErrorBoundary extends Component<BrowserErrorBoundaryProps, BrowserErrorBoundaryState> {\n override readonly state: BrowserErrorBoundaryState = { _tag: 'Uninitialized' };\n\n static getDerivedStateFromError() {\n return { _tag: 'Failed' } as const;\n }\n\n static getDerivedStateFromProps(\n props: BrowserErrorBoundaryProps,\n state: BrowserErrorBoundaryState,\n ): BrowserErrorBoundaryState | null {\n if (state._tag !== 'Uninitialized' && props.render === state.render) {\n return null;\n }\n // Discard acknowledges a cancelled candidate, not a request to retry the failed tree.\n return state._tag === 'Failed' && props.render._tag === 'Discard'\n ? { _tag: 'Failed', render: props.render }\n : { _tag: 'Ready', render: props.render };\n }\n\n override componentDidCatch(error: unknown, info: ErrorInfo) {\n this.props.onError(error, info);\n }\n\n override componentDidMount() {\n if (this.state._tag === 'Ready') {\n this.props.onRendered();\n }\n }\n\n override componentDidUpdate() {\n if (this.state._tag === 'Ready') {\n this.props.onRendered();\n }\n }\n\n override render() {\n if (this.state._tag === 'Failed') {\n return <BrowserFailureScreen />;\n }\n\n return this.props.children;\n }\n}\n\nexport class ReactDOMRenderer extends Context.Service<ReactDOMRenderer>()(\n 'ersc/client/ReactDOMRenderer',\n {\n make: Effect.gen(function* () {\n const browserRenderer = yield* BrowserRenderer;\n const run = yield* BrowserEffectRunner;\n const renderStatus = yield* BrowserRenderStatus;\n\n const hydrate = Effect.fnUntraced(function* (\n container: Element | Document,\n initialPayload: FlightPayload,\n ) {\n const browserRendererReady = Promise.withResolvers<void>();\n const reportError = (error: unknown, info: ErrorInfo) => {\n void run(\n Effect.gen(function* () {\n yield* renderStatus.report({\n _tag: 'Failed',\n error,\n componentStack: info.componentStack ?? null,\n });\n yield* Effect.logError('Uncaught client render error.', error, info.componentStack);\n }),\n );\n };\n\n const reportRendered = () => {\n void run(renderStatus.report({ _tag: 'Rendered' }));\n };\n\n function Root() {\n const [render, setRender] = useState<BrowserRender>(() => ({\n _tag: 'Initial',\n routeTree: initialPayload.routeTree,\n }));\n\n useLayoutEffect(() => {\n browserRenderer.initialize(initialPayload.routeTree, setRender);\n browserRendererReady.resolve();\n }, []);\n\n useLayoutEffect(() => {\n browserRenderer.commit(render);\n }, [render]);\n\n const routeTree = render._tag === 'Discard' ? render.restore.routeTree : render.routeTree;\n return (\n <BrowserErrorBoundary onError={reportError} onRendered={reportRendered} render={render}>\n <RouteTree root={routeTree} />\n </BrowserErrorBoundary>\n );\n }\n\n yield* Effect.acquireRelease(\n Effect.try({\n try: () =>\n hydrateRoot(\n container,\n <StrictMode>\n <Root />\n </StrictMode>,\n { formState: initialPayload.formState },\n ),\n catch: (cause) => new ReactDOMHydrationError({ cause }),\n }),\n (root) => Effect.sync(() => root.unmount()),\n );\n yield* Effect.promise(() => browserRendererReady.promise);\n });\n\n return { hydrate };\n }),\n },\n) {\n static readonly layer = Layer.effect(this, this.make);\n}\n"],"names":["Context","Effect","Layer","Schema","Component","StrictMode","useLayoutEffect","useState","hydrateRoot","BrowserEffectRunner","BrowserRenderStatus","BrowserRenderer","BrowserFailureScreen","RouteTree","ReactDOMHydrationError","BrowserErrorBoundary","props","state","error","info","ReactDOMRenderer","browserRenderer","run","renderStatus","hydrate","container","initialPayload","browserRendererReady","Promise","reportError","reportRendered","Root","render","setRender","routeTree","cause","root"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Context, Effect, Layer } from 'effect';
1
+ import { Context, Effect, Layer, Scope } from 'effect';
2
2
  import { BrowserRenderer } from './browser-renderer.js';
3
3
  import { NavigationApi } from './navigation-api.js';
4
4
  import { RouteLoader } from './route-loader.js';
@@ -26,5 +26,5 @@ export declare class RouteRefresher extends RouteRefresher_base {
26
26
  replace?: (replacement: RouteRefreshImplementation) => Effect.Effect<void, never, never>;
27
27
  }) => Layer.Layer<RouteRefresher, never, never>;
28
28
  }
29
- export declare const installRouteRefresh: Effect.Effect<void, never, BrowserRenderer | NavigationApi | RouteLoader | RouteRefresher | import("effect/Scope").Scope>;
29
+ export declare const installRouteRefresh: Effect.Effect<void, never, BrowserRenderer | NavigationApi | RouteLoader | RouteRefresher | Scope.Scope>;
30
30
  export {};
@@ -1,4 +1,4 @@
1
- import { Context, Effect, FiberMap, Layer, Ref } from "effect";
1
+ import { Context, Effect, Exit, FiberHandle, Layer, Ref, Scope } from "effect";
2
2
  import { addTransitionType, startTransition } from "react";
3
3
  import { BrowserRenderer } from "./browser-renderer.js";
4
4
  import { NavigationApi } from "./navigation-api.js";
@@ -17,7 +17,6 @@ import { RouteLoader } from "./route-loader.js";
17
17
 
18
18
 
19
19
 
20
- const CurrentRouteRefreshKey = 'CurrentRouteRefresh';
21
20
  class RouteRefresher extends Context.Service()('ersc/client/RouteRefresher', {
22
21
  make: Effect.gen(function*() {
23
22
  const navigationApi = yield* NavigationApi;
@@ -48,7 +47,8 @@ const installRouteRefresh = Effect.gen(function*() {
48
47
  const navigationApi = yield* NavigationApi;
49
48
  const routeLoader = yield* RouteLoader;
50
49
  const routeRefresher = yield* RouteRefresher;
51
- const refreshes = yield* FiberMap.make();
50
+ const refreshes = yield* FiberHandle.make();
51
+ const browserScope = yield* Effect.scope;
52
52
  const waitForNavigationIdle = Effect.suspend(()=>{
53
53
  const transition = navigationApi.getTransition();
54
54
  return transition === null ? Effect.succeed('Idle') : Effect.promise(()=>transition.finished.then(()=>undefined, ()=>undefined)).pipe(Effect.as('Settled'));
@@ -65,41 +65,56 @@ const installRouteRefresh = Effect.gen(function*() {
65
65
  return Effect.sync(unsubscribe);
66
66
  });
67
67
  const refreshRoute = Effect.fnUntraced(function*(transitionType) {
68
- const currentEntry = navigationApi.getCurrentEntry();
69
- const destination = new URL(currentEntry?.url ?? navigationApi.getCurrentUrl());
70
- const resource = yield* routeLoader.load({
71
- destination: {
72
- id: currentEntry?.id ?? '',
73
- url: destination.href
74
- },
75
- navigationType: 'replace'
76
- });
77
- if (resource._tag === 'Document') {
78
- yield* resource.release;
79
- yield* Effect.sync(navigationApi.reloadDocument);
80
- return;
81
- }
82
- const resolvedDestination = preserveRequestedHash(destination, resource.resolvedUrl);
83
- if (resolvedDestination.href !== destination.href) {
84
- yield* resource.release;
85
- yield* Effect.sync(()=>navigationApi.replaceDocument(resolvedDestination.href));
86
- return;
87
- }
88
- const commitRefresh = routeLoader.prepareRefresh(resource.routeTree);
89
- let renderCommitted;
90
- yield* Effect.sync(()=>{
91
- startTransition(()=>{
92
- addTransitionType(transitionType);
93
- renderCommitted = browserRenderer.refresh(resource.routeTree);
68
+ const responseScope = yield* Scope.make();
69
+ const render = yield* Effect.uninterruptibleMask(Effect.fnUntraced(function*(restore) {
70
+ const currentEntry = navigationApi.getCurrentEntry();
71
+ const destination = new URL(currentEntry?.url ?? navigationApi.getCurrentUrl());
72
+ const resource = yield* restore(routeLoader.load({
73
+ destination: {
74
+ id: currentEntry?.id ?? '',
75
+ url: destination.href
76
+ },
77
+ navigationType: 'replace'
78
+ }).pipe(Scope.provide(responseScope)));
79
+ const release = resource.release.pipe(Scope.use(responseScope));
80
+ if (resource._tag === 'Document') {
81
+ yield* release;
82
+ yield* Effect.sync(navigationApi.reloadDocument);
83
+ return;
84
+ }
85
+ const resolvedDestination = preserveRequestedHash(destination, resource.resolvedUrl);
86
+ if (resolvedDestination.href !== destination.href) {
87
+ yield* release;
88
+ yield* Effect.sync(()=>navigationApi.replaceDocument(resolvedDestination.href));
89
+ return;
90
+ }
91
+ const commitRefresh = routeLoader.prepareRefresh(resource.routeTree);
92
+ let published;
93
+ yield* Effect.sync(()=>{
94
+ startTransition(()=>{
95
+ addTransitionType(transitionType);
96
+ published = browserRenderer.refresh(resource.routeTree);
97
+ });
94
98
  });
95
- });
96
- yield* Effect.all([
97
- Effect.promise(()=>renderCommitted),
98
- resource.completed
99
- ], {
100
- concurrency: 'unbounded',
101
- discard: true
102
- }).pipe(Effect.andThen(Effect.sync(commitRefresh)), Effect.ensuring(resource.release));
99
+ // Finish publication and install its browser-owned lifetime before allowing cancellation.
100
+ yield* Effect.raceFirst(Effect.all([
101
+ Effect.promise(()=>published.committed),
102
+ resource.completed
103
+ ], {
104
+ concurrency: 'unbounded',
105
+ discard: true
106
+ }).pipe(Effect.andThen(Effect.sync(commitRefresh))), Effect.promise(()=>published.retired)).pipe(Effect.ensuring(release), Effect["catch"]((cause)=>Effect.logError('Failed to stream the refreshed route.', cause)), Effect.forkIn(browserScope, {
107
+ startImmediately: true
108
+ }));
109
+ yield* Effect.addFinalizer(()=>Effect.sync(()=>{
110
+ // The stream fiber awaits retirement; waiting here could block the replacement render.
111
+ void published.discard();
112
+ }));
113
+ return published;
114
+ }, Effect.onError((cause)=>Scope.close(responseScope, Exit.failCause(cause)))));
115
+ if (render !== undefined) {
116
+ yield* Effect.promise(()=>render.committed);
117
+ }
103
118
  });
104
119
  const refreshCurrentRoute = Effect.fnUntraced(function*(transitionType) {
105
120
  routeLoader.invalidate();
@@ -109,8 +124,8 @@ const installRouteRefresh = Effect.gen(function*() {
109
124
  yield* Effect.raceFirst(refreshRoute(transitionType), waitForRoutedNavigation);
110
125
  }, Effect.scoped, Effect["catch"]((cause)=>Effect.logError('Failed to refresh the current route.', cause)));
111
126
  yield* routeRefresher.replace({
112
- interruptCurrentRouteRefresh: FiberMap.remove(refreshes, CurrentRouteRefreshKey),
113
- refreshCurrentRoute: (transitionType)=>FiberMap.run(refreshes, CurrentRouteRefreshKey, refreshCurrentRoute(transitionType)).pipe(Effect.asVoid)
127
+ interruptCurrentRouteRefresh: FiberHandle.clear(refreshes),
128
+ refreshCurrentRoute: (transitionType)=>FiberHandle.run(refreshes, refreshCurrentRoute(transitionType)).pipe(Effect.asVoid)
114
129
  });
115
130
  });
116
131
 
@@ -1 +1 @@
1
- {"version":3,"file":"client/route-refresh.js","sources":["../../src/client/route-refresh.ts"],"sourcesContent":["import { Context, Effect, FiberMap, Layer, Ref } from 'effect';\nimport { addTransitionType, startTransition } from 'react';\n\nimport { BrowserRenderer } from './browser-renderer';\nimport { NavigationApi } from './navigation-api';\nimport { isRoutedNavigation, preserveRequestedHash } from './navigation-routing';\nimport { RouteLoader } from './route-loader';\n\nconst CurrentRouteRefreshKey = 'CurrentRouteRefresh';\n\nexport type RouteRefreshTransitionType = 'hmr-refresh' | 'server-function';\n\ntype RouteRefreshImplementation = {\n readonly interruptCurrentRouteRefresh: Effect.Effect<void>;\n readonly refreshCurrentRoute: (transitionType: RouteRefreshTransitionType) => Effect.Effect<void>;\n};\n\nexport class RouteRefresher extends Context.Service<RouteRefresher>()(\n 'ersc/client/RouteRefresher',\n {\n make: Effect.gen(function* () {\n const navigationApi = yield* NavigationApi;\n const implementation = yield* Ref.make<RouteRefreshImplementation>({\n interruptCurrentRouteRefresh: Effect.void,\n refreshCurrentRoute: () => Effect.sync(navigationApi.reloadDocument),\n });\n\n const interruptCurrentRouteRefresh = Effect.gen(function* () {\n const current = yield* Ref.get(implementation);\n yield* current.interruptCurrentRouteRefresh;\n });\n\n const refreshCurrentRoute = Effect.fn('RouteRefresher.refreshCurrentRoute')(function* (\n transitionType: RouteRefreshTransitionType,\n ) {\n const current = yield* Ref.get(implementation);\n yield* current.refreshCurrentRoute(transitionType);\n });\n\n return {\n interruptCurrentRouteRefresh,\n refreshCurrentRoute,\n replace: (replacement: RouteRefreshImplementation) => Ref.set(implementation, replacement),\n };\n }),\n },\n) {\n static readonly layer = Layer.effect(this, this.make);\n\n static readonly layerTest = Layer.mock(this);\n}\n\nexport const installRouteRefresh = Effect.gen(function* () {\n const browserRenderer = yield* BrowserRenderer;\n const navigationApi = yield* NavigationApi;\n const routeLoader = yield* RouteLoader;\n const routeRefresher = yield* RouteRefresher;\n const refreshes = yield* FiberMap.make<typeof CurrentRouteRefreshKey>();\n\n const waitForNavigationIdle = Effect.suspend(() => {\n const transition = navigationApi.getTransition();\n return transition === null\n ? Effect.succeed('Idle' as const)\n : Effect.promise(() =>\n transition.finished.then(\n () => undefined,\n () => undefined,\n ),\n ).pipe(Effect.as('Settled' as const));\n }).pipe(Effect.repeat({ while: (state) => state === 'Settled' }), Effect.asVoid);\n\n const waitForRoutedNavigation = Effect.callback<void>((resume) => {\n const onNavigate = (event: NavigateEvent) => {\n if (isRoutedNavigation(event)) {\n resume(Effect.void);\n }\n };\n const unsubscribe = navigationApi.subscribe(onNavigate);\n return Effect.sync(unsubscribe);\n });\n\n const refreshRoute = Effect.fnUntraced(function* (transitionType: RouteRefreshTransitionType) {\n const currentEntry = navigationApi.getCurrentEntry();\n const destination = new URL(currentEntry?.url ?? navigationApi.getCurrentUrl());\n const resource = yield* routeLoader.load({\n destination: {\n id: currentEntry?.id ?? '',\n url: destination.href,\n },\n navigationType: 'replace',\n });\n\n if (resource._tag === 'Document') {\n yield* resource.release;\n yield* Effect.sync(navigationApi.reloadDocument);\n return;\n }\n\n const resolvedDestination = preserveRequestedHash(destination, resource.resolvedUrl);\n if (resolvedDestination.href !== destination.href) {\n yield* resource.release;\n yield* Effect.sync(() => navigationApi.replaceDocument(resolvedDestination.href));\n return;\n }\n\n const commitRefresh = routeLoader.prepareRefresh(resource.routeTree);\n let renderCommitted!: Promise<void>;\n yield* Effect.sync(() => {\n startTransition(() => {\n addTransitionType(transitionType);\n renderCommitted = browserRenderer.refresh(resource.routeTree);\n });\n });\n yield* Effect.all([Effect.promise(() => renderCommitted), resource.completed], {\n concurrency: 'unbounded',\n discard: true,\n }).pipe(Effect.andThen(Effect.sync(commitRefresh)), Effect.ensuring(resource.release));\n });\n\n const refreshCurrentRoute = Effect.fnUntraced(\n function* (transitionType: RouteRefreshTransitionType) {\n routeLoader.invalidate();\n yield* waitForNavigationIdle;\n // Only publication belongs to a React Transition. An async Action waiting for this\n // effect would prevent the very UI commit that completes the refresh.\n yield* Effect.raceFirst(refreshRoute(transitionType), waitForRoutedNavigation);\n },\n Effect.scoped,\n Effect.catch((cause) => Effect.logError('Failed to refresh the current route.', cause)),\n );\n\n yield* routeRefresher.replace({\n interruptCurrentRouteRefresh: FiberMap.remove(refreshes, CurrentRouteRefreshKey),\n refreshCurrentRoute: (transitionType) =>\n FiberMap.run(refreshes, CurrentRouteRefreshKey, refreshCurrentRoute(transitionType)).pipe(\n Effect.asVoid,\n ),\n });\n});\n"],"names":["Context","Effect","FiberMap","Layer","Ref","addTransitionType","startTransition","BrowserRenderer","NavigationApi","isRoutedNavigation","preserveRequestedHash","RouteLoader","CurrentRouteRefreshKey","RouteRefresher","navigationApi","implementation","interruptCurrentRouteRefresh","current","refreshCurrentRoute","transitionType","replacement","installRouteRefresh","browserRenderer","routeLoader","routeRefresher","refreshes","waitForNavigationIdle","transition","undefined","state","waitForRoutedNavigation","resume","onNavigate","event","unsubscribe","refreshRoute","currentEntry","destination","URL","resource","resolvedDestination","commitRefresh","renderCommitted","cause"],"mappings":"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"}
1
+ {"version":3,"file":"client/route-refresh.js","sources":["../../src/client/route-refresh.ts"],"sourcesContent":["import { Context, Effect, Exit, FiberHandle, Layer, Ref, Scope } from 'effect';\nimport { addTransitionType, startTransition } from 'react';\n\nimport { BrowserRenderer } from './browser-renderer';\nimport { NavigationApi } from './navigation-api';\nimport { isRoutedNavigation, preserveRequestedHash } from './navigation-routing';\nimport { RouteLoader } from './route-loader';\n\nexport type RouteRefreshTransitionType = 'hmr-refresh' | 'server-function';\n\ntype RouteRefreshImplementation = {\n readonly interruptCurrentRouteRefresh: Effect.Effect<void>;\n readonly refreshCurrentRoute: (transitionType: RouteRefreshTransitionType) => Effect.Effect<void>;\n};\n\nexport class RouteRefresher extends Context.Service<RouteRefresher>()(\n 'ersc/client/RouteRefresher',\n {\n make: Effect.gen(function* () {\n const navigationApi = yield* NavigationApi;\n const implementation = yield* Ref.make<RouteRefreshImplementation>({\n interruptCurrentRouteRefresh: Effect.void,\n refreshCurrentRoute: () => Effect.sync(navigationApi.reloadDocument),\n });\n\n const interruptCurrentRouteRefresh = Effect.gen(function* () {\n const current = yield* Ref.get(implementation);\n yield* current.interruptCurrentRouteRefresh;\n });\n\n const refreshCurrentRoute = Effect.fn('RouteRefresher.refreshCurrentRoute')(function* (\n transitionType: RouteRefreshTransitionType,\n ) {\n const current = yield* Ref.get(implementation);\n yield* current.refreshCurrentRoute(transitionType);\n });\n\n return {\n interruptCurrentRouteRefresh,\n refreshCurrentRoute,\n replace: (replacement: RouteRefreshImplementation) => Ref.set(implementation, replacement),\n };\n }),\n },\n) {\n static readonly layer = Layer.effect(this, this.make);\n\n static readonly layerTest = Layer.mock(this);\n}\n\nexport const installRouteRefresh = Effect.gen(function* () {\n const browserRenderer = yield* BrowserRenderer;\n const navigationApi = yield* NavigationApi;\n const routeLoader = yield* RouteLoader;\n const routeRefresher = yield* RouteRefresher;\n const refreshes = yield* FiberHandle.make<void>();\n const browserScope = yield* Effect.scope;\n\n const waitForNavigationIdle = Effect.suspend(() => {\n const transition = navigationApi.getTransition();\n return transition === null\n ? Effect.succeed('Idle' as const)\n : Effect.promise(() =>\n transition.finished.then(\n () => undefined,\n () => undefined,\n ),\n ).pipe(Effect.as('Settled' as const));\n }).pipe(Effect.repeat({ while: (state) => state === 'Settled' }), Effect.asVoid);\n\n const waitForRoutedNavigation = Effect.callback<void>((resume) => {\n const onNavigate = (event: NavigateEvent) => {\n if (isRoutedNavigation(event)) {\n resume(Effect.void);\n }\n };\n const unsubscribe = navigationApi.subscribe(onNavigate);\n return Effect.sync(unsubscribe);\n });\n\n const refreshRoute = Effect.fnUntraced(function* (transitionType: RouteRefreshTransitionType) {\n const responseScope = yield* Scope.make();\n const render = yield* Effect.uninterruptibleMask(\n Effect.fnUntraced(\n function* (restore) {\n const currentEntry = navigationApi.getCurrentEntry();\n const destination = new URL(currentEntry?.url ?? navigationApi.getCurrentUrl());\n const resource = yield* restore(\n routeLoader\n .load({\n destination: {\n id: currentEntry?.id ?? '',\n url: destination.href,\n },\n navigationType: 'replace',\n })\n .pipe(Scope.provide(responseScope)),\n );\n const release = resource.release.pipe(Scope.use(responseScope));\n\n if (resource._tag === 'Document') {\n yield* release;\n yield* Effect.sync(navigationApi.reloadDocument);\n return;\n }\n\n const resolvedDestination = preserveRequestedHash(destination, resource.resolvedUrl);\n if (resolvedDestination.href !== destination.href) {\n yield* release;\n yield* Effect.sync(() => navigationApi.replaceDocument(resolvedDestination.href));\n return;\n }\n\n const commitRefresh = routeLoader.prepareRefresh(resource.routeTree);\n let published!: ReturnType<BrowserRenderer['Service']['refresh']>;\n yield* Effect.sync(() => {\n startTransition(() => {\n addTransitionType(transitionType);\n published = browserRenderer.refresh(resource.routeTree);\n });\n });\n // Finish publication and install its browser-owned lifetime before allowing cancellation.\n yield* Effect.raceFirst(\n Effect.all([Effect.promise(() => published.committed), resource.completed], {\n concurrency: 'unbounded',\n discard: true,\n }).pipe(Effect.andThen(Effect.sync(commitRefresh))),\n Effect.promise(() => published.retired),\n ).pipe(\n Effect.ensuring(release),\n Effect.catch((cause) =>\n Effect.logError('Failed to stream the refreshed route.', cause),\n ),\n Effect.forkIn(browserScope, { startImmediately: true }),\n );\n yield* Effect.addFinalizer(() =>\n Effect.sync(() => {\n // The stream fiber awaits retirement; waiting here could block the replacement render.\n void published.discard();\n }),\n );\n return published;\n },\n Effect.onError((cause) => Scope.close(responseScope, Exit.failCause(cause))),\n ),\n );\n\n if (render !== undefined) {\n yield* Effect.promise(() => render.committed);\n }\n });\n\n const refreshCurrentRoute = Effect.fnUntraced(\n function* (transitionType: RouteRefreshTransitionType) {\n routeLoader.invalidate();\n yield* waitForNavigationIdle;\n // Only publication belongs to a React Transition. An async Action waiting for this\n // effect would prevent the very UI commit that completes the refresh.\n yield* Effect.raceFirst(refreshRoute(transitionType), waitForRoutedNavigation);\n },\n Effect.scoped,\n Effect.catch((cause) => Effect.logError('Failed to refresh the current route.', cause)),\n );\n\n yield* routeRefresher.replace({\n interruptCurrentRouteRefresh: FiberHandle.clear(refreshes),\n refreshCurrentRoute: (transitionType) =>\n FiberHandle.run(refreshes, refreshCurrentRoute(transitionType)).pipe(Effect.asVoid),\n });\n});\n"],"names":["Context","Effect","Exit","FiberHandle","Layer","Ref","Scope","addTransitionType","startTransition","BrowserRenderer","NavigationApi","isRoutedNavigation","preserveRequestedHash","RouteLoader","RouteRefresher","navigationApi","implementation","interruptCurrentRouteRefresh","current","refreshCurrentRoute","transitionType","replacement","installRouteRefresh","browserRenderer","routeLoader","routeRefresher","refreshes","browserScope","waitForNavigationIdle","transition","undefined","state","waitForRoutedNavigation","resume","onNavigate","event","unsubscribe","refreshRoute","responseScope","render","restore","currentEntry","destination","URL","resource","release","resolvedDestination","commitRefresh","published","cause"],"mappings":"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"}
package/dist/dev/panel.js CHANGED
@@ -35,7 +35,7 @@ __webpack_require__.add = function registerModules(modules) { Object.assign(__we
35
35
  })();
36
36
 
37
37
  __webpack_require__.add({
38
- 7411(__unused_rspack_module, exports, __webpack_require__) {
38
+ 9501(__unused_rspack_module, exports, __webpack_require__) {
39
39
  /**
40
40
  * @license React
41
41
  * use-sync-external-store-shim.development.js
@@ -134,7 +134,7 @@ __webpack_require__.add({
134
134
 
135
135
 
136
136
  },
137
- 6007(__unused_rspack_module, exports, __webpack_require__) {
137
+ 1909(__unused_rspack_module, exports, __webpack_require__) {
138
138
  /**
139
139
  * @license React
140
140
  * use-sync-external-store-shim.production.js
@@ -204,7 +204,7 @@ exports.useSyncExternalStore =
204
204
 
205
205
 
206
206
  },
207
- 4302(__unused_rspack_module, exports, __webpack_require__) {
207
+ 4400(__unused_rspack_module, exports, __webpack_require__) {
208
208
  /**
209
209
  * @license React
210
210
  * use-sync-external-store-shim/with-selector.development.js
@@ -226,7 +226,7 @@ exports.useSyncExternalStore =
226
226
  typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&
227
227
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());
228
228
  var React = __webpack_require__(2015),
229
- shim = __webpack_require__(6666),
229
+ shim = __webpack_require__(9896),
230
230
  objectIs = "function" === typeof Object.is ? Object.is : is,
231
231
  useSyncExternalStore = shim.useSyncExternalStore,
232
232
  useRef = React.useRef,
@@ -305,7 +305,7 @@ exports.useSyncExternalStore =
305
305
 
306
306
 
307
307
  },
308
- 5284(__unused_rspack_module, exports, __webpack_require__) {
308
+ 5050(__unused_rspack_module, exports, __webpack_require__) {
309
309
  /**
310
310
  * @license React
311
311
  * use-sync-external-store-shim/with-selector.production.js
@@ -318,7 +318,7 @@ exports.useSyncExternalStore =
318
318
 
319
319
 
320
320
  var React = __webpack_require__(2015),
321
- shim = __webpack_require__(6666);
321
+ shim = __webpack_require__(9896);
322
322
  function is(x, y) {
323
323
  return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
324
324
  }
@@ -394,24 +394,24 @@ exports.useSyncExternalStoreWithSelector = function (
394
394
 
395
395
 
396
396
  },
397
- 6666(module, __unused_rspack_exports, __webpack_require__) {
397
+ 9896(module, __unused_rspack_exports, __webpack_require__) {
398
398
 
399
399
 
400
400
  if (process.env.NODE_ENV === 'production') {
401
- module.exports = __webpack_require__(6007);
401
+ module.exports = __webpack_require__(1909);
402
402
  } else {
403
- module.exports = __webpack_require__(7411);
403
+ module.exports = __webpack_require__(9501);
404
404
  }
405
405
 
406
406
 
407
407
  },
408
- 9892(module, __unused_rspack_exports, __webpack_require__) {
408
+ 4578(module, __unused_rspack_exports, __webpack_require__) {
409
409
 
410
410
 
411
411
  if (process.env.NODE_ENV === 'production') {
412
- module.exports = __webpack_require__(5284);
412
+ module.exports = __webpack_require__(5050);
413
413
  } else {
414
- module.exports = __webpack_require__(4302);
414
+ module.exports = __webpack_require__(4400);
415
415
  }
416
416
 
417
417
 
@@ -4455,8 +4455,8 @@ function useDismiss(context, props = {}) {
4455
4455
 
4456
4456
 
4457
4457
 
4458
- const shim = __webpack_require__("6666");
4459
- const with_selector = __webpack_require__("9892");
4458
+ const shim = __webpack_require__("9896");
4459
+ const with_selector = __webpack_require__("4578");
4460
4460
 
4461
4461
  /* We need to import the shim because React 17 does not support the `useSyncExternalStore` API.
4462
4462
  * More info: https://github.com/mui/mui-x/issues/18303#issuecomment-2958392341 */