@ultimat3/render 22.2.0 → 22.2.1
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 +6 -6
- package/src/module-loader.ts +28 -2
- package/src/server.ts +1 -0
- package/src/surfaces.ts +19 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ultimat3/render",
|
|
3
|
-
"version": "22.2.
|
|
3
|
+
"version": "22.2.1",
|
|
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.2.
|
|
40
|
-
"@ultimat3/core": "22.2.
|
|
41
|
-
"@ultimat3/http": "22.2.
|
|
42
|
-
"@ultimat3/i18n": "22.2.
|
|
43
|
-
"@ultimat3/seo": "22.2.
|
|
39
|
+
"@ultimat3/cache": "22.2.1",
|
|
40
|
+
"@ultimat3/core": "22.2.1",
|
|
41
|
+
"@ultimat3/http": "22.2.1",
|
|
42
|
+
"@ultimat3/i18n": "22.2.1",
|
|
43
|
+
"@ultimat3/seo": "22.2.1",
|
|
44
44
|
"sass": "1.104.0"
|
|
45
45
|
}
|
|
46
46
|
}
|
package/src/module-loader.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { renderThrowable } from '@ultimat3/core';
|
|
|
8
8
|
import { compileStylesheet, isGlobalStylesheet, stripCharset } from './css-modules';
|
|
9
9
|
import { PrerenderFailedError } from './errors';
|
|
10
10
|
import type { Surface } from './surfaces';
|
|
11
|
-
import {
|
|
11
|
+
import { surfaceUnder } from './surfaces';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Why a transform at all: `tsconfig.json` says `jsx: 'preserve'`, which makes Bun fall back to the
|
|
@@ -101,6 +101,32 @@ export function registeredStylesheets(): readonly Stylesheet[] {
|
|
|
101
101
|
return [...stylesheets.values()];
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* The directory a sheet's surface is read below. Absent, the process's working directory — which
|
|
106
|
+
* is the app root in the container (`WORKDIR /app`) and under every `x` command run from one.
|
|
107
|
+
*/
|
|
108
|
+
let stylesheetRoot: string | undefined;
|
|
109
|
+
|
|
110
|
+
const surfaceOfSheet = (path: string): Surface | null =>
|
|
111
|
+
surfaceUnder(stylesheetRoot ?? process.cwd(), path);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Names the app root the registry classifies against; `loadApp` calls it before importing a module.
|
|
115
|
+
* Every sheet already registered is classified again, because a sheet can load before the root is
|
|
116
|
+
* named — and a classification frozen then would keep the answer the wrong root gave. The revision
|
|
117
|
+
* moves only when an answer does, so naming the same root twice mints no new stylesheet URL.
|
|
118
|
+
* `undefined` returns to the working directory.
|
|
119
|
+
*/
|
|
120
|
+
export function setStylesheetRoot(root: string | undefined): void {
|
|
121
|
+
stylesheetRoot = root;
|
|
122
|
+
for (const [path, sheet] of stylesheets) {
|
|
123
|
+
const surface = surfaceOfSheet(path);
|
|
124
|
+
if (surface === sheet.surface) continue;
|
|
125
|
+
stylesheets.set(path, { ...sheet, surface });
|
|
126
|
+
revision += 1;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
104
130
|
/** Test seam: the registry is process-global because the module cache it mirrors is too. */
|
|
105
131
|
export function clearStylesheets(): void {
|
|
106
132
|
if (stylesheets.size > 0) revision += 1;
|
|
@@ -159,7 +185,7 @@ export function loadStylesheet(path: string, source: string): string {
|
|
|
159
185
|
if (stylesheets.get(path)?.css !== compiled.css) revision += 1;
|
|
160
186
|
stylesheets.set(path, {
|
|
161
187
|
file: path,
|
|
162
|
-
surface:
|
|
188
|
+
surface: surfaceOfSheet(path),
|
|
163
189
|
global: isGlobalStylesheet(path),
|
|
164
190
|
css: compiled.css,
|
|
165
191
|
});
|
package/src/server.ts
CHANGED
package/src/surfaces.ts
CHANGED
|
@@ -91,6 +91,25 @@ export function surfaceOf(file: string): Surface | null {
|
|
|
91
91
|
return locateSurface(file)?.surface ?? null;
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
+
/**
|
|
95
|
+
* The surface of an ABSOLUTE path, read from the part below the app `root`. `surfaceOf` takes the
|
|
96
|
+
* first surface-named segment, which is right for the root-relative paths the route table and the
|
|
97
|
+
* boundary check hold — and wrong for an absolute one whose root is itself called `app/`: the
|
|
98
|
+
* scaffold's container runs from `WORKDIR /app`, and every stylesheet there read as `app`, so the
|
|
99
|
+
* site bundle was empty and every site document shipped with no stylesheet at all.
|
|
100
|
+
*
|
|
101
|
+
* A file outside `root` is read as `surfaceOf` reads it. A file inside an installed package
|
|
102
|
+
* (`node_modules/…`) has no surface whatever its directories are called: it is a package sheet,
|
|
103
|
+
* which both graphs carry.
|
|
104
|
+
*/
|
|
105
|
+
export function surfaceUnder(root: string, file: string): Surface | null {
|
|
106
|
+
const base = normalize(root).replace(/\/+$/, '');
|
|
107
|
+
const path = normalize(file);
|
|
108
|
+
const relative = path.startsWith(`${base}/`) ? path.slice(base.length + 1) : path;
|
|
109
|
+
if (/(?:^|\/)node_modules\//.test(relative)) return null;
|
|
110
|
+
return surfaceOf(relative);
|
|
111
|
+
}
|
|
112
|
+
|
|
94
113
|
function normalize(file: string): string {
|
|
95
114
|
return file.replace(/\\/g, '/').replace(/^\.\//, '');
|
|
96
115
|
}
|