brustjs 0.1.36-alpha → 0.1.38-alpha

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.
@@ -62,6 +62,19 @@ export function createIslandUsedBox(): IslandUsedBox {
62
62
  return { used: false }
63
63
  }
64
64
 
65
+ // Component function → content-addressed island id (`<Name>_<hash>`). Populated
66
+ // at worker boot (configureIslandIdRegistry) by importing each island source and
67
+ // mapping its default export. Keyed by FUNCTION IDENTITY, so two same-named
68
+ // components from different files map to distinct ids — giving the React render
69
+ // path the same same-name parity the native jinja rewrite gives native routes.
70
+ // Empty in unit tests / when no manifest → markers fall back to Component.name.
71
+ let islandIdRegistry: Map<unknown, string> = new Map()
72
+
73
+ /** Seed the Component→id registry (worker boot). */
74
+ export function configureIslandIdRegistry(entries: Iterable<[unknown, string]>): void {
75
+ islandIdRegistry = new Map(entries)
76
+ }
77
+
65
78
  /** Carries the per-render {@link IslandUsedBox} down to every `<Island>`. The
66
79
  * renderer wraps the tree in a Provider with a fresh box; an `<Island>` rendered
67
80
  * with no Provider (e.g. a standalone `renderToString` outside the React render
@@ -83,7 +96,11 @@ export function Island<P extends object>({
83
96
  // rendered without a Provider (standalone renderToString).
84
97
  const usedBox = useContext(IslandUsedContext)
85
98
  if (usedBox) usedBox.used = true
86
- const resolvedId = Component.name
99
+ // Marker id: the content-addressed island id (`<Name>_<hash>`) from the
100
+ // registry (keyed by component identity → same-name parity), falling back to
101
+ // the plain Component name when the registry isn't seeded (unit test, or a
102
+ // component not in the manifest — the _islands.js name→url map resolves it).
103
+ const resolvedId = islandIdRegistry.get(Component) ?? Component.name
87
104
  if (!resolvedId) {
88
105
  throw new Error(
89
106
  '<Island> component has no `.name`; the island id is derived from ' +
package/runtime/routes.ts CHANGED
@@ -12,6 +12,7 @@ import * as native from './index.js'
12
12
  import { renderBranchStreaming } from './render/stream.ts'
13
13
  import { runInStoreContext, collectSnapshot } from './store/server-context.ts'
14
14
  import { buildStoreScripts } from './render/inject-store.ts'
15
+ import { getCssHrefsForRoute } from './css.ts'
15
16
  import { runInRequestCache } from './loader-cache.ts'
16
17
  import { runInRequestScope, __scope } from './request-context.ts'
17
18
  import {
@@ -816,6 +817,21 @@ export function makeRenderer(
816
817
  )
817
818
  }
818
819
  ;(data as Record<string, unknown>).__brust_store__ = buildStoreScripts(storeSnapshot)
820
+ // Component-CSS SSR. Fill the framework-owned
821
+ // `{{ __brust_component_css__ | safe }}` head slot with the route's
822
+ // component-CSS chunk <link>s (from the component-CSS manifest, seeded
823
+ // per-route in the worker). Empty string when the route imports no
824
+ // .module.css / co-located .css, so the slot always resolves.
825
+ if (process.env.BRUST_DEV === '1' && '__brust_component_css__' in data) {
826
+ console.warn(
827
+ `[brust] native loader for "${flat.nativeTemplate}" returned a reserved "__brust_component_css__" key — overwritten by the component-CSS links`,
828
+ )
829
+ }
830
+ ;(data as Record<string, unknown>).__brust_component_css__ = getCssHrefsForRoute(
831
+ flat.fullPath,
832
+ )
833
+ .map((href) => `<link rel="stylesheet" href="${href}"/>`)
834
+ .join('')
819
835
  }
820
836
  const json = JSON.stringify(data)
821
837
  // napiRenderJinja has no headers param — any Set-Cookie staged by a