flamefront 0.1.5 → 0.1.7

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.5",
3
+ "version": "0.1.7",
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.5",
55
- "@babel/parser": "^8.0.5",
56
- "@babel/traverse": "^8.0.5",
57
- "@babel/types": "^8.0.5",
58
- "@remix-run/route-pattern": "^0.24.0",
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": "^5.8.2",
60
+ "devalue": "^6.0.0",
61
61
  "satteri": "^0.10.5",
62
- "srvx": "^1.0.4",
62
+ "srvx": "^1.0.5",
63
63
  "vite-plugin-satteri": "^0.3.5"
64
64
  },
65
65
  "devDependencies": {
66
- "@octanejs/remix-router": "^0.1.48",
67
- "@octanejs/vite-plugin": "^0.1.54",
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.3.137",
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.5.1",
73
- "octane": "^0.2.7",
72
+ "@types/node": "^26.6.2",
73
+ "octane": "^0.3.2",
74
74
  "oxc-tsrx": "^0.6.1",
75
- "oxlint": "^1.82.0",
76
- "oxlint-tsgolint": "^7.0.2001",
75
+ "oxlint": "^1.83.0",
76
+ "oxlint-tsgolint": "^7.0.2002",
77
77
  "playwright": "^1.63.0",
78
- "prettier": "^3.9.6",
78
+ "prettier": "^3.9.8",
79
79
  "typescript": "^5.9.3",
80
80
  "vite": "^8.3.0",
81
- "vitest": "^5.0.0"
81
+ "vitest": "^5.0.1"
82
82
  },
83
83
  "peerDependencies": {
84
- "@octanejs/remix-router": ">=0.1.48",
85
- "octane": ">=0.2.7",
84
+ "@octanejs/remix-router": ">=0.1.49",
85
+ "octane": ">=0.3.2",
86
86
  "vite": ">=8.3.0"
87
87
  }
88
88
  }
@@ -1,6 +1,7 @@
1
1
  import * as devalue from "devalue"
2
2
  import { data } from "@octanejs/remix-router"
