Skip to content

Commit 9df315b

Browse files
acaosaihaj
andauthored
feat: monaco variables json, improved schema & worker loading & monaco api (#1997)
Co-authored-by: Saihajpreet Singh <[email protected]>
1 parent 9b72af5 commit 9df315b

Some content is hidden

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

45 files changed

+2498
-880
lines changed
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
'graphql-language-service-utils': minor
3+
'graphql-language-service': major
4+
'monaco-graphql': major
5+
---
6+
7+
This introduces some big changes to `monaco-graphql`, and some exciting features, including multi-model support, multi-schema support, and variables json language feature support 🎉.
8+
9+
see [the readme](https://github.com/graphql/graphiql/tree/main/packages/monaco-graphql#monaco-graphql) to learn how to configure and use the new interface.
10+
11+
## 🚨 BREAKING CHANGES!! 🚨
12+
13+
* `monaco-graphql` 🚨 **no longer loads schemas using `fetch` introspection** 🚨, you must specify the schema in one of many ways statically or dynamically. specifying just a schema `uri` no longer works. see [the readme](https://github.com/graphql/graphiql/tree/main/packages/monaco-graphql#monaco-graphql)
14+
* when specifying the language to an editor or model, **use `graphql` as the language id instead of `graphqlDev`**
15+
* the mode now extends the default basic language support from `monaco-editor` itself
16+
* when bundling, for syntax highlighting and basic language features, you must specify `graphql` in languages for your webpack or vite monaco plugins
17+
* The exported mode api for configfuration been entirely rewritten. It is simple for now, but we will add more powerful methods to the `monaco.languages.api` over time :)
18+
19+
## New Features
20+
21+
this introduces many improvements:
22+
- json language support, by mapping from each graphql model uri to a set of json variable model uris
23+
- we generate a json schema definition for the json variables on the fly
24+
- it updates alongside editor validation as you type
25+
- less redundant schema loading - schema is loaded in main process instead of in the webworker
26+
- web worker stability has been improved by contributors in previous patches, but removing remote schema loading vastly simplifies worker creation
27+
- the editor now supports multiple graphql models, configurable against multiple schema configurations
28+
* You can now use `intializeMode()` to initialize the language mode & worker with the schema, but you can still lazily load it, and fall back on default monaco editor basic languages support

examples/monaco-graphql-webpack/package.json

+6-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,11 @@
1111
"dependencies": {
1212
"graphql": "16.0.0-experimental-stream-defer.5",
1313
"monaco-graphql": "^0.6.5",
14-
"prettier": "^2.0.4"
14+
"prettier": "^2.0.4",
15+
"graphql-language-service": "^3.2.1",
16+
"json-schema": "^0.3.0",
17+
"jsonc-parser": "3.0.0",
18+
"monaco-editor": "^0.29.1"
1519
},
1620
"devDependencies": {
1721
"@babel/cli": "^7.8.4",
@@ -28,8 +32,7 @@
2832
"css-loader": "^3.5.1",
2933
"file-loader": "6.2.0",
3034
"html-webpack-plugin": "^4.2.0",
31-
"monaco-editor": "^0.27.0",
32-
"monaco-editor-webpack-plugin": "^4.0.0",
35+
"monaco-editor-webpack-plugin": "^5.0.0",
3336
"react-dom": "^16.12.0",
3437
"style-loader": "^1.1.3",
3538
"typescript": "^4.1.3",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import * as monaco from 'monaco-editor';
2+
3+
// NOTE: using loader syntax becuase Yaml worker imports editor.worker directly and that
4+
// import shouldn't go through loader syntax.
5+
// @ts-ignore
6+
import EditorWorker from 'worker-loader!monaco-editor/esm/vs/editor/editor.worker';
7+
// @ts-ignore
8+
import JSONWorker from 'worker-loader!monaco-editor/esm/vs/language/json/json.worker';
9+
// @ts-ignore
10+
import GraphQLWorker from 'worker-loader!monaco-graphql/esm/graphql.worker';
11+
12+
const GRAPHQL_LANGUAGE_ID = 'graphql';
13+
14+
// @ts-ignore
15+
window.MonacoEnvironment = {
16+
getWorker(_workerId: string, label: string) {
17+
if (label === GRAPHQL_LANGUAGE_ID) {
18+
return new GraphQLWorker();
19+
}
20+
if (label === 'json') {
21+
return new JSONWorker();
22+
}
23+
return new EditorWorker();
24+
},
25+
};
26+
27+
const operationString =
28+
localStorage.getItem('operations') ??
29+
`
30+
# right click to view context menu
31+
# F1 for command palette
32+
# enjoy prettier formatting, autocompletion,
33+
# validation, hinting and more for GraphQL SDL and operations!
34+
query Example(
35+
$owner: String!
36+
$name: String!
37+
$reviewEvent: PullRequestReviewEvent!
38+
$user: FollowUserInput!
39+
) {
40+
repository(owner: $owner, name: $name) {
41+
stargazerCount
42+
}
43+
}
44+
`;
45+
46+
const variablesString =
47+
localStorage.getItem('variables') ??
48+
`{
49+
"reviewEvent": "graphql",
50+
"name": true
51+
}`;
52+
53+
const resultsString = `{}`;
54+
55+
const THEME = 'vs-dark';
56+
57+
export function createEditors() {
58+
const variablesModel = monaco.editor.createModel(
59+
variablesString,
60+
'json',
61+
monaco.Uri.file('/1/variables.json'),
62+
);
63+
64+
const variablesEditor = monaco.editor.create(
65+
document.getElementById('variables') as HTMLElement,
66+
{
67+
model: variablesModel,
68+
language: 'json',
69+
formatOnPaste: true,
70+
formatOnType: true,
71+
theme: THEME,
72+
comments: {
73+
insertSpace: true,
74+
ignoreEmptyLines: true,
75+
},
76+
},
77+
);
78+
79+
const operationModel = monaco.editor.createModel(
80+
operationString,
81+
GRAPHQL_LANGUAGE_ID,
82+
monaco.Uri.file('/1/operation.graphql'),
83+
);
84+
85+
const operationEditor = monaco.editor.create(
86+
document.getElementById('operation') as HTMLElement,
87+
{
88+
model: operationModel,
89+
formatOnPaste: true,
90+
formatOnType: true,
91+
folding: true,
92+
theme: THEME,
93+
language: GRAPHQL_LANGUAGE_ID,
94+
},
95+
);
96+
97+
const resultsModel = monaco.editor.createModel(
98+
resultsString,
99+
'json',
100+
monaco.Uri.file('/1/results.json'),
101+
);
102+
103+
const resultsEditor = monaco.editor.create(
104+
document.getElementById('results') as HTMLElement,
105+
{
106+
model: resultsModel,
107+
language: 'json',
108+
theme: THEME,
109+
wordWrap: 'on',
110+
readOnly: true,
111+
showFoldingControls: 'always',
112+
},
113+
);
114+
115+
return {
116+
operationEditor,
117+
variablesEditor,
118+
resultsEditor,
119+
operationModel,
120+
variablesModel,
121+
};
122+
}

examples/monaco-graphql-webpack/src/index.html.ejs

+16-38
Original file line numberDiff line numberDiff line change
@@ -7,46 +7,24 @@
77
content="width=device-width, initial-scale=1, shrink-to-fit=no"
88
/>
99
<title>Monaco Example!</title>
10-
<style>
11-
body {
12-
background-color: #1e1e1e;
13-
}
14-
.div {
15-
margin: 0;
16-
padding: 0;
17-
}
18-
19-
.full-height {
20-
height: 100vh;
21-
}
22-
23-
.column {
24-
width: 50%;
25-
}
26-
#toolbar {
27-
background-color: #1e1e1e;
28-
text-align: right;
29-
}
30-
#button {
31-
padding: .5em 1em;
32-
}
33-
</style>
34-
3510
</head>
36-
<body style="margin: 0; padding: 0;">
37-
<div style="display: flex;">
38-
<div class="full-height column">
39-
<div id="toolbar"></div>
40-
<div id="operation" style="height: 70vh;"></div>
41-
<div id="variables" style="height: 30vh;"></div>
11+
<body>
12+
<div id="flex-wrapper" class="column">
13+
<div id="toolbar" class="row"></div>
14+
<div class="row">
15+
<div class="full-height column half-width">
16+
<div id="operation"></div>
17+
<div id="variables"></div>
18+
</div>
19+
<div class="full-height column half-width">
20+
<div
21+
aria-label="Result Window"
22+
aria-live="polite"
23+
aria-atomic="true"
24+
id="results"
25+
></div>
26+
</div>
4227
</div>
43-
<div
44-
id="results"
45-
class="full-height column"
46-
aria-label="Result Window"
47-
aria-live="polite"
48-
aria-atomic="true"
49-
></div>
5028
</div>
5129
<!-- for github auth -->
5230
<script src="https://unpkg.com/netlify-auth-providers"></script>

0 commit comments

Comments
 (0)