@bleedingdev/modern-js-renderer-core 3.9.3-ultramodern.8 → 3.9.3-ultramodern.9
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/adapter.js +1 -1
- package/dist/cjs/entry-client.js +5 -0
- package/dist/cjs/federation.js +14 -5
- package/dist/cjs/server/worker.js +2 -1
- package/dist/cjs/worker-federation/contract.js +298 -0
- package/dist/cjs/worker-federation/handler.js +197 -0
- package/dist/cjs/worker-federation/index.js +63 -0
- package/dist/cjs/worker-federation/lease.js +167 -0
- package/dist/cjs/worker-federation/transport.js +272 -0
- package/dist/esm/adapter.mjs +1 -1
- package/dist/esm/entry-client.mjs +5 -0
- package/dist/esm/federation.mjs +14 -5
- package/dist/esm/server/worker.mjs +2 -1
- package/dist/esm/worker-federation/contract.mjs +227 -0
- package/dist/esm/worker-federation/handler.mjs +159 -0
- package/dist/esm/worker-federation/index.mjs +3 -0
- package/dist/esm/worker-federation/lease.mjs +107 -0
- package/dist/esm/worker-federation/transport.mjs +234 -0
- package/dist/esm-node/adapter.mjs +1 -1
- package/dist/esm-node/entry-client.mjs +5 -0
- package/dist/esm-node/federation.mjs +14 -5
- package/dist/esm-node/server/worker.mjs +2 -1
- package/dist/esm-node/worker-federation/contract.mjs +228 -0
- package/dist/esm-node/worker-federation/handler.mjs +160 -0
- package/dist/esm-node/worker-federation/index.mjs +4 -0
- package/dist/esm-node/worker-federation/lease.mjs +108 -0
- package/dist/esm-node/worker-federation/transport.mjs +235 -0
- package/dist/types/entry-client.d.ts +2 -0
- package/dist/types/federation.d.ts +15 -2
- package/dist/types/server/types.d.ts +3 -0
- package/dist/types/server/worker.d.ts +19 -0
- package/dist/types/worker-federation/contract.d.ts +70 -0
- package/dist/types/worker-federation/handler.d.ts +21 -0
- package/dist/types/worker-federation/index.d.ts +6 -0
- package/dist/types/worker-federation/lease.d.ts +11 -0
- package/dist/types/worker-federation/transport.d.ts +47 -0
- package/package.json +12 -2
- package/src/adapter.ts +3 -1
- package/src/entry-client.ts +5 -0
- package/src/federation.ts +36 -8
- package/src/server/types.ts +3 -0
- package/src/server/worker.ts +23 -0
- package/src/worker-federation/contract.ts +449 -0
- package/src/worker-federation/handler.ts +274 -0
- package/src/worker-federation/index.ts +23 -0
- package/src/worker-federation/lease.ts +143 -0
- package/src/worker-federation/transport.ts +430 -0
package/dist/cjs/adapter.js
CHANGED
|
@@ -44,7 +44,7 @@ function defineRendererAdapter(adapter) {
|
|
|
44
44
|
function nativeRendererDependencies(profile) {
|
|
45
45
|
return {
|
|
46
46
|
...Object.fromEntries(Object.entries(profile.dependencies).filter(([name])=>!name.startsWith('@modern-js/'))),
|
|
47
|
-
[profile.router.coreName]: profile.router.coreVersion
|
|
47
|
+
[profile.router.coreName]: profile.dependencies[profile.router.coreName] ?? profile.router.coreVersion
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
__webpack_require__.d(__webpack_exports__, {
|
package/dist/cjs/entry-client.js
CHANGED
|
@@ -101,6 +101,11 @@ function startNativeClientEntry(options, adapter) {
|
|
|
101
101
|
rewrite: i18n.rewrite(()=>current.language)
|
|
102
102
|
} : {}
|
|
103
103
|
});
|
|
104
|
+
const releaseRouter = ()=>adapter.disposeRouter(router);
|
|
105
|
+
if (signal.aborted) releaseRouter();
|
|
106
|
+
else signal.addEventListener('abort', releaseRouter, {
|
|
107
|
+
once: true
|
|
108
|
+
});
|
|
104
109
|
const stopSync = i18n && current ? i18n.syncWithRouter(router, current) : void 0;
|
|
105
110
|
if (stopSync) signal.addEventListener('abort', stopSync, {
|
|
106
111
|
once: true
|
package/dist/cjs/federation.js
CHANGED
|
@@ -27,6 +27,7 @@ var __webpack_require__ = {};
|
|
|
27
27
|
})();
|
|
28
28
|
var __webpack_exports__ = {};
|
|
29
29
|
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
const LOAD_WITH_CAPTURE = Symbol.for('ultramodern.federation.load-with-capture');
|
|
30
31
|
function getFederationHost(binding) {
|
|
31
32
|
if (void 0 === binding) return;
|
|
32
33
|
if ('function' != typeof binding?.instance) throw new TypeError('The native federation host binding is invalid.');
|
|
@@ -36,16 +37,24 @@ function getFederationHost(binding) {
|
|
|
36
37
|
}
|
|
37
38
|
async function loadFederatedModule(instance, id) {
|
|
38
39
|
if (!instance) throw new Error(`Cannot load ${id}: this application has no Module Federation runtime. Add module-federation.config.ts with its remotes.`);
|
|
39
|
-
const
|
|
40
|
+
const coupledLoad = instance[LOAD_WITH_CAPTURE];
|
|
41
|
+
const result = coupledLoad ? await coupledLoad(id, (_module, resolution)=>remoteBrowserAssets(instance, id, resolution)) : {
|
|
42
|
+
module: await instance.loadRemote(id),
|
|
43
|
+
captured: remoteBrowserAssets(instance, id)
|
|
44
|
+
};
|
|
45
|
+
const module = result.module;
|
|
40
46
|
if (!module) throw new Error(`Remote module ${id} is unavailable`);
|
|
41
|
-
return
|
|
47
|
+
return {
|
|
48
|
+
module,
|
|
49
|
+
assets: result.captured
|
|
50
|
+
};
|
|
42
51
|
}
|
|
43
|
-
function remoteBrowserAssets(instance, id) {
|
|
52
|
+
function remoteBrowserAssets(instance, id, resolution) {
|
|
44
53
|
const target = instance.remoteHandler?.idToRemoteMap?.[id];
|
|
45
54
|
const loaded = target && instance.moduleCache?.get(target.name);
|
|
46
|
-
const snapshot = loaded && instance.snapshotHandler?.getGlobalRemoteInfo(loaded.remoteInfo).remoteSnapshot;
|
|
55
|
+
const snapshot = resolution ? resolution.remoteSnapshot : loaded && instance.snapshotHandler?.getGlobalRemoteInfo(loaded.remoteInfo).remoteSnapshot;
|
|
47
56
|
if (!snapshot || 'string' != typeof snapshot.publicPath || !snapshot.publicPath || 'string' != typeof snapshot.remoteEntry || !snapshot.remoteEntry) return;
|
|
48
|
-
const expose = snapshot.modules?.find((module)=>module.modulePath === target
|
|
57
|
+
const expose = snapshot.modules?.find((module)=>module.modulePath === (resolution?.expose ?? target?.expose));
|
|
49
58
|
if (!expose?.assets) return;
|
|
50
59
|
const publicPath = snapshot.publicPath;
|
|
51
60
|
const url = (file)=>/^(?:https?:)?\/\//iu.test(file) ? file : `${publicPath.replace(/\/$/u, '')}/${file.replace(/^\//u, '')}`;
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
WORKER_FEDERATION_METADATA_KEY: ()=>WORKER_FEDERATION_METADATA_KEY,
|
|
32
|
+
WORKER_FEDERATION_SCHEMA: ()=>WORKER_FEDERATION_SCHEMA,
|
|
33
|
+
WORKER_FEDERATION_VERSION: ()=>WORKER_FEDERATION_VERSION,
|
|
34
|
+
admitWorkerFederationExpose: ()=>admitWorkerFederationExpose,
|
|
35
|
+
readWorkerFederationEnvelope: ()=>readWorkerFederationEnvelope,
|
|
36
|
+
readWorkerFederationManifestUrl: ()=>readWorkerFederationManifestUrl,
|
|
37
|
+
readWorkerFederationPath: ()=>readWorkerFederationPath,
|
|
38
|
+
readWorkerFederationPublication: ()=>readWorkerFederationPublication,
|
|
39
|
+
readWorkerFederationStyles: ()=>readWorkerFederationStyles,
|
|
40
|
+
workerFederationEnvelope: ()=>workerFederationEnvelope,
|
|
41
|
+
workerFederationRecord: ()=>workerFederationRecord,
|
|
42
|
+
workerFederationWireJson: ()=>workerFederationWireJson
|
|
43
|
+
});
|
|
44
|
+
const external_identity_js_namespaceObject = require("../identity.js");
|
|
45
|
+
const WORKER_FEDERATION_METADATA_KEY = 'ultramodernWorkerFederation';
|
|
46
|
+
const WORKER_FEDERATION_SCHEMA = 'ultramodern.worker-federation';
|
|
47
|
+
const WORKER_FEDERATION_VERSION = 1;
|
|
48
|
+
function workerFederationRecord(value, label) {
|
|
49
|
+
if (!value || 'object' != typeof value || ![
|
|
50
|
+
Object.prototype,
|
|
51
|
+
null
|
|
52
|
+
].includes(Object.getPrototypeOf(value))) throw new Error(`Worker federation ${label} must be a plain record.`);
|
|
53
|
+
return value;
|
|
54
|
+
}
|
|
55
|
+
function exactFields(value, fields, label) {
|
|
56
|
+
if (Object.keys(value).length !== fields.length || Object.keys(value).some((key)=>!fields.includes(key))) throw new Error(`Worker federation ${label} has unsupported fields.`);
|
|
57
|
+
}
|
|
58
|
+
function requiredString(value, label) {
|
|
59
|
+
if ('string' != typeof value || 0 === value.length || value.trim() !== value || /[\u0000-\u001f\u007f]/u.test(value)) throw new Error(`Worker federation requires ${label}.`);
|
|
60
|
+
return value;
|
|
61
|
+
}
|
|
62
|
+
function readWorkerFederationPath(value) {
|
|
63
|
+
const path = requiredString(value, 'an endpoint path');
|
|
64
|
+
let decoded;
|
|
65
|
+
try {
|
|
66
|
+
decoded = decodeURIComponent(path);
|
|
67
|
+
} catch {
|
|
68
|
+
throw new Error('Worker federation endpoint path has invalid encoding.');
|
|
69
|
+
}
|
|
70
|
+
if (!path.startsWith('/') || path.startsWith('//') || /[\\?#\s\u0000-\u001f\u007f]/u.test(decoded) || /%[0-9a-f]{2}/iu.test(decoded) || decoded.split('/').some((segment)=>'.' === segment || '..' === segment) || new URL(path, 'https://worker.invalid').pathname !== path) throw new Error('Worker federation endpoint must be an exact root path.');
|
|
71
|
+
return path;
|
|
72
|
+
}
|
|
73
|
+
function readWorkerFederationManifestUrl(value) {
|
|
74
|
+
const url = new URL(value);
|
|
75
|
+
if (![
|
|
76
|
+
'http:',
|
|
77
|
+
'https:'
|
|
78
|
+
].includes(url.protocol) || url.username || url.password || url.hash) throw new Error('Worker federation manifest requires an HTTP(S) publication URL.');
|
|
79
|
+
return url;
|
|
80
|
+
}
|
|
81
|
+
function readWorkerFederationPublication(value, identities) {
|
|
82
|
+
const record = workerFederationRecord(value, 'publication');
|
|
83
|
+
exactFields(record, [
|
|
84
|
+
'schema',
|
|
85
|
+
'schemaVersion',
|
|
86
|
+
'remote',
|
|
87
|
+
'exposes'
|
|
88
|
+
], 'publication');
|
|
89
|
+
if (record.schema !== WORKER_FEDERATION_SCHEMA || record.schemaVersion !== WORKER_FEDERATION_VERSION) throw new Error('Unsupported Worker federation publication protocol.');
|
|
90
|
+
const remote = requiredString(record.remote, 'a remote');
|
|
91
|
+
const entries = workerFederationRecord(record.exposes, 'exposes');
|
|
92
|
+
if (0 === Object.keys(entries).length) throw new Error('Worker federation publication has no exposes.');
|
|
93
|
+
const paths = new Set();
|
|
94
|
+
const exposes = Object.fromEntries(Object.entries(entries).map(([expose, raw])=>{
|
|
95
|
+
if (!/^\.\/[A-Za-z0-9_$@.-]+(?:\/[A-Za-z0-9_$@.-]+)*$/u.test(expose) || expose.slice(2).split('/').some((segment)=>'.' === segment || '..' === segment)) throw new Error(`Unsupported Worker federation expose ${expose}.`);
|
|
96
|
+
const coordinate = workerFederationRecord(raw, 'expose coordinate');
|
|
97
|
+
exactFields(coordinate, [
|
|
98
|
+
'entryName',
|
|
99
|
+
'boundaryId',
|
|
100
|
+
'paths',
|
|
101
|
+
'native'
|
|
102
|
+
], 'expose coordinate');
|
|
103
|
+
const entryName = requiredString(coordinate.entryName, 'an entry name');
|
|
104
|
+
if (!Object.hasOwn(identities, entryName)) throw new Error(`Worker federation expose ${expose} has no built entry.`);
|
|
105
|
+
const identity = identities[entryName];
|
|
106
|
+
(0, external_identity_js_namespaceObject.identityCacheKey)(identity);
|
|
107
|
+
if (identity.entryName !== entryName) throw new Error('Worker federation entry identity conflicts with its key.');
|
|
108
|
+
const rawPaths = workerFederationRecord(coordinate.paths, 'locale paths');
|
|
109
|
+
const native = workerFederationRecord(coordinate.native, 'native authority');
|
|
110
|
+
exactFields(native, [
|
|
111
|
+
'publisherBuildId',
|
|
112
|
+
'runtimeABI'
|
|
113
|
+
], 'native authority');
|
|
114
|
+
if (1 !== native.runtimeABI) throw new Error('Unsupported native Worker federation runtime ABI.');
|
|
115
|
+
if (0 === Object.keys(rawPaths).length) throw new Error('Worker federation expose has no locale endpoints.');
|
|
116
|
+
const locales = Object.keys(rawPaths);
|
|
117
|
+
if (new Set(locales.map((locale)=>locale.toLowerCase())).size !== locales.length || locales.includes('default') && 1 !== locales.length) throw new Error('Worker federation requires unique locales or only default.');
|
|
118
|
+
const localePaths = Object.fromEntries(Object.entries(rawPaths).map(([locale, rawPath])=>{
|
|
119
|
+
if (!/^[a-zA-Z0-9]+(?:[-_][a-zA-Z0-9]+)*$/u.test(locale)) throw new Error('Worker federation endpoint has an invalid locale.');
|
|
120
|
+
const path = readWorkerFederationPath(rawPath);
|
|
121
|
+
if (paths.has(path)) throw new Error('Worker federation exposes have conflicting endpoint paths.');
|
|
122
|
+
paths.add(path);
|
|
123
|
+
return [
|
|
124
|
+
locale,
|
|
125
|
+
path
|
|
126
|
+
];
|
|
127
|
+
}));
|
|
128
|
+
return [
|
|
129
|
+
expose,
|
|
130
|
+
Object.freeze({
|
|
131
|
+
entryName,
|
|
132
|
+
boundaryId: requiredString(coordinate.boundaryId, 'a boundary ID'),
|
|
133
|
+
paths: Object.freeze(localePaths),
|
|
134
|
+
native: Object.freeze({
|
|
135
|
+
publisherBuildId: requiredString(native.publisherBuildId, 'a native publisher build ID'),
|
|
136
|
+
runtimeABI: 1
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
];
|
|
140
|
+
}));
|
|
141
|
+
return Object.freeze({
|
|
142
|
+
schema: WORKER_FEDERATION_SCHEMA,
|
|
143
|
+
schemaVersion: WORKER_FEDERATION_VERSION,
|
|
144
|
+
remote,
|
|
145
|
+
exposes: Object.freeze(exposes)
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
function workerFederationWireJson(value) {
|
|
149
|
+
const encode = (input)=>{
|
|
150
|
+
if (null === input || 'string' == typeof input || 'boolean' == typeof input) return input;
|
|
151
|
+
if ('number' == typeof input && Number.isFinite(input)) return input;
|
|
152
|
+
if (Array.isArray(input)) return input.map(encode);
|
|
153
|
+
const record = workerFederationRecord(input, 'wire value');
|
|
154
|
+
return Object.fromEntries(Object.keys(record).toSorted().map((key)=>[
|
|
155
|
+
key,
|
|
156
|
+
encode(record[key])
|
|
157
|
+
]));
|
|
158
|
+
};
|
|
159
|
+
return JSON.stringify(encode(value));
|
|
160
|
+
}
|
|
161
|
+
function freezeWireValue(value) {
|
|
162
|
+
const copy = JSON.parse(workerFederationWireJson(value));
|
|
163
|
+
const freeze = (input)=>{
|
|
164
|
+
if (input && 'object' == typeof input) {
|
|
165
|
+
Object.values(input).forEach(freeze);
|
|
166
|
+
Object.freeze(input);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
freeze(copy);
|
|
170
|
+
return copy;
|
|
171
|
+
}
|
|
172
|
+
function readWorkerFederationStyles(options) {
|
|
173
|
+
const manifest = workerFederationRecord(options.manifest, 'manifest');
|
|
174
|
+
const metadata = workerFederationRecord(manifest.metaData, 'manifest metadata');
|
|
175
|
+
const manifestUrl = readWorkerFederationManifestUrl(options.manifestUrl);
|
|
176
|
+
if (!Array.isArray(manifest.exposes)) throw new Error('Worker federation manifest exposes must be an array.');
|
|
177
|
+
const selected = manifest.exposes.map((value)=>workerFederationRecord(value, 'manifest expose')).filter((value)=>value.path === options.expose);
|
|
178
|
+
if (1 !== selected.length) throw new Error('Worker federation styles require one exact manifest expose.');
|
|
179
|
+
if (void 0 === selected[0].assets) return Object.freeze([]);
|
|
180
|
+
const assets = workerFederationRecord(selected[0].assets, 'expose assets');
|
|
181
|
+
if (void 0 === assets.css) return Object.freeze([]);
|
|
182
|
+
const css = workerFederationRecord(assets.css, 'expose CSS assets');
|
|
183
|
+
const files = [
|
|
184
|
+
'sync',
|
|
185
|
+
'async'
|
|
186
|
+
].flatMap((kind)=>{
|
|
187
|
+
const values = css[kind];
|
|
188
|
+
if (void 0 === values) return [];
|
|
189
|
+
if (!Array.isArray(values)) throw new Error('Worker federation CSS assets must be string arrays.');
|
|
190
|
+
return values.map((value)=>requiredString(value, 'a CSS asset URL'));
|
|
191
|
+
});
|
|
192
|
+
if (0 === files.length) return Object.freeze([]);
|
|
193
|
+
if (void 0 === metadata.publicPath || 'auto' === metadata.publicPath) throw new Error('Worker federation CSS requires a completed static publicPath; auto and getPublicPath cannot resolve styles in a Worker.');
|
|
194
|
+
const publicPath = requiredString(metadata.publicPath, 'a completed public path');
|
|
195
|
+
const explicitScheme = /^[a-z][a-z0-9+.-]*:/iu;
|
|
196
|
+
const isHttpScheme = /^https?:/iu;
|
|
197
|
+
const assertScheme = (value)=>{
|
|
198
|
+
if (explicitScheme.test(value) && !isHttpScheme.test(value)) throw new Error('Worker federation styles require an HTTP(S) publication URL.');
|
|
199
|
+
};
|
|
200
|
+
assertScheme(publicPath);
|
|
201
|
+
const publicUrl = new URL(publicPath, manifestUrl);
|
|
202
|
+
if (![
|
|
203
|
+
'http:',
|
|
204
|
+
'https:'
|
|
205
|
+
].includes(publicUrl.protocol) || publicUrl.username || publicUrl.password || publicUrl.hash) throw new Error('Worker federation styles require an HTTP(S) publication URL.');
|
|
206
|
+
const styles = files.map((file)=>{
|
|
207
|
+
assertScheme(file);
|
|
208
|
+
const resolved = /^(?:https?:)?\/\//iu.test(file) ? file : `${publicPath.replace(/\/$/u, '')}/${file.replace(/^\//u, '')}`;
|
|
209
|
+
const url = new URL(resolved, manifestUrl);
|
|
210
|
+
if (![
|
|
211
|
+
'http:',
|
|
212
|
+
'https:'
|
|
213
|
+
].includes(url.protocol) || url.username || url.password || url.hash) throw new Error('Worker federation styles require an HTTP(S) publication URL.');
|
|
214
|
+
return resolved;
|
|
215
|
+
});
|
|
216
|
+
return Object.freeze([
|
|
217
|
+
...new Set(styles)
|
|
218
|
+
]);
|
|
219
|
+
}
|
|
220
|
+
function admitWorkerFederationExpose(options) {
|
|
221
|
+
const url = readWorkerFederationManifestUrl(options.manifestUrl);
|
|
222
|
+
const manifest = workerFederationRecord(options.manifest, 'manifest');
|
|
223
|
+
const metadata = workerFederationRecord(manifest.metaData, 'manifest metadata');
|
|
224
|
+
const renderer = freezeWireValue(options.admitRendererContract(metadata.ultramodernRenderer));
|
|
225
|
+
const worker = readWorkerFederationPublication(metadata[WORKER_FEDERATION_METADATA_KEY], renderer.identities);
|
|
226
|
+
if (worker.remote !== options.remote) throw new Error('Worker federation publication names another remote.');
|
|
227
|
+
if (!Object.hasOwn(worker.exposes, options.expose)) throw new Error(`Worker federation expose ${options.expose} is not published.`);
|
|
228
|
+
const coordinate = worker.exposes[options.expose];
|
|
229
|
+
if (!Object.hasOwn(coordinate.paths, options.locale)) throw new Error('Worker federation locale has no published endpoint.');
|
|
230
|
+
const path = coordinate.paths[options.locale];
|
|
231
|
+
const identity = (0, external_identity_js_namespaceObject.readRendererIdentity)(renderer.identities[coordinate.entryName], renderer.identities[coordinate.entryName]);
|
|
232
|
+
return Object.freeze({
|
|
233
|
+
authority: Object.freeze({
|
|
234
|
+
origin: url.origin,
|
|
235
|
+
renderer,
|
|
236
|
+
worker
|
|
237
|
+
}),
|
|
238
|
+
expose: options.expose,
|
|
239
|
+
locale: options.locale,
|
|
240
|
+
coordinate,
|
|
241
|
+
path,
|
|
242
|
+
identity,
|
|
243
|
+
endpoint: new URL(path, url.origin).href,
|
|
244
|
+
styles: Object.freeze([])
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
function workerFederationEnvelope(kind, admitted, payload) {
|
|
248
|
+
return {
|
|
249
|
+
schema: `ultramodern.worker-federation-${kind}`,
|
|
250
|
+
schemaVersion: 1,
|
|
251
|
+
authority: admitted.authority,
|
|
252
|
+
expose: admitted.expose,
|
|
253
|
+
locale: admitted.locale,
|
|
254
|
+
payload
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
function readWorkerFederationEnvelope(value, kind, admitted) {
|
|
258
|
+
const record = workerFederationRecord(value, `${kind} envelope`);
|
|
259
|
+
exactFields(record, [
|
|
260
|
+
'schema',
|
|
261
|
+
'schemaVersion',
|
|
262
|
+
'authority',
|
|
263
|
+
'expose',
|
|
264
|
+
'locale',
|
|
265
|
+
'payload'
|
|
266
|
+
], `${kind} envelope`);
|
|
267
|
+
if (record.schema !== `ultramodern.worker-federation-${kind}` || 1 !== record.schemaVersion || record.expose !== admitted.expose || record.locale !== admitted.locale || workerFederationWireJson(record.authority) !== workerFederationWireJson(admitted.authority)) throw new Error(`Worker federation ${kind} conflicts with the admitted publication.`);
|
|
268
|
+
return record.payload;
|
|
269
|
+
}
|
|
270
|
+
exports.WORKER_FEDERATION_METADATA_KEY = __webpack_exports__.WORKER_FEDERATION_METADATA_KEY;
|
|
271
|
+
exports.WORKER_FEDERATION_SCHEMA = __webpack_exports__.WORKER_FEDERATION_SCHEMA;
|
|
272
|
+
exports.WORKER_FEDERATION_VERSION = __webpack_exports__.WORKER_FEDERATION_VERSION;
|
|
273
|
+
exports.admitWorkerFederationExpose = __webpack_exports__.admitWorkerFederationExpose;
|
|
274
|
+
exports.readWorkerFederationEnvelope = __webpack_exports__.readWorkerFederationEnvelope;
|
|
275
|
+
exports.readWorkerFederationManifestUrl = __webpack_exports__.readWorkerFederationManifestUrl;
|
|
276
|
+
exports.readWorkerFederationPath = __webpack_exports__.readWorkerFederationPath;
|
|
277
|
+
exports.readWorkerFederationPublication = __webpack_exports__.readWorkerFederationPublication;
|
|
278
|
+
exports.readWorkerFederationStyles = __webpack_exports__.readWorkerFederationStyles;
|
|
279
|
+
exports.workerFederationEnvelope = __webpack_exports__.workerFederationEnvelope;
|
|
280
|
+
exports.workerFederationRecord = __webpack_exports__.workerFederationRecord;
|
|
281
|
+
exports.workerFederationWireJson = __webpack_exports__.workerFederationWireJson;
|
|
282
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
283
|
+
"WORKER_FEDERATION_METADATA_KEY",
|
|
284
|
+
"WORKER_FEDERATION_SCHEMA",
|
|
285
|
+
"WORKER_FEDERATION_VERSION",
|
|
286
|
+
"admitWorkerFederationExpose",
|
|
287
|
+
"readWorkerFederationEnvelope",
|
|
288
|
+
"readWorkerFederationManifestUrl",
|
|
289
|
+
"readWorkerFederationPath",
|
|
290
|
+
"readWorkerFederationPublication",
|
|
291
|
+
"readWorkerFederationStyles",
|
|
292
|
+
"workerFederationEnvelope",
|
|
293
|
+
"workerFederationRecord",
|
|
294
|
+
"workerFederationWireJson"
|
|
295
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
296
|
+
Object.defineProperty(exports, '__esModule', {
|
|
297
|
+
value: true
|
|
298
|
+
});
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
createWorkerFederationHandler: ()=>createWorkerFederationHandler
|
|
32
|
+
});
|
|
33
|
+
const external_contract_js_namespaceObject = require("./contract.js");
|
|
34
|
+
const external_lease_js_namespaceObject = require("./lease.js");
|
|
35
|
+
function createWorkerFederationHandler(options) {
|
|
36
|
+
if ('function' != typeof options.admitRendererContract || 'function' != typeof options.admitNativeRequest || 'function' != typeof options.releaseNativeRequest || 'function' != typeof options.renderNativeSnapshot) throw new Error('Worker federation requires canonical and native admission callbacks.');
|
|
37
|
+
const timeout = options.requestTimeout ?? 3000;
|
|
38
|
+
if (!Number.isFinite(timeout) || timeout <= 0) throw new Error('Worker federation requires a positive request deadline.');
|
|
39
|
+
const renderer = options.admitRendererContract(options.publication.renderer);
|
|
40
|
+
const worker = (0, external_contract_js_namespaceObject.readWorkerFederationPublication)(options.publication.worker, renderer.identities);
|
|
41
|
+
const manifest = JSON.parse((0, external_contract_js_namespaceObject.workerFederationWireJson)({
|
|
42
|
+
metaData: {
|
|
43
|
+
ultramodernRenderer: renderer,
|
|
44
|
+
ultramodernWorkerFederation: worker
|
|
45
|
+
}
|
|
46
|
+
}));
|
|
47
|
+
const loaders = (0, external_contract_js_namespaceObject.workerFederationRecord)(options.exposes, 'compiled exposes');
|
|
48
|
+
if (Object.keys(loaders).length !== Object.keys(worker.exposes).length || Object.keys(loaders).some((expose)=>!Object.hasOwn(worker.exposes, expose) || 'function' != typeof loaders[expose])) throw new Error('Worker federation registry conflicts with its own publication.');
|
|
49
|
+
const pinnedLoaders = {
|
|
50
|
+
...options.exposes
|
|
51
|
+
};
|
|
52
|
+
const endpoints = new Map();
|
|
53
|
+
for (const [expose, coordinate] of Object.entries(worker.exposes))for (const locale of Object.keys(coordinate.paths)){
|
|
54
|
+
const admitted = (0, external_contract_js_namespaceObject.admitWorkerFederationExpose)({
|
|
55
|
+
manifest,
|
|
56
|
+
manifestUrl: options.manifestUrl,
|
|
57
|
+
remote: worker.remote,
|
|
58
|
+
expose,
|
|
59
|
+
locale,
|
|
60
|
+
admitRendererContract: options.admitRendererContract
|
|
61
|
+
});
|
|
62
|
+
endpoints.set(admitted.path, admitted);
|
|
63
|
+
}
|
|
64
|
+
const admitNativeRequest = options.admitNativeRequest;
|
|
65
|
+
const releaseNativeRequest = options.releaseNativeRequest;
|
|
66
|
+
const renderNativeSnapshot = options.renderNativeSnapshot;
|
|
67
|
+
return async (request)=>{
|
|
68
|
+
const deadlineAt = performance.now() + timeout;
|
|
69
|
+
const url = new URL(request.url);
|
|
70
|
+
const admitted = endpoints.get(url.pathname);
|
|
71
|
+
if (!admitted) return;
|
|
72
|
+
if ('POST' !== request.method || url.href !== admitted.endpoint || request.headers.get('content-type')?.split(';')[0].trim().toLowerCase() !== 'application/json') {
|
|
73
|
+
request.body?.cancel().catch(()=>void 0);
|
|
74
|
+
return new Response('Worker federation endpoint coordinate conflicts with its publication.', {
|
|
75
|
+
status: 400
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (request.signal.aborted) {
|
|
79
|
+
request.body?.cancel().catch(()=>void 0);
|
|
80
|
+
throw (0, external_lease_js_namespaceObject.workerAbortReason)(request.signal);
|
|
81
|
+
}
|
|
82
|
+
const controller = new AbortController();
|
|
83
|
+
const signal = AbortSignal.any([
|
|
84
|
+
request.signal,
|
|
85
|
+
controller.signal
|
|
86
|
+
]);
|
|
87
|
+
const checkDeadline = ()=>(0, external_lease_js_namespaceObject.checkWorkerFederationDeadline)(deadlineAt, signal, controller);
|
|
88
|
+
const execution = Object.freeze({
|
|
89
|
+
admitted,
|
|
90
|
+
signal
|
|
91
|
+
});
|
|
92
|
+
const deadline = setTimeout(()=>{
|
|
93
|
+
controller.abort(new Error('Worker federation request deadline exceeded.'));
|
|
94
|
+
}, Math.max(0, deadlineAt - performance.now()));
|
|
95
|
+
let executing = false;
|
|
96
|
+
let admittedRequest;
|
|
97
|
+
let release;
|
|
98
|
+
let response;
|
|
99
|
+
let failedRequest;
|
|
100
|
+
const releaseOnce = (value)=>{
|
|
101
|
+
if (!release) try {
|
|
102
|
+
release = Promise.resolve(releaseNativeRequest(value));
|
|
103
|
+
} catch (error) {
|
|
104
|
+
release = Promise.reject(error);
|
|
105
|
+
}
|
|
106
|
+
return release ?? Promise.resolve();
|
|
107
|
+
};
|
|
108
|
+
try {
|
|
109
|
+
if (!request.body) throw new Error('Worker federation request has no native payload.');
|
|
110
|
+
const envelope = await (0, external_lease_js_namespaceObject.readWorkerFederationJsonBody)(request.body, signal, request.headers.get('content-length'), checkDeadline);
|
|
111
|
+
checkDeadline();
|
|
112
|
+
const payload = (0, external_contract_js_namespaceObject.readWorkerFederationEnvelope)(envelope, 'request', admitted);
|
|
113
|
+
checkDeadline();
|
|
114
|
+
const preparing = Promise.resolve().then(()=>{
|
|
115
|
+
checkDeadline();
|
|
116
|
+
return admitNativeRequest(payload, execution);
|
|
117
|
+
});
|
|
118
|
+
preparing.then((value)=>{
|
|
119
|
+
if (signal.aborted) releaseOnce(value).catch(()=>void 0);
|
|
120
|
+
}, ()=>void 0);
|
|
121
|
+
const nativeRequest = await (0, external_lease_js_namespaceObject.workerAbortable)(preparing, signal);
|
|
122
|
+
admittedRequest = {
|
|
123
|
+
value: nativeRequest
|
|
124
|
+
};
|
|
125
|
+
checkDeadline();
|
|
126
|
+
executing = true;
|
|
127
|
+
const module = await (0, external_lease_js_namespaceObject.workerAbortable)(pinnedLoaders[admitted.expose](), signal);
|
|
128
|
+
checkDeadline();
|
|
129
|
+
const snapshot = await (0, external_lease_js_namespaceObject.workerAbortable)(Promise.resolve(renderNativeSnapshot(module, nativeRequest, execution)), signal);
|
|
130
|
+
checkDeadline();
|
|
131
|
+
if ('string' == typeof snapshot) (0, external_lease_js_namespaceObject.assertWorkerFederationBodySize)(snapshot);
|
|
132
|
+
const body = (0, external_lease_js_namespaceObject.assertWorkerFederationBodySize)((0, external_contract_js_namespaceObject.workerFederationWireJson)((0, external_contract_js_namespaceObject.workerFederationEnvelope)('response', admitted, snapshot)));
|
|
133
|
+
checkDeadline();
|
|
134
|
+
response = new Response(body, {
|
|
135
|
+
headers: {
|
|
136
|
+
'content-type': 'application/json'
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
} catch (error) {
|
|
140
|
+
let failure = error;
|
|
141
|
+
try {
|
|
142
|
+
checkDeadline();
|
|
143
|
+
} catch (deadlineError) {
|
|
144
|
+
failure = deadlineError;
|
|
145
|
+
}
|
|
146
|
+
failedRequest = {
|
|
147
|
+
error: failure
|
|
148
|
+
};
|
|
149
|
+
response = new Response((0, external_lease_js_namespaceObject.workerFederationErrorMessage)(failure, 'Worker federation request failed.'), {
|
|
150
|
+
status: signal.aborted ? 504 : executing ? 502 : failure instanceof external_lease_js_namespaceObject.WorkerFederationBodyTooLargeError ? 413 : 400
|
|
151
|
+
});
|
|
152
|
+
} finally{
|
|
153
|
+
try {
|
|
154
|
+
if (admittedRequest) {
|
|
155
|
+
const releasing = releaseOnce(admittedRequest.value);
|
|
156
|
+
if (signal.aborted) releasing.catch(()=>void 0);
|
|
157
|
+
else try {
|
|
158
|
+
await (0, external_lease_js_namespaceObject.workerAbortable)(releasing, signal);
|
|
159
|
+
checkDeadline();
|
|
160
|
+
} catch (error) {
|
|
161
|
+
response?.body?.cancel().catch(()=>void 0);
|
|
162
|
+
let releaseFailure = error;
|
|
163
|
+
try {
|
|
164
|
+
checkDeadline();
|
|
165
|
+
} catch (deadlineError) {
|
|
166
|
+
releaseFailure = new AggregateError([
|
|
167
|
+
error,
|
|
168
|
+
deadlineError
|
|
169
|
+
], `${(0, external_lease_js_namespaceObject.workerFederationErrorMessage)(error, 'Native request release failed.', 384)}; ${(0, external_lease_js_namespaceObject.workerFederationErrorMessage)(deadlineError, 'Worker federation deadline exceeded.', 384)}`);
|
|
170
|
+
}
|
|
171
|
+
const failure = failedRequest ? new AggregateError([
|
|
172
|
+
failedRequest.error,
|
|
173
|
+
releaseFailure
|
|
174
|
+
], `${(0, external_lease_js_namespaceObject.workerFederationErrorMessage)(failedRequest.error, 'Worker federation request failed.', 384)}; native request release failed: ${(0, external_lease_js_namespaceObject.workerFederationErrorMessage)(releaseFailure, 'Native request release failed.', 384)}`) : releaseFailure;
|
|
175
|
+
response = new Response((0, external_lease_js_namespaceObject.workerFederationErrorMessage)(failure, 'Worker federation native request release failed.'), {
|
|
176
|
+
status: signal.aborted ? 504 : 502
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
} finally{
|
|
181
|
+
clearTimeout(deadline);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (request.signal.aborted) {
|
|
185
|
+
response?.body?.cancel().catch(()=>void 0);
|
|
186
|
+
throw (0, external_lease_js_namespaceObject.workerAbortReason)(request.signal);
|
|
187
|
+
}
|
|
188
|
+
return response;
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
exports.createWorkerFederationHandler = __webpack_exports__.createWorkerFederationHandler;
|
|
192
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
193
|
+
"createWorkerFederationHandler"
|
|
194
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
195
|
+
Object.defineProperty(exports, '__esModule', {
|
|
196
|
+
value: true
|
|
197
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, getters, values)=>{
|
|
5
|
+
var define = (defs, kind)=>{
|
|
6
|
+
for(var key in defs)if (__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
[kind]: defs[key]
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
define(getters, "get");
|
|
12
|
+
define(values, "value");
|
|
13
|
+
};
|
|
14
|
+
})();
|
|
15
|
+
(()=>{
|
|
16
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
17
|
+
})();
|
|
18
|
+
(()=>{
|
|
19
|
+
__webpack_require__.r = (exports1)=>{
|
|
20
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
21
|
+
value: 'Module'
|
|
22
|
+
});
|
|
23
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
24
|
+
value: true
|
|
25
|
+
});
|
|
26
|
+
};
|
|
27
|
+
})();
|
|
28
|
+
var __webpack_exports__ = {};
|
|
29
|
+
__webpack_require__.r(__webpack_exports__);
|
|
30
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
31
|
+
WORKER_FEDERATION_METADATA_KEY: ()=>external_contract_js_namespaceObject.WORKER_FEDERATION_METADATA_KEY,
|
|
32
|
+
WORKER_FEDERATION_SCHEMA: ()=>external_contract_js_namespaceObject.WORKER_FEDERATION_SCHEMA,
|
|
33
|
+
WORKER_FEDERATION_VERSION: ()=>external_contract_js_namespaceObject.WORKER_FEDERATION_VERSION,
|
|
34
|
+
createWorkerFederationHandler: ()=>external_handler_js_namespaceObject.createWorkerFederationHandler,
|
|
35
|
+
createWorkerFederationTransport: ()=>external_transport_js_namespaceObject.createWorkerFederationTransport,
|
|
36
|
+
readWorkerFederationManifestUrl: ()=>external_contract_js_namespaceObject.readWorkerFederationManifestUrl,
|
|
37
|
+
readWorkerFederationPath: ()=>external_contract_js_namespaceObject.readWorkerFederationPath,
|
|
38
|
+
readWorkerFederationPublication: ()=>external_contract_js_namespaceObject.readWorkerFederationPublication
|
|
39
|
+
});
|
|
40
|
+
const external_contract_js_namespaceObject = require("./contract.js");
|
|
41
|
+
const external_handler_js_namespaceObject = require("./handler.js");
|
|
42
|
+
const external_transport_js_namespaceObject = require("./transport.js");
|
|
43
|
+
exports.WORKER_FEDERATION_METADATA_KEY = __webpack_exports__.WORKER_FEDERATION_METADATA_KEY;
|
|
44
|
+
exports.WORKER_FEDERATION_SCHEMA = __webpack_exports__.WORKER_FEDERATION_SCHEMA;
|
|
45
|
+
exports.WORKER_FEDERATION_VERSION = __webpack_exports__.WORKER_FEDERATION_VERSION;
|
|
46
|
+
exports.createWorkerFederationHandler = __webpack_exports__.createWorkerFederationHandler;
|
|
47
|
+
exports.createWorkerFederationTransport = __webpack_exports__.createWorkerFederationTransport;
|
|
48
|
+
exports.readWorkerFederationManifestUrl = __webpack_exports__.readWorkerFederationManifestUrl;
|
|
49
|
+
exports.readWorkerFederationPath = __webpack_exports__.readWorkerFederationPath;
|
|
50
|
+
exports.readWorkerFederationPublication = __webpack_exports__.readWorkerFederationPublication;
|
|
51
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
52
|
+
"WORKER_FEDERATION_METADATA_KEY",
|
|
53
|
+
"WORKER_FEDERATION_SCHEMA",
|
|
54
|
+
"WORKER_FEDERATION_VERSION",
|
|
55
|
+
"createWorkerFederationHandler",
|
|
56
|
+
"createWorkerFederationTransport",
|
|
57
|
+
"readWorkerFederationManifestUrl",
|
|
58
|
+
"readWorkerFederationPath",
|
|
59
|
+
"readWorkerFederationPublication"
|
|
60
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
61
|
+
Object.defineProperty(exports, '__esModule', {
|
|
62
|
+
value: true
|
|
63
|
+
});
|