Skip to content

Commit 1a96a48

Browse files
Merge pull request #134 from gridaco/staging
APR Release #1
2 parents a0dd9fd + 6155b95 commit 1a96a48

File tree

102 files changed

+4940
-3370
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

102 files changed

+4940
-3370
lines changed

editor-packages/editor-canvas/canvas-event-target/canvas-event-target.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ export function CanvasEventTarget({
194194
overflow: "hidden",
195195
touchAction: "none",
196196
cursor: isSpacebarPressed ? "grab" : "default",
197+
userSelect: "none",
198+
WebkitUserSelect: "none",
197199
}}
198200
id="gesture-event-listener"
199201
ref={interactionEventTargetRef}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"name": "@code-editor/dart-services",
3+
"description": "dart build services for flutter framework",
4+
"version": "0.0.0",
5+
"private": false
6+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# About esbuild-wasm version.
2+
3+
The wasm file downloaded over network must match the locally installed esbuild-wasm package, so always use exact version. (not ^v, ^v0.0.0, etc.)
4+
5+
currently using `0.14.34`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.out.js
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
import { OnLoadResult, PluginBuild } from "esbuild-wasm";
2+
import axios from "axios";
3+
import localforage from "localforage";
4+
import { normalizeCss } from ".";
5+
6+
const fileCache = localforage.createInstance({
7+
name: "filecache",
8+
});
9+
10+
export const fetchPlugin = (
11+
inputCode: string,
12+
lang: OnLoadResult["loader"]
13+
) => ({
14+
name: "fetch-plugin",
15+
16+
setup(build: PluginBuild) {
17+
build.onLoad({ filter: /^index\.js$/ }, () => {
18+
return {
19+
loader: lang,
20+
contents: inputCode,
21+
};
22+
});
23+
24+
build.onLoad({ filter: /.*/ }, async (args: any) => {
25+
/**
26+
* Check if module is already in filecache
27+
* if yes? return it immediately
28+
*
29+
* if not, fetch it from unpkg and cache it
30+
* and return the result
31+
*/
32+
const cachedResult = await fileCache.getItem<OnLoadResult>(args.path);
33+
34+
if (cachedResult) {
35+
return cachedResult;
36+
}
37+
38+
return null;
39+
});
40+
41+
build.onLoad({ filter: /.css$/ }, async (args: any) => {
42+
const { data, request } = await axios.get(args.path);
43+
44+
const contents = normalizeCss(data);
45+
46+
const result: OnLoadResult = {
47+
loader: "jsx",
48+
contents,
49+
resolveDir: new URL("./", request.responseURL).pathname,
50+
};
51+
52+
await fileCache.setItem(args.path, result);
53+
54+
return result;
55+
});
56+
57+
build.onLoad({ filter: /.*/ }, async (args: any) => {
58+
const { data, request } = await axios.get(args.path);
59+
60+
const result: OnLoadResult = {
61+
loader: "jsx",
62+
contents: data,
63+
resolveDir: new URL("./", request.responseURL).pathname,
64+
};
65+
66+
await fileCache.setItem(args.path, result);
67+
68+
return result;
69+
});
70+
},
71+
});
72+
73+
// const libSource = ReactTypes.toString()
74+
75+
// const libUri = "ts:filename/facts.d.ts";
76+
// monaco.languages.typescript.javascriptDefaults.addExtraLib(libSource, libUri);
77+
78+
// monaco.editor.createModel(libSource, "typescript", monaco.Uri.parse(libUri));
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
import { Monaco } from "@monaco-editor/react";
2+
import { nanoid } from "nanoid";
3+
import { build, initialize, Loader } from "esbuild-wasm";
4+
import { fetchPlugin } from "./fetch.plugin";
5+
import { unpkgPathPlugin } from "./unpkg-path.plugin";
6+
7+
declare const window: {
8+
monaco: Monaco;
9+
};
10+
11+
let serviceLoaded: boolean | null = null;
12+
13+
const bundler = async (rawCode: string, lang: Loader) => {
14+
if (!serviceLoaded) {
15+
await initialize({
16+
wasmURL: "https://unpkg.com/[email protected]/esbuild.wasm",
17+
worker: true,
18+
});
19+
console.log("esbuild-wasm initialized");
20+
serviceLoaded = true;
21+
}
22+
23+
try {
24+
const result = await build({
25+
entryPoints: ["index.js"],
26+
bundle: true,
27+
write: false,
28+
metafile: true,
29+
legalComments: "none",
30+
plugins: [unpkgPathPlugin(), fetchPlugin(rawCode, lang)],
31+
define: {
32+
"process.env.NODE_ENV": `"production"`,
33+
global: "window",
34+
},
35+
});
36+
37+
const imports = result.metafile?.inputs["a:index.js"].imports
38+
.map((el) => el.path.replace("a:https://unpkg.com/", ""))
39+
.filter((e) => !e.includes("/"));
40+
41+
loadTypes(imports);
42+
43+
// console.log("esbuild result: ", result);
44+
45+
return { code: result.outputFiles[0].text, err: null };
46+
} catch (error: any) {
47+
console.error("esbuild error: ", error);
48+
return {
49+
code: null,
50+
err: { method: "error", data: [error.message], id: nanoid() },
51+
};
52+
}
53+
};
54+
55+
export const normalizeCss = (data: string) => {
56+
/**
57+
* Function to remove any new lines, quotes from imported css packages.
58+
*/
59+
const escaped = data
60+
.replace(/\n/g, "")
61+
.replace(/"/g, '\\"')
62+
.replace(/'/g, "\\'");
63+
return `const style = document.createElement('style')
64+
style.innerText = '${escaped}';
65+
document.head.appendChild(style)`;
66+
};
67+
68+
export default bundler;
69+
70+
let typesWorker;
71+
72+
const loadTypes = (types) => {
73+
const disposables: any = [];
74+
const monaco = window && window.monaco;
75+
76+
const dependencies = types.map((e) => ({ name: e, version: "latest" })) || [];
77+
78+
if (!typesWorker) {
79+
typesWorker = new Worker(
80+
new URL("./workers/fetch-types.worker.js", import.meta.url)
81+
);
82+
}
83+
84+
dependencies.forEach((dep) => {
85+
typesWorker.postMessage({
86+
name: dep.name,
87+
version: dep.version,
88+
});
89+
});
90+
91+
typesWorker.addEventListener("message", (event) => {
92+
// name,
93+
// version,
94+
// typings: result,
95+
const key = `node_modules/${event.data.name}/index.d.ts`;
96+
const source = event.data.typings[key];
97+
98+
// const path = `${MONACO_LIB_PREFIX}${event.data.name}`;
99+
const libUri = `file:///node_modules/@types/${event.data.name}/index.d.ts`;
100+
101+
disposables.push(
102+
monaco.languages.typescript.javascriptDefaults.addExtraLib(source, libUri)
103+
);
104+
disposables.push(
105+
monaco.languages.typescript.typescriptDefaults.addExtraLib(source, libUri)
106+
);
107+
108+
// When resolving definitions and references, the editor will try to use created models.
109+
// Creating a model for the library allows "peek definition/references" commands to work with the library.
110+
});
111+
112+
return {
113+
dispose() {
114+
disposables.forEach((d) => d.dispose());
115+
if (typesWorker) {
116+
typesWorker.terminate();
117+
}
118+
},
119+
};
120+
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "@code-editor/esbuild-services",
3+
"version": "0.0.0",
4+
"private": false,
5+
"dependencies": {
6+
"esbuild-wasm": "0.14.34",
7+
"localforage": "^1.10.0"
8+
},
9+
"peerDependencies": {
10+
"@monaco-editor/react": "^4.4.1",
11+
"axios": "^0.26.1",
12+
"nanoid": "^3.3.2"
13+
}
14+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { PluginBuild } from "esbuild-wasm";
2+
3+
const unpkg_path = "https://unpkg.com";
4+
5+
export const unpkgPathPlugin = () => ({
6+
name: "unpkg-path-plugin",
7+
setup(build: PluginBuild) {
8+
/**
9+
* Resolve the entry file eg. `index.js`
10+
*/
11+
build.onResolve({ filter: /^index\.js$/ }, (args: any) => {
12+
return { path: args.path, namespace: "a" };
13+
});
14+
15+
/**
16+
* Resolve relative modules imports
17+
*/
18+
build.onResolve({ filter: /^\.+\// }, (args: any) => {
19+
const url = new URL(args.path, unpkg_path + args.resolveDir + "/").href;
20+
return {
21+
namespace: "a",
22+
path: url,
23+
};
24+
});
25+
26+
/**
27+
* Resolve main module files
28+
*/
29+
build.onResolve({ filter: /.*/ }, async (args: any) => {
30+
return {
31+
namespace: "a",
32+
path: new URL(args.path, unpkg_path + "/").href,
33+
};
34+
});
35+
},
36+
});

0 commit comments

Comments
 (0)