flamefront 0.1.6 → 0.1.8
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flamefront",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Typed centralized route manifests for Octane.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -51,38 +51,38 @@
|
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@alloc/cmd-ts": "^0.17.1",
|
|
54
|
-
"@babel/generator": "^8.0.
|
|
55
|
-
"@babel/parser": "^8.0.
|
|
56
|
-
"@babel/traverse": "^8.0.
|
|
57
|
-
"@babel/types": "^8.0.
|
|
58
|
-
"@remix-run/route-pattern": "^0.24.
|
|
54
|
+
"@babel/generator": "^8.0.6",
|
|
55
|
+
"@babel/parser": "^8.0.6",
|
|
56
|
+
"@babel/traverse": "^8.0.6",
|
|
57
|
+
"@babel/types": "^8.0.6",
|
|
58
|
+
"@remix-run/route-pattern": "^0.24.1",
|
|
59
59
|
"babel-dead-code-elimination": "^2.0.0",
|
|
60
|
-
"devalue": "^
|
|
60
|
+
"devalue": "^6.0.0",
|
|
61
61
|
"satteri": "^0.10.5",
|
|
62
|
-
"srvx": "^1.0.
|
|
62
|
+
"srvx": "^1.0.5",
|
|
63
63
|
"vite-plugin-satteri": "^0.3.5"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|
|
66
|
-
"@octanejs/remix-router": "^0.1.
|
|
67
|
-
"@octanejs/vite-plugin": "^0.1.
|
|
66
|
+
"@octanejs/remix-router": "^0.1.49",
|
|
67
|
+
"@octanejs/vite-plugin": "^0.1.57",
|
|
68
68
|
"@stylistic/eslint-plugin": "^5.10.0",
|
|
69
|
-
"@tsrx/prettier-plugin": "^0.
|
|
69
|
+
"@tsrx/prettier-plugin": "^0.4.6",
|
|
70
70
|
"@types/babel__generator": "^7.27.0",
|
|
71
71
|
"@types/babel__traverse": "^7.28.0",
|
|
72
|
-
"@types/node": "^26.
|
|
73
|
-
"octane": "^0.2
|
|
72
|
+
"@types/node": "^26.6.2",
|
|
73
|
+
"octane": "^0.3.2",
|
|
74
74
|
"oxc-tsrx": "^0.6.1",
|
|
75
|
-
"oxlint": "^1.
|
|
76
|
-
"oxlint-tsgolint": "^7.0.
|
|
75
|
+
"oxlint": "^1.83.0",
|
|
76
|
+
"oxlint-tsgolint": "^7.0.2002",
|
|
77
77
|
"playwright": "^1.63.0",
|
|
78
|
-
"prettier": "^3.9.
|
|
78
|
+
"prettier": "^3.9.8",
|
|
79
79
|
"typescript": "^5.9.3",
|
|
80
80
|
"vite": "^8.3.0",
|
|
81
|
-
"vitest": "^5.0.
|
|
81
|
+
"vitest": "^5.0.1"
|
|
82
82
|
},
|
|
83
83
|
"peerDependencies": {
|
|
84
|
-
"@octanejs/remix-router": ">=0.1.
|
|
85
|
-
"octane": ">=0.2
|
|
84
|
+
"@octanejs/remix-router": ">=0.1.49",
|
|
85
|
+
"octane": ">=0.3.2",
|
|
86
86
|
"vite": ">=8.3.0"
|
|
87
87
|
}
|
|
88
88
|
}
|
package/src/fragment-client.ts
CHANGED
|
@@ -77,6 +77,29 @@ function basenamePath(pathname: string, basename: string): string | null {
|
|
|
77
77
|
return pathname.slice(basename.length) || "/"
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
function joinBasename(basename: string, pathname: string): string {
|
|
81
|
+
if (basename === "/") {
|
|
82
|
+
return pathname || "/"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (pathname === "/") {
|
|
86
|
+
return basename
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return `${basename}${pathname.startsWith("/") ? pathname : `/${pathname}`}`
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** The static build emits one fragment artifact beside each route document. */
|
|
93
|
+
function staticRouteFragmentPath(routeUrl: URL, basename: string): string {
|
|
94
|
+
const appPathname =
|
|
95
|
+
basenamePath(routeUrl.pathname, basename) ?? routeUrl.pathname
|
|
96
|
+
const pathname = joinBasename(basename, appPathname).replace(/\/+$/, "")
|
|
97
|
+
|
|
98
|
+
return pathname === ""
|
|
99
|
+
? "/index.fragment.json"
|
|
100
|
+
: `${pathname}/index.fragment.json`
|
|
101
|
+
}
|
|
102
|
+
|
|
80
103
|
function staticFragmentKey(url: URL, basename: string): string {
|
|
81
104
|
const pathname = basenamePath(url.pathname, basename) ?? url.pathname
|
|
82
105
|
|
|
@@ -214,6 +237,49 @@ function fetchRouteFragment(
|
|
|
214
237
|
})
|
|
215
238
|
}
|
|
216
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Read the emitted artifact file for a static route. Hosts that cannot serve
|
|
242
|
+
* it — the dev server, or a deployment without generated files — fall back to
|
|
243
|
+
* the live fragment endpoint.
|
|
244
|
+
*/
|
|
245
|
+
async function readStaticRouteFragment(
|
|
246
|
+
routeUrl: URL,
|
|
247
|
+
basename: string,
|
|
248
|
+
signal: AbortSignal | undefined,
|
|
249
|
+
): Promise<RouteFragmentArtifact | undefined> {
|
|
250
|
+
const endpoint = new URL(
|
|
251
|
+
staticRouteFragmentPath(routeUrl, basename),
|
|
252
|
+
routeUrl.origin,
|
|
253
|
+
)
|
|
254
|
+
const response = await globalThis.fetch(endpoint, {
|
|
255
|
+
headers: { Accept: "application/vnd.flamefront.fragment+json" },
|
|
256
|
+
...(signal ? { signal } : {}),
|
|
257
|
+
})
|
|
258
|
+
|
|
259
|
+
if (!response.ok) {
|
|
260
|
+
return undefined
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
try {
|
|
264
|
+
return assertRouteFragmentArtifact(await response.json())
|
|
265
|
+
} catch {
|
|
266
|
+
return undefined
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function fetchStaticRouteFragment(
|
|
271
|
+
routeUrl: URL,
|
|
272
|
+
basename: string,
|
|
273
|
+
signal: AbortSignal | undefined,
|
|
274
|
+
): Promise<RouteFragmentArtifact> {
|
|
275
|
+
const fallback = () => fetchRouteFragment(routeUrl, basename, signal)
|
|
276
|
+
|
|
277
|
+
return readStaticRouteFragment(routeUrl, basename, signal).then(
|
|
278
|
+
(artifact) => artifact ?? fallback(),
|
|
279
|
+
fallback,
|
|
280
|
+
)
|
|
281
|
+
}
|
|
282
|
+
|
|
217
283
|
export function loadRouteFragment(
|
|
218
284
|
url: string | URL,
|
|
219
285
|
routing: RouteFragmentRoutingOptions = {},
|
|
@@ -238,11 +304,12 @@ export function loadRouteFragment(
|
|
|
238
304
|
let pending = requests.get(requestKey)
|
|
239
305
|
|
|
240
306
|
if (!pending) {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
307
|
+
const fetchFragment =
|
|
308
|
+
options.policy === "static"
|
|
309
|
+
? fetchStaticRouteFragment
|
|
310
|
+
: fetchRouteFragment
|
|
311
|
+
|
|
312
|
+
pending = fetchFragment(routeUrl, routing.basename ?? "/", options.signal)
|
|
246
313
|
requests.set(requestKey, pending)
|
|
247
314
|
|
|
248
315
|
const evict = () => {
|
package/src/fragment.tsx
CHANGED
|
@@ -438,9 +438,9 @@ function createShellBoundary(
|
|
|
438
438
|
),
|
|
439
439
|
}
|
|
440
440
|
const shell = (
|
|
441
|
-
<UNSAFE_RouteContext
|
|
441
|
+
<UNSAFE_RouteContext value={shellRoute}>
|
|
442
442
|
<Component {...props} />
|
|
443
|
-
</UNSAFE_RouteContext
|
|
443
|
+
</UNSAFE_RouteContext>
|
|
444
444
|
)
|
|
445
445
|
const body = shellHydrationBoundary(
|
|
446
446
|
metadata.hydration ?? "full",
|
|
@@ -481,13 +481,13 @@ export function createRouteBoundary(
|
|
|
481
481
|
function createContextBridge(stateRef: {
|
|
482
482
|
readonly current: ContextBridgeState
|
|
483
483
|
}): (props: Record<string, unknown>) => unknown {
|
|
484
|
-
const DataRouterProvider = UNSAFE_DataRouterContext
|
|
485
|
-
const DataRouterStateProvider = UNSAFE_DataRouterStateContext
|
|
486
|
-
const FetchersProvider = UNSAFE_FetchersContext
|
|
487
|
-
const LocationProvider = UNSAFE_LocationContext
|
|
488
|
-
const NavigationProvider = UNSAFE_NavigationContext
|
|
489
|
-
const RouteProvider = UNSAFE_RouteContext
|
|
490
|
-
const ViewTransitionProvider = UNSAFE_ViewTransitionContext
|
|
484
|
+
const DataRouterProvider = UNSAFE_DataRouterContext
|
|
485
|
+
const DataRouterStateProvider = UNSAFE_DataRouterStateContext
|
|
486
|
+
const FetchersProvider = UNSAFE_FetchersContext
|
|
487
|
+
const LocationProvider = UNSAFE_LocationContext
|
|
488
|
+
const NavigationProvider = UNSAFE_NavigationContext
|
|
489
|
+
const RouteProvider = UNSAFE_RouteContext
|
|
490
|
+
const ViewTransitionProvider = UNSAFE_ViewTransitionContext
|
|
491
491
|
|
|
492
492
|
return () => {
|
|
493
493
|
const { component, contexts } = stateRef.current
|
|
@@ -97,7 +97,7 @@ export const defaultOctaneRenderer: OctaneRenderer = {
|
|
|
97
97
|
errors: errorsForBoundary(staticContext, matches),
|
|
98
98
|
}
|
|
99
99
|
const outletRouter = createStaticRouter([outletRoute], outletContext)
|
|
100
|
-
const FragmentBoundaryProvider = routeFragmentBoundaryTarget
|
|
100
|
+
const FragmentBoundaryProvider = routeFragmentBoundaryTarget
|
|
101
101
|
const FragmentRoot = () => (
|
|
102
102
|
<FragmentBoundaryProvider
|
|
103
103
|
value={options?.includeBoundary ? null : boundary}
|
|
@@ -16,14 +16,14 @@ export const RouterDocument: RouterDocumentComponent = (
|
|
|
16
16
|
}) => unknown
|
|
17
17
|
|
|
18
18
|
const content = createElement(
|
|
19
|
-
routeOutletHtmlContext
|
|
19
|
+
routeOutletHtmlContext,
|
|
20
20
|
{ value: props.outletHtml ?? null },
|
|
21
21
|
createElement(Router, { router: props.router }),
|
|
22
22
|
)
|
|
23
23
|
|
|
24
24
|
return props.documentAssets
|
|
25
25
|
? createElement(
|
|
26
|
-
documentAssetsContext
|
|
26
|
+
documentAssetsContext,
|
|
27
27
|
{ value: props.documentAssets },
|
|
28
28
|
content,
|
|
29
29
|
)
|