@bleedingdev/modern-js-runtime 3.8.3-ultramodern.1 → 3.8.3-ultramodern.3
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/cli/ssr/loadable-bundler-plugin.js +1 -1
- package/dist/cjs/core/browser/hydrate.js +1 -11
- package/dist/cjs/core/context/extensions.js +7 -2
- package/dist/cjs/core/context/runtime.js +13 -2
- package/dist/cjs/core/react/wrapper.js +10 -8
- package/dist/cjs/core/server/federatedCss.js +7 -4
- package/dist/cjs/core/server/helmet.js +2 -0
- package/dist/cjs/core/server/requestResponse.js +35 -11
- package/dist/cjs/core/server/routerCleanup.js +10 -1
- package/dist/cjs/core/server/scriptOrder.js +5 -2
- package/dist/cjs/core/server/stream/beforeTemplate.worker.js +1 -1
- package/dist/cjs/core/server/stream/createReadableStream.js +18 -5
- package/dist/cjs/core/server/stream/createReadableStream.worker.js +10 -2
- package/dist/cjs/core/server/stream/deferredScript.js +2 -1
- package/dist/cjs/core/server/string/index.js +4 -0
- package/dist/cjs/core/server/string/loadable.js +11 -2
- package/dist/cjs/core/server/utils.js +12 -5
- package/dist/cjs/exports/head.js +7 -242
- package/dist/cjs/module-federation/last-known-good.js +35 -2
- package/dist/cjs/router/cli/nestedRoutesSpec.js +7 -38
- package/dist/cjs/router/runtime/PrefetchLink.js +55 -8
- package/dist/cjs/router/runtime/redirect.js +11 -1
- package/dist/cjs/router/runtime/utils.js +2 -0
- package/dist/esm/cli/ssr/loadable-bundler-plugin.mjs +1 -1
- package/dist/esm/core/browser/hydrate.mjs +1 -11
- package/dist/esm/core/context/extensions.mjs +7 -2
- package/dist/esm/core/context/runtime.mjs +13 -2
- package/dist/esm/core/react/wrapper.mjs +11 -9
- package/dist/esm/core/server/federatedCss.mjs +7 -4
- package/dist/esm/core/server/helmet.mjs +2 -0
- package/dist/esm/core/server/requestResponse.mjs +35 -11
- package/dist/esm/core/server/routerCleanup.mjs +10 -1
- package/dist/esm/core/server/scriptOrder.mjs +6 -3
- package/dist/esm/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm/core/server/stream/createReadableStream.mjs +16 -3
- package/dist/esm/core/server/stream/createReadableStream.worker.mjs +10 -2
- package/dist/esm/core/server/stream/deferredScript.mjs +2 -1
- package/dist/esm/core/server/string/index.mjs +4 -0
- package/dist/esm/core/server/string/loadable.mjs +11 -2
- package/dist/esm/core/server/utils.mjs +8 -4
- package/dist/esm/exports/head.mjs +8 -237
- package/dist/esm/module-federation/last-known-good.mjs +35 -2
- package/dist/esm/router/cli/nestedRoutesSpec.mjs +7 -38
- package/dist/esm/router/runtime/PrefetchLink.mjs +28 -8
- package/dist/esm/router/runtime/redirect.mjs +11 -1
- package/dist/esm/router/runtime/utils.mjs +2 -0
- package/dist/esm/rslib-runtime.mjs +9 -0
- package/dist/esm-node/cli/ssr/loadable-bundler-plugin.mjs +1 -1
- package/dist/esm-node/core/browser/hydrate.mjs +1 -11
- package/dist/esm-node/core/context/extensions.mjs +7 -2
- package/dist/esm-node/core/context/runtime.mjs +13 -2
- package/dist/esm-node/core/react/wrapper.mjs +11 -9
- package/dist/esm-node/core/server/federatedCss.mjs +7 -4
- package/dist/esm-node/core/server/helmet.mjs +2 -0
- package/dist/esm-node/core/server/requestResponse.mjs +35 -11
- package/dist/esm-node/core/server/routerCleanup.mjs +10 -1
- package/dist/esm-node/core/server/scriptOrder.mjs +6 -3
- package/dist/esm-node/core/server/stream/beforeTemplate.worker.mjs +2 -2
- package/dist/esm-node/core/server/stream/createReadableStream.mjs +16 -3
- package/dist/esm-node/core/server/stream/createReadableStream.worker.mjs +10 -2
- package/dist/esm-node/core/server/stream/deferredScript.mjs +2 -1
- package/dist/esm-node/core/server/string/index.mjs +4 -0
- package/dist/esm-node/core/server/string/loadable.mjs +11 -2
- package/dist/esm-node/core/server/utils.mjs +8 -4
- package/dist/esm-node/exports/head.mjs +8 -237
- package/dist/esm-node/module-federation/last-known-good.mjs +35 -2
- package/dist/esm-node/router/cli/nestedRoutesSpec.mjs +7 -38
- package/dist/esm-node/router/runtime/PrefetchLink.mjs +28 -8
- package/dist/esm-node/router/runtime/redirect.mjs +11 -1
- package/dist/esm-node/router/runtime/utils.mjs +2 -0
- package/dist/esm-node/rslib-runtime.mjs +10 -0
- package/dist/types/core/context/extensions.d.ts +2 -4
- package/dist/types/core/context/public.d.ts +4 -8
- package/dist/types/core/server/requestResponse.d.ts +1 -1
- package/dist/types/core/server/routerCleanup.d.ts +2 -0
- package/dist/types/core/server/string/loadable.d.ts +1 -0
- package/dist/types/core/server/utils.d.ts +1 -0
- package/dist/types/exports/head.d.ts +1 -2
- package/dist/types/module-federation/last-known-good.d.ts +0 -20
- package/package.json +10 -9
- package/rstest.config.mts +11 -4
package/dist/cjs/exports/head.js
CHANGED
|
@@ -39,256 +39,25 @@ var __webpack_exports__ = {};
|
|
|
39
39
|
__webpack_require__.r(__webpack_exports__);
|
|
40
40
|
__webpack_require__.d(__webpack_exports__, {
|
|
41
41
|
Helmet: ()=>Helmet,
|
|
42
|
-
HelmetData: ()=>external_react_helmet_async_namespaceObject.HelmetData,
|
|
43
|
-
HelmetProvider: ()=>external_react_helmet_async_namespaceObject.HelmetProvider,
|
|
44
42
|
default: ()=>exports_head
|
|
45
43
|
});
|
|
44
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
46
45
|
const external_react_namespaceObject = require("react");
|
|
47
46
|
var external_react_default = /*#__PURE__*/ __webpack_require__.n(external_react_namespaceObject);
|
|
48
47
|
const external_react_helmet_async_namespaceObject = require("react-helmet-async");
|
|
49
48
|
const index_js_namespaceObject = require("../core/context/index.js");
|
|
50
49
|
const helmetContext_js_namespaceObject = require("../core/context/helmetContext.js");
|
|
51
|
-
const ATTRIBUTE_NAME_MAP = {
|
|
52
|
-
charSet: 'charset',
|
|
53
|
-
className: 'class',
|
|
54
|
-
contentEditable: 'contenteditable',
|
|
55
|
-
httpEquiv: 'http-equiv',
|
|
56
|
-
hrefLang: 'hreflang',
|
|
57
|
-
itemProp: 'itemprop',
|
|
58
|
-
tabIndex: 'tabindex'
|
|
59
|
-
};
|
|
60
|
-
const CONTENT_PROPERTIES = new Set([
|
|
61
|
-
'innerHTML',
|
|
62
|
-
'cssText'
|
|
63
|
-
]);
|
|
64
|
-
const escapeHtml = (value)=>String(value).replaceAll('&', '&').replaceAll('"', '"').replaceAll('<', '<').replaceAll('>', '>');
|
|
65
|
-
const toHtmlAttributeName = (name)=>ATTRIBUTE_NAME_MAP[name] ?? name;
|
|
66
|
-
const attributesToString = (attributes, includeHelmetAttribute = false)=>{
|
|
67
|
-
const pairs = [];
|
|
68
|
-
if (includeHelmetAttribute) pairs.push('data-rh="true"');
|
|
69
|
-
for (const [name, value] of Object.entries(attributes ?? {})){
|
|
70
|
-
if (false === value || null == value) continue;
|
|
71
|
-
if (CONTENT_PROPERTIES.has(name)) continue;
|
|
72
|
-
const htmlName = toHtmlAttributeName(name);
|
|
73
|
-
if (true === value) pairs.push(htmlName);
|
|
74
|
-
else pairs.push(`${htmlName}="${escapeHtml(value)}"`);
|
|
75
|
-
}
|
|
76
|
-
return pairs.join(' ');
|
|
77
|
-
};
|
|
78
|
-
const createDatum = (tagName, tags)=>({
|
|
79
|
-
toComponent: ()=>[],
|
|
80
|
-
toString: ()=>tags.map((tag)=>{
|
|
81
|
-
const attrs = attributesToString(tag, true);
|
|
82
|
-
if ("script" === tagName && 'string' == typeof tag.innerHTML) return `<script ${attrs}>${tag.innerHTML}</script>`;
|
|
83
|
-
if ('style' === tagName && 'string' == typeof tag.cssText) return `<style ${attrs}>${tag.cssText}</style>`;
|
|
84
|
-
if ("noscript" === tagName && 'string' == typeof tag.innerHTML) return `<noscript ${attrs}>${tag.innerHTML}</noscript>`;
|
|
85
|
-
return `<${tagName} ${attrs}>`;
|
|
86
|
-
}).join('')
|
|
87
|
-
});
|
|
88
|
-
const createAttributeDatum = (attributes)=>({
|
|
89
|
-
toComponent: ()=>attributes,
|
|
90
|
-
toString: ()=>attributesToString(attributes)
|
|
91
|
-
});
|
|
92
|
-
const createTitleDatum = (title, attributes)=>({
|
|
93
|
-
toComponent: ()=>[],
|
|
94
|
-
toString: ()=>{
|
|
95
|
-
if (void 0 === title || '' === title) return '';
|
|
96
|
-
const attrs = attributesToString(attributes, true);
|
|
97
|
-
return `<title ${attrs}>${escapeHtml(title)}</title>`;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
const normalizeHelmetTitle = (title)=>{
|
|
101
|
-
if ('string' == typeof title) return title;
|
|
102
|
-
if (Array.isArray(title)) return title.map((part)=>String(part)).join('');
|
|
103
|
-
};
|
|
104
|
-
const mergeAttributes = (current, next)=>({
|
|
105
|
-
...current,
|
|
106
|
-
...next ?? {}
|
|
107
|
-
});
|
|
108
|
-
const collectChildren = (children, draft)=>{
|
|
109
|
-
external_react_default().Children.forEach(children, (child)=>{
|
|
110
|
-
if (!external_react_default().isValidElement(child)) return;
|
|
111
|
-
if (child.type === external_react_default().Fragment) return void collectChildren(child.props.children, draft);
|
|
112
|
-
if ('string' != typeof child.type) return;
|
|
113
|
-
const { children: nestedChildren, ...props } = child.props;
|
|
114
|
-
if ('title' === child.type) {
|
|
115
|
-
draft.title = external_react_default().Children.toArray(nestedChildren).join('');
|
|
116
|
-
draft.titleAttributes = mergeAttributes(draft.titleAttributes, props);
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
if ('html' === child.type) {
|
|
120
|
-
draft.htmlAttributes = mergeAttributes(draft.htmlAttributes ?? {}, props);
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
if ('body' === child.type) {
|
|
124
|
-
draft.bodyAttributes = mergeAttributes(draft.bodyAttributes ?? {}, props);
|
|
125
|
-
return;
|
|
126
|
-
}
|
|
127
|
-
if ('base' === child.type || 'link' === child.type || 'meta' === child.type || "noscript" === child.type || "script" === child.type || 'style' === child.type) {
|
|
128
|
-
const tag = {
|
|
129
|
-
...props
|
|
130
|
-
};
|
|
131
|
-
if (("script" === child.type || 'style' === child.type || "noscript" === child.type) && 'string' == typeof nestedChildren) tag['style' === child.type ? 'cssText' : 'innerHTML'] = nestedChildren;
|
|
132
|
-
draft[child.type].push(tag);
|
|
133
|
-
}
|
|
134
|
-
});
|
|
135
|
-
};
|
|
136
|
-
const createHelmetRecord = (props)=>{
|
|
137
|
-
const draft = {
|
|
138
|
-
base: [
|
|
139
|
-
...void 0 !== props.base ? [
|
|
140
|
-
props.base
|
|
141
|
-
] : []
|
|
142
|
-
],
|
|
143
|
-
bodyAttributes: props.bodyAttributes,
|
|
144
|
-
htmlAttributes: props.htmlAttributes,
|
|
145
|
-
link: [
|
|
146
|
-
...props.link ?? []
|
|
147
|
-
],
|
|
148
|
-
meta: [
|
|
149
|
-
...props.meta ?? []
|
|
150
|
-
],
|
|
151
|
-
noscript: [
|
|
152
|
-
...props.noscript ?? []
|
|
153
|
-
],
|
|
154
|
-
script: [
|
|
155
|
-
...props.script ?? []
|
|
156
|
-
],
|
|
157
|
-
style: [
|
|
158
|
-
...props.style ?? []
|
|
159
|
-
],
|
|
160
|
-
title: normalizeHelmetTitle(props.title),
|
|
161
|
-
titleAttributes: props.titleAttributes ?? {}
|
|
162
|
-
};
|
|
163
|
-
collectChildren(props.children, draft);
|
|
164
|
-
return {
|
|
165
|
-
...draft,
|
|
166
|
-
titleTemplate: props.titleTemplate,
|
|
167
|
-
defaultTitle: props.defaultTitle
|
|
168
|
-
};
|
|
169
|
-
};
|
|
170
|
-
const getInnermostDefined = (records, pick)=>{
|
|
171
|
-
for(let i = records.length - 1; i >= 0; i -= 1){
|
|
172
|
-
const value = pick(records[i]);
|
|
173
|
-
if (void 0 !== value) return value;
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const deriveTitle = (records)=>{
|
|
177
|
-
const innermostTitle = getInnermostDefined(records, (record)=>record.title);
|
|
178
|
-
const innermostTemplate = getInnermostDefined(records, (record)=>record.titleTemplate);
|
|
179
|
-
if (innermostTemplate && innermostTitle) return innermostTemplate.replaceAll('%s', innermostTitle);
|
|
180
|
-
return innermostTitle || getInnermostDefined(records, (record)=>record.defaultTitle);
|
|
181
|
-
};
|
|
182
|
-
const mergeRecordAttributes = (records, pick)=>records.reduce((merged, record)=>mergeAttributes(merged, pick(record)), {});
|
|
183
|
-
const deriveBaseTags = (records)=>{
|
|
184
|
-
for(let i = records.length - 1; i >= 0; i -= 1){
|
|
185
|
-
const tags = records[i].base;
|
|
186
|
-
for(let j = tags.length - 1; j >= 0; j -= 1)if (tags[j].href) return [
|
|
187
|
-
tags[j]
|
|
188
|
-
];
|
|
189
|
-
}
|
|
190
|
-
return [];
|
|
191
|
-
};
|
|
192
|
-
const TAG_PRIMARY_ATTRIBUTES = {
|
|
193
|
-
link: [
|
|
194
|
-
'rel',
|
|
195
|
-
'href'
|
|
196
|
-
],
|
|
197
|
-
meta: [
|
|
198
|
-
'name',
|
|
199
|
-
'charset',
|
|
200
|
-
'http-equiv',
|
|
201
|
-
'property',
|
|
202
|
-
'itemprop'
|
|
203
|
-
],
|
|
204
|
-
noscript: [
|
|
205
|
-
'innerHTML'
|
|
206
|
-
],
|
|
207
|
-
script: [
|
|
208
|
-
'src',
|
|
209
|
-
'innerHTML'
|
|
210
|
-
],
|
|
211
|
-
style: [
|
|
212
|
-
'cssText'
|
|
213
|
-
]
|
|
214
|
-
};
|
|
215
|
-
const getPrimaryAttribute = (tagName, tag)=>{
|
|
216
|
-
const candidates = TAG_PRIMARY_ATTRIBUTES[tagName];
|
|
217
|
-
let selectedKey;
|
|
218
|
-
let selectedValue;
|
|
219
|
-
for (const [key, value] of Object.entries(tag)){
|
|
220
|
-
const normalizedKey = CONTENT_PROPERTIES.has(key) ? key : toHtmlAttributeName(key).toLowerCase();
|
|
221
|
-
if (candidates.includes(normalizedKey)) {
|
|
222
|
-
if ('rel' !== selectedKey || 'canonical' !== String(selectedValue).toLowerCase()) {
|
|
223
|
-
if ('rel' !== normalizedKey || 'stylesheet' !== String(value).toLowerCase()) {
|
|
224
|
-
selectedKey = normalizedKey;
|
|
225
|
-
selectedValue = value;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
if (void 0 === selectedKey || !selectedValue) return;
|
|
231
|
-
return {
|
|
232
|
-
key: selectedKey,
|
|
233
|
-
value: String(selectedValue).toLowerCase()
|
|
234
|
-
};
|
|
235
|
-
};
|
|
236
|
-
const dedupeTags = (tagName, records)=>{
|
|
237
|
-
const approvedValues = new Map();
|
|
238
|
-
const approved = [];
|
|
239
|
-
for(let i = records.length - 1; i >= 0; i -= 1){
|
|
240
|
-
const instanceValues = new Map();
|
|
241
|
-
const kept = [];
|
|
242
|
-
for (const tag of records[i][tagName]){
|
|
243
|
-
const primary = getPrimaryAttribute(tagName, tag);
|
|
244
|
-
if (void 0 === primary) continue;
|
|
245
|
-
if (approvedValues.get(primary.key)?.has(primary.value)) continue;
|
|
246
|
-
let seen = instanceValues.get(primary.key);
|
|
247
|
-
if (void 0 === seen) {
|
|
248
|
-
seen = new Set();
|
|
249
|
-
instanceValues.set(primary.key, seen);
|
|
250
|
-
}
|
|
251
|
-
seen.add(primary.value);
|
|
252
|
-
kept.push(tag);
|
|
253
|
-
}
|
|
254
|
-
approved.unshift(...kept);
|
|
255
|
-
for (const [key, values] of instanceValues){
|
|
256
|
-
const target = approvedValues.get(key);
|
|
257
|
-
if (void 0 === target) approvedValues.set(key, values);
|
|
258
|
-
else for (const value of values)target.add(value);
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
return approved;
|
|
262
|
-
};
|
|
263
|
-
const deriveHelmetServerState = (records)=>({
|
|
264
|
-
base: createDatum('base', deriveBaseTags(records)),
|
|
265
|
-
bodyAttributes: createAttributeDatum(mergeRecordAttributes(records, (record)=>record.bodyAttributes)),
|
|
266
|
-
htmlAttributes: createAttributeDatum(mergeRecordAttributes(records, (record)=>record.htmlAttributes)),
|
|
267
|
-
link: createDatum('link', dedupeTags('link', records)),
|
|
268
|
-
meta: createDatum('meta', dedupeTags('meta', records)),
|
|
269
|
-
noscript: createDatum("noscript", dedupeTags("noscript", records)),
|
|
270
|
-
priority: createDatum('meta', []),
|
|
271
|
-
script: createDatum("script", dedupeTags("script", records)),
|
|
272
|
-
style: createDatum('style', dedupeTags('style', records)),
|
|
273
|
-
title: createTitleDatum(deriveTitle(records), mergeRecordAttributes(records, (record)=>record.titleAttributes))
|
|
274
|
-
});
|
|
275
|
-
const serverHelmetRecords = new WeakMap();
|
|
276
50
|
const collectServerHelmet = (runtimeContext, props)=>{
|
|
277
51
|
const helmetContext = (0, helmetContext_js_namespaceObject.ensureHelmetContext)(runtimeContext);
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
records.push(createHelmetRecord(props));
|
|
284
|
-
helmetContext.helmet = deriveHelmetServerState(records);
|
|
52
|
+
const createRecord = ()=>runtime_extensions_namespaceObject.createHelmetRecord(external_react_default(), props);
|
|
53
|
+
const deriveState = (records)=>runtime_extensions_namespaceObject.deriveHelmetServerState(external_react_default(), records);
|
|
54
|
+
const marker = runtime_extensions_namespaceObject.collectHeadState(runtimeContext, createRecord, deriveState, helmetContext);
|
|
55
|
+
if (void 0 !== marker) return marker;
|
|
56
|
+
helmetContext.helmet = runtime_extensions_namespaceObject.collectImmediateHelmetState(external_react_default(), helmetContext, createRecord());
|
|
285
57
|
};
|
|
286
58
|
const Helmet = (props)=>{
|
|
287
59
|
const runtimeContext = external_react_default().useContext(index_js_namespaceObject.InternalRuntimeContext);
|
|
288
|
-
if (null !== runtimeContext && false === runtimeContext.isBrowser)
|
|
289
|
-
collectServerHelmet(runtimeContext, props);
|
|
290
|
-
return null;
|
|
291
|
-
}
|
|
60
|
+
if (null !== runtimeContext && false === runtimeContext.isBrowser) return runtime_extensions_namespaceObject.renderHeadMarker(external_react_default(), collectServerHelmet(runtimeContext, props));
|
|
292
61
|
return external_react_default().createElement(external_react_helmet_async_namespaceObject.Helmet, props);
|
|
293
62
|
};
|
|
294
63
|
const head = {
|
|
@@ -298,13 +67,9 @@ const head = {
|
|
|
298
67
|
};
|
|
299
68
|
const exports_head = head;
|
|
300
69
|
exports.Helmet = __webpack_exports__.Helmet;
|
|
301
|
-
exports.HelmetData = __webpack_exports__.HelmetData;
|
|
302
|
-
exports.HelmetProvider = __webpack_exports__.HelmetProvider;
|
|
303
70
|
exports["default"] = __webpack_exports__["default"];
|
|
304
71
|
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
305
72
|
"Helmet",
|
|
306
|
-
"HelmetData",
|
|
307
|
-
"HelmetProvider",
|
|
308
73
|
"default"
|
|
309
74
|
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
310
75
|
Object.defineProperty(exports, '__esModule', {
|
|
@@ -32,6 +32,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
32
32
|
createInMemoryLkgStorage: ()=>createInMemoryLkgStorage,
|
|
33
33
|
createLastKnownGoodProvider: ()=>createLastKnownGoodProvider
|
|
34
34
|
});
|
|
35
|
+
const universal_namespaceObject = require("@modern-js/utils/universal");
|
|
35
36
|
const external_surface_resolution_types_js_namespaceObject = require("./surface-resolution-types.js");
|
|
36
37
|
const LAST_KNOWN_GOOD_PROVIDER_NAME = 'last-known-good';
|
|
37
38
|
function createInMemoryLkgStorage() {
|
|
@@ -65,16 +66,38 @@ function staleRecordResult(ref, env, ageMs, maxStaleMs) {
|
|
|
65
66
|
})
|
|
66
67
|
};
|
|
67
68
|
}
|
|
69
|
+
function resolutionAnswersRef(resolved, ref) {
|
|
70
|
+
const selected = (0, universal_namespaceObject.selectResolvedSurface)(resolved, ref);
|
|
71
|
+
return selected.ok && selected.surface.servedMajor === ref.major;
|
|
72
|
+
}
|
|
68
73
|
function createLastKnownGoodProvider(options) {
|
|
69
74
|
const storage = options.storage ?? createInMemoryLkgStorage();
|
|
70
75
|
const now = options.now ?? (()=>Math.floor(performance.timeOrigin + performance.now()));
|
|
71
76
|
const maxStaleMs = options.freshness?.maxStaleMs;
|
|
77
|
+
let nextResolutionGeneration = 0;
|
|
78
|
+
const latestCacheableGenerationByKey = new Map();
|
|
79
|
+
const writeTailByKey = new Map();
|
|
80
|
+
async function cacheCompatibleResolution(key, generation, record) {
|
|
81
|
+
latestCacheableGenerationByKey.set(key, Math.max(latestCacheableGenerationByKey.get(key) ?? 0, generation));
|
|
82
|
+
const previous = writeTailByKey.get(key) ?? Promise.resolve();
|
|
83
|
+
const write = previous.catch(()=>void 0).then(async ()=>{
|
|
84
|
+
if (latestCacheableGenerationByKey.get(key) !== generation) return;
|
|
85
|
+
await storage.write(key, record);
|
|
86
|
+
});
|
|
87
|
+
writeTailByKey.set(key, write);
|
|
88
|
+
try {
|
|
89
|
+
await write;
|
|
90
|
+
} finally{
|
|
91
|
+
if (writeTailByKey.get(key) === write) writeTailByKey.delete(key);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
72
94
|
async function serveFromCache(ref, env, fallback) {
|
|
73
95
|
const key = (0, external_surface_resolution_types_js_namespaceObject.deliveryUnitResolutionKey)(ref.unitId, env);
|
|
74
96
|
const cached = await storage.read(key);
|
|
75
97
|
if (!cached) return fallback();
|
|
76
98
|
if (cached.major !== ref.major) return fallback();
|
|
77
|
-
if (
|
|
99
|
+
if (!resolutionAnswersRef(cached.resolved, ref)) return fallback();
|
|
100
|
+
if ('compatible' !== cached.resolved.compatibility.status) return fallback();
|
|
78
101
|
const ageMs = now() - cached.storedAt;
|
|
79
102
|
if (void 0 !== maxStaleMs && ageMs > maxStaleMs) return staleRecordResult(ref, env, ageMs, maxStaleMs);
|
|
80
103
|
return {
|
|
@@ -86,6 +109,7 @@ function createLastKnownGoodProvider(options) {
|
|
|
86
109
|
name: LAST_KNOWN_GOOD_PROVIDER_NAME,
|
|
87
110
|
async resolve (ref, env) {
|
|
88
111
|
const key = (0, external_surface_resolution_types_js_namespaceObject.deliveryUnitResolutionKey)(ref.unitId, env);
|
|
112
|
+
const generation = ++nextResolutionGeneration;
|
|
89
113
|
let resolution;
|
|
90
114
|
try {
|
|
91
115
|
resolution = await options.provider.resolve(ref, env);
|
|
@@ -102,7 +126,16 @@ function createLastKnownGoodProvider(options) {
|
|
|
102
126
|
const failure = resolution;
|
|
103
127
|
return serveFromCache(ref, env, ()=>failure);
|
|
104
128
|
}
|
|
105
|
-
if (
|
|
129
|
+
if (!resolutionAnswersRef(resolution.unit, ref)) return serveFromCache(ref, env, ()=>({
|
|
130
|
+
ok: false,
|
|
131
|
+
error: (0, external_surface_resolution_types_js_namespaceObject.createDiscoveryError)('identity-mismatch', ref, `Provider ${options.provider.name} returned a delivery unit that does not answer the requested surface.`, {
|
|
132
|
+
env,
|
|
133
|
+
provider: options.provider.name,
|
|
134
|
+
recordUnitId: resolution.unit.unitId,
|
|
135
|
+
availableSurfaces: resolution.unit.surfaces.map((surface)=>surface.surfaceId)
|
|
136
|
+
})
|
|
137
|
+
}));
|
|
138
|
+
if ('compatible' === resolution.unit.compatibility.status) await cacheCompatibleResolution(key, generation, {
|
|
106
139
|
resolved: resolution.unit,
|
|
107
140
|
storedAt: now(),
|
|
108
141
|
major: ref.major
|
|
@@ -41,40 +41,13 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
41
41
|
});
|
|
42
42
|
const external_node_path_namespaceObject = require("node:path");
|
|
43
43
|
var external_node_path_default = /*#__PURE__*/ __webpack_require__.n(external_node_path_namespaceObject);
|
|
44
|
-
const promises_namespaceObject = require("node:timers/promises");
|
|
45
44
|
const utils_namespaceObject = require("@modern-js/utils");
|
|
46
45
|
const lodash_namespaceObject = require("@modern-js/utils/lodash");
|
|
47
|
-
const lockPollIntervalMs = 25;
|
|
48
|
-
const staleLockAgeMs = 120000;
|
|
49
46
|
const pendingUpdates = new Map();
|
|
50
47
|
let tempFileCounter = 0;
|
|
51
|
-
async function acquireSpecLock(specPath) {
|
|
52
|
-
const lockDir = `${specPath}.lock`;
|
|
53
|
-
await utils_namespaceObject.fs.ensureDir(external_node_path_default().dirname(specPath));
|
|
54
|
-
while(true){
|
|
55
|
-
try {
|
|
56
|
-
await utils_namespaceObject.fs.mkdir(lockDir);
|
|
57
|
-
return async ()=>{
|
|
58
|
-
await utils_namespaceObject.fs.remove(lockDir);
|
|
59
|
-
};
|
|
60
|
-
} catch (error) {
|
|
61
|
-
if ('EEXIST' !== error.code) throw error;
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
const stat = await utils_namespaceObject.fs.stat(lockDir);
|
|
65
|
-
if (performance.timeOrigin + performance.now() - stat.mtimeMs > staleLockAgeMs) {
|
|
66
|
-
await utils_namespaceObject.fs.remove(lockDir);
|
|
67
|
-
continue;
|
|
68
|
-
}
|
|
69
|
-
} catch (error) {
|
|
70
|
-
if ('ENOENT' !== error.code) throw error;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
await (0, promises_namespaceObject.setTimeout)(lockPollIntervalMs);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
48
|
async function writeJSONAtomically(filePath, value) {
|
|
77
49
|
const directory = external_node_path_default().dirname(filePath);
|
|
50
|
+
await utils_namespaceObject.fs.ensureDir(directory);
|
|
78
51
|
const tempPath = external_node_path_default().join(directory, `.${external_node_path_default().basename(filePath)}.${process.pid}.${tempFileCounter += 1}.tmp`);
|
|
79
52
|
try {
|
|
80
53
|
await utils_namespaceObject.fs.writeFile(tempPath, `${JSON.stringify(value)}\n`);
|
|
@@ -89,16 +62,12 @@ async function updateNestedRoutesSpec(specPath, nextRoutes) {
|
|
|
89
62
|
const nextRoutesSnapshot = (0, lodash_namespaceObject.cloneDeep)(nextRoutes);
|
|
90
63
|
const previousUpdate = pendingUpdates.get(resolvedSpecPath) ?? Promise.resolve();
|
|
91
64
|
const currentUpdate = previousUpdate.catch(()=>void 0).then(async ()=>{
|
|
92
|
-
const
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
99
|
-
} finally{
|
|
100
|
-
await releaseLock();
|
|
101
|
-
}
|
|
65
|
+
const existingRoutes = await utils_namespaceObject.fs.pathExists(resolvedSpecPath) ? await utils_namespaceObject.fs.readJSON(resolvedSpecPath) : {};
|
|
66
|
+
const mergedRoutes = {
|
|
67
|
+
...existingRoutes,
|
|
68
|
+
...nextRoutesSnapshot
|
|
69
|
+
};
|
|
70
|
+
await writeJSONAtomically(resolvedSpecPath, mergedRoutes);
|
|
102
71
|
});
|
|
103
72
|
pendingUpdates.set(resolvedSpecPath, currentUpdate);
|
|
104
73
|
try {
|
|
@@ -22,6 +22,16 @@ var __webpack_require__ = {};
|
|
|
22
22
|
define(values, "value");
|
|
23
23
|
};
|
|
24
24
|
})();
|
|
25
|
+
(()=>{
|
|
26
|
+
__webpack_require__.g = (()=>{
|
|
27
|
+
if ('object' == typeof globalThis) return globalThis;
|
|
28
|
+
try {
|
|
29
|
+
return this || new Function('return this')();
|
|
30
|
+
} catch (e) {
|
|
31
|
+
if ('object' == typeof window) return window;
|
|
32
|
+
}
|
|
33
|
+
})();
|
|
34
|
+
})();
|
|
25
35
|
(()=>{
|
|
26
36
|
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
27
37
|
})();
|
|
@@ -35,6 +45,24 @@ var __webpack_require__ = {};
|
|
|
35
45
|
});
|
|
36
46
|
};
|
|
37
47
|
})();
|
|
48
|
+
(()=>{
|
|
49
|
+
var scriptUrl;
|
|
50
|
+
if (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + "";
|
|
51
|
+
var document = __webpack_require__.g.document;
|
|
52
|
+
if (!scriptUrl && document) {
|
|
53
|
+
if (document.currentScript && 'SCRIPT' === document.currentScript.tagName.toUpperCase()) scriptUrl = document.currentScript.src;
|
|
54
|
+
if (!scriptUrl) {
|
|
55
|
+
var scripts = document.getElementsByTagName("script");
|
|
56
|
+
if (scripts.length) {
|
|
57
|
+
var i = scripts.length - 1;
|
|
58
|
+
while(i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl)))scriptUrl = scripts[i--].src;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!scriptUrl) throw new Error("Automatic publicPath is not supported in this browser");
|
|
63
|
+
scriptUrl = scriptUrl.replace(/^blob:/, "").replace(/#.*$/, "").replace(/\?.*$/, "").replace(/\/[^\/]+$/, "/");
|
|
64
|
+
__webpack_require__.p = scriptUrl + '../../';
|
|
65
|
+
})();
|
|
38
66
|
var __webpack_exports__ = {};
|
|
39
67
|
__webpack_require__.r(__webpack_exports__);
|
|
40
68
|
__webpack_require__.d(__webpack_exports__, {
|
|
@@ -42,10 +70,19 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
42
70
|
NavLink: ()=>NavLink
|
|
43
71
|
});
|
|
44
72
|
const jsx_runtime_namespaceObject = require("react/jsx-runtime");
|
|
73
|
+
const runtime_extensions_namespaceObject = require("@modern-js/runtime-extensions");
|
|
45
74
|
const router_namespaceObject = require("@modern-js/runtime-utils/router");
|
|
46
75
|
const external_react_namespaceObject = require("react");
|
|
47
76
|
var external_react_default = /*#__PURE__*/ __webpack_require__.n(external_react_namespaceObject);
|
|
48
77
|
const index_js_namespaceObject = require("../../core/context/index.js");
|
|
78
|
+
const getWebpackChunkLoader = ()=>__webpack_chunk_load__;
|
|
79
|
+
const getWebpackPublicPath = ()=>{
|
|
80
|
+
try {
|
|
81
|
+
return __webpack_require__.p || '';
|
|
82
|
+
} catch {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
};
|
|
49
86
|
function composeEventHandlers(theirHandler, ourHandler) {
|
|
50
87
|
return (event)=>{
|
|
51
88
|
theirHandler?.(event);
|
|
@@ -84,8 +121,7 @@ const runNextWarmup = ()=>{
|
|
|
84
121
|
const task = warmupQueue.shift();
|
|
85
122
|
if (task.cancelled) continue;
|
|
86
123
|
activeWarmups += 1;
|
|
87
|
-
task.run().catch((
|
|
88
|
-
console.error(error);
|
|
124
|
+
task.run().catch(()=>{
|
|
89
125
|
warmupCache.delete(task.key);
|
|
90
126
|
}).finally(()=>{
|
|
91
127
|
activeWarmups -= 1;
|
|
@@ -107,6 +143,7 @@ const scheduleWarmup = (key, run)=>{
|
|
|
107
143
|
runNextWarmup();
|
|
108
144
|
return ()=>{
|
|
109
145
|
task.cancelled = true;
|
|
146
|
+
if (warmupQueue.includes(task)) warmupCache.delete(task.key);
|
|
110
147
|
};
|
|
111
148
|
};
|
|
112
149
|
const setRef = (ref, value)=>{
|
|
@@ -190,16 +227,17 @@ function usePrefetchBehavior(prefetch, preload, theirElementProps) {
|
|
|
190
227
|
setViewportElement
|
|
191
228
|
];
|
|
192
229
|
}
|
|
193
|
-
async function loadRouteModule(route, routeAssets) {
|
|
230
|
+
async function loadRouteModule(route, routeAssets, chunkLoader) {
|
|
194
231
|
const routeId = route.id;
|
|
195
232
|
if (!routeId) return;
|
|
196
233
|
if (!routeAssets[routeId]) return;
|
|
197
234
|
const { chunkIds } = routeAssets[routeId];
|
|
198
235
|
if (!chunkIds) return;
|
|
199
236
|
try {
|
|
200
|
-
await Promise.all(chunkIds.map((chunkId)=>
|
|
237
|
+
await Promise.all(chunkIds.map((chunkId)=>chunkLoader(chunkId)));
|
|
201
238
|
} catch (error) {
|
|
202
239
|
console.error(error);
|
|
240
|
+
throw error;
|
|
203
241
|
}
|
|
204
242
|
}
|
|
205
243
|
const getRequestUrl = (pathname, routeId)=>{
|
|
@@ -232,22 +270,31 @@ const PrefetchPageLinks = ({ path, includeData })=>{
|
|
|
232
270
|
pathname,
|
|
233
271
|
routes
|
|
234
272
|
]);
|
|
273
|
+
const chunkLoader = getWebpackChunkLoader();
|
|
274
|
+
const routeAssetGeneration = JSON.stringify([
|
|
275
|
+
getWebpackPublicPath(),
|
|
276
|
+
matches?.map(({ route: { id } })=>[
|
|
277
|
+
id,
|
|
278
|
+
routeAssets?.[id]?.chunkIds
|
|
279
|
+
])
|
|
280
|
+
]);
|
|
235
281
|
external_react_default().useEffect(()=>{
|
|
236
|
-
if (!allowNetworkWarmup || !Array.isArray(matches) || !routeAssets || !
|
|
282
|
+
if (!allowNetworkWarmup || !Array.isArray(matches) || !routeAssets || !chunkLoader) return;
|
|
237
283
|
const cancellations = matches.map((match)=>{
|
|
238
284
|
const routeId = match.route.id;
|
|
239
285
|
const routeAsset = routeId ? routeAssets[routeId] : void 0;
|
|
240
286
|
const chunkIds = routeAsset?.chunkIds;
|
|
241
287
|
if (!routeId || !Array.isArray(chunkIds) || 0 === chunkIds.length) return ()=>{};
|
|
242
|
-
return scheduleWarmup(`route-module:${routeId}:${chunkIds.join(',')}
|
|
288
|
+
return scheduleWarmup((0, runtime_extensions_namespaceObject.getNavigationWarmupCacheKey)(context, chunkLoader, getWebpackPublicPath(), `route-module:${routeId}:${chunkIds.join(',')}`), ()=>loadRouteModule(match.route, routeAssets, chunkLoader));
|
|
243
289
|
});
|
|
244
290
|
return ()=>{
|
|
245
291
|
cancellations.forEach((cancel)=>cancel());
|
|
246
292
|
};
|
|
247
293
|
}, [
|
|
248
294
|
allowNetworkWarmup,
|
|
249
|
-
|
|
250
|
-
|
|
295
|
+
chunkLoader,
|
|
296
|
+
context,
|
|
297
|
+
routeAssetGeneration
|
|
251
298
|
]);
|
|
252
299
|
if (!allowNetworkWarmup || !includeData || !window._SSR_DATA) return null;
|
|
253
300
|
return /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(PrefetchDataLinks, {
|
|
@@ -30,7 +30,17 @@ __webpack_require__.r(__webpack_exports__);
|
|
|
30
30
|
const handleRSCRedirect = (headers, basename, status)=>{
|
|
31
31
|
const newHeaders = new Headers(headers);
|
|
32
32
|
let redirectUrl = headers.get('Location');
|
|
33
|
-
if (
|
|
33
|
+
if (!redirectUrl || ![
|
|
34
|
+
301,
|
|
35
|
+
302,
|
|
36
|
+
303,
|
|
37
|
+
307,
|
|
38
|
+
308
|
|
39
|
+
].includes(status) || !URL.canParse(redirectUrl, 'http://localhost')) return new Response(null, {
|
|
40
|
+
status,
|
|
41
|
+
headers: newHeaders
|
|
42
|
+
});
|
|
43
|
+
if ('/' !== basename && redirectUrl.startsWith(basename)) redirectUrl = redirectUrl.slice(basename.length) || '/';
|
|
34
44
|
newHeaders.set('X-Modernjs-Redirect', redirectUrl);
|
|
35
45
|
newHeaders.set('X-Modernjs-BaseUrl', basename);
|
|
36
46
|
newHeaders.delete('Location');
|
|
@@ -227,12 +227,14 @@ function serializeRouteErrorResponse(error) {
|
|
|
227
227
|
status: error.status,
|
|
228
228
|
statusText: 'Internal Server Error',
|
|
229
229
|
data: 'Unexpected Server Error',
|
|
230
|
+
internal: error.internal,
|
|
230
231
|
__type: 'RouteErrorResponse'
|
|
231
232
|
};
|
|
232
233
|
return {
|
|
233
234
|
status: error.status,
|
|
234
235
|
statusText: error.statusText,
|
|
235
236
|
data: error.data,
|
|
237
|
+
internal: error.internal,
|
|
236
238
|
__type: 'RouteErrorResponse'
|
|
237
239
|
};
|
|
238
240
|
}
|
|
@@ -12,7 +12,7 @@ class LoadablePlugin {
|
|
|
12
12
|
const chunkLoadingGlobal = this.opts.chunkLoadingGlobal ?? compiler.options.output.chunkLoadingGlobal ?? DEFAULT_CHUNK_LOADING_GLOBAL;
|
|
13
13
|
compiler.options.output.chunkLoadingGlobal = chunkLoadingGlobal;
|
|
14
14
|
new compiler.webpack.DefinePlugin({
|
|
15
|
-
|
|
15
|
+
__MODERN_CHUNK_LOADING_GLOBAL__: JSON.stringify(chunkLoadingGlobal)
|
|
16
16
|
}).apply(compiler);
|
|
17
17
|
if (this.opts.outputAsset || this.opts.writeToDisk) compiler.hooks.make.tap(LoadablePlugin.name, (compilation)=>{
|
|
18
18
|
compilation.hooks.processAssets.tap({
|
|
@@ -5,18 +5,8 @@ import { hydrateRoot } from "react-dom/client";
|
|
|
5
5
|
import { RenderLevel } from "../constants.mjs";
|
|
6
6
|
import { wrapRuntimeContextProvider } from "../react/wrapper.mjs";
|
|
7
7
|
import { WithCallback } from "./withCallback.mjs";
|
|
8
|
-
const runtimeProcess = Reflect.get(globalThis, 'process');
|
|
9
|
-
const runtimeEnvironment = null !== runtimeProcess && 'object' == typeof runtimeProcess ? Reflect.get(runtimeProcess, 'env') : void 0;
|
|
10
|
-
const readRuntimeEnvironment = (name)=>{
|
|
11
|
-
if (null === runtimeEnvironment || 'object' != typeof runtimeEnvironment) return;
|
|
12
|
-
const value = Reflect.get(runtimeEnvironment, name);
|
|
13
|
-
return 'string' == typeof value ? value : void 0;
|
|
14
|
-
};
|
|
15
8
|
const loadableReadyOptions = {
|
|
16
|
-
chunkLoadingGlobal:
|
|
17
|
-
const configured = readRuntimeEnvironment('MODERN_CHUNK_LOADING_GLOBAL');
|
|
18
|
-
return void 0 === configured || '' === configured ? '__LOADABLE_LOADED_CHUNKS__' : configured;
|
|
19
|
-
})()
|
|
9
|
+
chunkLoadingGlobal: 'string' == typeof __MODERN_CHUNK_LOADING_GLOBAL__ && '' !== __MODERN_CHUNK_LOADING_GLOBAL__ ? __MODERN_CHUNK_LOADING_GLOBAL__ : '__LOADABLE_LOADED_CHUNKS__'
|
|
20
10
|
};
|
|
21
11
|
function hydrateWithReact(App, rootElement) {
|
|
22
12
|
return Promise.resolve(hydrateRoot(rootElement, App, {
|
|
@@ -4,8 +4,13 @@ function getStore(context) {
|
|
|
4
4
|
}
|
|
5
5
|
function ensureStore(context) {
|
|
6
6
|
const target = context;
|
|
7
|
-
target[EXTENSIONS_SLOT]
|
|
8
|
-
|
|
7
|
+
const store = target[EXTENSIONS_SLOT] ?? new Map();
|
|
8
|
+
Object.defineProperty(target, EXTENSIONS_SLOT, {
|
|
9
|
+
configurable: true,
|
|
10
|
+
enumerable: true,
|
|
11
|
+
value: store
|
|
12
|
+
});
|
|
13
|
+
return store;
|
|
9
14
|
}
|
|
10
15
|
function stripRuntimeContextExtensions(context) {
|
|
11
16
|
delete context[EXTENSIONS_SLOT];
|
|
@@ -3,8 +3,19 @@ const ROUTE_MANIFEST = '_MODERNJS_ROUTE_MANIFEST';
|
|
|
3
3
|
const InternalRuntimeContext = createContext({});
|
|
4
4
|
const getInitialContext = (isBrowser = true, routeManifest)=>{
|
|
5
5
|
const requestContext = {
|
|
6
|
-
request: {
|
|
7
|
-
|
|
6
|
+
request: {
|
|
7
|
+
params: {},
|
|
8
|
+
pathname: '',
|
|
9
|
+
query: {},
|
|
10
|
+
headers: {},
|
|
11
|
+
host: '',
|
|
12
|
+
url: ''
|
|
13
|
+
},
|
|
14
|
+
response: {
|
|
15
|
+
setHeader () {},
|
|
16
|
+
status () {},
|
|
17
|
+
locals: {}
|
|
18
|
+
}
|
|
8
19
|
};
|
|
9
20
|
return {
|
|
10
21
|
isBrowser,
|