@octanejs/rspack-plugin 0.1.7 → 0.1.11
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/README.md +28 -0
- package/package.json +6 -6
- package/src/loader.js +14 -4
- package/src/plugin.js +74 -12
- package/src/shared.js +76 -11
- package/types/index.d.ts +34 -8
- package/types/options.test-d.ts +41 -0
package/README.md
CHANGED
|
@@ -67,6 +67,34 @@ new OctaneRspackPlugin({
|
|
|
67
67
|
Options remain serializable data—there are no renderer callbacks—so the same
|
|
68
68
|
configuration is safe to reuse across compiler environments and caches.
|
|
69
69
|
|
|
70
|
+
Rspack layers can compile the same authored module against distinct universal
|
|
71
|
+
renderer graphs. Configure the background graph at the top level, then key
|
|
72
|
+
`layerSpecializations` by the exact value of `module.layer`:
|
|
73
|
+
|
|
74
|
+
```js
|
|
75
|
+
new OctaneRspackPlugin({
|
|
76
|
+
runtime: '@fixture/native-background-runtime',
|
|
77
|
+
renderers: backgroundRenderers,
|
|
78
|
+
universalRuntime: { runtime: 'native', thread: 'background' },
|
|
79
|
+
layerSpecializations: {
|
|
80
|
+
'native:main': {
|
|
81
|
+
runtime: '@fixture/native-main-runtime',
|
|
82
|
+
renderers: mainThreadRenderers,
|
|
83
|
+
universalRuntime: { runtime: 'native', thread: 'main-thread' },
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
The compiler selects `renderers` and `universalRuntime` from each transformed
|
|
90
|
+
module's layer. The plugin also installs `runtime` as an exact `octane` alias
|
|
91
|
+
for requests whose issuer belongs to that layer. Unconfigured and unknown
|
|
92
|
+
layers keep the top-level options. All renderer configurations participate in
|
|
93
|
+
source-dependency discovery and watching, and their normalized signatures and
|
|
94
|
+
runtime identities salt Rspack's persistent cache. The standalone loader
|
|
95
|
+
supports layer-specific compiler options but cannot install runtime aliases,
|
|
96
|
+
so `runtime` specializations require `OctaneRspackPlugin`.
|
|
97
|
+
|
|
70
98
|
Rspack's dev server enables the loader's hot context. If you run a custom dev
|
|
71
99
|
server, add Rspack's `HotModuleReplacementPlugin` as usual.
|
|
72
100
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@octanejs/rspack-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -45,13 +45,13 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@rspack/core": "^2.0.0",
|
|
48
|
-
"octane": "0.1.
|
|
48
|
+
"octane": "0.1.16"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
|
-
"@rspack/core": "^2.1.
|
|
52
|
-
"@types/node": "^24.3
|
|
53
|
-
"vitest": "^4.1.
|
|
54
|
-
"octane": "0.1.
|
|
51
|
+
"@rspack/core": "^2.1.4",
|
|
52
|
+
"@types/node": "^24.13.3",
|
|
53
|
+
"vitest": "^4.1.10",
|
|
54
|
+
"octane": "0.1.16"
|
|
55
55
|
},
|
|
56
56
|
"scripts": {
|
|
57
57
|
"test": "vitest run --config vitest.config.js"
|
package/src/loader.js
CHANGED
|
@@ -2,7 +2,11 @@ import { realpathSync } from 'node:fs';
|
|
|
2
2
|
import { dirname, isAbsolute, resolve } from 'node:path';
|
|
3
3
|
import remapping from '@jridgewell/remapping';
|
|
4
4
|
import { canonicalModuleId, cleanModuleId, createOctaneCompiler } from 'octane/compiler/bundler';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
inferRspackEnvironment,
|
|
7
|
+
normalizeLoaderOptions,
|
|
8
|
+
selectLayerCompilerOptions,
|
|
9
|
+
} from './shared.js';
|
|
6
10
|
|
|
7
11
|
function realRoot(path) {
|
|
8
12
|
try {
|
|
@@ -99,14 +103,20 @@ export default function octaneLoader(source, inputSourceMap) {
|
|
|
99
103
|
environment === 'client' &&
|
|
100
104
|
(options.dev ?? (this.mode === undefined || this.mode !== 'production'));
|
|
101
105
|
const profile = environment === 'client' && options.profile === true;
|
|
106
|
+
const compilerOptions =
|
|
107
|
+
options.layerSpecializations === undefined
|
|
108
|
+
? options
|
|
109
|
+
: selectLayerCompilerOptions(options, this._module);
|
|
102
110
|
const compiler = createOctaneCompiler({
|
|
103
111
|
root,
|
|
104
112
|
profile,
|
|
105
113
|
...(options.exclude === undefined ? null : { exclude: options.exclude }),
|
|
106
|
-
...(
|
|
107
|
-
...(options.universalRuntime === undefined
|
|
114
|
+
...(compilerOptions.renderers === undefined
|
|
108
115
|
? null
|
|
109
|
-
: {
|
|
116
|
+
: { renderers: compilerOptions.renderers }),
|
|
117
|
+
...(compilerOptions.universalRuntime === undefined
|
|
118
|
+
? null
|
|
119
|
+
: { universalRuntime: compilerOptions.universalRuntime }),
|
|
110
120
|
...(options.requireDirective === undefined
|
|
111
121
|
? null
|
|
112
122
|
: { requireDirective: options.requireDirective }),
|
package/src/plugin.js
CHANGED
|
@@ -78,6 +78,54 @@ function addProjectRendererAliases(resolveOptions, renderers, root) {
|
|
|
78
78
|
resolveOptions.alias = { ...aliases, ...additions };
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
+
function layerSpecializationCacheIdentity(layerSpecializations) {
|
|
82
|
+
if (layerSpecializations === undefined) return undefined;
|
|
83
|
+
return Object.fromEntries(
|
|
84
|
+
Object.entries(layerSpecializations).map(([layer, specialization]) => [
|
|
85
|
+
layer,
|
|
86
|
+
{
|
|
87
|
+
...(specialization.runtime === undefined ? null : { runtime: specialization.runtime }),
|
|
88
|
+
...(specialization.renderers === undefined
|
|
89
|
+
? null
|
|
90
|
+
: { renderers: specialization.renderers.signature }),
|
|
91
|
+
...(specialization.universalRuntime === undefined
|
|
92
|
+
? null
|
|
93
|
+
: { universalRuntime: specialization.universalRuntime }),
|
|
94
|
+
},
|
|
95
|
+
]),
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function createDiscoveryCompiler(options, root, profile, specialization) {
|
|
100
|
+
const renderers = specialization?.renderers ?? options.renderers;
|
|
101
|
+
const universalRuntime = specialization?.universalRuntime ?? options.universalRuntime;
|
|
102
|
+
return createOctaneCompiler({
|
|
103
|
+
root,
|
|
104
|
+
profile,
|
|
105
|
+
...(options.exclude === undefined ? null : { exclude: options.exclude }),
|
|
106
|
+
...(renderers === undefined ? null : { renderers }),
|
|
107
|
+
...(universalRuntime === undefined ? null : { universalRuntime }),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function discoverAll(compilers) {
|
|
112
|
+
if (compilers.length === 1) return compilers[0].discoverSourceDependencies();
|
|
113
|
+
const packages = new Set();
|
|
114
|
+
const dependencies = new Set();
|
|
115
|
+
const missingDependencies = new Set();
|
|
116
|
+
for (const compiler of compilers) {
|
|
117
|
+
const discovery = compiler.discoverSourceDependencies();
|
|
118
|
+
for (const value of discovery.packages ?? []) packages.add(value);
|
|
119
|
+
for (const value of discovery.dependencies ?? []) dependencies.add(value);
|
|
120
|
+
for (const value of discovery.missingDependencies ?? []) missingDependencies.add(value);
|
|
121
|
+
}
|
|
122
|
+
return {
|
|
123
|
+
packages: [...packages].sort(),
|
|
124
|
+
dependencies: [...dependencies].sort(),
|
|
125
|
+
missingDependencies: [...missingDependencies].sort(),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
81
129
|
function addDependencies(collection, values) {
|
|
82
130
|
if (!collection?.add) return;
|
|
83
131
|
for (const value of values ?? []) collection.add(value);
|
|
@@ -239,21 +287,18 @@ export class OctaneRspackPlugin {
|
|
|
239
287
|
renderers: this.options.renderers?.signature,
|
|
240
288
|
runtime: this.options.runtime,
|
|
241
289
|
universalRuntime: this.options.universalRuntime,
|
|
290
|
+
layerSpecializations: layerSpecializationCacheIdentity(this.options.layerSpecializations),
|
|
242
291
|
// Ownership flips which modules compile vs pass through — cached
|
|
243
292
|
// transform results must not survive a requireDirective toggle.
|
|
244
293
|
requireDirective: this.options.requireDirective === true,
|
|
245
294
|
transpile: this.options.transpile !== false,
|
|
246
295
|
});
|
|
247
296
|
installProfilingDefine(compiler, profile);
|
|
248
|
-
const neutralCompiler =
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
...(this.options.universalRuntime === undefined
|
|
254
|
-
? null
|
|
255
|
-
: { universalRuntime: this.options.universalRuntime }),
|
|
256
|
-
});
|
|
297
|
+
const neutralCompiler = createDiscoveryCompiler(this.options, root, profile);
|
|
298
|
+
const discoveryCompilers = [neutralCompiler];
|
|
299
|
+
for (const specialization of Object.values(this.options.layerSpecializations ?? {})) {
|
|
300
|
+
discoveryCompilers.push(createDiscoveryCompiler(this.options, root, profile, specialization));
|
|
301
|
+
}
|
|
257
302
|
const runtimeRequest =
|
|
258
303
|
this.options.runtime ?? neutralCompiler.resolveRuntimeRequest('octane', environment);
|
|
259
304
|
|
|
@@ -261,6 +306,9 @@ export class OctaneRspackPlugin {
|
|
|
261
306
|
addUniqueExtensions(compiler.options.resolve);
|
|
262
307
|
addRuntimeAlias(compiler.options.resolve, runtimeRequest, root);
|
|
263
308
|
addProjectRendererAliases(compiler.options.resolve, this.options.renderers, root);
|
|
309
|
+
for (const specialization of Object.values(this.options.layerSpecializations ?? {})) {
|
|
310
|
+
addProjectRendererAliases(compiler.options.resolve, specialization.renderers, root);
|
|
311
|
+
}
|
|
264
312
|
|
|
265
313
|
compiler.options.module ??= {};
|
|
266
314
|
compiler.options.module.rules ??= [];
|
|
@@ -275,6 +323,9 @@ export class OctaneRspackPlugin {
|
|
|
275
323
|
...(this.options.universalRuntime === undefined
|
|
276
324
|
? null
|
|
277
325
|
: { universalRuntime: this.options.universalRuntime }),
|
|
326
|
+
...(this.options.layerSpecializations === undefined
|
|
327
|
+
? null
|
|
328
|
+
: { layerSpecializations: this.options.layerSpecializations }),
|
|
278
329
|
...(this.options.requireDirective === undefined
|
|
279
330
|
? null
|
|
280
331
|
: { requireDirective: this.options.requireDirective }),
|
|
@@ -292,21 +343,32 @@ export class OctaneRspackPlugin {
|
|
|
292
343
|
use: [{ loader: 'builtin:swc-loader', options: { detectSyntax: 'auto' } }],
|
|
293
344
|
});
|
|
294
345
|
}
|
|
346
|
+
for (const [layer, specialization] of Object.entries(this.options.layerSpecializations ?? {})) {
|
|
347
|
+
if (specialization.runtime === undefined) continue;
|
|
348
|
+
compiler.options.module.rules.push({
|
|
349
|
+
issuerLayer: layer,
|
|
350
|
+
resolve: {
|
|
351
|
+
alias: {
|
|
352
|
+
octane$: resolveRuntimeModule(specialization.runtime, root),
|
|
353
|
+
},
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
}
|
|
295
357
|
|
|
296
358
|
let discovery;
|
|
297
359
|
const discover = () => {
|
|
298
360
|
if (discovery === undefined) {
|
|
299
|
-
discovery =
|
|
361
|
+
discovery = discoverAll(discoveryCompilers);
|
|
300
362
|
this.sourceDependencies = Object.freeze([...(discovery.packages ?? [])]);
|
|
301
363
|
}
|
|
302
364
|
return discovery;
|
|
303
365
|
};
|
|
304
366
|
compiler.hooks.invalid?.tap(PLUGIN_NAME, (filename) => {
|
|
305
|
-
|
|
367
|
+
for (const current of discoveryCompilers) current.invalidate(filename);
|
|
306
368
|
discovery = undefined;
|
|
307
369
|
});
|
|
308
370
|
compiler.hooks.watchRun?.tap(PLUGIN_NAME, () => {
|
|
309
|
-
|
|
371
|
+
for (const current of discoveryCompilers) current.invalidate();
|
|
310
372
|
discovery = undefined;
|
|
311
373
|
});
|
|
312
374
|
compiler.hooks.thisCompilation?.tap(PLUGIN_NAME, (compilation) => {
|
package/src/shared.js
CHANGED
|
@@ -44,8 +44,19 @@ const LOADER_OPTION_KEYS = new Set([
|
|
|
44
44
|
'renderers',
|
|
45
45
|
'requireDirective',
|
|
46
46
|
'universalRuntime',
|
|
47
|
+
'layerSpecializations',
|
|
47
48
|
]);
|
|
48
49
|
const PLUGIN_OPTION_KEYS = new Set([...LOADER_OPTION_KEYS, 'runtime', 'transpile']);
|
|
50
|
+
const LAYER_SPECIALIZATION_KEYS = new Set(['runtime', 'renderers', 'universalRuntime']);
|
|
51
|
+
|
|
52
|
+
function normalizeRuntimeRequest(value, label = 'runtime') {
|
|
53
|
+
if (value !== undefined && (typeof value !== 'string' || value.trim() !== value || !value)) {
|
|
54
|
+
throw new TypeError(
|
|
55
|
+
`@octanejs/rspack-plugin: \`${label}\` must be a non-empty module request string.`,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
49
60
|
|
|
50
61
|
function normalizeUniversalRuntime(value) {
|
|
51
62
|
if (value === undefined) return undefined;
|
|
@@ -73,6 +84,68 @@ function normalizeUniversalRuntime(value) {
|
|
|
73
84
|
return Object.freeze({ runtime: value.runtime, thread: value.thread });
|
|
74
85
|
}
|
|
75
86
|
|
|
87
|
+
function normalizeLayerSpecializations(value) {
|
|
88
|
+
if (value === undefined) return undefined;
|
|
89
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
90
|
+
throw new TypeError('@octanejs/rspack-plugin: `layerSpecializations` must be an object map.');
|
|
91
|
+
}
|
|
92
|
+
const entries = Object.entries(value).sort(([left], [right]) =>
|
|
93
|
+
left < right ? -1 : left > right ? 1 : 0,
|
|
94
|
+
);
|
|
95
|
+
const normalized = [];
|
|
96
|
+
for (const [layer, specialization] of entries) {
|
|
97
|
+
if (!layer || layer.trim() !== layer) {
|
|
98
|
+
throw new TypeError(
|
|
99
|
+
'@octanejs/rspack-plugin: `layerSpecializations` keys must be non-empty layer names without surrounding whitespace.',
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
if (
|
|
103
|
+
specialization === null ||
|
|
104
|
+
typeof specialization !== 'object' ||
|
|
105
|
+
Array.isArray(specialization)
|
|
106
|
+
) {
|
|
107
|
+
throw new TypeError(
|
|
108
|
+
`@octanejs/rspack-plugin: \`layerSpecializations.${layer}\` must be an object.`,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
for (const key of Object.keys(specialization)) {
|
|
112
|
+
if (!LAYER_SPECIALIZATION_KEYS.has(key)) {
|
|
113
|
+
throw new TypeError(
|
|
114
|
+
`@octanejs/rspack-plugin: unknown \`layerSpecializations.${layer}.${key}\` option.`,
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
const runtime = normalizeRuntimeRequest(
|
|
119
|
+
specialization.runtime,
|
|
120
|
+
`layerSpecializations.${layer}.runtime`,
|
|
121
|
+
);
|
|
122
|
+
const renderers =
|
|
123
|
+
specialization.renderers === undefined
|
|
124
|
+
? undefined
|
|
125
|
+
: normalizeRendererConfig(specialization.renderers);
|
|
126
|
+
const universalRuntime = normalizeUniversalRuntime(specialization.universalRuntime);
|
|
127
|
+
normalized.push([
|
|
128
|
+
layer,
|
|
129
|
+
Object.freeze({
|
|
130
|
+
...(runtime === undefined ? null : { runtime }),
|
|
131
|
+
...(renderers === undefined ? null : { renderers }),
|
|
132
|
+
...(universalRuntime === undefined ? null : { universalRuntime }),
|
|
133
|
+
}),
|
|
134
|
+
]);
|
|
135
|
+
}
|
|
136
|
+
return Object.freeze(Object.fromEntries(normalized));
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** Select the compiler-facing options for a module's Rspack layer. */
|
|
140
|
+
export function selectLayerCompilerOptions(options, module) {
|
|
141
|
+
const layer = typeof module?.layer === 'string' ? module.layer : undefined;
|
|
142
|
+
const specialization = layer === undefined ? undefined : options.layerSpecializations?.[layer];
|
|
143
|
+
return {
|
|
144
|
+
renderers: specialization?.renderers ?? options.renderers,
|
|
145
|
+
universalRuntime: specialization?.universalRuntime ?? options.universalRuntime,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
76
149
|
function assertBooleanOption(options, key) {
|
|
77
150
|
if (options[key] !== undefined && typeof options[key] !== 'boolean') {
|
|
78
151
|
throw new TypeError(`@octanejs/rspack-plugin: \`${key}\` must be a boolean.`);
|
|
@@ -93,17 +166,7 @@ function normalizeOptions(value, plugin) {
|
|
|
93
166
|
if (options.root !== undefined && typeof options.root !== 'string') {
|
|
94
167
|
throw new TypeError('@octanejs/rspack-plugin: `root` must be a path string.');
|
|
95
168
|
}
|
|
96
|
-
if (
|
|
97
|
-
plugin &&
|
|
98
|
-
options.runtime !== undefined &&
|
|
99
|
-
(typeof options.runtime !== 'string' ||
|
|
100
|
-
options.runtime.trim() !== options.runtime ||
|
|
101
|
-
!options.runtime)
|
|
102
|
-
) {
|
|
103
|
-
throw new TypeError(
|
|
104
|
-
'@octanejs/rspack-plugin: `runtime` must be a non-empty module request string.',
|
|
105
|
-
);
|
|
106
|
-
}
|
|
169
|
+
if (plugin) normalizeRuntimeRequest(options.runtime);
|
|
107
170
|
if (
|
|
108
171
|
options.environment !== undefined &&
|
|
109
172
|
options.environment !== 'client' &&
|
|
@@ -125,6 +188,7 @@ function normalizeOptions(value, plugin) {
|
|
|
125
188
|
const renderers =
|
|
126
189
|
options.renderers === undefined ? undefined : normalizeRendererConfig(options.renderers);
|
|
127
190
|
const universalRuntime = normalizeUniversalRuntime(options.universalRuntime);
|
|
191
|
+
const layerSpecializations = normalizeLayerSpecializations(options.layerSpecializations);
|
|
128
192
|
|
|
129
193
|
const normalized = {
|
|
130
194
|
...(options.root === undefined ? null : { root: options.root }),
|
|
@@ -135,6 +199,7 @@ function normalizeOptions(value, plugin) {
|
|
|
135
199
|
...(options.exclude === undefined ? null : { exclude: [...options.exclude] }),
|
|
136
200
|
...(renderers === undefined ? null : { renderers }),
|
|
137
201
|
...(universalRuntime === undefined ? null : { universalRuntime }),
|
|
202
|
+
...(layerSpecializations === undefined ? null : { layerSpecializations }),
|
|
138
203
|
...(options.requireDirective === undefined
|
|
139
204
|
? null
|
|
140
205
|
: { requireDirective: options.requireDirective }),
|
package/types/index.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export type OctaneRendererRegistryEntry =
|
|
|
32
32
|
intrinsics?: string;
|
|
33
33
|
text?: 'reject' | 'ignore' | 'host';
|
|
34
34
|
capabilities?: readonly string[];
|
|
35
|
+
/** Host event prop names or prefix patterns retained as first-screen listener sentinels. */
|
|
36
|
+
firstScreenEvents?: readonly string[];
|
|
35
37
|
validation?: OctaneRendererValidationOptions;
|
|
36
38
|
};
|
|
37
39
|
|
|
@@ -64,6 +66,7 @@ export interface OctaneResolvedRendererConfig {
|
|
|
64
66
|
readonly intrinsics?: string;
|
|
65
67
|
readonly text: 'reject' | 'ignore' | 'host';
|
|
66
68
|
readonly capabilities: readonly string[];
|
|
69
|
+
readonly firstScreenEvents?: readonly string[];
|
|
67
70
|
readonly validation?: Readonly<OctaneRendererValidationOptions>;
|
|
68
71
|
}
|
|
69
72
|
>
|
|
@@ -80,6 +83,24 @@ export interface OctaneResolvedRendererConfig {
|
|
|
80
83
|
readonly signature: string;
|
|
81
84
|
}
|
|
82
85
|
|
|
86
|
+
/** Compile-only host identity attached to a universal renderer graph. */
|
|
87
|
+
export interface OctaneUniversalRuntimeOptions {
|
|
88
|
+
readonly runtime: string;
|
|
89
|
+
readonly thread: 'background' | 'main-thread';
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** Compiler options selected for modules issued from one Rspack layer. */
|
|
93
|
+
export interface OctaneRspackLoaderLayerSpecializationOptions {
|
|
94
|
+
renderers?: OctaneRendererConfigOptions | OctaneResolvedRendererConfig;
|
|
95
|
+
universalRuntime?: OctaneUniversalRuntimeOptions;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Plugin-owned compiler and runtime options selected for one Rspack layer. */
|
|
99
|
+
export interface OctaneRspackLayerSpecializationOptions extends OctaneRspackLoaderLayerSpecializationOptions {
|
|
100
|
+
/** Override exact `octane` imports for modules issued from this layer. */
|
|
101
|
+
runtime?: string;
|
|
102
|
+
}
|
|
103
|
+
|
|
83
104
|
export interface OctaneRspackLoaderOptions {
|
|
84
105
|
/** Project root used to canonicalize module IDs and discover package manifests. */
|
|
85
106
|
root?: string;
|
|
@@ -101,10 +122,13 @@ export interface OctaneRspackLoaderOptions {
|
|
|
101
122
|
/** @experimental Renderer registry and ordered per-file selection rules. */
|
|
102
123
|
renderers?: OctaneRendererConfigOptions | OctaneResolvedRendererConfig;
|
|
103
124
|
/** Compile-only host runtime/thread identity for a universal renderer graph. */
|
|
104
|
-
universalRuntime?:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
125
|
+
universalRuntime?: OctaneUniversalRuntimeOptions;
|
|
126
|
+
/**
|
|
127
|
+
* Compiler options selected by the current module's Rspack layer. Unknown
|
|
128
|
+
* layers retain the top-level compiler options. Runtime aliases remain a
|
|
129
|
+
* class-plugin concern and cannot be configured by the standalone loader.
|
|
130
|
+
*/
|
|
131
|
+
layerSpecializations?: Readonly<Record<string, OctaneRspackLoaderLayerSpecializationOptions>>;
|
|
108
132
|
/**
|
|
109
133
|
* Mixed-toolchain ownership gate: when `true`, a project `.tsrx` is
|
|
110
134
|
* Octane's by extension, and a project `.tsx` (full compile) or plain
|
|
@@ -119,6 +143,11 @@ export interface OctaneRspackLoaderOptions {
|
|
|
119
143
|
}
|
|
120
144
|
|
|
121
145
|
export interface OctaneRspackPluginOptions extends OctaneRspackLoaderOptions {
|
|
146
|
+
/**
|
|
147
|
+
* Compiler and exact-runtime overrides selected by the current module's
|
|
148
|
+
* Rspack layer. Unknown layers retain the top-level plugin options.
|
|
149
|
+
*/
|
|
150
|
+
layerSpecializations?: Readonly<Record<string, OctaneRspackLayerSpecializationOptions>>;
|
|
122
151
|
/**
|
|
123
152
|
* Override the exact module used for plain `octane` imports in this graph.
|
|
124
153
|
* Universal host integrations use this to share one hook/context runtime
|
|
@@ -138,10 +167,7 @@ export interface OctaneRspackBuildInfo {
|
|
|
138
167
|
transformKind: 'compile' | 'slots' | 'client-only-stub';
|
|
139
168
|
serverRpc: boolean;
|
|
140
169
|
/** Universal host runtime/thread identity, when this module was specialized. */
|
|
141
|
-
universalRuntime?:
|
|
142
|
-
readonly runtime: string;
|
|
143
|
-
readonly thread: 'background' | 'main-thread';
|
|
144
|
-
};
|
|
170
|
+
universalRuntime?: OctaneUniversalRuntimeOptions;
|
|
145
171
|
/** Stable identity shared by the client compile and its inert server stub. */
|
|
146
172
|
clientReference?: {
|
|
147
173
|
readonly id: string;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { OctaneRspackLoaderOptions, OctaneRspackPluginOptions } from './index.js';
|
|
2
|
+
|
|
3
|
+
const loaderOptions: OctaneRspackLoaderOptions = {
|
|
4
|
+
layerSpecializations: {
|
|
5
|
+
'native:main': {
|
|
6
|
+
renderers: {
|
|
7
|
+
registry: {
|
|
8
|
+
native: {
|
|
9
|
+
module: '@fixture/native-main-renderer',
|
|
10
|
+
capabilities: ['main-thread-render-only'],
|
|
11
|
+
firstScreenEvents: ['bind*', 'catch*'],
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
default: 'native',
|
|
15
|
+
},
|
|
16
|
+
universalRuntime: { runtime: 'native', thread: 'main-thread' },
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const pluginOptions: OctaneRspackPluginOptions = {
|
|
22
|
+
layerSpecializations: {
|
|
23
|
+
'native:main': {
|
|
24
|
+
runtime: '@fixture/native-main-runtime',
|
|
25
|
+
universalRuntime: { runtime: 'native', thread: 'main-thread' },
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const unsupportedLoaderRuntime: OctaneRspackLoaderOptions = {
|
|
31
|
+
layerSpecializations: {
|
|
32
|
+
'native:main': {
|
|
33
|
+
// @ts-expect-error The standalone loader cannot install an issuer-layer runtime alias.
|
|
34
|
+
runtime: '@fixture/native-main-runtime',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
void loaderOptions;
|
|
40
|
+
void pluginOptions;
|
|
41
|
+
void unsupportedLoaderRuntime;
|