Skip to content

Commit 503a34a

Browse files
committed
feat: add ?legacy feature
1 parent 4ca0f52 commit 503a34a

File tree

8 files changed

+51
-5
lines changed

8 files changed

+51
-5
lines changed

packages/instrument-bundler/src/build.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function parseBuildResult(result: BuildResult): BuildOutput {
2828
`Unexpected number of exports in output file: expected '0', found '${exportsCount}'`
2929
);
3030
}
31-
return { css: cssOutput?.text, js: jsOutput.text };
31+
return { css: cssOutput?.text, js: jsOutput.text, legacyScripts: result.legacyScripts };
3232
}
3333

3434
export async function build({ inputs }: { inputs: BundlerInput[] }): Promise<BuildOutput> {

packages/instrument-bundler/src/bundle.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@ const GLOBALS = `
4242
*/
4343
export async function createBundle(output: BuildOutput, options: { minify: boolean }) {
4444
let inject = '';
45-
if (output.css) {
46-
inject = `Object.defineProperty(__exports.content, '__injectHead', { value: Object.freeze({ style: "${btoa(output.css)}" }), writable: false });`;
45+
const style = output.css ? `"${btoa(output.css)}"` : undefined;
46+
const scripts = output.legacyScripts
47+
? `[${output.legacyScripts.map((content) => `"${btoa(content)}"`).join(', ')}]`
48+
: undefined;
49+
if (style || scripts) {
50+
inject = `Object.defineProperty(__exports.content, '__injectHead', { value: Object.freeze({ scripts: ${scripts}, style: ${style} }), writable: false });`;
4751
}
4852
const bundle = `(async () => {
4953
${GLOBALS}

packages/instrument-bundler/src/plugin.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export const plugin = (options: { inputs: BundlerInput[] }): Plugin => {
99
name: 'instrument-bundler-plugin',
1010
setup(build) {
1111
const namespaces = { bundle: 'bundle' };
12+
const legacyScripts: string[] = [];
1213
build.onResolve({ filter: /.*/ }, (args) => {
1314
// css @import statement
1415
if (args.kind === 'import-rule') {
@@ -43,6 +44,21 @@ export const plugin = (options: { inputs: BundlerInput[] }): Plugin => {
4344
}
4445
return { contents: input?.content, loader: 'text' };
4546
});
47+
build.onLoad({ filter: /.+\?legacy$/, namespace: namespaces.bundle }, (args) => {
48+
const input = resolveInput(/(.+)\?legacy$/.exec(args.path)![1]!, options.inputs);
49+
if (!input) {
50+
return {
51+
errors: [
52+
{
53+
location: { file: args.path },
54+
text: `Failed to resolve '${args.path}' from input filenames: ${options.inputs.map((file) => `'${file.name}'`).join(', ')}`
55+
}
56+
]
57+
};
58+
}
59+
legacyScripts.push(input.content as string);
60+
return { contents: input.content, loader: 'empty' };
61+
});
4662
build.onLoad({ filter: /^\/runtime\/v1\/.*.css$/, namespace: namespaces.bundle }, (args) => {
4763
return { contents: `@import "${args.path}";`, loader: 'css' };
4864
});
@@ -67,6 +83,9 @@ export const plugin = (options: { inputs: BundlerInput[] }): Plugin => {
6783
}
6884
return { contents, loader };
6985
});
86+
build.onEnd((result) => {
87+
result.legacyScripts = legacyScripts;
88+
});
7089
}
7190
};
7291
};

packages/instrument-bundler/src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,5 @@ export type BundlerInputFileExtension =
1717
export type BuildOutput = {
1818
css?: string;
1919
js: string;
20+
legacyScripts?: string[];
2021
};

packages/instrument-bundler/src/vendor/esbuild.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
/* eslint-disable no-var */
22

3+
declare module 'esbuild' {
4+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/consistent-type-definitions
5+
export interface BuildResult<ProvidedOptions extends BuildOptions = BuildOptions> {
6+
legacyScripts?: string[];
7+
}
8+
}
9+
10+
declare module 'esbuild-wasm' {
11+
// eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/consistent-type-definitions
12+
export interface BuildResult<ProvidedOptions extends BuildOptions = BuildOptions> {
13+
legacyScripts?: string[];
14+
}
15+
}
16+
317
if (typeof window === 'undefined') {
418
var { build, transform } = await import('esbuild');
519
} else {

packages/runtime-core/src/types/instrument.interactive.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ declare type InteractiveInstrument<
2020
content: {
2121
/** attributes to inject in the iframe head */
2222
readonly __injectHead?: {
23+
/** an array of base64 encoded legacy scripts */
24+
readonly scripts?: readonly string[];
2325
/** base64 encoded css */
24-
readonly style: string;
26+
readonly style?: string;
2527
};
2628
render: (done: (data: TData) => void) => Promisable<void>;
2729
};

packages/schemas/src/instrument/instrument.interactive.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ const $InteractiveInstrument = $ScalarInstrument.extend({
88
content: z.object({
99
__injectHead: z
1010
.object({
11-
style: z.string().readonly()
11+
scripts: z.array(z.string().readonly()).readonly().optional(),
12+
style: z.string().readonly().optional()
1213
})
1314
.optional()
1415
.readonly(),

runtime/v1/env.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,8 @@ declare module '*?raw' {
4949
const src: string;
5050
export default src;
5151
}
52+
53+
declare module '*?legacy' {
54+
const src: void;
55+
export default src;
56+
}

0 commit comments

Comments
 (0)