3
3
  import {
4
+ actionRedirectStatusHeader,
4
5
  actionProtocolEnvelope,
5
6
  actionResponseInit,
6
7
  type ActionEnvelope,
@@ -45,6 +46,19 @@ function isRedirect(response: Response): boolean {
45
46
  return response.status >= 300 && response.status < 400
46
47
  }
47
48
 
49
+ function transportedRedirect(response: Response): Response | undefined {
50
+ const status = Number(response.headers.get(actionRedirectStatusHeader))
51
+
52
+ if (!Number.isInteger(status) || status < 300 || status >= 400) {
53
+ return undefined
54
+ }
55
+
56
+ const headers = new Headers(response.headers)
57
+
58
+ headers.delete(actionRedirectStatusHeader)
59
+ return new Response(null, { status, headers })
60
+ }
61
+
48
62
  function headersFromEnvelope(envelope: ActionEnvelope): Headers | undefined {
49
63
  return envelope.headers.length > 0
50
64
  ? new Headers(
@@ -83,6 +97,14 @@ async function decodeActionResponse(
83
97
  response: Response,
84
98
  options: ActionRequestOptions,
85
99
  ): Promise<unknown> {
100
+ const redirect = transportedRedirect(response)
101
+
102
+ if (redirect) {
103
+ invalidateRouteDataCache()
104
+ invalidateRouteFragments()
105
+ throw redirect
106
+ }
107
+
86
108
  if (isRedirect(response)) {
87
109
  invalidateRouteDataCache()
88
110
  invalidateRouteFragments()
@@ -157,7 +179,6 @@ export function createActionProxy<
157
179
  const response = await globalThis.fetch(endpoint, {
158
180
  method: "POST",
159
181
  credentials: "same-origin",
160
- redirect: "manual",
161
182
  headers: {
162
183
  "Content-Type": "application/vnd.flamefront.action+devalue",
163
184
  Accept: "application/vnd.flamefront.action+devalue",
@@ -178,8 +199,13 @@ export async function submitRouteAction(
178
199
 
179
200
  url.searchParams.set("__flamefront_action", "1")
180
201
  const source = request.clone()
181
- const response = await globalThis.fetch(new Request(url, source), {
182
- redirect: "manual",
202
+ const actionRequest = new Request(url, {
203
+ method: source.method,
204
+ headers: source.headers,
205
+ body: await source.blob(),
206
+ signal: source.signal,
207
+ })
208
+ const response = await globalThis.fetch(actionRequest, {
183
209
  credentials: "same-origin",
184
210
  })
185
211
 
package/src/action.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as devalue from "devalue"
2
2
 
3
+ export const actionRedirectStatusHeader = "X-Flamefront-Redirect-Status"
4
+
3
5
  /** The structural value returned by the router's `data()` helper. */
4
6
  export interface ActionDataWithResponseInit<Data = unknown> {
5
7
  readonly type: "DataWithResponseInit"
@@ -339,6 +341,13 @@ function envelopeResponse(envelope: ActionEnvelope): Response {
339
341
  /** Encode an action return value or error as a Fetch response. */
340
342
  export function actionResultResponse(value: unknown): Response {
341
343
  if (value instanceof Response) {
344
+ if (value.status >= 300 && value.status < 400) {
345
+ const headers = new Headers(value.headers)
346
+
347
+ headers.set(actionRedirectStatusHeader, String(value.status))
348
+ return new Response(null, { status: 204, headers })
349
+ }
350
+
342
351
  return value
343
352
  }
344
353
 
package/src/fragment.tsx CHANGED
@@ -438,9 +438,9 @@ function createShellBoundary(
438
438
  ),
439
439
  }
440
440
  const shell = (
441
- <UNSAFE_RouteContext.Provider value={shellRoute}>
441
+ <UNSAFE_RouteContext value={shellRoute}>
442
442
  <Component {...props} />
443
- </UNSAFE_RouteContext.Provider>
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.Provider
485
- const DataRouterStateProvider = UNSAFE_DataRouterStateContext.Provider
486
- const FetchersProvider = UNSAFE_FetchersContext.Provider
487
- const LocationProvider = UNSAFE_LocationContext.Provider
488
- const NavigationProvider = UNSAFE_NavigationContext.Provider
489
- const RouteProvider = UNSAFE_RouteContext.Provider
490
- const ViewTransitionProvider = UNSAFE_ViewTransitionContext.Provider
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.Provider
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.Provider,
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.Provider,
26
+ documentAssetsContext,
27
27
  { value: props.documentAssets },
28
28
  content,
29
29
  )
package/src/vite.ts CHANGED
@@ -820,10 +820,15 @@ export function flamefront(options: FlamefrontOptions = {}) {
820
820
  transformOptions?: TransformOptions,
821
821
  ) {
822
822
  const context = this as Pick<PluginContext, "environment">
823
+ const moduleId = cleanModuleId(id)
824
+
825
+ if (moduleId.endsWith(".md") || moduleId.endsWith(".mdx")) {
826
+ return null
827
+ }
823
828
 
824
829
  if (
825
830
  isServerEnvironment(context, transformOptions) &&
826
- !cleanModuleId(id).endsWith(".tsrx") &&
831
+ !moduleId.endsWith(".tsrx") &&
827
832
  source.includes("action") &&
828
833
  /flamefront(?:\/server)?["']/.test(source)
829
834
  ) {
@@ -838,7 +843,7 @@ export function flamefront(options: FlamefrontOptions = {}) {
838
843
  }
839
844
 
840
845
  if (
841
- !cleanModuleId(id).endsWith(".tsrx") &&
846
+ !moduleId.endsWith(".tsrx") &&
842
847
  source.includes("action") &&
843
848
  /flamefront(?:\/server)?["']/.test(source)
844
849
  ) {
@@ -1134,7 +1139,13 @@ export function flamefront(options: FlamefrontOptions = {}) {
1134
1139
  return null
1135
1140
  }
1136
1141
 
1137
- if (!(await loadRouteModuleIds()).has(cleanModuleId(id))) {
1142
+ const moduleId = cleanModuleId(id)
1143
+
1144
+ if (moduleId.endsWith(".md") || moduleId.endsWith(".mdx")) {
1145
+ return null
1146
+ }
1147
+
1148
+ if (!(await loadRouteModuleIds()).has(moduleId)) {
1138
1149
  return null
1139
1150
  }
1140
1151