@ultimat3/render 22.2.0 → 22.2.2
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 +33 -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.2",
|
|
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.2",
|
|
40
|
+
"@ultimat3/core": "22.2.2",
|
|
41
|
+
"@ultimat3/http": "22.2.2",
|
|
42
|
+
"@ultimat3/i18n": "22.2.2",
|
|
43
|
+
"@ultimat3/seo": "22.2.2",
|
|
44
44
|
"sass": "1.104.0"
|
|
45
45
|
}
|
|
46
46
|
}
|
package/src/module-loader.ts
CHANGED
|
@@ -4,11 +4,14 @@
|
|
|
4
4
|
* `bun test` all load a component the same way and there is no separate "bundled" behaviour.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
+
// why: Bun ships no path API, and a relative app root has to be resolved against the working
|
|
8
|
+
// directory before it can be compared with the absolute paths the Bun plugin hands this loader.
|
|
9
|
+
import { resolve } from 'node:path';
|
|
7
10
|
import { renderThrowable } from '@ultimat3/core';
|
|
8
11
|
import { compileStylesheet, isGlobalStylesheet, stripCharset } from './css-modules';
|
|
9
12
|
import { PrerenderFailedError } from './errors';
|
|
10
13
|
import type { Surface } from './surfaces';
|
|
11
|
-
import {
|
|
14
|
+
import { surfaceUnder } from './surfaces';
|
|
12
15
|
|
|
13
16
|
/**
|
|
14
17
|
* Why a transform at all: `tsconfig.json` says `jsx: 'preserve'`, which makes Bun fall back to the
|
|
@@ -101,6 +104,34 @@ export function registeredStylesheets(): readonly Stylesheet[] {
|
|
|
101
104
|
return [...stylesheets.values()];
|
|
102
105
|
}
|
|
103
106
|
|
|
107
|
+
/**
|
|
108
|
+
* The directory a sheet's surface is read below. Absent, the process's working directory — which
|
|
109
|
+
* is the app root in the container (`WORKDIR /app`) and under every `x` command run from one.
|
|
110
|
+
*/
|
|
111
|
+
let stylesheetRoot: string | undefined;
|
|
112
|
+
|
|
113
|
+
const surfaceOfSheet = (path: string): Surface | null =>
|
|
114
|
+
surfaceUnder(stylesheetRoot ?? process.cwd(), path);
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Names the app root the registry classifies against; `loadApp` calls it before importing a module.
|
|
118
|
+
* Every sheet already registered is classified again, because a sheet can load before the root is
|
|
119
|
+
* named — and a classification frozen then would keep the answer the wrong root gave. The revision
|
|
120
|
+
* moves only when an answer does, so naming the same root twice mints no new stylesheet URL.
|
|
121
|
+
* A relative root is resolved against the working directory. `undefined` returns to the working
|
|
122
|
+
* directory.
|
|
123
|
+
*/
|
|
124
|
+
export function setStylesheetRoot(root: string | undefined): void {
|
|
125
|
+
// Resolved: `loadApp('.')` is a legal call, and `.` is a prefix of no absolute path.
|
|
126
|
+
stylesheetRoot = root === undefined ? undefined : resolve(root);
|
|
127
|
+
for (const [path, sheet] of stylesheets) {
|
|
128
|
+
const surface = surfaceOfSheet(path);
|
|
129
|
+
if (surface === sheet.surface) continue;
|
|
130
|
+
stylesheets.set(path, { ...sheet, surface });
|
|
131
|
+
revision += 1;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
104
135
|
/** Test seam: the registry is process-global because the module cache it mirrors is too. */
|
|
105
136
|
export function clearStylesheets(): void {
|
|
106
137
|
if (stylesheets.size > 0) revision += 1;
|
|
@@ -159,7 +190,7 @@ export function loadStylesheet(path: string, source: string): string {
|
|
|
159
190
|
if (stylesheets.get(path)?.css !== compiled.css) revision += 1;
|
|
160
191
|
stylesheets.set(path, {
|
|
161
192
|
file: path,
|
|
162
|
-
surface:
|
|
193
|
+
surface: surfaceOfSheet(path),
|
|
163
194
|
global: isGlobalStylesheet(path),
|
|
164
195
|
css: compiled.css,
|
|
165
196
|
});
|
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
|
}
|