@symbo.ls/brender 3.8.0 → 3.8.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/dist/cjs/env.js +14 -0
- package/dist/cjs/prefetch.js +2 -1
- package/dist/cjs/render.js +64 -49
- package/dist/esm/env.js +14 -0
- package/dist/esm/prefetch.js +2 -1
- package/dist/esm/render.js +64 -49
- package/env.js +11 -0
- package/load.js +2 -2
- package/package.json +2 -2
- package/prefetch.js +3 -1
- package/render.js +125 -49
package/dist/cjs/env.js
CHANGED
|
@@ -71,10 +71,24 @@ const createEnv = (html = "<!DOCTYPE html><html><head></head><body></body></html
|
|
|
71
71
|
if (!window.sessionStorage) window.sessionStorage = createStorage();
|
|
72
72
|
if (!globalThis.localStorage) globalThis.localStorage = window.localStorage;
|
|
73
73
|
if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage;
|
|
74
|
+
if (!window.MutationObserver) {
|
|
75
|
+
window.MutationObserver = class MutationObserver {
|
|
76
|
+
constructor() {
|
|
77
|
+
}
|
|
78
|
+
observe() {
|
|
79
|
+
}
|
|
80
|
+
disconnect() {
|
|
81
|
+
}
|
|
82
|
+
takeRecords() {
|
|
83
|
+
return [];
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
74
87
|
globalThis.window = window;
|
|
75
88
|
globalThis.document = document;
|
|
76
89
|
globalThis.Node = window.Node || globalThis.Node;
|
|
77
90
|
globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement;
|
|
91
|
+
globalThis.MutationObserver = window.MutationObserver;
|
|
78
92
|
globalThis.Window = window.constructor;
|
|
79
93
|
return { window, document };
|
|
80
94
|
};
|
package/dist/cjs/prefetch.js
CHANGED
|
@@ -207,7 +207,8 @@ const fetchSSRTranslations = async (data) => {
|
|
|
207
207
|
if (result.translations) {
|
|
208
208
|
translations[lang] = result.translations;
|
|
209
209
|
}
|
|
210
|
-
} catch {
|
|
210
|
+
} catch (e) {
|
|
211
|
+
console.warn("[brender] SSR translation fetch failed:", e.message);
|
|
211
212
|
}
|
|
212
213
|
})
|
|
213
214
|
);
|
package/dist/cjs/render.js
CHANGED
|
@@ -122,7 +122,7 @@ const safeJsonReplacer = () => {
|
|
|
122
122
|
return value;
|
|
123
123
|
};
|
|
124
124
|
};
|
|
125
|
-
const
|
|
125
|
+
const _brenderRequire = (0, import_module.createRequire)(import_meta.url);
|
|
126
126
|
const detectWorkspace = () => {
|
|
127
127
|
const brenderDir = (0, import_fs.realpathSync)(new URL(".", import_meta.url).pathname);
|
|
128
128
|
const monorepoRoot = (0, import_path.resolve)(brenderDir, "../..");
|
|
@@ -132,53 +132,68 @@ const detectWorkspace = () => {
|
|
|
132
132
|
}
|
|
133
133
|
let smblsRoot;
|
|
134
134
|
try {
|
|
135
|
-
const smblsPkg =
|
|
135
|
+
const smblsPkg = _brenderRequire.resolve("smbls/package.json");
|
|
136
136
|
smblsRoot = (0, import_path.dirname)(smblsPkg);
|
|
137
137
|
} catch {
|
|
138
|
-
let
|
|
139
|
-
while (
|
|
140
|
-
const candidate = (0, import_path.resolve)(
|
|
138
|
+
let dir2 = brenderDir;
|
|
139
|
+
while (dir2 !== (0, import_path.dirname)(dir2)) {
|
|
140
|
+
const candidate = (0, import_path.resolve)(dir2, "node_modules", "smbls");
|
|
141
141
|
if ((0, import_fs.existsSync)((0, import_path.resolve)(candidate, "package.json"))) {
|
|
142
142
|
smblsRoot = candidate;
|
|
143
143
|
break;
|
|
144
144
|
}
|
|
145
|
-
|
|
145
|
+
dir2 = (0, import_path.dirname)(dir2);
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
148
|
+
let _smblsRequire = _brenderRequire;
|
|
149
|
+
if (smblsRoot) {
|
|
150
|
+
try {
|
|
151
|
+
_smblsRequire = (0, import_module.createRequire)((0, import_path.resolve)(smblsRoot, "package.json"));
|
|
152
|
+
} catch {
|
|
153
|
+
}
|
|
153
154
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
let projectRoot;
|
|
156
|
+
let dir = process.cwd();
|
|
157
|
+
while (dir !== (0, import_path.dirname)(dir)) {
|
|
158
|
+
if ((0, import_fs.existsSync)((0, import_path.resolve)(dir, "package.json"))) {
|
|
159
|
+
projectRoot = dir;
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
dir = (0, import_path.dirname)(dir);
|
|
158
163
|
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
"css-in-props": "css-in-props",
|
|
162
|
-
"attrs-in-props": "attrs-in-props"
|
|
163
|
-
};
|
|
164
|
-
if (scopedNames[pkgName]) {
|
|
164
|
+
let _projectRequire = _smblsRequire;
|
|
165
|
+
if (projectRoot) {
|
|
165
166
|
try {
|
|
166
|
-
|
|
167
|
-
return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
167
|
+
_projectRequire = (0, import_module.createRequire)((0, import_path.resolve)(projectRoot, "package.json"));
|
|
168
168
|
} catch {
|
|
169
169
|
}
|
|
170
170
|
}
|
|
171
|
+
return { isMonorepo: false, smblsRoot, brenderDir, projectRoot, _smblsRequire, _projectRequire };
|
|
172
|
+
};
|
|
173
|
+
const tryRequireResolve = (ws, specifier) => {
|
|
174
|
+
const requireFns = ws.isMonorepo ? [_brenderRequire] : [ws._smblsRequire, ws._projectRequire, _brenderRequire].filter(Boolean);
|
|
175
|
+
for (const req of requireFns) {
|
|
176
|
+
try {
|
|
177
|
+
return req.resolve(specifier);
|
|
178
|
+
} catch {
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
};
|
|
183
|
+
const resolvePackagePath = (ws, pkgName, ...subpath) => {
|
|
184
|
+
if (ws.isMonorepo) {
|
|
185
|
+
return (0, import_path.resolve)(ws.monorepoRoot, "packages", pkgName, ...subpath);
|
|
186
|
+
}
|
|
187
|
+
const pkgJson = tryRequireResolve(ws, `${pkgName}/package.json`);
|
|
188
|
+
if (pkgJson) return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
171
189
|
return null;
|
|
172
190
|
};
|
|
173
191
|
const resolvePluginPath = (ws, pluginName, ...subpath) => {
|
|
174
192
|
if (ws.isMonorepo) {
|
|
175
193
|
return (0, import_path.resolve)(ws.monorepoRoot, "plugins", pluginName, ...subpath);
|
|
176
194
|
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
195
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pluginName}/package.json`);
|
|
196
|
+
if (pkgJson) return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
182
197
|
return null;
|
|
183
198
|
};
|
|
184
199
|
const resolveSymbolsPackage = (ws, pkg, ...subpath) => {
|
|
@@ -189,22 +204,16 @@ const resolveSymbolsPackage = (ws, pkg, ...subpath) => {
|
|
|
189
204
|
}
|
|
190
205
|
return null;
|
|
191
206
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
195
|
-
} catch {
|
|
196
|
-
}
|
|
207
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pkg}/package.json`);
|
|
208
|
+
if (pkgJson) return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
197
209
|
return null;
|
|
198
210
|
};
|
|
199
211
|
const resolveDomqlPackage = (ws, pkg, ...subpath) => {
|
|
200
212
|
if (ws.isMonorepo) {
|
|
201
213
|
return (0, import_path.resolve)(ws.monorepoRoot, "packages", "domql", "packages", pkg, ...subpath);
|
|
202
214
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
206
|
-
} catch {
|
|
207
|
-
}
|
|
215
|
+
const pkgJson = tryRequireResolve(ws, `@domql/${pkg}/package.json`);
|
|
216
|
+
if (pkgJson) return (0, import_path.resolve)((0, import_path.dirname)(pkgJson), ...subpath);
|
|
208
217
|
return null;
|
|
209
218
|
};
|
|
210
219
|
let _cachedCreateDomql = null;
|
|
@@ -307,10 +316,8 @@ const bundleCreateDomql = async () => {
|
|
|
307
316
|
if (ws.isMonorepo) {
|
|
308
317
|
base = (0, import_path.resolve)(ws.monorepoRoot, "packages", "css-in-props");
|
|
309
318
|
} else {
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
} catch {
|
|
313
|
-
}
|
|
319
|
+
const pkgJson = tryRequireResolve(ws, "css-in-props/package.json");
|
|
320
|
+
if (pkgJson) base = (0, import_path.dirname)(pkgJson);
|
|
314
321
|
}
|
|
315
322
|
if (!base) return;
|
|
316
323
|
const subpath = args.path.replace(/^css-in-props\/?/, "");
|
|
@@ -329,11 +336,9 @@ const bundleCreateDomql = async () => {
|
|
|
329
336
|
if (ws.isMonorepo) {
|
|
330
337
|
nm = (0, import_path.resolve)(ws.monorepoRoot, "node_modules", args.path);
|
|
331
338
|
} else {
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
339
|
+
const pkgJson = tryRequireResolve(ws, `${args.path}/package.json`);
|
|
340
|
+
if (!pkgJson) return;
|
|
341
|
+
nm = (0, import_path.dirname)(pkgJson);
|
|
337
342
|
}
|
|
338
343
|
if ((0, import_fs.existsSync)(nm)) {
|
|
339
344
|
const pkg = (0, import_path.resolve)(nm, "package.json");
|
|
@@ -407,7 +412,11 @@ const bundleCreateDomql = async () => {
|
|
|
407
412
|
write: true,
|
|
408
413
|
logLevel: "warning",
|
|
409
414
|
plugins: [workspacePlugin],
|
|
410
|
-
nodePaths: ws.isMonorepo ? [(0, import_path.resolve)(ws.monorepoRoot, "node_modules")] : [
|
|
415
|
+
nodePaths: ws.isMonorepo ? [(0, import_path.resolve)(ws.monorepoRoot, "node_modules")] : [
|
|
416
|
+
...ws.smblsRoot ? [(0, import_path.resolve)(ws.smblsRoot, "node_modules")] : [],
|
|
417
|
+
...ws.projectRoot ? [(0, import_path.resolve)(ws.projectRoot, "node_modules")] : [],
|
|
418
|
+
...ws.smblsRoot ? [(0, import_path.resolve)(ws.smblsRoot, "..", "..", "node_modules")] : []
|
|
419
|
+
].filter((p) => (0, import_fs.existsSync)(p)),
|
|
411
420
|
supported: { "import-attributes": false },
|
|
412
421
|
external: [
|
|
413
422
|
"fs",
|
|
@@ -561,7 +570,8 @@ const render = async (data, options = {}) => {
|
|
|
561
570
|
if (prefetch) {
|
|
562
571
|
try {
|
|
563
572
|
ssrTranslations = await (0, import_prefetch.fetchSSRTranslations)(data);
|
|
564
|
-
} catch {
|
|
573
|
+
} catch (e) {
|
|
574
|
+
console.warn("[brender] SSR translation fetch failed:", e.message);
|
|
565
575
|
}
|
|
566
576
|
}
|
|
567
577
|
if (_prevLocPrefetch !== void 0) globalThis.location = _prevLocPrefetch;
|
|
@@ -836,6 +846,11 @@ const generateGlobalCSS = async (ds, config) => {
|
|
|
836
846
|
write: true,
|
|
837
847
|
logLevel: "silent",
|
|
838
848
|
plugins: [workspacePlugin],
|
|
849
|
+
nodePaths: ws.isMonorepo ? [(0, import_path.resolve)(ws.monorepoRoot, "node_modules")] : [
|
|
850
|
+
...ws.smblsRoot ? [(0, import_path.resolve)(ws.smblsRoot, "node_modules")] : [],
|
|
851
|
+
...ws.projectRoot ? [(0, import_path.resolve)(ws.projectRoot, "node_modules")] : [],
|
|
852
|
+
...ws.smblsRoot ? [(0, import_path.resolve)(ws.smblsRoot, "..", "..", "node_modules")] : []
|
|
853
|
+
].filter((p) => existsSync2(p)),
|
|
839
854
|
external: ["fs", "path", "os", "crypto", "url", "http", "https", "stream", "util", "events", "buffer", "child_process", "worker_threads", "net", "tls", "dns", "dgram", "zlib", "assert", "querystring", "string_decoder", "readline", "perf_hooks", "async_hooks", "v8", "vm", "cluster", "inspector", "module", "process", "tty", "color-contrast-checker"]
|
|
840
855
|
});
|
|
841
856
|
const mod = await import(`file://${tmpOut}`);
|
package/dist/esm/env.js
CHANGED
|
@@ -49,10 +49,24 @@ const createEnv = (html = "<!DOCTYPE html><html><head></head><body></body></html
|
|
|
49
49
|
if (!window.sessionStorage) window.sessionStorage = createStorage();
|
|
50
50
|
if (!globalThis.localStorage) globalThis.localStorage = window.localStorage;
|
|
51
51
|
if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage;
|
|
52
|
+
if (!window.MutationObserver) {
|
|
53
|
+
window.MutationObserver = class MutationObserver {
|
|
54
|
+
constructor() {
|
|
55
|
+
}
|
|
56
|
+
observe() {
|
|
57
|
+
}
|
|
58
|
+
disconnect() {
|
|
59
|
+
}
|
|
60
|
+
takeRecords() {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
}
|
|
52
65
|
globalThis.window = window;
|
|
53
66
|
globalThis.document = document;
|
|
54
67
|
globalThis.Node = window.Node || globalThis.Node;
|
|
55
68
|
globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement;
|
|
69
|
+
globalThis.MutationObserver = window.MutationObserver;
|
|
56
70
|
globalThis.Window = window.constructor;
|
|
57
71
|
return { window, document };
|
|
58
72
|
};
|
package/dist/esm/prefetch.js
CHANGED
|
@@ -173,7 +173,8 @@ const fetchSSRTranslations = async (data) => {
|
|
|
173
173
|
if (result.translations) {
|
|
174
174
|
translations[lang] = result.translations;
|
|
175
175
|
}
|
|
176
|
-
} catch {
|
|
176
|
+
} catch (e) {
|
|
177
|
+
console.warn("[brender] SSR translation fetch failed:", e.message);
|
|
177
178
|
}
|
|
178
179
|
})
|
|
179
180
|
);
|
package/dist/esm/render.js
CHANGED
|
@@ -83,7 +83,7 @@ const safeJsonReplacer = () => {
|
|
|
83
83
|
return value;
|
|
84
84
|
};
|
|
85
85
|
};
|
|
86
|
-
const
|
|
86
|
+
const _brenderRequire = createRequire(import.meta.url);
|
|
87
87
|
const detectWorkspace = () => {
|
|
88
88
|
const brenderDir = realpathSync(new URL(".", import.meta.url).pathname);
|
|
89
89
|
const monorepoRoot = resolve(brenderDir, "../..");
|
|
@@ -93,53 +93,68 @@ const detectWorkspace = () => {
|
|
|
93
93
|
}
|
|
94
94
|
let smblsRoot;
|
|
95
95
|
try {
|
|
96
|
-
const smblsPkg =
|
|
96
|
+
const smblsPkg = _brenderRequire.resolve("smbls/package.json");
|
|
97
97
|
smblsRoot = dirname(smblsPkg);
|
|
98
98
|
} catch {
|
|
99
|
-
let
|
|
100
|
-
while (
|
|
101
|
-
const candidate = resolve(
|
|
99
|
+
let dir2 = brenderDir;
|
|
100
|
+
while (dir2 !== dirname(dir2)) {
|
|
101
|
+
const candidate = resolve(dir2, "node_modules", "smbls");
|
|
102
102
|
if (existsSync(resolve(candidate, "package.json"))) {
|
|
103
103
|
smblsRoot = candidate;
|
|
104
104
|
break;
|
|
105
105
|
}
|
|
106
|
-
|
|
106
|
+
dir2 = dirname(dir2);
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
let _smblsRequire = _brenderRequire;
|
|
110
|
+
if (smblsRoot) {
|
|
111
|
+
try {
|
|
112
|
+
_smblsRequire = createRequire(resolve(smblsRoot, "package.json"));
|
|
113
|
+
} catch {
|
|
114
|
+
}
|
|
114
115
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
116
|
+
let projectRoot;
|
|
117
|
+
let dir = process.cwd();
|
|
118
|
+
while (dir !== dirname(dir)) {
|
|
119
|
+
if (existsSync(resolve(dir, "package.json"))) {
|
|
120
|
+
projectRoot = dir;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
dir = dirname(dir);
|
|
119
124
|
}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"css-in-props": "css-in-props",
|
|
123
|
-
"attrs-in-props": "attrs-in-props"
|
|
124
|
-
};
|
|
125
|
-
if (scopedNames[pkgName]) {
|
|
125
|
+
let _projectRequire = _smblsRequire;
|
|
126
|
+
if (projectRoot) {
|
|
126
127
|
try {
|
|
127
|
-
|
|
128
|
-
return resolve(dirname(pkgJson), ...subpath);
|
|
128
|
+
_projectRequire = createRequire(resolve(projectRoot, "package.json"));
|
|
129
129
|
} catch {
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
+
return { isMonorepo: false, smblsRoot, brenderDir, projectRoot, _smblsRequire, _projectRequire };
|
|
133
|
+
};
|
|
134
|
+
const tryRequireResolve = (ws, specifier) => {
|
|
135
|
+
const requireFns = ws.isMonorepo ? [_brenderRequire] : [ws._smblsRequire, ws._projectRequire, _brenderRequire].filter(Boolean);
|
|
136
|
+
for (const req of requireFns) {
|
|
137
|
+
try {
|
|
138
|
+
return req.resolve(specifier);
|
|
139
|
+
} catch {
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return null;
|
|
143
|
+
};
|
|
144
|
+
const resolvePackagePath = (ws, pkgName, ...subpath) => {
|
|
145
|
+
if (ws.isMonorepo) {
|
|
146
|
+
return resolve(ws.monorepoRoot, "packages", pkgName, ...subpath);
|
|
147
|
+
}
|
|
148
|
+
const pkgJson = tryRequireResolve(ws, `${pkgName}/package.json`);
|
|
149
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath);
|
|
132
150
|
return null;
|
|
133
151
|
};
|
|
134
152
|
const resolvePluginPath = (ws, pluginName, ...subpath) => {
|
|
135
153
|
if (ws.isMonorepo) {
|
|
136
154
|
return resolve(ws.monorepoRoot, "plugins", pluginName, ...subpath);
|
|
137
155
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
return resolve(dirname(pkgJson), ...subpath);
|
|
141
|
-
} catch {
|
|
142
|
-
}
|
|
156
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pluginName}/package.json`);
|
|
157
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath);
|
|
143
158
|
return null;
|
|
144
159
|
};
|
|
145
160
|
const resolveSymbolsPackage = (ws, pkg, ...subpath) => {
|
|
@@ -150,22 +165,16 @@ const resolveSymbolsPackage = (ws, pkg, ...subpath) => {
|
|
|
150
165
|
}
|
|
151
166
|
return null;
|
|
152
167
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
return resolve(dirname(pkgJson), ...subpath);
|
|
156
|
-
} catch {
|
|
157
|
-
}
|
|
168
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pkg}/package.json`);
|
|
169
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath);
|
|
158
170
|
return null;
|
|
159
171
|
};
|
|
160
172
|
const resolveDomqlPackage = (ws, pkg, ...subpath) => {
|
|
161
173
|
if (ws.isMonorepo) {
|
|
162
174
|
return resolve(ws.monorepoRoot, "packages", "domql", "packages", pkg, ...subpath);
|
|
163
175
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
return resolve(dirname(pkgJson), ...subpath);
|
|
167
|
-
} catch {
|
|
168
|
-
}
|
|
176
|
+
const pkgJson = tryRequireResolve(ws, `@domql/${pkg}/package.json`);
|
|
177
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath);
|
|
169
178
|
return null;
|
|
170
179
|
};
|
|
171
180
|
let _cachedCreateDomql = null;
|
|
@@ -268,10 +277,8 @@ const bundleCreateDomql = async () => {
|
|
|
268
277
|
if (ws.isMonorepo) {
|
|
269
278
|
base = resolve(ws.monorepoRoot, "packages", "css-in-props");
|
|
270
279
|
} else {
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
} catch {
|
|
274
|
-
}
|
|
280
|
+
const pkgJson = tryRequireResolve(ws, "css-in-props/package.json");
|
|
281
|
+
if (pkgJson) base = dirname(pkgJson);
|
|
275
282
|
}
|
|
276
283
|
if (!base) return;
|
|
277
284
|
const subpath = args.path.replace(/^css-in-props\/?/, "");
|
|
@@ -290,11 +297,9 @@ const bundleCreateDomql = async () => {
|
|
|
290
297
|
if (ws.isMonorepo) {
|
|
291
298
|
nm = resolve(ws.monorepoRoot, "node_modules", args.path);
|
|
292
299
|
} else {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
300
|
+
const pkgJson = tryRequireResolve(ws, `${args.path}/package.json`);
|
|
301
|
+
if (!pkgJson) return;
|
|
302
|
+
nm = dirname(pkgJson);
|
|
298
303
|
}
|
|
299
304
|
if (existsSync(nm)) {
|
|
300
305
|
const pkg = resolve(nm, "package.json");
|
|
@@ -368,7 +373,11 @@ const bundleCreateDomql = async () => {
|
|
|
368
373
|
write: true,
|
|
369
374
|
logLevel: "warning",
|
|
370
375
|
plugins: [workspacePlugin],
|
|
371
|
-
nodePaths: ws.isMonorepo ? [resolve(ws.monorepoRoot, "node_modules")] : [
|
|
376
|
+
nodePaths: ws.isMonorepo ? [resolve(ws.monorepoRoot, "node_modules")] : [
|
|
377
|
+
...ws.smblsRoot ? [resolve(ws.smblsRoot, "node_modules")] : [],
|
|
378
|
+
...ws.projectRoot ? [resolve(ws.projectRoot, "node_modules")] : [],
|
|
379
|
+
...ws.smblsRoot ? [resolve(ws.smblsRoot, "..", "..", "node_modules")] : []
|
|
380
|
+
].filter((p) => existsSync(p)),
|
|
372
381
|
supported: { "import-attributes": false },
|
|
373
382
|
external: [
|
|
374
383
|
"fs",
|
|
@@ -522,7 +531,8 @@ const render = async (data, options = {}) => {
|
|
|
522
531
|
if (prefetch) {
|
|
523
532
|
try {
|
|
524
533
|
ssrTranslations = await fetchSSRTranslations(data);
|
|
525
|
-
} catch {
|
|
534
|
+
} catch (e) {
|
|
535
|
+
console.warn("[brender] SSR translation fetch failed:", e.message);
|
|
526
536
|
}
|
|
527
537
|
}
|
|
528
538
|
if (_prevLocPrefetch !== void 0) globalThis.location = _prevLocPrefetch;
|
|
@@ -797,6 +807,11 @@ const generateGlobalCSS = async (ds, config) => {
|
|
|
797
807
|
write: true,
|
|
798
808
|
logLevel: "silent",
|
|
799
809
|
plugins: [workspacePlugin],
|
|
810
|
+
nodePaths: ws.isMonorepo ? [resolve(ws.monorepoRoot, "node_modules")] : [
|
|
811
|
+
...ws.smblsRoot ? [resolve(ws.smblsRoot, "node_modules")] : [],
|
|
812
|
+
...ws.projectRoot ? [resolve(ws.projectRoot, "node_modules")] : [],
|
|
813
|
+
...ws.smblsRoot ? [resolve(ws.smblsRoot, "..", "..", "node_modules")] : []
|
|
814
|
+
].filter((p) => existsSync2(p)),
|
|
800
815
|
external: ["fs", "path", "os", "crypto", "url", "http", "https", "stream", "util", "events", "buffer", "child_process", "worker_threads", "net", "tls", "dns", "dgram", "zlib", "assert", "querystring", "string_decoder", "readline", "perf_hooks", "async_hooks", "v8", "vm", "cluster", "inspector", "module", "process", "tty", "color-contrast-checker"]
|
|
801
816
|
});
|
|
802
817
|
const mod = await import(`file://${tmpOut}`);
|
package/env.js
CHANGED
|
@@ -48,12 +48,23 @@ export const createEnv = (html = '<!DOCTYPE html><html><head></head><body></body
|
|
|
48
48
|
if (!globalThis.localStorage) globalThis.localStorage = window.localStorage
|
|
49
49
|
if (!globalThis.sessionStorage) globalThis.sessionStorage = window.sessionStorage
|
|
50
50
|
|
|
51
|
+
// Stub MutationObserver for SSR (not provided by linkedom)
|
|
52
|
+
if (!window.MutationObserver) {
|
|
53
|
+
window.MutationObserver = class MutationObserver {
|
|
54
|
+
constructor () {}
|
|
55
|
+
observe () {}
|
|
56
|
+
disconnect () {}
|
|
57
|
+
takeRecords () { return [] }
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
51
61
|
// Expose linkedom constructors on globalThis so @domql/utils isDOMNode
|
|
52
62
|
// can use instanceof checks (it reads from globalThis.Node, etc.)
|
|
53
63
|
globalThis.window = window
|
|
54
64
|
globalThis.document = document
|
|
55
65
|
globalThis.Node = window.Node || globalThis.Node
|
|
56
66
|
globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement
|
|
67
|
+
globalThis.MutationObserver = window.MutationObserver
|
|
57
68
|
globalThis.Window = window.constructor
|
|
58
69
|
|
|
59
70
|
return { window, document }
|
package/load.js
CHANGED
|
@@ -38,9 +38,9 @@ const bundleAndImport = async (entryPath) => {
|
|
|
38
38
|
return mod
|
|
39
39
|
} catch {
|
|
40
40
|
// Fallback: try raw import
|
|
41
|
-
try { return await import(entryPath) } catch { return null }
|
|
41
|
+
try { return await import(entryPath) } catch { return null } // fallback: module not found via this resolver, trying next
|
|
42
42
|
} finally {
|
|
43
|
-
try { unlinkSync(outFile) } catch {}
|
|
43
|
+
try { unlinkSync(outFile) } catch {} // cleanup: ignore if temp file already removed
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@symbo.ls/brender",
|
|
3
|
-
"version": "3.8.
|
|
3
|
+
"version": "3.8.2",
|
|
4
4
|
"license": "CC-BY-NC-4.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/esm/index.js",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"dev:rita": "node examples/serve-rita.js"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@symbo.ls/helmet": "^3.8.
|
|
39
|
+
"@symbo.ls/helmet": "^3.8.1",
|
|
40
40
|
"linkedom": "^0.16.8"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
package/prefetch.js
CHANGED
|
@@ -278,7 +278,9 @@ export const fetchSSRTranslations = async (data) => {
|
|
|
278
278
|
if (result.translations) {
|
|
279
279
|
translations[lang] = result.translations
|
|
280
280
|
}
|
|
281
|
-
} catch {
|
|
281
|
+
} catch (e) {
|
|
282
|
+
console.warn('[brender] SSR translation fetch failed:', e.message)
|
|
283
|
+
}
|
|
282
284
|
})
|
|
283
285
|
)
|
|
284
286
|
|
package/render.js
CHANGED
|
@@ -104,7 +104,7 @@ const safeJsonReplacer = () => {
|
|
|
104
104
|
// ── Workspace detection ──────────────────────────────────────────────────────
|
|
105
105
|
// Detect whether brender is running inside the monorepo or as an installed
|
|
106
106
|
// npm package, and resolve paths accordingly.
|
|
107
|
-
const
|
|
107
|
+
const _brenderRequire = createRequire(import.meta.url)
|
|
108
108
|
|
|
109
109
|
const detectWorkspace = () => {
|
|
110
110
|
const brenderDir = realpathSync(new URL('.', import.meta.url).pathname)
|
|
@@ -121,7 +121,7 @@ const detectWorkspace = () => {
|
|
|
121
121
|
// Find the smbls package root via require.resolve
|
|
122
122
|
let smblsRoot
|
|
123
123
|
try {
|
|
124
|
-
const smblsPkg =
|
|
124
|
+
const smblsPkg = _brenderRequire.resolve('smbls/package.json')
|
|
125
125
|
smblsRoot = dirname(smblsPkg)
|
|
126
126
|
} catch {
|
|
127
127
|
// Fallback: walk up from brenderDir looking for node_modules/smbls
|
|
@@ -136,7 +136,48 @@ const detectWorkspace = () => {
|
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
// Create a require function from smbls root so we can resolve its dependencies
|
|
140
|
+
// (e.g. @symbo.ls/scratch, @symbo.ls/default-config which are deps of smbls, not brender)
|
|
141
|
+
let _smblsRequire = _brenderRequire
|
|
142
|
+
if (smblsRoot) {
|
|
143
|
+
try {
|
|
144
|
+
_smblsRequire = createRequire(resolve(smblsRoot, 'package.json'))
|
|
145
|
+
} catch {} // fallback: module not found via this resolver, trying next
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Also find the project root (where the user's package.json is)
|
|
149
|
+
let projectRoot
|
|
150
|
+
let dir = process.cwd()
|
|
151
|
+
while (dir !== dirname(dir)) {
|
|
152
|
+
if (existsSync(resolve(dir, 'package.json'))) {
|
|
153
|
+
projectRoot = dir
|
|
154
|
+
break
|
|
155
|
+
}
|
|
156
|
+
dir = dirname(dir)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Create a require from project root for hoisted deps
|
|
160
|
+
let _projectRequire = _smblsRequire
|
|
161
|
+
if (projectRoot) {
|
|
162
|
+
try {
|
|
163
|
+
_projectRequire = createRequire(resolve(projectRoot, 'package.json'))
|
|
164
|
+
} catch {} // fallback: module not found via this resolver, trying next
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return { isMonorepo: false, smblsRoot, brenderDir, projectRoot, _smblsRequire, _projectRequire }
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Try multiple require functions to resolve a package (brender scope, smbls scope, project scope)
|
|
171
|
+
const tryRequireResolve = (ws, specifier) => {
|
|
172
|
+
const requireFns = ws.isMonorepo
|
|
173
|
+
? [_brenderRequire]
|
|
174
|
+
: [ws._smblsRequire, ws._projectRequire, _brenderRequire].filter(Boolean)
|
|
175
|
+
for (const req of requireFns) {
|
|
176
|
+
try {
|
|
177
|
+
return req.resolve(specifier)
|
|
178
|
+
} catch {} // fallback: module not found via this resolver, trying next
|
|
179
|
+
}
|
|
180
|
+
return null
|
|
140
181
|
}
|
|
141
182
|
|
|
142
183
|
// Resolve a package path — monorepo layout or node_modules
|
|
@@ -144,23 +185,8 @@ const resolvePackagePath = (ws, pkgName, ...subpath) => {
|
|
|
144
185
|
if (ws.isMonorepo) {
|
|
145
186
|
return resolve(ws.monorepoRoot, 'packages', pkgName, ...subpath)
|
|
146
187
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const pkgJson = _require.resolve(`${pkgName}/package.json`)
|
|
150
|
-
return resolve(dirname(pkgJson), ...subpath)
|
|
151
|
-
} catch {}
|
|
152
|
-
// Try scoped name
|
|
153
|
-
const scopedNames = {
|
|
154
|
-
'domql': 'domql',
|
|
155
|
-
'css-in-props': 'css-in-props',
|
|
156
|
-
'attrs-in-props': 'attrs-in-props'
|
|
157
|
-
}
|
|
158
|
-
if (scopedNames[pkgName]) {
|
|
159
|
-
try {
|
|
160
|
-
const pkgJson = _require.resolve(`${pkgName}/package.json`)
|
|
161
|
-
return resolve(dirname(pkgJson), ...subpath)
|
|
162
|
-
} catch {}
|
|
163
|
-
}
|
|
188
|
+
const pkgJson = tryRequireResolve(ws, `${pkgName}/package.json`)
|
|
189
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath)
|
|
164
190
|
return null
|
|
165
191
|
}
|
|
166
192
|
|
|
@@ -168,10 +194,8 @@ const resolvePluginPath = (ws, pluginName, ...subpath) => {
|
|
|
168
194
|
if (ws.isMonorepo) {
|
|
169
195
|
return resolve(ws.monorepoRoot, 'plugins', pluginName, ...subpath)
|
|
170
196
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return resolve(dirname(pkgJson), ...subpath)
|
|
174
|
-
} catch {}
|
|
197
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pluginName}/package.json`)
|
|
198
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath)
|
|
175
199
|
return null
|
|
176
200
|
}
|
|
177
201
|
|
|
@@ -183,10 +207,8 @@ const resolveSymbolsPackage = (ws, pkg, ...subpath) => {
|
|
|
183
207
|
}
|
|
184
208
|
return null
|
|
185
209
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return resolve(dirname(pkgJson), ...subpath)
|
|
189
|
-
} catch {}
|
|
210
|
+
const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pkg}/package.json`)
|
|
211
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath)
|
|
190
212
|
return null
|
|
191
213
|
}
|
|
192
214
|
|
|
@@ -194,10 +216,8 @@ const resolveDomqlPackage = (ws, pkg, ...subpath) => {
|
|
|
194
216
|
if (ws.isMonorepo) {
|
|
195
217
|
return resolve(ws.monorepoRoot, 'packages', 'domql', 'packages', pkg, ...subpath)
|
|
196
218
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
return resolve(dirname(pkgJson), ...subpath)
|
|
200
|
-
} catch {}
|
|
219
|
+
const pkgJson = tryRequireResolve(ws, `@domql/${pkg}/package.json`)
|
|
220
|
+
if (pkgJson) return resolve(dirname(pkgJson), ...subpath)
|
|
201
221
|
return null
|
|
202
222
|
}
|
|
203
223
|
|
|
@@ -273,7 +293,7 @@ const bundleCreateDomql = async () => {
|
|
|
273
293
|
const pkgJson = _require.resolve('domql/package.json')
|
|
274
294
|
const r = tryResolve(dirname(pkgJson))
|
|
275
295
|
if (r) return { path: r }
|
|
276
|
-
} catch {}
|
|
296
|
+
} catch {} // fallback: module not found via this resolver, trying next
|
|
277
297
|
}
|
|
278
298
|
})
|
|
279
299
|
// Resolve @symbo.ls/* packages (skip sync — stubbed above)
|
|
@@ -322,9 +342,8 @@ const bundleCreateDomql = async () => {
|
|
|
322
342
|
if (ws.isMonorepo) {
|
|
323
343
|
base = resolve(ws.monorepoRoot, 'packages', 'css-in-props')
|
|
324
344
|
} else {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
} catch {}
|
|
345
|
+
const pkgJson = tryRequireResolve(ws, 'css-in-props/package.json')
|
|
346
|
+
if (pkgJson) base = dirname(pkgJson)
|
|
328
347
|
}
|
|
329
348
|
if (!base) return
|
|
330
349
|
const subpath = args.path.replace(/^css-in-props\/?/, '')
|
|
@@ -344,11 +363,9 @@ const bundleCreateDomql = async () => {
|
|
|
344
363
|
if (ws.isMonorepo) {
|
|
345
364
|
nm = resolve(ws.monorepoRoot, 'node_modules', args.path)
|
|
346
365
|
} else {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
return
|
|
351
|
-
}
|
|
366
|
+
const pkgJson = tryRequireResolve(ws, `${args.path}/package.json`)
|
|
367
|
+
if (!pkgJson) return
|
|
368
|
+
nm = dirname(pkgJson)
|
|
352
369
|
}
|
|
353
370
|
if (existsSync(nm)) {
|
|
354
371
|
const pkg = resolve(nm, 'package.json')
|
|
@@ -357,7 +374,7 @@ const bundleCreateDomql = async () => {
|
|
|
357
374
|
const p = JSON.parse(readFileSync(pkg, 'utf8'))
|
|
358
375
|
const main = p.module || p.main || 'dist/emotion-css.esm.js'
|
|
359
376
|
return { path: resolve(nm, main) }
|
|
360
|
-
} catch {}
|
|
377
|
+
} catch {} // expected: value is not a valid JSON
|
|
361
378
|
}
|
|
362
379
|
return { path: nm }
|
|
363
380
|
}
|
|
@@ -436,7 +453,11 @@ const bundleCreateDomql = async () => {
|
|
|
436
453
|
plugins: [workspacePlugin],
|
|
437
454
|
nodePaths: ws.isMonorepo
|
|
438
455
|
? [resolve(ws.monorepoRoot, 'node_modules')]
|
|
439
|
-
: [
|
|
456
|
+
: [
|
|
457
|
+
...(ws.smblsRoot ? [resolve(ws.smblsRoot, 'node_modules')] : []),
|
|
458
|
+
...(ws.projectRoot ? [resolve(ws.projectRoot, 'node_modules')] : []),
|
|
459
|
+
...(ws.smblsRoot ? [resolve(ws.smblsRoot, '..', '..', 'node_modules')] : [])
|
|
460
|
+
].filter(p => existsSync(p)),
|
|
440
461
|
supported: { 'import-attributes': false },
|
|
441
462
|
external: [
|
|
442
463
|
'fs', 'path', 'os', 'crypto', 'url', 'http', 'https', 'stream',
|
|
@@ -449,7 +470,7 @@ const bundleCreateDomql = async () => {
|
|
|
449
470
|
})
|
|
450
471
|
|
|
451
472
|
const mod = await import(`file://${outFile}`)
|
|
452
|
-
try { unlinkSync(outFile) } catch {}
|
|
473
|
+
try { unlinkSync(outFile) } catch {} // cleanup: ignore if temp file already removed
|
|
453
474
|
|
|
454
475
|
_cachedCreateDomql = mod
|
|
455
476
|
return mod
|
|
@@ -522,6 +543,40 @@ const UIKIT_STUBS = {
|
|
|
522
543
|
Text: { tag: 'span' }
|
|
523
544
|
}
|
|
524
545
|
|
|
546
|
+
// ── BR path registry ─────────────────────────────────────────────────────────
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Walks a DOMQL element tree (after mapKeysToElements has set __brKey on each
|
|
550
|
+
* element) and returns a plain object mapping "element path" → "data-br key".
|
|
551
|
+
*
|
|
552
|
+
* The path is a dot-separated chain of element keys from root to leaf:
|
|
553
|
+
* '' (root element itself) → '__root'
|
|
554
|
+
* 'Header' → 'Header'
|
|
555
|
+
* 'Header.Nav' → 'Header.Nav'
|
|
556
|
+
*
|
|
557
|
+
* The registry is serialized into the pre-rendered HTML so the browser can
|
|
558
|
+
* assign the correct brKey to each skeleton element during true hydration.
|
|
559
|
+
*/
|
|
560
|
+
const buildPathRegistry = (element, path = '') => {
|
|
561
|
+
if (!element || !element.__ref) return {}
|
|
562
|
+
const registry = {}
|
|
563
|
+
|
|
564
|
+
const brKey = element.__ref.__brKey
|
|
565
|
+
if (brKey) registry[path === '' ? '__root' : path] = brKey
|
|
566
|
+
|
|
567
|
+
if (element.__ref.__children) {
|
|
568
|
+
for (const childKey of element.__ref.__children) {
|
|
569
|
+
const child = element[childKey]
|
|
570
|
+
if (child && child.__ref) {
|
|
571
|
+
const childPath = path === '' ? childKey : `${path}.${childKey}`
|
|
572
|
+
Object.assign(registry, buildPathRegistry(child, childPath))
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
return registry
|
|
578
|
+
}
|
|
579
|
+
|
|
525
580
|
/**
|
|
526
581
|
* Renders a Symbols/DOMQL project to HTML on the server.
|
|
527
582
|
*
|
|
@@ -595,7 +650,9 @@ export const render = async (data, options = {}) => {
|
|
|
595
650
|
if (prefetch) {
|
|
596
651
|
try {
|
|
597
652
|
ssrTranslations = await fetchSSRTranslations(data)
|
|
598
|
-
} catch {
|
|
653
|
+
} catch (e) {
|
|
654
|
+
console.warn('[brender] SSR translation fetch failed:', e.message)
|
|
655
|
+
}
|
|
599
656
|
}
|
|
600
657
|
|
|
601
658
|
// Restore location/window before createEnv sets them properly
|
|
@@ -717,6 +774,10 @@ export const render = async (data, options = {}) => {
|
|
|
717
774
|
|
|
718
775
|
const registry = mapKeysToElements(element)
|
|
719
776
|
|
|
777
|
+
// Build element path → brKey registry for client-side true hydration.
|
|
778
|
+
// Walks the element tree after mapKeysToElements has set __brKey on each element.
|
|
779
|
+
const brRegistry = buildPathRegistry(element)
|
|
780
|
+
|
|
720
781
|
// Extract metadata for the rendered route
|
|
721
782
|
// Pass the rendered element and its state so function-valued metadata
|
|
722
783
|
// (e.g. detail page titles from fetched data) can be resolved
|
|
@@ -786,7 +847,7 @@ export const render = async (data, options = {}) => {
|
|
|
786
847
|
if (_prevLoc !== undefined) globalThis.location = _prevLoc
|
|
787
848
|
else delete globalThis.location
|
|
788
849
|
|
|
789
|
-
return { html, metadata, registry, element, emotionCSS, document, window, ssrTranslations, prefetchedPages }
|
|
850
|
+
return { html, metadata, registry, brRegistry, element, emotionCSS, document, window, ssrTranslations, prefetchedPages }
|
|
790
851
|
}
|
|
791
852
|
|
|
792
853
|
/**
|
|
@@ -980,13 +1041,20 @@ const generateGlobalCSS = async (ds, config) => {
|
|
|
980
1041
|
write: true,
|
|
981
1042
|
logLevel: 'silent',
|
|
982
1043
|
plugins: [workspacePlugin],
|
|
1044
|
+
nodePaths: ws.isMonorepo
|
|
1045
|
+
? [resolve(ws.monorepoRoot, 'node_modules')]
|
|
1046
|
+
: [
|
|
1047
|
+
...(ws.smblsRoot ? [resolve(ws.smblsRoot, 'node_modules')] : []),
|
|
1048
|
+
...(ws.projectRoot ? [resolve(ws.projectRoot, 'node_modules')] : []),
|
|
1049
|
+
...(ws.smblsRoot ? [resolve(ws.smblsRoot, '..', '..', 'node_modules')] : [])
|
|
1050
|
+
].filter(p => existsSync(p)),
|
|
983
1051
|
external: ['fs', 'path', 'os', 'crypto', 'url', 'http', 'https', 'stream', 'util', 'events', 'buffer', 'child_process', 'worker_threads', 'net', 'tls', 'dns', 'dgram', 'zlib', 'assert', 'querystring', 'string_decoder', 'readline', 'perf_hooks', 'async_hooks', 'v8', 'vm', 'cluster', 'inspector', 'module', 'process', 'tty', 'color-contrast-checker']
|
|
984
1052
|
})
|
|
985
1053
|
|
|
986
1054
|
const mod = await import(`file://${tmpOut}`)
|
|
987
1055
|
const data = mod.default || {}
|
|
988
|
-
try { unlinkSync(tmpEntry) } catch {}
|
|
989
|
-
try { unlinkSync(tmpOut) } catch {}
|
|
1056
|
+
try { unlinkSync(tmpEntry) } catch {} // cleanup: ignore if temp file already removed
|
|
1057
|
+
try { unlinkSync(tmpOut) } catch {} // cleanup: ignore if temp file already removed
|
|
990
1058
|
|
|
991
1059
|
const cssVars = data.CSS_VARS || {}
|
|
992
1060
|
const cssMediaVars = data.CSS_MEDIA_VARS || {}
|
|
@@ -1141,6 +1209,7 @@ export const renderRoute = async (data, options = {}) => {
|
|
|
1141
1209
|
fontLinks: generateFontLinks(ds),
|
|
1142
1210
|
metadata: result.metadata || extractMetadata(data, route),
|
|
1143
1211
|
brKeyCount: result.registry ? Object.keys(result.registry).length : 0,
|
|
1212
|
+
brRegistry: result.brRegistry || {},
|
|
1144
1213
|
ssrTranslations: result.ssrTranslations,
|
|
1145
1214
|
prefetchedState,
|
|
1146
1215
|
activeLang
|
|
@@ -1235,7 +1304,14 @@ export const renderPage = async (data, route = '/', options = {}) => {
|
|
|
1235
1304
|
translationSeed = `<script>try{${seedEntries.join(';')}}catch(e){}</script>\n`
|
|
1236
1305
|
}
|
|
1237
1306
|
}
|
|
1238
|
-
|
|
1307
|
+
// Embed BR registry for true DOM-adoption hydration
|
|
1308
|
+
const brRegistryJson = result.brRegistry && Object.keys(result.brRegistry).length
|
|
1309
|
+
? JSON.stringify(result.brRegistry)
|
|
1310
|
+
: null
|
|
1311
|
+
const brRegistryScript = brRegistryJson
|
|
1312
|
+
? `<script>window.__BR_REGISTRY__=${brRegistryJson}</script>\n`
|
|
1313
|
+
: ''
|
|
1314
|
+
isrBody = `${translationSeed}${brRegistryScript}<script>window.__BRENDER__=true</script>
|
|
1239
1315
|
<script type="module" src="${prefix}${isr.clientScript}"></script>`
|
|
1240
1316
|
} else {
|
|
1241
1317
|
// Legacy swap mode: SPA creates new DOM, MutationObserver removes brender nodes
|