@zikojs/notebook 0.15.0 → 0.15.1
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/LICENSE +21 -21
- package/package.json +1 -1
- package/src/code-editor/index.js +302 -302
- package/src/compiler/evaluate.js +129 -129
- package/src/compiler/imports.js +189 -189
- package/src/compiler/index.js +11 -11
- package/src/compiler/scope.js +94 -94
- package/src/compiler/transform.js +115 -115
- package/src/components/Button/index.css +54 -54
- package/src/components/Button/index.js +4 -4
- package/src/components/CellItem/index.js +180 -180
- package/src/components/ErrorOutput/index.css +9 -9
- package/src/components/ErrorOutput/index.js +1 -1
- package/src/components/Header/index.css +46 -46
- package/src/components/Header/index.js +47 -47
- package/src/components/MarkdownView/index.css +91 -91
- package/src/components/MarkdownView/index.js +134 -134
- package/src/components/icons/index.js +31 -31
- package/src/components/index.css +22 -22
- package/src/components/index.js +3 -3
- package/src/index.css +176 -176
- package/src/index.js +1 -1
- package/src/index.ts +96 -96
- package/src/notebook.js +816 -816
- package/src/store.js +37 -37
package/src/compiler/evaluate.js
CHANGED
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
import { transformImportsAndScope } from "./transform.js";
|
|
2
|
-
import { Console as _Console } from '@zikojs/console/no-css'
|
|
3
|
-
import { tags } from 'ziko/dom'
|
|
4
|
-
const { div } = tags
|
|
5
|
-
|
|
6
|
-
const Console = {
|
|
7
|
-
log : (...args) => div(_Console.log(...args)),
|
|
8
|
-
table : (...args) => div(_Console.table(...args)),
|
|
9
|
-
warn : (...args) => div(_Console.warn(...args)),
|
|
10
|
-
error : (...args) => div(_Console.error(...args))
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export const evaluateCodeAsync = async (
|
|
14
|
-
code,
|
|
15
|
-
TARGET,
|
|
16
|
-
{
|
|
17
|
-
importMap = {},
|
|
18
|
-
plugins = [],
|
|
19
|
-
runtime = null,
|
|
20
|
-
cdnFallback = true,
|
|
21
|
-
} = {},
|
|
22
|
-
scope,
|
|
23
|
-
) => {
|
|
24
|
-
const validScope = scope || Object.create(null);
|
|
25
|
-
const importScope = Object.create(null);
|
|
26
|
-
|
|
27
|
-
validScope.console = Console;
|
|
28
|
-
|
|
29
|
-
const context = {
|
|
30
|
-
TARGET,
|
|
31
|
-
scope: validScope,
|
|
32
|
-
importMap,
|
|
33
|
-
plugins,
|
|
34
|
-
runtime,
|
|
35
|
-
cdnFallback
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const selectedPlugin = plugins.find(
|
|
39
|
-
p => p.name === runtime,
|
|
40
|
-
);
|
|
41
|
-
|
|
42
|
-
// Runtime-specific evaluator
|
|
43
|
-
if (
|
|
44
|
-
selectedPlugin &&
|
|
45
|
-
selectedPlugin.evaluate
|
|
46
|
-
) {
|
|
47
|
-
return await selectedPlugin.evaluate(
|
|
48
|
-
code,
|
|
49
|
-
context,
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let compiledCode = code;
|
|
54
|
-
|
|
55
|
-
for (const plugin of plugins) {
|
|
56
|
-
if (
|
|
57
|
-
selectedPlugin &&
|
|
58
|
-
plugin.name !== runtime
|
|
59
|
-
) {
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (plugin.transform) {
|
|
64
|
-
compiledCode = await plugin.transform(
|
|
65
|
-
compiledCode,
|
|
66
|
-
context,
|
|
67
|
-
);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
compiledCode = await transformImportsAndScope(
|
|
72
|
-
compiledCode,
|
|
73
|
-
{
|
|
74
|
-
importMap,
|
|
75
|
-
plugins,
|
|
76
|
-
cdnFallback,
|
|
77
|
-
importScopeIdentifier: "__imports__",
|
|
78
|
-
},
|
|
79
|
-
);
|
|
80
|
-
// console.log(compiledCode)
|
|
81
|
-
|
|
82
|
-
const runCell = new Function(
|
|
83
|
-
"TARGET",
|
|
84
|
-
"__scope__",
|
|
85
|
-
"__imports__",
|
|
86
|
-
`
|
|
87
|
-
// Bind the active TARGET for this cell evaluation
|
|
88
|
-
if (typeof __Ziko__ !== "undefined" && __Ziko__.__Config__) {
|
|
89
|
-
__Ziko__.__Config__.default.target = TARGET;
|
|
90
|
-
__Ziko__.__Config__.default.autoMount = true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
return (async () => {
|
|
96
|
-
with (__scope__) {
|
|
97
|
-
return await (async () => {
|
|
98
|
-
with (__imports__) {
|
|
99
|
-
${compiledCode}
|
|
100
|
-
}
|
|
101
|
-
})();
|
|
102
|
-
}
|
|
103
|
-
})();
|
|
104
|
-
`,
|
|
105
|
-
);
|
|
106
|
-
|
|
107
|
-
let result = await runCell(
|
|
108
|
-
TARGET,
|
|
109
|
-
validScope,
|
|
110
|
-
importScope,
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
for (const plugin of plugins) {
|
|
114
|
-
if (
|
|
115
|
-
selectedPlugin &&
|
|
116
|
-
plugin.name !== runtime
|
|
117
|
-
) {
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
if (plugin.afterEvaluate) {
|
|
122
|
-
result = await plugin.afterEvaluate(
|
|
123
|
-
result,
|
|
124
|
-
context,
|
|
125
|
-
);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
return result;
|
|
1
|
+
import { transformImportsAndScope } from "./transform.js";
|
|
2
|
+
import { Console as _Console } from '@zikojs/console/no-css'
|
|
3
|
+
import { tags } from 'ziko/dom'
|
|
4
|
+
const { div } = tags
|
|
5
|
+
|
|
6
|
+
const Console = {
|
|
7
|
+
log : (...args) => div(_Console.log(...args)),
|
|
8
|
+
table : (...args) => div(_Console.table(...args)),
|
|
9
|
+
warn : (...args) => div(_Console.warn(...args)),
|
|
10
|
+
error : (...args) => div(_Console.error(...args))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const evaluateCodeAsync = async (
|
|
14
|
+
code,
|
|
15
|
+
TARGET,
|
|
16
|
+
{
|
|
17
|
+
importMap = {},
|
|
18
|
+
plugins = [],
|
|
19
|
+
runtime = null,
|
|
20
|
+
cdnFallback = true,
|
|
21
|
+
} = {},
|
|
22
|
+
scope,
|
|
23
|
+
) => {
|
|
24
|
+
const validScope = scope || Object.create(null);
|
|
25
|
+
const importScope = Object.create(null);
|
|
26
|
+
|
|
27
|
+
validScope.console = Console;
|
|
28
|
+
|
|
29
|
+
const context = {
|
|
30
|
+
TARGET,
|
|
31
|
+
scope: validScope,
|
|
32
|
+
importMap,
|
|
33
|
+
plugins,
|
|
34
|
+
runtime,
|
|
35
|
+
cdnFallback
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const selectedPlugin = plugins.find(
|
|
39
|
+
p => p.name === runtime,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
// Runtime-specific evaluator
|
|
43
|
+
if (
|
|
44
|
+
selectedPlugin &&
|
|
45
|
+
selectedPlugin.evaluate
|
|
46
|
+
) {
|
|
47
|
+
return await selectedPlugin.evaluate(
|
|
48
|
+
code,
|
|
49
|
+
context,
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let compiledCode = code;
|
|
54
|
+
|
|
55
|
+
for (const plugin of plugins) {
|
|
56
|
+
if (
|
|
57
|
+
selectedPlugin &&
|
|
58
|
+
plugin.name !== runtime
|
|
59
|
+
) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (plugin.transform) {
|
|
64
|
+
compiledCode = await plugin.transform(
|
|
65
|
+
compiledCode,
|
|
66
|
+
context,
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
compiledCode = await transformImportsAndScope(
|
|
72
|
+
compiledCode,
|
|
73
|
+
{
|
|
74
|
+
importMap,
|
|
75
|
+
plugins,
|
|
76
|
+
cdnFallback,
|
|
77
|
+
importScopeIdentifier: "__imports__",
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
// console.log(compiledCode)
|
|
81
|
+
|
|
82
|
+
const runCell = new Function(
|
|
83
|
+
"TARGET",
|
|
84
|
+
"__scope__",
|
|
85
|
+
"__imports__",
|
|
86
|
+
`
|
|
87
|
+
// Bind the active TARGET for this cell evaluation
|
|
88
|
+
if (typeof __Ziko__ !== "undefined" && __Ziko__.__Config__) {
|
|
89
|
+
__Ziko__.__Config__.default.target = TARGET;
|
|
90
|
+
__Ziko__.__Config__.default.autoMount = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
return (async () => {
|
|
96
|
+
with (__scope__) {
|
|
97
|
+
return await (async () => {
|
|
98
|
+
with (__imports__) {
|
|
99
|
+
${compiledCode}
|
|
100
|
+
}
|
|
101
|
+
})();
|
|
102
|
+
}
|
|
103
|
+
})();
|
|
104
|
+
`,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
let result = await runCell(
|
|
108
|
+
TARGET,
|
|
109
|
+
validScope,
|
|
110
|
+
importScope,
|
|
111
|
+
);
|
|
112
|
+
|
|
113
|
+
for (const plugin of plugins) {
|
|
114
|
+
if (
|
|
115
|
+
selectedPlugin &&
|
|
116
|
+
plugin.name !== runtime
|
|
117
|
+
) {
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (plugin.afterEvaluate) {
|
|
122
|
+
result = await plugin.afterEvaluate(
|
|
123
|
+
result,
|
|
124
|
+
context,
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return result;
|
|
130
130
|
};
|
package/src/compiler/imports.js
CHANGED
|
@@ -1,190 +1,190 @@
|
|
|
1
|
-
|
|
2
|
-
const CDN = "https://esm.sh/";
|
|
3
|
-
const MANIFEST_FILE = "ziko-notebook-imports.json";
|
|
4
|
-
const isProductionBuild =
|
|
5
|
-
typeof import.meta.env !== "undefined" && import.meta.env.PROD;
|
|
6
|
-
|
|
7
|
-
let buildImportMapPromise;
|
|
8
|
-
|
|
9
|
-
const loadBuildImportMap = () => {
|
|
10
|
-
if (!isProductionBuild || typeof document === "undefined") {
|
|
11
|
-
return Promise.resolve({});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
if (!buildImportMapPromise) {
|
|
15
|
-
const manifestUrl = new URL(MANIFEST_FILE, document.baseURI);
|
|
16
|
-
|
|
17
|
-
buildImportMapPromise = fetch(manifestUrl).then(async (response) => {
|
|
18
|
-
if (response.status === 404) {
|
|
19
|
-
return {};
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if (!response.ok) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
`Failed to load the notebook import map: ${response.status} ${response.statusText}`,
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const imports = await response.json();
|
|
29
|
-
|
|
30
|
-
if (!imports || typeof imports !== "object" || Array.isArray(imports)) {
|
|
31
|
-
throw new TypeError("The notebook import map must be a JSON object.");
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return imports;
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
return buildImportMapPromise;
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const isURL = (source) =>
|
|
42
|
-
/^(?:https?:\/\/|data:|blob:)/i.test(source);
|
|
43
|
-
|
|
44
|
-
const isBareSpecifier = (source) =>
|
|
45
|
-
!source.startsWith(".") &&
|
|
46
|
-
!source.startsWith("/") &&
|
|
47
|
-
!source.startsWith("#") &&
|
|
48
|
-
!isURL(source);
|
|
49
|
-
|
|
50
|
-
export const resolveImport = async (
|
|
51
|
-
source,
|
|
52
|
-
{
|
|
53
|
-
importMap = {},
|
|
54
|
-
plugins = [],
|
|
55
|
-
resolverEndpoint = "/__notebook_resolve",
|
|
56
|
-
cdnFallback = true,
|
|
57
|
-
} = {},
|
|
58
|
-
) => {
|
|
59
|
-
// Preserve explicit mappings, including package subpaths.
|
|
60
|
-
if (importMap[source]) {
|
|
61
|
-
return importMap[source];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (!isBareSpecifier(source)) {
|
|
65
|
-
return source;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Preserve runtime-specific and custom resolution hooks.
|
|
69
|
-
for (const plugin of plugins) {
|
|
70
|
-
if (typeof plugin.resolveImport !== "function") {
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
const resolved = await plugin.resolveImport(source);
|
|
75
|
-
|
|
76
|
-
if (typeof resolved === "string" && resolved) {
|
|
77
|
-
return resolved;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
const buildImportMap = await loadBuildImportMap();
|
|
82
|
-
|
|
83
|
-
if (typeof buildImportMap[source] === "string") {
|
|
84
|
-
return buildImportMap[source];
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// Ask the host dev server to resolve installed packages.
|
|
88
|
-
try {
|
|
89
|
-
const params = new URLSearchParams({
|
|
90
|
-
specifier: source,
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
const response = await fetch(
|
|
94
|
-
`${resolverEndpoint}?${params.toString()}`,
|
|
95
|
-
);
|
|
96
|
-
|
|
97
|
-
if (response.ok) {
|
|
98
|
-
const result = await response.json();
|
|
99
|
-
|
|
100
|
-
if (typeof result.url === "string" && result.url) {
|
|
101
|
-
return result.url;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
} catch {
|
|
105
|
-
// The Vite endpoint may not be available outside development.
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (cdnFallback) {
|
|
109
|
-
return `${CDN}${source}`;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
throw new Error(
|
|
113
|
-
`Cannot resolve "${source}" locally. ` +
|
|
114
|
-
`Install the package or provide an importMap entry. ` +
|
|
115
|
-
`CDN fallback is disabled.`,
|
|
116
|
-
);
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// Keep your existing rewriteImportNode implementation below.
|
|
120
|
-
|
|
121
|
-
export const rewriteImportNode = async (
|
|
122
|
-
node,
|
|
123
|
-
code,
|
|
124
|
-
context,
|
|
125
|
-
) => {
|
|
126
|
-
const source = await resolveImport(
|
|
127
|
-
node.source.value,
|
|
128
|
-
context,
|
|
129
|
-
);
|
|
130
|
-
const importScope =
|
|
131
|
-
context.importScopeIdentifier || "__scope__";
|
|
132
|
-
|
|
133
|
-
// Safely quote the URL in generated JavaScript.
|
|
134
|
-
const url = JSON.stringify(source);
|
|
135
|
-
|
|
136
|
-
if (node.specifiers.length === 0) {
|
|
137
|
-
return `await import(${url});`;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
let defaultImportName = null;
|
|
141
|
-
let namespaceId = null;
|
|
142
|
-
const namedImports = [];
|
|
143
|
-
|
|
144
|
-
for (const spec of node.specifiers) {
|
|
145
|
-
if (spec.type === "ImportNamespaceSpecifier") {
|
|
146
|
-
namespaceId = spec.local.name;
|
|
147
|
-
} else if (spec.type === "ImportDefaultSpecifier") {
|
|
148
|
-
defaultImportName = spec.local.name;
|
|
149
|
-
} else if (spec.type === "ImportSpecifier") {
|
|
150
|
-
namedImports.push({
|
|
151
|
-
imported:
|
|
152
|
-
spec.imported.name ?? spec.imported.value,
|
|
153
|
-
local: spec.local.name,
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
if (namespaceId) {
|
|
159
|
-
return (
|
|
160
|
-
`${importScope}.${namespaceId} = ` +
|
|
161
|
-
`await import(${url});`
|
|
162
|
-
);
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const tmp = `__mod_${node.start}`;
|
|
166
|
-
|
|
167
|
-
const lines = [
|
|
168
|
-
`const ${tmp} = await import(${url});`,
|
|
169
|
-
];
|
|
170
|
-
|
|
171
|
-
if (defaultImportName) {
|
|
172
|
-
lines.push(
|
|
173
|
-
`${importScope}.${defaultImportName} = ` +
|
|
174
|
-
`${tmp}.default ?? ${tmp};`,
|
|
175
|
-
);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
for (const { imported, local } of namedImports) {
|
|
179
|
-
lines.push(
|
|
180
|
-
`${importScope}.${local} = ` +
|
|
181
|
-
`${tmp}[${JSON.stringify(imported)}] !== undefined ` +
|
|
182
|
-
`? ${tmp}[${JSON.stringify(imported)}] ` +
|
|
183
|
-
`: (${tmp}.default?.[${JSON.stringify(imported)}] !== undefined ` +
|
|
184
|
-
`? ${tmp}.default[${JSON.stringify(imported)}] ` +
|
|
185
|
-
`: (${tmp}.default ?? ${tmp}));`,
|
|
186
|
-
);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return lines.join("\n");
|
|
1
|
+
|
|
2
|
+
const CDN = "https://esm.sh/";
|
|
3
|
+
const MANIFEST_FILE = "ziko-notebook-imports.json";
|
|
4
|
+
const isProductionBuild =
|
|
5
|
+
typeof import.meta.env !== "undefined" && import.meta.env.PROD;
|
|
6
|
+
|
|
7
|
+
let buildImportMapPromise;
|
|
8
|
+
|
|
9
|
+
const loadBuildImportMap = () => {
|
|
10
|
+
if (!isProductionBuild || typeof document === "undefined") {
|
|
11
|
+
return Promise.resolve({});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!buildImportMapPromise) {
|
|
15
|
+
const manifestUrl = new URL(MANIFEST_FILE, document.baseURI);
|
|
16
|
+
|
|
17
|
+
buildImportMapPromise = fetch(manifestUrl).then(async (response) => {
|
|
18
|
+
if (response.status === 404) {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(
|
|
24
|
+
`Failed to load the notebook import map: ${response.status} ${response.statusText}`,
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const imports = await response.json();
|
|
29
|
+
|
|
30
|
+
if (!imports || typeof imports !== "object" || Array.isArray(imports)) {
|
|
31
|
+
throw new TypeError("The notebook import map must be a JSON object.");
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return imports;
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return buildImportMapPromise;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const isURL = (source) =>
|
|
42
|
+
/^(?:https?:\/\/|data:|blob:)/i.test(source);
|
|
43
|
+
|
|
44
|
+
const isBareSpecifier = (source) =>
|
|
45
|
+
!source.startsWith(".") &&
|
|
46
|
+
!source.startsWith("/") &&
|
|
47
|
+
!source.startsWith("#") &&
|
|
48
|
+
!isURL(source);
|
|
49
|
+
|
|
50
|
+
export const resolveImport = async (
|
|
51
|
+
source,
|
|
52
|
+
{
|
|
53
|
+
importMap = {},
|
|
54
|
+
plugins = [],
|
|
55
|
+
resolverEndpoint = "/__notebook_resolve",
|
|
56
|
+
cdnFallback = true,
|
|
57
|
+
} = {},
|
|
58
|
+
) => {
|
|
59
|
+
// Preserve explicit mappings, including package subpaths.
|
|
60
|
+
if (importMap[source]) {
|
|
61
|
+
return importMap[source];
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!isBareSpecifier(source)) {
|
|
65
|
+
return source;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Preserve runtime-specific and custom resolution hooks.
|
|
69
|
+
for (const plugin of plugins) {
|
|
70
|
+
if (typeof plugin.resolveImport !== "function") {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const resolved = await plugin.resolveImport(source);
|
|
75
|
+
|
|
76
|
+
if (typeof resolved === "string" && resolved) {
|
|
77
|
+
return resolved;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const buildImportMap = await loadBuildImportMap();
|
|
82
|
+
|
|
83
|
+
if (typeof buildImportMap[source] === "string") {
|
|
84
|
+
return buildImportMap[source];
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Ask the host dev server to resolve installed packages.
|
|
88
|
+
try {
|
|
89
|
+
const params = new URLSearchParams({
|
|
90
|
+
specifier: source,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
const response = await fetch(
|
|
94
|
+
`${resolverEndpoint}?${params.toString()}`,
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
if (response.ok) {
|
|
98
|
+
const result = await response.json();
|
|
99
|
+
|
|
100
|
+
if (typeof result.url === "string" && result.url) {
|
|
101
|
+
return result.url;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
} catch {
|
|
105
|
+
// The Vite endpoint may not be available outside development.
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (cdnFallback) {
|
|
109
|
+
return `${CDN}${source}`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
throw new Error(
|
|
113
|
+
`Cannot resolve "${source}" locally. ` +
|
|
114
|
+
`Install the package or provide an importMap entry. ` +
|
|
115
|
+
`CDN fallback is disabled.`,
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// Keep your existing rewriteImportNode implementation below.
|
|
120
|
+
|
|
121
|
+
export const rewriteImportNode = async (
|
|
122
|
+
node,
|
|
123
|
+
code,
|
|
124
|
+
context,
|
|
125
|
+
) => {
|
|
126
|
+
const source = await resolveImport(
|
|
127
|
+
node.source.value,
|
|
128
|
+
context,
|
|
129
|
+
);
|
|
130
|
+
const importScope =
|
|
131
|
+
context.importScopeIdentifier || "__scope__";
|
|
132
|
+
|
|
133
|
+
// Safely quote the URL in generated JavaScript.
|
|
134
|
+
const url = JSON.stringify(source);
|
|
135
|
+
|
|
136
|
+
if (node.specifiers.length === 0) {
|
|
137
|
+
return `await import(${url});`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
let defaultImportName = null;
|
|
141
|
+
let namespaceId = null;
|
|
142
|
+
const namedImports = [];
|
|
143
|
+
|
|
144
|
+
for (const spec of node.specifiers) {
|
|
145
|
+
if (spec.type === "ImportNamespaceSpecifier") {
|
|
146
|
+
namespaceId = spec.local.name;
|
|
147
|
+
} else if (spec.type === "ImportDefaultSpecifier") {
|
|
148
|
+
defaultImportName = spec.local.name;
|
|
149
|
+
} else if (spec.type === "ImportSpecifier") {
|
|
150
|
+
namedImports.push({
|
|
151
|
+
imported:
|
|
152
|
+
spec.imported.name ?? spec.imported.value,
|
|
153
|
+
local: spec.local.name,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (namespaceId) {
|
|
159
|
+
return (
|
|
160
|
+
`${importScope}.${namespaceId} = ` +
|
|
161
|
+
`await import(${url});`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const tmp = `__mod_${node.start}`;
|
|
166
|
+
|
|
167
|
+
const lines = [
|
|
168
|
+
`const ${tmp} = await import(${url});`,
|
|
169
|
+
];
|
|
170
|
+
|
|
171
|
+
if (defaultImportName) {
|
|
172
|
+
lines.push(
|
|
173
|
+
`${importScope}.${defaultImportName} = ` +
|
|
174
|
+
`${tmp}.default ?? ${tmp};`,
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const { imported, local } of namedImports) {
|
|
179
|
+
lines.push(
|
|
180
|
+
`${importScope}.${local} = ` +
|
|
181
|
+
`${tmp}[${JSON.stringify(imported)}] !== undefined ` +
|
|
182
|
+
`? ${tmp}[${JSON.stringify(imported)}] ` +
|
|
183
|
+
`: (${tmp}.default?.[${JSON.stringify(imported)}] !== undefined ` +
|
|
184
|
+
`? ${tmp}.default[${JSON.stringify(imported)}] ` +
|
|
185
|
+
`: (${tmp}.default ?? ${tmp}));`,
|
|
186
|
+
);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return lines.join("\n");
|
|
190
190
|
};
|
package/src/compiler/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export {
|
|
2
|
-
evaluateCodeAsync,
|
|
3
|
-
} from "./evaluate.js";
|
|
4
|
-
|
|
5
|
-
export {
|
|
6
|
-
transformImportsAndScope,
|
|
7
|
-
} from "./transform.js";
|
|
8
|
-
|
|
9
|
-
export {
|
|
10
|
-
resolveImport,
|
|
11
|
-
rewriteImportNode,
|
|
1
|
+
export {
|
|
2
|
+
evaluateCodeAsync,
|
|
3
|
+
} from "./evaluate.js";
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
transformImportsAndScope,
|
|
7
|
+
} from "./transform.js";
|
|
8
|
+
|
|
9
|
+
export {
|
|
10
|
+
resolveImport,
|
|
11
|
+
rewriteImportNode,
|
|
12
12
|
} from "./imports.js";
|