effective-rsc 0.1.1 → 0.1.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.
- package/LLMS.md +6 -3
- package/README.md +3 -3
- package/dist/client/application.js +8 -8
- package/dist/client/application.js.map +1 -1
- package/dist/client/browser-capabilities.d.ts +2 -9
- package/dist/client/browser-capabilities.js +3 -14
- package/dist/client/browser-capabilities.js.map +1 -1
- package/dist/client/navigation-api.js +5 -4
- package/dist/client/navigation-api.js.map +1 -1
- package/dist/dev/client.js +14 -1
- package/dist/dev/client.js.map +1 -1
- package/dist/dev/panel.d.ts +6 -0
- package/dist/dev/panel.js +55 -2
- package/dist/dev/panel.js.map +1 -1
- package/docs/03-advanced/02-client-navigation/index.md +6 -3
- package/package.json +1 -1
package/LLMS.md
CHANGED
|
@@ -183,9 +183,12 @@ Give work that must outlive a request an explicit application-owned scope.
|
|
|
183
183
|
|
|
184
184
|
ERSC handles eligible document navigations through the browser Navigation API and
|
|
185
185
|
`NavigationPrecommitController`. There is no History API fallback. A browser missing either one
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
186
|
+
still hydrates Client Components and supports Server Functions and streamed current-page refreshes,
|
|
187
|
+
including HMR. Links use full-page navigation instead of the client router. Without JavaScript,
|
|
188
|
+
the server-rendered document retains working links and natively submitted forms.
|
|
189
|
+
|
|
190
|
+
Development reports a missing navigation API in the console and a dismissible development-panel
|
|
191
|
+
warning. The warning does not block interaction and is absent in production.
|
|
189
192
|
|
|
190
193
|
An intercepted Page navigation has two milestones:
|
|
191
194
|
|
package/README.md
CHANGED
|
@@ -24,9 +24,9 @@ native RSC support.
|
|
|
24
24
|
## Requirements
|
|
25
25
|
|
|
26
26
|
- Bun 1.4 or newer is the only supported server runtime.
|
|
27
|
-
- Client navigation
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
- Client navigation requires the Navigation API and `NavigationPrecommitController`; there is no
|
|
28
|
+
History API fallback. Browsers without them still hydrate Client Components and support Server
|
|
29
|
+
Functions, but links use full-page navigation. Without JavaScript, links and native forms still work.
|
|
30
30
|
- React, React DOM, Effect, Effect's browser and Bun platforms, and
|
|
31
31
|
`react-server-dom-rspack` must use the exact compatible versions shown below.
|
|
32
32
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Effect, Layer } from "effect";
|
|
2
|
-
import {
|
|
2
|
+
import { navigationMode } from "./browser-capabilities.js";
|
|
3
3
|
import { BrowserEffectRunner } from "./browser-effect-runner.js";
|
|
4
4
|
import { BrowserRenderStatus } from "./browser-render-status.js";
|
|
5
5
|
import { BrowserRenderer } from "./browser-renderer.js";
|
|
@@ -48,25 +48,25 @@ import * as __rspack_external__effect_platform_browser_BrowserHttpClient_04160dc
|
|
|
48
48
|
const BrowserServicesLayer = Layer.mergeAll(BrowserEffectRunner.layer, BrowserRenderer.layer, BrowserRenderStatus.layer, FlightClient.layer, NavigationApi.layer).pipe(Layer.provide(InitialFlightStream.layer));
|
|
49
49
|
const BrowserLayer = Layer.mergeAll(ReactDOMRenderer.layer, RouteLoader.layer, RouteRefresher.layer).pipe(Layer.provideMerge(BrowserServicesLayer), Layer.provide(__rspack_external__effect_platform_browser_BrowserHttpClient_04160dce.layerFetch));
|
|
50
50
|
const renderBrowserFailure = Effect.sync(showBrowserFailure);
|
|
51
|
-
const
|
|
52
|
-
const activateClientNavigation = Effect.gen(function*() {
|
|
51
|
+
const activateBrowser = Effect.gen(function*() {
|
|
53
52
|
const routeLoader = yield* RouteLoader;
|
|
54
53
|
const reactDOMRenderer = yield* ReactDOMRenderer;
|
|
55
54
|
const initialPayload = yield* routeLoader.loadInitial;
|
|
56
55
|
yield* reactDOMRenderer.hydrate(document, initialPayload);
|
|
57
|
-
yield* installClientRouter;
|
|
58
56
|
yield* installRouteRefresh;
|
|
59
57
|
yield* installCallServer;
|
|
58
|
+
const mode = yield* navigationMode;
|
|
59
|
+
if (mode === 'Client') {
|
|
60
|
+
yield* installClientRouter;
|
|
61
|
+
}
|
|
60
62
|
});
|
|
61
63
|
const browserMain = Effect.scoped(Effect.gen(function*() {
|
|
62
64
|
if (process.env.NODE_ENV === 'development') {
|
|
63
65
|
yield* Effect.tryPromise(()=>import("../dev/client.js")).pipe(Effect.flatMap(({ startDevClient })=>startDevClient), Effect["catch"]((cause)=>Effect.logError('Development client stopped.', cause)), Effect.forkScoped);
|
|
64
66
|
}
|
|
65
|
-
yield*
|
|
67
|
+
yield* activateBrowser.pipe(Effect.catchTags({
|
|
66
68
|
FlightLoadError: ()=>renderBrowserFailure,
|
|
67
|
-
ReactDOMHydrationError: ()=>renderBrowserFailure
|
|
68
|
-
NavigationApiUnavailableError: ()=>skipHydration('the Navigation API'),
|
|
69
|
-
NavigationPrecommitUnavailableError: ()=>skipHydration('NavigationPrecommitController')
|
|
69
|
+
ReactDOMHydrationError: ()=>renderBrowserFailure
|
|
70
70
|
}));
|
|
71
71
|
return yield* Effect.never;
|
|
72
72
|
})).pipe(Effect.provide(BrowserLayer));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client/application.js","sources":["../../src/client/application.ts"],"sourcesContent":["// oxlint-disable effecttsgo/process-env, effecttsgo/process-env-in-effect -- Rspack replaces NODE_ENV at compile time.\nimport * as BrowserHttpClient from '@effect/platform-browser/BrowserHttpClient';\nimport { Effect, Layer } from 'effect';\n\nimport {
|
|
1
|
+
{"version":3,"file":"client/application.js","sources":["../../src/client/application.ts"],"sourcesContent":["// oxlint-disable effecttsgo/process-env, effecttsgo/process-env-in-effect -- Rspack replaces NODE_ENV at compile time.\nimport * as BrowserHttpClient from '@effect/platform-browser/BrowserHttpClient';\nimport { Effect, Layer } from 'effect';\n\nimport { navigationMode } from './browser-capabilities';\nimport { BrowserEffectRunner } from './browser-effect-runner';\nimport { BrowserRenderStatus } from './browser-render-status';\nimport { BrowserRenderer } from './browser-renderer';\nimport { showBrowserFailure } from './browser-screen';\nimport { installCallServer } from './call-server';\nimport { installClientRouter } from './client-router';\nimport { FlightClient } from './flight-client';\nimport { InitialFlightStream } from './initial-flight-stream';\nimport { NavigationApi } from './navigation-api';\nimport { ReactDOMRenderer } from './react-dom-renderer';\nimport { RouteLoader } from './route-loader';\nimport { installRouteRefresh, RouteRefresher } from './route-refresh';\n\nconst BrowserServicesLayer = Layer.mergeAll(\n BrowserEffectRunner.layer,\n BrowserRenderer.layer,\n BrowserRenderStatus.layer,\n FlightClient.layer,\n NavigationApi.layer,\n).pipe(Layer.provide(InitialFlightStream.layer));\n\nconst BrowserLayer = Layer.mergeAll(\n ReactDOMRenderer.layer,\n RouteLoader.layer,\n RouteRefresher.layer,\n).pipe(Layer.provideMerge(BrowserServicesLayer), Layer.provide(BrowserHttpClient.layerFetch));\n\nconst renderBrowserFailure = Effect.sync(showBrowserFailure);\n\nconst activateBrowser = Effect.gen(function* () {\n const routeLoader = yield* RouteLoader;\n const reactDOMRenderer = yield* ReactDOMRenderer;\n\n const initialPayload = yield* routeLoader.loadInitial;\n yield* reactDOMRenderer.hydrate(document, initialPayload);\n yield* installRouteRefresh;\n yield* installCallServer;\n const mode = yield* navigationMode;\n if (mode === 'Client') {\n yield* installClientRouter;\n }\n});\n\nexport const browserMain = Effect.scoped(\n Effect.gen(function* () {\n if (process.env.NODE_ENV === 'development') {\n yield* Effect.tryPromise(() => import('../dev/client')).pipe(\n Effect.flatMap(({ startDevClient }) => startDevClient),\n Effect.catch((cause) => Effect.logError('Development client stopped.', cause)),\n Effect.forkScoped,\n );\n }\n\n yield* activateBrowser.pipe(\n Effect.catchTags({\n FlightLoadError: () => renderBrowserFailure,\n ReactDOMHydrationError: () => renderBrowserFailure,\n }),\n );\n return yield* Effect.never;\n }),\n).pipe(Effect.provide(BrowserLayer));\n"],"names":["BrowserHttpClient","Effect","Layer","navigationMode","BrowserEffectRunner","BrowserRenderStatus","BrowserRenderer","showBrowserFailure","installCallServer","installClientRouter","FlightClient","InitialFlightStream","NavigationApi","ReactDOMRenderer","RouteLoader","installRouteRefresh","RouteRefresher","BrowserServicesLayer","BrowserLayer","renderBrowserFailure","activateBrowser","routeLoader","reactDOMRenderer","initialPayload","document","mode","browserMain","process","startDevClient","cause"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uHAAuH;AACvC;AACzC;AAEiB;AACM;AACA;AACT;AACC;AACJ;AACI;AACP;AACe;AACb;AACO;AACX;AACyB;AAEtE,MAAMiB,oBAAoBA,GAAGf,cAAc,CACzCE,yBAAyB,EACzBE,qBAAqB,EACrBD,yBAAyB,EACzBK,kBAAkB,EAClBE,mBAAmB,EACnB,IAAI,CAACV,aAAa,CAACS,yBAAyB;AAE9C,MAAMO,YAAYA,GAAGhB,cAAc,CACjCW,sBAAsB,EACtBC,iBAAiB,EACjBE,oBAAoB,EACpB,IAAI,CAACd,kBAAkB,CAACe,oBAAoBA,GAAGf,aAAa,CAACF,gFAA4B;AAE3F,MAAMmB,oBAAoBA,GAAGlB,WAAW,CAACM,kBAAkBA;AAE3D,MAAMa,eAAeA,GAAGnB,UAAU,CAAC;IACjC,MAAMoB,cAAc,OAAOP,WAAWA;IACtC,MAAMQ,mBAAmB,OAAOT,gBAAgBA;IAEhD,MAAMU,iBAAiB,OAAOF,YAAY,WAAW;IACrD,OAAOC,iBAAiB,OAAO,CAACE,UAAUD;IAC1C,OAAOR,mBAAmBA;IAC1B,OAAOP,iBAAiBA;IACxB,MAAMiB,OAAO,OAAOtB,cAAcA;IAClC,IAAIsB,SAAS,UAAU;QACrB,OAAOhB,mBAAmBA;IAC5B;AACF;AAEO,MAAMiB,WAAWA,GAAGzB,aAAa,CACtCA,UAAU,CAAC;IACT,IAAI0B,QAAQ,GAAG,CAAC,QAAQ,KAAK,eAAe;QAC1C,OAAO1B,iBAAiB,CAAC,IAAM,0BAAuB,EAAE,IAAI,CAC1DA,cAAc,CAAC,CAAC,EAAE2B,cAAc,EAAE,GAAKA,iBACvC3B,eAAY,CAAC,CAAC4B,QAAU5B,eAAe,CAAC,+BAA+B4B,SACvE5B,iBAAiB;IAErB;IAEA,OAAOmB,eAAeA,CAAC,IAAI,CACzBnB,gBAAgB,CAAC;QACf,iBAAiB,IAAMkB,oBAAoBA;QAC3C,wBAAwB,IAAMA,oBAAoBA;IACpD;IAEF,OAAO,OAAOlB,YAAY;AAC5B,IACA,IAAI,CAACA,cAAc,CAACiB,YAAYA,GAAG"}
|
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
import { Effect
|
|
2
|
-
declare const
|
|
3
|
-
export declare class NavigationApiUnavailableError extends NavigationApiUnavailableError_base {
|
|
4
|
-
}
|
|
5
|
-
declare const NavigationPrecommitUnavailableError_base: Schema.Class<NavigationPrecommitUnavailableError, Schema.TaggedStruct<"NavigationPrecommitUnavailableError", {}>, import("effect/Cause").YieldableError>;
|
|
6
|
-
export declare class NavigationPrecommitUnavailableError extends NavigationPrecommitUnavailableError_base {
|
|
7
|
-
}
|
|
8
|
-
export declare const checkBrowserCapabilities: Effect.Effect<undefined, NavigationApiUnavailableError | NavigationPrecommitUnavailableError, never>;
|
|
9
|
-
export {};
|
|
1
|
+
import { Effect } from 'effect';
|
|
2
|
+
export declare const navigationMode: Effect.Effect<"Client" | "Document", never, never>;
|
|
@@ -1,20 +1,9 @@
|
|
|
1
|
-
import { Effect
|
|
1
|
+
import { Effect } from "effect";
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
}
|
|
7
|
-
class NavigationPrecommitUnavailableError extends Schema.TaggedError()('NavigationPrecommitUnavailableError', {}) {
|
|
8
|
-
}
|
|
9
|
-
const checkBrowserCapabilities = Effect.gen(function*() {
|
|
10
|
-
if (window.navigation === undefined) {
|
|
11
|
-
return yield* new NavigationApiUnavailableError();
|
|
12
|
-
}
|
|
13
|
-
if (window.NavigationPrecommitController === undefined) {
|
|
14
|
-
return yield* new NavigationPrecommitUnavailableError();
|
|
15
|
-
}
|
|
16
|
-
});
|
|
5
|
+
const navigationMode = Effect.sync(()=>window.navigation !== undefined && window.NavigationPrecommitController !== undefined ? 'Client' : 'Document');
|
|
17
6
|
|
|
18
|
-
export {
|
|
7
|
+
export { navigationMode };
|
|
19
8
|
|
|
20
9
|
//# sourceMappingURL=browser-capabilities.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client/browser-capabilities.js","sources":["../../src/client/browser-capabilities.ts"],"sourcesContent":["import { Effect
|
|
1
|
+
{"version":3,"file":"client/browser-capabilities.js","sources":["../../src/client/browser-capabilities.ts"],"sourcesContent":["import { Effect } from 'effect';\n\nexport const navigationMode = Effect.sync(() =>\n window.navigation !== undefined && window.NavigationPrecommitController !== undefined\n ? ('Client' as const)\n : ('Document' as const),\n);\n"],"names":["Effect","navigationMode","window","undefined"],"mappings":";;;AAAgC;AAEzB,MAAMC,cAAcA,GAAGD,WAAW,CAAC,IACxCE,OAAO,UAAU,KAAKC,aAAaD,OAAO,6BAA6B,KAAKC,YACvE,WACA,YACL"}
|
|
@@ -4,15 +4,16 @@ import { Context, Effect, Layer } from "effect";
|
|
|
4
4
|
|
|
5
5
|
class NavigationApi extends Context.Service()('ersc/client/NavigationApi', {
|
|
6
6
|
make: Effect.succeed({
|
|
7
|
-
getCurrentEntry: ()=>window.navigation
|
|
7
|
+
getCurrentEntry: ()=>window.navigation?.currentEntry ?? null,
|
|
8
8
|
getCurrentUrl: ()=>window.location.href,
|
|
9
|
-
getTransition: ()=>window.navigation
|
|
9
|
+
getTransition: ()=>window.navigation?.transition ?? null,
|
|
10
10
|
navigate: (url, options)=>window.navigation.navigate(url, options),
|
|
11
11
|
reloadDocument: ()=>window.location.reload(),
|
|
12
12
|
replaceDocument: (url)=>window.location.replace(url),
|
|
13
13
|
subscribe: (listener)=>{
|
|
14
|
-
window.navigation
|
|
15
|
-
|
|
14
|
+
const navigation = window.navigation;
|
|
15
|
+
navigation?.addEventListener('navigate', listener);
|
|
16
|
+
return ()=>navigation?.removeEventListener('navigate', listener);
|
|
16
17
|
}
|
|
17
18
|
})
|
|
18
19
|
}) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client/navigation-api.js","sources":["../../src/client/navigation-api.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect';\n\ntype NavigateListener = (event: NavigateEvent) => void;\n\nexport class NavigationApi extends Context.Service<NavigationApi>()('ersc/client/NavigationApi', {\n make: Effect.succeed({\n getCurrentEntry: () => window.navigation
|
|
1
|
+
{"version":3,"file":"client/navigation-api.js","sources":["../../src/client/navigation-api.ts"],"sourcesContent":["import { Context, Effect, Layer } from 'effect';\n\ntype NavigateListener = (event: NavigateEvent) => void;\n\nexport class NavigationApi extends Context.Service<NavigationApi>()('ersc/client/NavigationApi', {\n make: Effect.succeed({\n getCurrentEntry: () => window.navigation?.currentEntry ?? null,\n getCurrentUrl: () => window.location.href,\n getTransition: () => window.navigation?.transition ?? null,\n navigate: (url: string | URL, options?: NavigationNavigateOptions) =>\n window.navigation.navigate(url, options),\n reloadDocument: () => window.location.reload(),\n replaceDocument: (url: string) => window.location.replace(url),\n subscribe: (listener: NavigateListener) => {\n const navigation = window.navigation;\n navigation?.addEventListener('navigate', listener);\n return () => navigation?.removeEventListener('navigate', listener);\n },\n }),\n}) {\n static readonly layer = Layer.effect(this, this.make);\n\n static readonly layerTest = Layer.mock(this);\n}\n"],"names":["Context","Effect","Layer","NavigationApi","window","url","options","listener","navigation"],"mappings":";;;AAAgD;AAIzC,MAAMG,aAAaA,SAASH,eAAe,GAAkB,6BAA6B;IAC/F,MAAMC,cAAc,CAAC;QACnB,iBAAiB,IAAMG,OAAO,UAAU,EAAE,gBAAgB;QAC1D,eAAe,IAAMA,OAAO,QAAQ,CAAC,IAAI;QACzC,eAAe,IAAMA,OAAO,UAAU,EAAE,cAAc;QACtD,UAAU,CAACC,KAAmBC,UAC5BF,OAAO,UAAU,CAAC,QAAQ,CAACC,KAAKC;QAClC,gBAAgB,IAAMF,OAAO,QAAQ,CAAC,MAAM;QAC5C,iBAAiB,CAACC,MAAgBD,OAAO,QAAQ,CAAC,OAAO,CAACC;QAC1D,WAAW,CAACE;YACV,MAAMC,aAAaJ,OAAO,UAAU;YACpCI,YAAY,iBAAiB,YAAYD;YACzC,OAAO,IAAMC,YAAY,oBAAoB,YAAYD;QAC3D;IACF;AACF;IACE,OAAgB,QAAQL,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;IAEtD,OAAgB,YAAYA,UAAU,CAAC,IAAI,EAAE;AAC/C"}
|
package/dist/dev/client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { Effect, Layer, Ref, Semaphore, Stream } from "effect";
|
|
1
|
+
import { Console, Effect, Layer, Ref, Semaphore, Stream } from "effect";
|
|
2
2
|
import { RpcClient, RpcSerialization } from "effect/unstable/rpc";
|
|
3
|
+
import { navigationMode } from "../client/browser-capabilities.js";
|
|
3
4
|
import { BrowserRenderStatus } from "../client/browser-render-status.js";
|
|
4
5
|
import { RouteRefresher } from "../client/route-refresh.js";
|
|
5
6
|
import { DevChannelPath, DevRpcs } from "./channel.js";
|
|
@@ -26,6 +27,8 @@ import * as __rspack_external__effect_platform_browser_BrowserSocket_31178d5b fr
|
|
|
26
27
|
|
|
27
28
|
|
|
28
29
|
|
|
30
|
+
|
|
31
|
+
|
|
29
32
|
const socketProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
30
33
|
const socketUrl = `${socketProtocol}//${location.host}${DevChannelPath}`;
|
|
31
34
|
const DevRpcProtocolLayer = RpcClient.layerProtocolSocket({
|
|
@@ -93,6 +96,16 @@ const startDevClient = Effect.gen(function*() {
|
|
|
93
96
|
const routeRefresher = yield* RouteRefresher;
|
|
94
97
|
const renderStatus = yield* BrowserRenderStatus;
|
|
95
98
|
const panel = yield* makeDevPanel;
|
|
99
|
+
const mode = yield* navigationMode;
|
|
100
|
+
if (mode === 'Document') {
|
|
101
|
+
const missingApi = window.navigation === undefined ? 'Navigation API' : 'NavigationPrecommitController';
|
|
102
|
+
const message = `This browser does not support ${missingApi}. Links use full-page navigation. Client Components, Server Functions, and HMR remain enabled.`;
|
|
103
|
+
yield* Console.warn(`[effective-rsc] ${message}`);
|
|
104
|
+
yield* panel.dispatch({
|
|
105
|
+
_tag: 'Warning',
|
|
106
|
+
message
|
|
107
|
+
});
|
|
108
|
+
}
|
|
96
109
|
const pendingUpdate = yield* Ref.make({
|
|
97
110
|
acknowledgedClientHash: import.meta.rspackHash,
|
|
98
111
|
clientHash: import.meta.rspackHash,
|
package/dist/dev/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev/client.js","sources":["../../src/dev/client.ts"],"sourcesContent":["import * as BrowserSocket from '@effect/platform-browser/BrowserSocket';\nimport { Effect, Layer, Ref, Semaphore, Stream } from 'effect';\nimport { RpcClient, RpcSerialization } from 'effect/unstable/rpc';\n\nimport { BrowserRenderStatus } from '../client/browser-render-status';\nimport { RouteRefresher } from '../client/route-refresh';\nimport { DevChannelPath, DevRpcs, type DevUpdate } from './channel';\nimport { decideHotUpdate, type HotUpdateCheck, type PendingDevUpdate } from './hmr-update';\nimport { makeDevPanel } from './panel';\nimport { fromRenderError, reportBrowserFailures } from './runtime-failure';\n\nconst socketProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';\nconst socketUrl = `${socketProtocol}//${location.host}${DevChannelPath}`;\n\nconst DevRpcProtocolLayer = RpcClient.layerProtocolSocket({ retryTransientErrors: true }).pipe(\n Layer.provide(BrowserSocket.layerWebSocket(socketUrl)),\n Layer.provide(RpcSerialization.layerJson),\n);\n\ntype DevHotUpdate = Exclude<DevUpdate, { readonly _tag: 'BuildFailed' }>;\ntype DevUpdatePhase = 'Snapshot' | 'Live';\n\nconst recordUpdate = (pending: PendingDevUpdate, message: DevHotUpdate): PendingDevUpdate => ({\n acknowledgedClientHash: pending.acknowledgedClientHash,\n clientHash: message.clientHash,\n rscRefresh:\n pending.rscRefresh === 'Pending' || message._tag === 'RscUpdate' ? 'Pending' : 'Current',\n});\n\nconst settlePendingUpdate = Effect.fnUntraced(function* (pendingUpdate: Ref.Ref<PendingDevUpdate>) {\n const reconcile = Effect.gen(function* () {\n const pending = yield* Ref.get(pendingUpdate);\n if (pending.acknowledgedClientHash !== pending.clientHash) {\n const previousHash = import.meta.rspackHash;\n const check = yield* Effect.tryPromise(() => import.meta.webpackHot!.check(true)).pipe(\n Effect.match({\n onFailure: (): HotUpdateCheck => ({ _tag: 'Failed' }),\n onSuccess: (updatedModules): HotUpdateCheck => ({\n _tag: 'Completed',\n currentHash: import.meta.rspackHash,\n previousHash,\n updatedModules,\n }),\n }),\n );\n const decision = decideHotUpdate(pending, check);\n if (decision._tag === 'Reload') {\n yield* Effect.sync(() => location.reload());\n return 'Reloading' as const;\n }\n\n yield* Ref.update(pendingUpdate, (current) => ({\n ...current,\n acknowledgedClientHash: decision.acknowledgedClientHash,\n }));\n return 'Retry' as const;\n }\n\n return yield* Ref.modify(pendingUpdate, (current) => {\n if (current.acknowledgedClientHash !== current.clientHash) {\n return ['Retry', current] as const;\n }\n if (current.rscRefresh === 'Current') {\n return ['Current', current] as const;\n }\n return ['Refresh', { ...current, rscRefresh: 'Current' }] as const;\n });\n });\n\n return yield* reconcile.pipe(Effect.repeat({ while: (action) => action === 'Retry' }));\n});\n\nexport const startDevClient = Effect.gen(function* () {\n const routeRefresher = yield* RouteRefresher;\n const renderStatus = yield* BrowserRenderStatus;\n const panel = yield* makeDevPanel;\n const pendingUpdate = yield* Ref.make<PendingDevUpdate>({\n acknowledgedClientHash: import.meta.rspackHash,\n clientHash: import.meta.rspackHash,\n rscRefresh: 'Current',\n });\n const updateLock = yield* Semaphore.make(1);\n const handleHotUpdate = Effect.fnUntraced(function* (message: DevHotUpdate) {\n yield* Ref.update(pendingUpdate, (pending) => recordUpdate(pending, message));\n const action = yield* updateLock.withPermit(settlePendingUpdate(pendingUpdate));\n if (action === 'Reloading') {\n return;\n }\n const status = yield* renderStatus.get;\n if (action === 'Refresh' || status._tag === 'Failed') {\n yield* routeRefresher.refreshCurrentRoute('hmr-refresh');\n // Starting a refresh is not evidence that the replacement rendered successfully.\n return;\n }\n yield* panel.dispatch({ _tag: 'RuntimeReconciled' });\n });\n yield* renderStatus.changes.pipe(\n Stream.runForEach((status) => {\n switch (status._tag) {\n case 'Waiting':\n return Effect.void;\n case 'Rendered':\n return panel.dispatch({ _tag: 'RuntimeReconciled' });\n case 'Failed':\n return panel.dispatch({\n _tag: 'RenderFailed',\n failure: fromRenderError(status.error, status.componentStack),\n });\n }\n }),\n Effect.forkScoped,\n );\n yield* reportBrowserFailures((failure) =>\n panel.dispatch({ _tag: 'RuntimeFailed', failure }),\n ).pipe(Effect.forkScoped);\n\n const observeUpdates = Effect.gen(function* () {\n const client = yield* RpcClient.make(DevRpcs);\n const handleUpdate = Effect.fnUntraced(function* (phase: DevUpdatePhase, message: DevUpdate) {\n if (message._tag === 'BuildFailed') {\n yield* panel.dispatch(message);\n } else {\n yield* panel.dispatch({ _tag: 'BuildSucceeded' });\n if (phase === 'Live' || message.clientHash !== import.meta.rspackHash) {\n yield* handleHotUpdate(message);\n }\n }\n\n return 'Live' as const;\n });\n\n yield* client.ObserveDevUpdates().pipe(\n Stream.runFoldEffect((): DevUpdatePhase => 'Snapshot', handleUpdate),\n Effect.asVoid,\n );\n });\n\n yield* observeUpdates.pipe(Effect.provide(DevRpcProtocolLayer));\n});\n"],"names":["BrowserSocket","Effect","Layer","Ref","Semaphore","Stream","RpcClient","RpcSerialization","BrowserRenderStatus","RouteRefresher","DevChannelPath","DevRpcs","decideHotUpdate","makeDevPanel","fromRenderError","reportBrowserFailures","socketProtocol","location","socketUrl","DevRpcProtocolLayer","recordUpdate","pending","message","settlePendingUpdate","pendingUpdate","reconcile","previousHash","check","updatedModules","decision","current","action","startDevClient","routeRefresher","renderStatus","panel","updateLock","handleHotUpdate","status","failure","observeUpdates","client","handleUpdate","phase"],"mappings":";;;;;;;;;;;;;;;;;;;AAAwE;AACT;AACG;AAEI;AACb;AACW;AACuB;AACpD;AACoC;AAE3E,MAAMgB,cAAcA,GAAGC,SAAS,QAAQ,KAAK,WAAW,SAAS;AACjE,MAAMC,SAASA,GAAG,GAAGF,cAAcA,CAAC,EAAE,EAAEC,SAAS,IAAI,GAAGP,cAAcA,EAAE;AAExE,MAAMS,mBAAmBA,GAAGb,6BAA6B,CAAC;IAAE,sBAAsB;AAAK,GAAG,IAAI,CAC5FJ,aAAa,CAACF,gFAA4B,CAACkB,SAASA,IACpDhB,aAAa,CAACK,0BAA0B;AAM1C,MAAMa,YAAYA,GAAG,CAACC,SAA2BC,UAA6C;QAC5F,wBAAwBD,QAAQ,sBAAsB;QACtD,YAAYC,QAAQ,UAAU;QAC9B,YACED,QAAQ,UAAU,KAAK,aAAaC,QAAQ,IAAI,KAAK,cAAc,YAAY;IACnF;AAEA,MAAMC,mBAAmBA,GAAGtB,iBAAiB,CAAC,UAAWuB,aAAwC;IAC/F,MAAMC,YAAYxB,UAAU,CAAC;QAC3B,MAAMoB,UAAU,OAAOlB,OAAO,CAACqB;QAC/B,IAAIH,QAAQ,sBAAsB,KAAKA,QAAQ,UAAU,EAAE;YACzD,MAAMK,eAAe,YAAY,UAAU;YAC3C,MAAMC,QAAQ,OAAO1B,iBAAiB,CAAC,IAAM,YAAY,UAAU,CAAE,KAAK,CAAC,OAAO,IAAI,CACpFA,YAAY,CAAC;gBACX,WAAW,IAAuB;wBAAE,MAAM;oBAAS;gBACnD,WAAW,CAAC2B,iBAAoC;wBAC9C,MAAM;wBACN,aAAa,YAAY,UAAU;wBACnCF;wBACAE;oBACF;YACF;YAEF,MAAMC,WAAWjB,eAAeA,CAACS,SAASM;YAC1C,IAAIE,SAAS,IAAI,KAAK,UAAU;gBAC9B,OAAO5B,WAAW,CAAC,IAAMgB,SAAS,MAAM;gBACxC,OAAO;YACT;YAEA,OAAOd,UAAU,CAACqB,eAAe,CAACM,UAAa;oBAC7C,GAAGA,OAAO;oBACV,wBAAwBD,SAAS,sBAAsB;gBACzD;YACA,OAAO;QACT;QAEA,OAAO,OAAO1B,UAAU,CAACqB,eAAe,CAACM;YACvC,IAAIA,QAAQ,sBAAsB,KAAKA,QAAQ,UAAU,EAAE;gBACzD,OAAO;oBAAC;oBAASA;iBAAQ;YAC3B;YACA,IAAIA,QAAQ,UAAU,KAAK,WAAW;gBACpC,OAAO;oBAAC;oBAAWA;iBAAQ;YAC7B;YACA,OAAO;gBAAC;gBAAW;oBAAE,GAAGA,OAAO;oBAAE,YAAY;gBAAU;aAAE;QAC3D;IACF;IAEA,OAAO,OAAOL,UAAU,IAAI,CAACxB,aAAa,CAAC;QAAE,OAAO,CAAC8B,SAAWA,WAAW;IAAQ;AACrF;AAEO,MAAMC,cAAcA,GAAG/B,UAAU,CAAC;IACvC,MAAMgC,iBAAiB,OAAOxB,cAAcA;IAC5C,MAAMyB,eAAe,OAAO1B,mBAAmBA;IAC/C,MAAM2B,QAAQ,OAAOtB,YAAYA;IACjC,MAAMW,gBAAgB,OAAOrB,QAAQ,CAAmB;QACtD,wBAAwB,YAAY,UAAU;QAC9C,YAAY,YAAY,UAAU;QAClC,YAAY;IACd;IACA,MAAMiC,aAAa,OAAOhC,cAAc,CAAC;IACzC,MAAMiC,kBAAkBpC,iBAAiB,CAAC,UAAWqB,OAAqB;QACxE,OAAOnB,UAAU,CAACqB,eAAe,CAACH,UAAYD,YAAYA,CAACC,SAASC;QACpE,MAAMS,SAAS,OAAOK,WAAW,UAAU,CAACb,mBAAmBA,CAACC;QAChE,IAAIO,WAAW,aAAa;YAC1B;QACF;QACA,MAAMO,SAAS,OAAOJ,aAAa,GAAG;QACtC,IAAIH,WAAW,aAAaO,OAAO,IAAI,KAAK,UAAU;YACpD,OAAOL,eAAe,mBAAmB,CAAC;YAC1C,iFAAiF;YACjF;QACF;QACA,OAAOE,MAAM,QAAQ,CAAC;YAAE,MAAM;QAAoB;IACpD;IACA,OAAOD,aAAa,OAAO,CAAC,IAAI,CAC9B7B,iBAAiB,CAAC,CAACiC;QACjB,OAAQA,OAAO,IAAI;YACjB,KAAK;gBACH,OAAOrC,cAAW;YACpB,KAAK;gBACH,OAAOkC,MAAM,QAAQ,CAAC;oBAAE,MAAM;gBAAoB;YACpD,KAAK;gBACH,OAAOA,MAAM,QAAQ,CAAC;oBACpB,MAAM;oBACN,SAASrB,eAAeA,CAACwB,OAAO,KAAK,EAAEA,OAAO,cAAc;gBAC9D;QACJ;IACF,IACArC,iBAAiB;IAEnB,OAAOc,qBAAqBA,CAAC,CAACwB,UAC5BJ,MAAM,QAAQ,CAAC;YAAE,MAAM;YAAiBI;QAAQ,IAChD,IAAI,CAACtC,iBAAiB;IAExB,MAAMuC,iBAAiBvC,UAAU,CAAC;QAChC,MAAMwC,SAAS,OAAOnC,cAAc,CAACK,OAAOA;QAC5C,MAAM+B,eAAezC,iBAAiB,CAAC,UAAW0C,KAAqB,EAAErB,OAAkB;YACzF,IAAIA,QAAQ,IAAI,KAAK,eAAe;gBAClC,OAAOa,MAAM,QAAQ,CAACb;YACxB,OAAO;gBACL,OAAOa,MAAM,QAAQ,CAAC;oBAAE,MAAM;gBAAiB;gBAC/C,IAAIQ,UAAU,UAAUrB,QAAQ,UAAU,KAAK,YAAY,UAAU,EAAE;oBACrE,OAAOe,gBAAgBf;gBACzB;YACF;YAEA,OAAO;QACT;QAEA,OAAOmB,OAAO,iBAAiB,GAAG,IAAI,CACpCpC,oBAAoB,CAAC,IAAsB,YAAYqC,eACvDzC,aAAa;IAEjB;IAEA,OAAOuC,eAAe,IAAI,CAACvC,cAAc,CAACkB,mBAAmBA;AAC/D,GAAG"}
|
|
1
|
+
{"version":3,"file":"dev/client.js","sources":["../../src/dev/client.ts"],"sourcesContent":["import * as BrowserSocket from '@effect/platform-browser/BrowserSocket';\nimport { Console, Effect, Layer, Ref, Semaphore, Stream } from 'effect';\nimport { RpcClient, RpcSerialization } from 'effect/unstable/rpc';\n\nimport { navigationMode } from '../client/browser-capabilities';\nimport { BrowserRenderStatus } from '../client/browser-render-status';\nimport { RouteRefresher } from '../client/route-refresh';\nimport { DevChannelPath, DevRpcs, type DevUpdate } from './channel';\nimport { decideHotUpdate, type HotUpdateCheck, type PendingDevUpdate } from './hmr-update';\nimport { makeDevPanel } from './panel';\nimport { fromRenderError, reportBrowserFailures } from './runtime-failure';\n\nconst socketProtocol = location.protocol === 'https:' ? 'wss:' : 'ws:';\nconst socketUrl = `${socketProtocol}//${location.host}${DevChannelPath}`;\n\nconst DevRpcProtocolLayer = RpcClient.layerProtocolSocket({ retryTransientErrors: true }).pipe(\n Layer.provide(BrowserSocket.layerWebSocket(socketUrl)),\n Layer.provide(RpcSerialization.layerJson),\n);\n\ntype DevHotUpdate = Exclude<DevUpdate, { readonly _tag: 'BuildFailed' }>;\ntype DevUpdatePhase = 'Snapshot' | 'Live';\n\nconst recordUpdate = (pending: PendingDevUpdate, message: DevHotUpdate): PendingDevUpdate => ({\n acknowledgedClientHash: pending.acknowledgedClientHash,\n clientHash: message.clientHash,\n rscRefresh:\n pending.rscRefresh === 'Pending' || message._tag === 'RscUpdate' ? 'Pending' : 'Current',\n});\n\nconst settlePendingUpdate = Effect.fnUntraced(function* (pendingUpdate: Ref.Ref<PendingDevUpdate>) {\n const reconcile = Effect.gen(function* () {\n const pending = yield* Ref.get(pendingUpdate);\n if (pending.acknowledgedClientHash !== pending.clientHash) {\n const previousHash = import.meta.rspackHash;\n const check = yield* Effect.tryPromise(() => import.meta.webpackHot!.check(true)).pipe(\n Effect.match({\n onFailure: (): HotUpdateCheck => ({ _tag: 'Failed' }),\n onSuccess: (updatedModules): HotUpdateCheck => ({\n _tag: 'Completed',\n currentHash: import.meta.rspackHash,\n previousHash,\n updatedModules,\n }),\n }),\n );\n const decision = decideHotUpdate(pending, check);\n if (decision._tag === 'Reload') {\n yield* Effect.sync(() => location.reload());\n return 'Reloading' as const;\n }\n\n yield* Ref.update(pendingUpdate, (current) => ({\n ...current,\n acknowledgedClientHash: decision.acknowledgedClientHash,\n }));\n return 'Retry' as const;\n }\n\n return yield* Ref.modify(pendingUpdate, (current) => {\n if (current.acknowledgedClientHash !== current.clientHash) {\n return ['Retry', current] as const;\n }\n if (current.rscRefresh === 'Current') {\n return ['Current', current] as const;\n }\n return ['Refresh', { ...current, rscRefresh: 'Current' }] as const;\n });\n });\n\n return yield* reconcile.pipe(Effect.repeat({ while: (action) => action === 'Retry' }));\n});\n\nexport const startDevClient = Effect.gen(function* () {\n const routeRefresher = yield* RouteRefresher;\n const renderStatus = yield* BrowserRenderStatus;\n const panel = yield* makeDevPanel;\n const mode = yield* navigationMode;\n if (mode === 'Document') {\n const missingApi =\n window.navigation === undefined ? 'Navigation API' : 'NavigationPrecommitController';\n const message = `This browser does not support ${missingApi}. Links use full-page navigation. Client Components, Server Functions, and HMR remain enabled.`;\n yield* Console.warn(`[effective-rsc] ${message}`);\n yield* panel.dispatch({ _tag: 'Warning', message });\n }\n const pendingUpdate = yield* Ref.make<PendingDevUpdate>({\n acknowledgedClientHash: import.meta.rspackHash,\n clientHash: import.meta.rspackHash,\n rscRefresh: 'Current',\n });\n const updateLock = yield* Semaphore.make(1);\n const handleHotUpdate = Effect.fnUntraced(function* (message: DevHotUpdate) {\n yield* Ref.update(pendingUpdate, (pending) => recordUpdate(pending, message));\n const action = yield* updateLock.withPermit(settlePendingUpdate(pendingUpdate));\n if (action === 'Reloading') {\n return;\n }\n const status = yield* renderStatus.get;\n if (action === 'Refresh' || status._tag === 'Failed') {\n yield* routeRefresher.refreshCurrentRoute('hmr-refresh');\n // Starting a refresh is not evidence that the replacement rendered successfully.\n return;\n }\n yield* panel.dispatch({ _tag: 'RuntimeReconciled' });\n });\n yield* renderStatus.changes.pipe(\n Stream.runForEach((status) => {\n switch (status._tag) {\n case 'Waiting':\n return Effect.void;\n case 'Rendered':\n return panel.dispatch({ _tag: 'RuntimeReconciled' });\n case 'Failed':\n return panel.dispatch({\n _tag: 'RenderFailed',\n failure: fromRenderError(status.error, status.componentStack),\n });\n }\n }),\n Effect.forkScoped,\n );\n yield* reportBrowserFailures((failure) =>\n panel.dispatch({ _tag: 'RuntimeFailed', failure }),\n ).pipe(Effect.forkScoped);\n\n const observeUpdates = Effect.gen(function* () {\n const client = yield* RpcClient.make(DevRpcs);\n const handleUpdate = Effect.fnUntraced(function* (phase: DevUpdatePhase, message: DevUpdate) {\n if (message._tag === 'BuildFailed') {\n yield* panel.dispatch(message);\n } else {\n yield* panel.dispatch({ _tag: 'BuildSucceeded' });\n if (phase === 'Live' || message.clientHash !== import.meta.rspackHash) {\n yield* handleHotUpdate(message);\n }\n }\n\n return 'Live' as const;\n });\n\n yield* client.ObserveDevUpdates().pipe(\n Stream.runFoldEffect((): DevUpdatePhase => 'Snapshot', handleUpdate),\n Effect.asVoid,\n );\n });\n\n yield* observeUpdates.pipe(Effect.provide(DevRpcProtocolLayer));\n});\n"],"names":["BrowserSocket","Console","Effect","Layer","Ref","Semaphore","Stream","RpcClient","RpcSerialization","navigationMode","BrowserRenderStatus","RouteRefresher","DevChannelPath","DevRpcs","decideHotUpdate","makeDevPanel","fromRenderError","reportBrowserFailures","socketProtocol","location","socketUrl","DevRpcProtocolLayer","recordUpdate","pending","message","settlePendingUpdate","pendingUpdate","reconcile","previousHash","check","updatedModules","decision","current","action","startDevClient","routeRefresher","renderStatus","panel","mode","missingApi","window","undefined","updateLock","handleHotUpdate","status","failure","observeUpdates","client","handleUpdate","phase"],"mappings":"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"}
|
package/dist/dev/panel.d.ts
CHANGED
|
@@ -3,6 +3,9 @@ import type { DevRuntimeFailure } from './runtime-failure.js';
|
|
|
3
3
|
export type { DevRuntimeFailure } from './runtime-failure.js';
|
|
4
4
|
export declare const DevPanelElementName = "ersc-dev-panel";
|
|
5
5
|
type DevPanelContent = {
|
|
6
|
+
readonly _tag: 'Warning';
|
|
7
|
+
readonly message: string;
|
|
8
|
+
} | {
|
|
6
9
|
readonly _tag: 'BuildFailed';
|
|
7
10
|
readonly diagnostics: string;
|
|
8
11
|
} | {
|
|
@@ -19,6 +22,9 @@ export type DevPanelState = {
|
|
|
19
22
|
readonly content: DevPanelContent;
|
|
20
23
|
};
|
|
21
24
|
export type DevPanelEvent = {
|
|
25
|
+
readonly _tag: 'Warning';
|
|
26
|
+
readonly message: string;
|
|
27
|
+
} | {
|
|
22
28
|
readonly _tag: 'BuildFailed';
|
|
23
29
|
readonly diagnostics: string;
|
|
24
30
|
} | {
|
package/dist/dev/panel.js
CHANGED
|
@@ -9582,7 +9582,7 @@ const ScrollAreaThumb_ScrollAreaThumb = /*#__PURE__*/__rspack_external_react.for
|
|
|
9582
9582
|
if (process.env.NODE_ENV !== "production") ScrollAreaThumb_ScrollAreaThumb.displayName = "ScrollAreaThumb";
|
|
9583
9583
|
|
|
9584
9584
|
|
|
9585
|
-
const panelraw_namespaceObject = ":host {\n all: initial;\n color-scheme: dark;\n --ersc-canvas: #111110;\n --ersc-surface: #181817;\n --ersc-raised: #201f1e;\n --ersc-border: #343230;\n --ersc-border-subtle: #292725;\n --ersc-text: #f3f2ef;\n --ersc-text-secondary: #aaa7a1;\n --ersc-text-tertiary: #77736d;\n --ersc-danger: #ff615a;\n --ersc-danger-muted: #3a1f1d;\n --ersc-ease-out: cubic-bezier(0.23, 1, 0.32, 1);\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton {\n font: inherit;\n}\n\n.backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483646;\n width: 100vw;\n background: rgb(9 9 8 / 76%);\n backdrop-filter: blur(2px);\n transition: opacity 160ms var(--ersc-ease-out);\n}\n\n.backdrop[data-starting-style],\n.backdrop[data-ending-style] {\n opacity: 0;\n}\n\n.viewport {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n width: 100vw;\n overflow: auto;\n padding: clamp(24px, 6vh, 72px) 20px;\n font-family:\n Inter,\n ui-sans-serif,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n sans-serif;\n color: var(--ersc-text);\n}\n\n.popup {\n display: flex;\n width: min(920px, 100%);\n max-height: calc(100svh - clamp(48px, 12vh, 144px));\n margin: 0 auto;\n overflow: hidden;\n color: var(--ersc-text);\n background: var(--ersc-canvas);\n border: 1px solid var(--ersc-border);\n border-radius: 10px;\n box-shadow:\n 0 32px 80px rgb(0 0 0 / 48%),\n 0 2px 8px rgb(0 0 0 / 32%);\n flex-direction: column;\n transition:\n opacity 180ms var(--ersc-ease-out),\n transform 180ms var(--ersc-ease-out);\n transform-origin: center;\n}\n\n.popup[data-starting-style],\n.popup[data-ending-style] {\n opacity: 0;\n transform: translateY(8px) scale(0.985);\n}\n\nheader {\n display: flex;\n min-height: 76px;\n gap: 14px;\n align-items: center;\n padding: 14px 16px 14px 18px;\n background: var(--ersc-surface);\n border-bottom: 1px solid var(--ersc-border-subtle);\n}\n\n.error-mark {\n display: grid;\n width: 34px;\n height: 34px;\n color: var(--ersc-danger);\n background: var(--ersc-danger-muted);\n border: 1px solid rgb(255 97 90 / 24%);\n border-radius: 7px;\n flex: 0 0 auto;\n place-items: center;\n}\n\n.error-mark svg {\n width: 18px;\n height: 18px;\n}\n\n.heading {\n display: grid;\n min-width: 0;\n gap: 5px;\n flex: 1;\n}\n\n.brand {\n overflow: hidden;\n color: var(--ersc-text-secondary);\n font:\n 600 10px/1.1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: 0.08em;\n text-overflow: ellipsis;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.brand span {\n color: var(--ersc-text-tertiary);\n}\n\n.title {\n margin: 0;\n color: var(--ersc-text);\n font-size: 17px;\n font-weight: 600;\n line-height: 1.2;\n letter-spacing: -0.015em;\n}\n\n.failure-count {\n padding: 5px 8px;\n color: var(--ersc-text-secondary);\n font:\n 500 11px/1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n background: var(--ersc-raised);\n border: 1px solid var(--ersc-border);\n border-radius: 999px;\n white-space: nowrap;\n}\n\n.close {\n display: grid;\n width: 34px;\n height: 34px;\n padding: 0;\n color: var(--ersc-text-secondary);\n cursor: pointer;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 7px;\n transition:\n color 140ms ease,\n background-color 140ms ease,\n border-color 140ms ease,\n transform 140ms var(--ersc-ease-out);\n place-items: center;\n}\n\n.close svg {\n width: 18px;\n height: 18px;\n}\n\n.close:focus-visible {\n color: var(--ersc-text);\n outline: 2px solid var(--ersc-danger);\n outline-offset: 2px;\n}\n\n.close:active {\n transform: scale(0.94);\n}\n\n.content {\n position: relative;\n min-height: 0;\n overflow: hidden;\n overscroll-behavior: contain;\n}\n\n.content-viewport {\n max-height: calc(100svh - clamp(124px, calc(12vh + 76px), 220px));\n overscroll-behavior: contain;\n scrollbar-width: none;\n}\n\n.scrollbar {\n position: absolute;\n top: 4px;\n right: 3px;\n bottom: 4px;\n display: flex;\n width: 8px;\n padding: 2px;\n border-radius: 999px;\n opacity: 0;\n transition: opacity 140ms ease;\n user-select: none;\n}\n\n.content[data-scrolling] .scrollbar,\n.scrollbar[data-hovering] {\n opacity: 1;\n}\n\n.scrollbar-thumb {\n width: 100%;\n background: #55514c;\n border-radius: inherit;\n}\n\narticle + article {\n border-top: 1px solid var(--ersc-border-subtle);\n}\n\n.failure {\n display: grid;\n grid-template-columns: 58px minmax(0, 1fr);\n}\n\n.failure-index {\n padding: 23px 12px;\n color: var(--ersc-text-tertiary);\n font:\n 500 11px/1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n text-align: center;\n background: var(--ersc-surface);\n border-right: 1px solid var(--ersc-border-subtle);\n}\n\n.failure-body {\n min-width: 0;\n padding: 22px 24px 24px;\n}\n\n.category,\n.component-stack-title,\n.message {\n margin: 0;\n}\n\n.category {\n display: flex;\n gap: 8px;\n align-items: center;\n color: var(--ersc-danger);\n font-size: 11px;\n font-weight: 650;\n line-height: 16px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.status-dot {\n width: 6px;\n height: 6px;\n background: currentcolor;\n border-radius: 50%;\n box-shadow: 0 0 0 3px rgb(255 97 90 / 12%);\n}\n\n.component-stack-title {\n margin: 0 0 8px;\n color: var(--ersc-text-secondary);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.trace-section {\n margin-top: 18px;\n}\n\n.stack {\n margin-top: 16px;\n}\n\n.stack-trigger {\n display: flex;\n width: fit-content;\n gap: 5px;\n align-items: center;\n padding: 5px 0;\n color: var(--ersc-text-secondary);\n font:\n 600 11px/1.4 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n cursor: pointer;\n background: transparent;\n border: 0;\n transition:\n color 140ms ease,\n transform 140ms var(--ersc-ease-out);\n}\n\n.stack-trigger:focus-visible {\n color: var(--ersc-text);\n outline: 2px solid var(--ersc-danger);\n outline-offset: 2px;\n}\n\n.stack-trigger:active {\n transform: scale(0.97);\n}\n\n.stack-trigger svg {\n width: 14px;\n height: 14px;\n transition: transform 160ms var(--ersc-ease-out);\n}\n\n.stack-trigger[aria-expanded='true'] svg {\n transform: rotate(90deg);\n}\n\n.stack-panel pre {\n margin-top: 6px;\n}\n\n.message {\n margin-top: 10px;\n color: var(--ersc-text);\n font:\n 500 15px/1.55 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: -0.015em;\n overflow-wrap: anywhere;\n}\n\n.error-name {\n color: #ff8c87;\n font-weight: 650;\n}\n\npre {\n margin: 0;\n overflow: auto;\n color: #cbc8c2;\n font:\n 12px/1.65 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n tab-size: 2;\n word-break: break-word;\n white-space: pre-wrap;\n}\n\n.code-frame,\n.build-output {\n padding: 14px 16px;\n background: var(--ersc-surface);\n border: 1px solid var(--ersc-border-subtle);\n border-radius: 7px;\n}\n\n.build-failure {\n padding: 22px 24px 24px;\n}\n\n.section-heading {\n display: flex;\n gap: 16px;\n align-items: baseline;\n justify-content: space-between;\n margin-bottom: 10px;\n color: var(--ersc-text-secondary);\n font:\n 600 10px/1.4 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.section-heading span:last-child {\n color: var(--ersc-text-tertiary);\n font-weight: 500;\n letter-spacing: 0;\n text-transform: none;\n}\n\n.build-output {\n color: var(--ersc-text);\n background: #0d0d0c;\n border-left: 2px solid var(--ersc-danger);\n}\n\n@media (hover: hover) and (pointer: fine) {\n .close:hover {\n color: var(--ersc-text);\n background: var(--ersc-raised);\n border-color: var(--ersc-border);\n }\n\n .stack-trigger:hover {\n color: var(--ersc-text);\n }\n}\n\n@media (max-width: 560px) {\n .viewport {\n padding: 12px;\n }\n\n .popup {\n max-height: calc(100svh - 24px);\n }\n\n .content-viewport {\n max-height: calc(100svh - 92px);\n }\n\n header {\n min-height: 68px;\n gap: 10px;\n padding-inline: 12px;\n }\n\n .error-mark,\n .close {\n width: 32px;\n height: 32px;\n }\n\n .failure-count {\n display: none;\n }\n\n .failure {\n grid-template-columns: 38px minmax(0, 1fr);\n }\n\n .failure-index {\n padding-inline: 8px;\n }\n\n .failure-body,\n .build-failure {\n padding: 18px 16px 20px;\n }\n\n .section-heading span:last-child {\n display: none;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .popup,\n .close,\n .stack-trigger,\n .stack-trigger svg,\n .scrollbar {\n transition-duration: 0ms;\n }\n\n .popup[data-starting-style],\n .popup[data-ending-style] {\n transform: none;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n white-space: nowrap;\n border: 0;\n clip: rect(0, 0, 0, 0);\n}\n";
|
|
9585
|
+
const panelraw_namespaceObject = ":host {\n all: initial;\n color-scheme: dark;\n --ersc-canvas: #111110;\n --ersc-surface: #181817;\n --ersc-raised: #201f1e;\n --ersc-border: #343230;\n --ersc-border-subtle: #292725;\n --ersc-text: #f3f2ef;\n --ersc-text-secondary: #aaa7a1;\n --ersc-text-tertiary: #77736d;\n --ersc-danger: #ff615a;\n --ersc-danger-muted: #3a1f1d;\n --ersc-ease-out: cubic-bezier(0.23, 1, 0.32, 1);\n}\n\n*,\n*::before,\n*::after {\n box-sizing: border-box;\n}\n\nbutton {\n font: inherit;\n}\n\n.warning-notice {\n position: fixed;\n right: 16px;\n bottom: 16px;\n z-index: 2147483645;\n display: flex;\n width: min(440px, calc(100% - 32px));\n gap: 12px;\n padding: 16px;\n color: var(--ersc-text);\n font:\n 14px/1.5 system-ui,\n sans-serif;\n background: var(--ersc-surface);\n border: 1px solid #b88a36;\n border-radius: 10px;\n box-shadow: 0 8px 32px rgb(0 0 0 / 24%);\n}\n\n.warning-notice .title {\n margin-top: 6px;\n color: #f3c56b;\n}\n\n.warning-notice p {\n margin: 8px 0 0;\n}\n\n.warning-notice .close {\n flex: 0 0 auto;\n}\n\n.backdrop {\n position: fixed;\n inset: 0;\n z-index: 2147483646;\n width: 100vw;\n background: rgb(9 9 8 / 76%);\n backdrop-filter: blur(2px);\n transition: opacity 160ms var(--ersc-ease-out);\n}\n\n.backdrop[data-starting-style],\n.backdrop[data-ending-style] {\n opacity: 0;\n}\n\n.viewport {\n position: fixed;\n inset: 0;\n z-index: 2147483647;\n width: 100vw;\n overflow: auto;\n padding: clamp(24px, 6vh, 72px) 20px;\n font-family:\n Inter,\n ui-sans-serif,\n -apple-system,\n BlinkMacSystemFont,\n 'Segoe UI',\n sans-serif;\n color: var(--ersc-text);\n}\n\n.popup {\n display: flex;\n width: min(920px, 100%);\n max-height: calc(100svh - clamp(48px, 12vh, 144px));\n margin: 0 auto;\n overflow: hidden;\n color: var(--ersc-text);\n background: var(--ersc-canvas);\n border: 1px solid var(--ersc-border);\n border-radius: 10px;\n box-shadow:\n 0 32px 80px rgb(0 0 0 / 48%),\n 0 2px 8px rgb(0 0 0 / 32%);\n flex-direction: column;\n transition:\n opacity 180ms var(--ersc-ease-out),\n transform 180ms var(--ersc-ease-out);\n transform-origin: center;\n}\n\n.popup[data-starting-style],\n.popup[data-ending-style] {\n opacity: 0;\n transform: translateY(8px) scale(0.985);\n}\n\nheader {\n display: flex;\n min-height: 76px;\n gap: 14px;\n align-items: center;\n padding: 14px 16px 14px 18px;\n background: var(--ersc-surface);\n border-bottom: 1px solid var(--ersc-border-subtle);\n}\n\n.error-mark {\n display: grid;\n width: 34px;\n height: 34px;\n color: var(--ersc-danger);\n background: var(--ersc-danger-muted);\n border: 1px solid rgb(255 97 90 / 24%);\n border-radius: 7px;\n flex: 0 0 auto;\n place-items: center;\n}\n\n.error-mark svg {\n width: 18px;\n height: 18px;\n}\n\n.heading {\n display: grid;\n min-width: 0;\n gap: 5px;\n flex: 1;\n}\n\n.brand {\n overflow: hidden;\n color: var(--ersc-text-secondary);\n font:\n 600 10px/1.1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: 0.08em;\n text-overflow: ellipsis;\n text-transform: uppercase;\n white-space: nowrap;\n}\n\n.brand span {\n color: var(--ersc-text-tertiary);\n}\n\n.title {\n margin: 0;\n color: var(--ersc-text);\n font-size: 17px;\n font-weight: 600;\n line-height: 1.2;\n letter-spacing: -0.015em;\n}\n\n.failure-count {\n padding: 5px 8px;\n color: var(--ersc-text-secondary);\n font:\n 500 11px/1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n background: var(--ersc-raised);\n border: 1px solid var(--ersc-border);\n border-radius: 999px;\n white-space: nowrap;\n}\n\n.close {\n display: grid;\n width: 34px;\n height: 34px;\n padding: 0;\n color: var(--ersc-text-secondary);\n cursor: pointer;\n background: transparent;\n border: 1px solid transparent;\n border-radius: 7px;\n transition:\n color 140ms ease,\n background-color 140ms ease,\n border-color 140ms ease,\n transform 140ms var(--ersc-ease-out);\n place-items: center;\n}\n\n.close svg {\n width: 18px;\n height: 18px;\n}\n\n.close:focus-visible {\n color: var(--ersc-text);\n outline: 2px solid var(--ersc-danger);\n outline-offset: 2px;\n}\n\n.close:active {\n transform: scale(0.94);\n}\n\n.content {\n position: relative;\n min-height: 0;\n overflow: hidden;\n overscroll-behavior: contain;\n}\n\n.content-viewport {\n max-height: calc(100svh - clamp(124px, calc(12vh + 76px), 220px));\n overscroll-behavior: contain;\n scrollbar-width: none;\n}\n\n.scrollbar {\n position: absolute;\n top: 4px;\n right: 3px;\n bottom: 4px;\n display: flex;\n width: 8px;\n padding: 2px;\n border-radius: 999px;\n opacity: 0;\n transition: opacity 140ms ease;\n user-select: none;\n}\n\n.content[data-scrolling] .scrollbar,\n.scrollbar[data-hovering] {\n opacity: 1;\n}\n\n.scrollbar-thumb {\n width: 100%;\n background: #55514c;\n border-radius: inherit;\n}\n\narticle + article {\n border-top: 1px solid var(--ersc-border-subtle);\n}\n\n.failure {\n display: grid;\n grid-template-columns: 58px minmax(0, 1fr);\n}\n\n.failure-index {\n padding: 23px 12px;\n color: var(--ersc-text-tertiary);\n font:\n 500 11px/1 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n text-align: center;\n background: var(--ersc-surface);\n border-right: 1px solid var(--ersc-border-subtle);\n}\n\n.failure-body {\n min-width: 0;\n padding: 22px 24px 24px;\n}\n\n.category,\n.component-stack-title,\n.message {\n margin: 0;\n}\n\n.category {\n display: flex;\n gap: 8px;\n align-items: center;\n color: var(--ersc-danger);\n font-size: 11px;\n font-weight: 650;\n line-height: 16px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.status-dot {\n width: 6px;\n height: 6px;\n background: currentcolor;\n border-radius: 50%;\n box-shadow: 0 0 0 3px rgb(255 97 90 / 12%);\n}\n\n.component-stack-title {\n margin: 0 0 8px;\n color: var(--ersc-text-secondary);\n font-size: 10px;\n font-weight: 600;\n line-height: 16px;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.trace-section {\n margin-top: 18px;\n}\n\n.stack {\n margin-top: 16px;\n}\n\n.stack-trigger {\n display: flex;\n width: fit-content;\n gap: 5px;\n align-items: center;\n padding: 5px 0;\n color: var(--ersc-text-secondary);\n font:\n 600 11px/1.4 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n cursor: pointer;\n background: transparent;\n border: 0;\n transition:\n color 140ms ease,\n transform 140ms var(--ersc-ease-out);\n}\n\n.stack-trigger:focus-visible {\n color: var(--ersc-text);\n outline: 2px solid var(--ersc-danger);\n outline-offset: 2px;\n}\n\n.stack-trigger:active {\n transform: scale(0.97);\n}\n\n.stack-trigger svg {\n width: 14px;\n height: 14px;\n transition: transform 160ms var(--ersc-ease-out);\n}\n\n.stack-trigger[aria-expanded='true'] svg {\n transform: rotate(90deg);\n}\n\n.stack-panel pre {\n margin-top: 6px;\n}\n\n.message {\n margin-top: 10px;\n color: var(--ersc-text);\n font:\n 500 15px/1.55 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: -0.015em;\n overflow-wrap: anywhere;\n}\n\n.error-name {\n color: #ff8c87;\n font-weight: 650;\n}\n\npre {\n margin: 0;\n overflow: auto;\n color: #cbc8c2;\n font:\n 12px/1.65 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n tab-size: 2;\n word-break: break-word;\n white-space: pre-wrap;\n}\n\n.code-frame,\n.build-output {\n padding: 14px 16px;\n background: var(--ersc-surface);\n border: 1px solid var(--ersc-border-subtle);\n border-radius: 7px;\n}\n\n.build-failure {\n padding: 22px 24px 24px;\n}\n\n.section-heading {\n display: flex;\n gap: 16px;\n align-items: baseline;\n justify-content: space-between;\n margin-bottom: 10px;\n color: var(--ersc-text-secondary);\n font:\n 600 10px/1.4 ui-monospace,\n SFMono-Regular,\n Consolas,\n 'Liberation Mono',\n monospace;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n}\n\n.section-heading span:last-child {\n color: var(--ersc-text-tertiary);\n font-weight: 500;\n letter-spacing: 0;\n text-transform: none;\n}\n\n.build-output {\n color: var(--ersc-text);\n background: #0d0d0c;\n border-left: 2px solid var(--ersc-danger);\n}\n\n@media (hover: hover) and (pointer: fine) {\n .close:hover {\n color: var(--ersc-text);\n background: var(--ersc-raised);\n border-color: var(--ersc-border);\n }\n\n .stack-trigger:hover {\n color: var(--ersc-text);\n }\n}\n\n@media (max-width: 560px) {\n .viewport {\n padding: 12px;\n }\n\n .popup {\n max-height: calc(100svh - 24px);\n }\n\n .content-viewport {\n max-height: calc(100svh - 92px);\n }\n\n header {\n min-height: 68px;\n gap: 10px;\n padding-inline: 12px;\n }\n\n .error-mark,\n .close {\n width: 32px;\n height: 32px;\n }\n\n .failure-count {\n display: none;\n }\n\n .failure {\n grid-template-columns: 38px minmax(0, 1fr);\n }\n\n .failure-index {\n padding-inline: 8px;\n }\n\n .failure-body,\n .build-failure {\n padding: 18px 16px 20px;\n }\n\n .section-heading span:last-child {\n display: none;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .backdrop,\n .popup,\n .close,\n .stack-trigger,\n .stack-trigger svg,\n .scrollbar {\n transition-duration: 0ms;\n }\n\n .popup[data-starting-style],\n .popup[data-ending-style] {\n transform: none;\n }\n}\n\n.sr-only {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n white-space: nowrap;\n border: 0;\n clip: rect(0, 0, 0, 0);\n}\n";
|
|
9586
9586
|
|
|
9587
9587
|
|
|
9588
9588
|
|
|
@@ -9607,6 +9607,11 @@ const appendRuntimeFailure = (failures, failure)=>{
|
|
|
9607
9607
|
};
|
|
9608
9608
|
const applyDevPanelEvent = (state, event)=>{
|
|
9609
9609
|
switch(event._tag){
|
|
9610
|
+
case 'Warning':
|
|
9611
|
+
return state._tag === 'Inactive' ? {
|
|
9612
|
+
_tag: 'Visible',
|
|
9613
|
+
content: event
|
|
9614
|
+
} : state;
|
|
9610
9615
|
case 'RenderFailed':
|
|
9611
9616
|
if (state._tag !== 'Inactive' && state.content._tag === 'BuildFailed') {
|
|
9612
9617
|
return state;
|
|
@@ -9657,6 +9662,16 @@ const applyDevPanelEvent = (state, event)=>{
|
|
|
9657
9662
|
failures: appendRuntimeFailure(state.content.failures, event.failure)
|
|
9658
9663
|
}
|
|
9659
9664
|
};
|
|
9665
|
+
case 'Warning':
|
|
9666
|
+
return {
|
|
9667
|
+
_tag: 'Visible',
|
|
9668
|
+
content: {
|
|
9669
|
+
_tag: 'RuntimeFailed',
|
|
9670
|
+
failures: [
|
|
9671
|
+
event.failure
|
|
9672
|
+
]
|
|
9673
|
+
}
|
|
9674
|
+
};
|
|
9660
9675
|
}
|
|
9661
9676
|
}
|
|
9662
9677
|
}
|
|
@@ -9787,7 +9802,7 @@ function RuntimeFailure({ failure, index }) {
|
|
|
9787
9802
|
});
|
|
9788
9803
|
}
|
|
9789
9804
|
function DevPanelContent({ state }) {
|
|
9790
|
-
if (state._tag === 'Inactive') {
|
|
9805
|
+
if (state._tag === 'Inactive' || state.content._tag === 'Warning') {
|
|
9791
9806
|
return null;
|
|
9792
9807
|
}
|
|
9793
9808
|
const isBuildFailure = state.content._tag === 'BuildFailed';
|
|
@@ -9883,6 +9898,44 @@ function DevPanelContent({ state }) {
|
|
|
9883
9898
|
});
|
|
9884
9899
|
}
|
|
9885
9900
|
function DevPanel({ onOpenChange, portalContainer, state }) {
|
|
9901
|
+
if (state._tag !== 'Inactive' && state.content._tag === 'Warning') {
|
|
9902
|
+
return state._tag === 'Dismissed' ? null : /*#__PURE__*/ jsxs(Fragment, {
|
|
9903
|
+
children: [
|
|
9904
|
+
/*#__PURE__*/ jsx("style", {
|
|
9905
|
+
children: panelraw_namespaceObject
|
|
9906
|
+
}),
|
|
9907
|
+
/*#__PURE__*/ jsxs("aside", {
|
|
9908
|
+
"aria-label": "Development warning",
|
|
9909
|
+
"aria-live": "polite",
|
|
9910
|
+
className: "warning-notice",
|
|
9911
|
+
children: [
|
|
9912
|
+
/*#__PURE__*/ jsxs("div", {
|
|
9913
|
+
children: [
|
|
9914
|
+
/*#__PURE__*/ jsx("span", {
|
|
9915
|
+
className: "brand",
|
|
9916
|
+
children: "effective-rsc / development"
|
|
9917
|
+
}),
|
|
9918
|
+
/*#__PURE__*/ jsx("h2", {
|
|
9919
|
+
className: "title",
|
|
9920
|
+
children: "Client navigation unavailable"
|
|
9921
|
+
}),
|
|
9922
|
+
/*#__PURE__*/ jsx("p", {
|
|
9923
|
+
children: state.content.message
|
|
9924
|
+
})
|
|
9925
|
+
]
|
|
9926
|
+
}),
|
|
9927
|
+
/*#__PURE__*/ jsx("button", {
|
|
9928
|
+
"aria-label": "Dismiss development warning",
|
|
9929
|
+
className: "close",
|
|
9930
|
+
onClick: ()=>onOpenChange(false),
|
|
9931
|
+
type: "button",
|
|
9932
|
+
children: "\xd7"
|
|
9933
|
+
})
|
|
9934
|
+
]
|
|
9935
|
+
})
|
|
9936
|
+
]
|
|
9937
|
+
});
|
|
9938
|
+
}
|
|
9886
9939
|
return /*#__PURE__*/ jsx(DialogRoot_DialogRoot, {
|
|
9887
9940
|
onOpenChange: onOpenChange,
|
|
9888
9941
|
open: state._tag === 'Visible',
|