@ultimat3/render 22.3.3 → 22.3.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ultimat3/render",
3
- "version": "22.3.3",
3
+ "version": "22.3.4",
4
4
  "description": "The route primitive and the five render modes: static, isr, ssr, stream, spa.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -36,11 +36,11 @@
36
36
  "test": "bun test"
37
37
  },
38
38
  "dependencies": {
39
- "@ultimat3/cache": "22.3.3",
40
- "@ultimat3/core": "22.3.3",
41
- "@ultimat3/http": "22.3.3",
42
- "@ultimat3/i18n": "22.3.3",
43
- "@ultimat3/seo": "22.3.3",
39
+ "@ultimat3/cache": "22.3.4",
40
+ "@ultimat3/core": "22.3.4",
41
+ "@ultimat3/http": "22.3.4",
42
+ "@ultimat3/i18n": "22.3.4",
43
+ "@ultimat3/seo": "22.3.4",
44
44
  "sass": "1.104.0"
45
45
  }
46
46
  }
@@ -78,6 +78,14 @@ export interface Stylesheet {
78
78
  readonly surface: Surface | null;
79
79
  /** A plain (non-module) stylesheet: the tokens and the reset, which the cascade needs first. */
80
80
  readonly global: boolean;
81
+ /**
82
+ * Registered only by an ISLAND build, never by the server's module graph. Such a sheet is ordered
83
+ * by path, not by arrival: `Bun.build` loads an island graph in parallel, so its arrival order
84
+ * differs between processes, and the surface stylesheet — its URL a hash of the joined bytes —
85
+ * differed between two pods of one image (notificado.co, 22.3.2: one pod's `/styles/<hash>.css`
86
+ * was the other's 404, and each `sw.js` precached a sheet the other did not serve).
87
+ */
88
+ readonly island: boolean;
81
89
  readonly css: string;
82
90
  }
83
91
 
@@ -158,9 +166,17 @@ export function stylesFor(surface: Surface | null): string {
158
166
  );
159
167
  // `stripCharset` on every sheet, not only the first: a `@charset` or a BOM is legal at byte 0 of
160
168
  // a FILE and nowhere else, and this join is what turns seven files into one.
161
- return [...carried.filter((sheet) => sheet.global), ...carried.filter((sheet) => !sheet.global)]
162
- .map((sheet) => stripCharset(sheet.css))
163
- .join('');
169
+ //
170
+ // Within each group, the server graph's sheets keep load order — deterministic, because `loadApp`
171
+ // imports in sorted order, and meaningful, because a page's module loads after the component
172
+ // module it overrides — and the island-only sheets follow, by path.
173
+ const byPath = (a: Stylesheet, b: Stylesheet): number =>
174
+ a.file < b.file ? -1 : a.file > b.file ? 1 : 0;
175
+ const group = (global: boolean): Stylesheet[] => [
176
+ ...carried.filter((sheet) => sheet.global === global && !sheet.island),
177
+ ...carried.filter((sheet) => sheet.global === global && sheet.island).sort(byPath),
178
+ ];
179
+ return [...group(true), ...group(false)].map((sheet) => stripCharset(sheet.css)).join('');
164
180
  }
165
181
 
166
182
  /**
@@ -181,17 +197,26 @@ export function transformTsx(source: string): string {
181
197
  * compilation — so a token file `@use`d by twenty `page.module.scss` would inline its `:root` block
182
198
  * twenty times. One file, imported for its side effect, is the shape that cannot do that.
183
199
  */
184
- export function loadStylesheet(path: string, source: string): string {
200
+ export function loadStylesheet(
201
+ path: string,
202
+ source: string,
203
+ origin: 'module' | 'island' = 'module',
204
+ ): string {
185
205
  const compiled = compileStylesheet(path, source);
186
206
  // An EMPTY compile unregisters: under `x dev` an edit that deleted every rule left the old entry
187
207
  // in place, serving rules the file no longer had until the process restarted.
188
208
  if (compiled.css.length === 0 && stylesheets.delete(path)) revision += 1;
189
209
  if (compiled.css.length > 0) {
190
- if (stylesheets.get(path)?.css !== compiled.css) revision += 1;
210
+ const held = stylesheets.get(path);
211
+ // Island-only until the server graph loads it too; then it takes its place in load order.
212
+ const island = origin === 'island' && (held === undefined || held.island);
213
+ if (held?.css !== compiled.css || held.island !== island) revision += 1;
214
+ if (held?.island === true && !island) stylesheets.delete(path);
191
215
  stylesheets.set(path, {
192
216
  file: path,
193
217
  surface: surfaceOfSheet(path),
194
218
  global: isGlobalStylesheet(path),
219
+ island,
195
220
  css: compiled.css,
196
221
  });
197
222
  }