Skip to content

Commit

Permalink
feat: monaco variables json, improved schema & worker loading & monac…
Browse files Browse the repository at this point in the history
…o api (#1997)

Co-authored-by: Saihajpreet Singh <saihajpreet.singh@gmail.com>
  • Loading branch information
acao and saihaj committed Dec 5, 2021
1 parent 9b72af5 commit 9df315b
Show file tree
Hide file tree
Showing 45 changed files with 2,498 additions and 880 deletions.
28 changes: 28 additions & 0 deletions .changeset/shiny-starfishes-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
'graphql-language-service-utils': minor
'graphql-language-service': major
'monaco-graphql': major
---

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 🎉.

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.

## 🚨 BREAKING CHANGES!! 🚨

* `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)
* when specifying the language to an editor or model, **use `graphql` as the language id instead of `graphqlDev`**
* the mode now extends the default basic language support from `monaco-editor` itself
* when bundling, for syntax highlighting and basic language features, you must specify `graphql` in languages for your webpack or vite monaco plugins
* 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 :)

## New Features

this introduces many improvements:
- json language support, by mapping from each graphql model uri to a set of json variable model uris
- we generate a json schema definition for the json variables on the fly
- it updates alongside editor validation as you type
- less redundant schema loading - schema is loaded in main process instead of in the webworker
- web worker stability has been improved by contributors in previous patches, but removing remote schema loading vastly simplifies worker creation
- the editor now supports multiple graphql models, configurable against multiple schema configurations
* 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
9 changes: 6 additions & 3 deletions examples/monaco-graphql-webpack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
"dependencies": {
"graphql": "16.0.0-experimental-stream-defer.5",
"monaco-graphql": "^0.6.5",
"prettier": "^2.0.4"
"prettier": "^2.0.4",
"graphql-language-service": "^3.2.1",
"json-schema": "^0.3.0",
"jsonc-parser": "3.0.0",
"monaco-editor": "^0.29.1"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
Expand All @@ -28,8 +32,7 @@
"css-loader": "^3.5.1",
"file-loader": "6.2.0",
"html-webpack-plugin": "^4.2.0",
"monaco-editor": "^0.27.0",
"monaco-editor-webpack-plugin": "^4.0.0",
"monaco-editor-webpack-plugin": "^5.0.0",
"react-dom": "^16.12.0",
"style-loader": "^1.1.3",
"typescript": "^4.1.3",
Expand Down
122 changes: 122 additions & 0 deletions examples/monaco-graphql-webpack/src/editors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import * as monaco from 'monaco-editor';

// NOTE: using loader syntax becuase Yaml worker imports editor.worker directly and that
// import shouldn't go through loader syntax.
// @ts-ignore
import EditorWorker from 'worker-loader!monaco-editor/esm/vs/editor/editor.worker';
// @ts-ignore
import JSONWorker from 'worker-loader!monaco-editor/esm/vs/language/json/json.worker';
// @ts-ignore
import GraphQLWorker from 'worker-loader!monaco-graphql/esm/graphql.worker';

const GRAPHQL_LANGUAGE_ID = 'graphql';

// @ts-ignore
window.MonacoEnvironment = {
getWorker(_workerId: string, label: string) {
if (label === GRAPHQL_LANGUAGE_ID) {
return new GraphQLWorker();
}
if (label === 'json') {
return new JSONWorker();
}
return new EditorWorker();
},
};

const operationString =
localStorage.getItem('operations') ??
`
# right click to view context menu
# F1 for command palette
# enjoy prettier formatting, autocompletion,
# validation, hinting and more for GraphQL SDL and operations!
query Example(
$owner: String!
$name: String!
$reviewEvent: PullRequestReviewEvent!
$user: FollowUserInput!
) {
repository(owner: $owner, name: $name) {
stargazerCount
}
}
`;

const variablesString =
localStorage.getItem('variables') ??
`{
"reviewEvent": "graphql",
"name": true
}`;

const resultsString = `{}`;

const THEME = 'vs-dark';

export function createEditors() {
const variablesModel = monaco.editor.createModel(
variablesString,
'json',
monaco.Uri.file('/1/variables.json'),
);

const variablesEditor = monaco.editor.create(
document.getElementById('variables') as HTMLElement,
{
model: variablesModel,
language: 'json',
formatOnPaste: true,
formatOnType: true,
theme: THEME,
comments: {
insertSpace: true,
ignoreEmptyLines: true,
},
},
);

const operationModel = monaco.editor.createModel(
operationString,
GRAPHQL_LANGUAGE_ID,
monaco.Uri.file('/1/operation.graphql'),
);

const operationEditor = monaco.editor.create(
document.getElementById('operation') as HTMLElement,
{
model: operationModel,
formatOnPaste: true,
formatOnType: true,
folding: true,
theme: THEME,
language: GRAPHQL_LANGUAGE_ID,
},
);

const resultsModel = monaco.editor.createModel(
resultsString,
'json',
monaco.Uri.file('/1/results.json'),
);

const resultsEditor = monaco.editor.create(
document.getElementById('results') as HTMLElement,
{
model: resultsModel,
language: 'json',
theme: THEME,
wordWrap: 'on',
readOnly: true,
showFoldingControls: 'always',
},
);

return {
operationEditor,
variablesEditor,
resultsEditor,
operationModel,
variablesModel,
};
}
54 changes: 16 additions & 38 deletions examples/monaco-graphql-webpack/src/index.html.ejs
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,24 @@
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
<title>Monaco Example!</title>
<style>
body {
background-color: #1e1e1e;
}
.div {
margin: 0;
padding: 0;
}
.full-height {
height: 100vh;
}
.column {
width: 50%;
}
#toolbar {
background-color: #1e1e1e;
text-align: right;
}
#button {
padding: .5em 1em;
}
</style>

</head>
<body style="margin: 0; padding: 0;">
<div style="display: flex;">
<div class="full-height column">
<div id="toolbar"></div>
<div id="operation" style="height: 70vh;"></div>
<div id="variables" style="height: 30vh;"></div>
<body>
<div id="flex-wrapper" class="column">
<div id="toolbar" class="row"></div>
<div class="row">
<div class="full-height column half-width">
<div id="operation"></div>
<div id="variables"></div>
</div>
<div class="full-height column half-width">
<div
aria-label="Result Window"
aria-live="polite"
aria-atomic="true"
id="results"
></div>
</div>
</div>
<div
id="results"
class="full-height column"
aria-label="Result Window"
aria-live="polite"
aria-atomic="true"
></div>
</div>
<!-- for github auth -->
<script src="https://unpkg.com/netlify-auth-providers"></script>
Expand Down
Loading

2 comments on commit 9df315b

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.