Sample query

Pick an example on the left, or just type. loading…
No problems detected.

Putting this in your own page

A complete, self-contained page — highlighting, completion, hover and the real worker-backed validation. Serve it next to the lib/ folder from xql-monaco.zip; those relative paths are all it needs.

snippet-editor.html — open it running →
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />
  <title>Minimal XQL editor</title>
  <style>
    html, body { height: 100%; margin: 0; }
    #editor { height: 100%; }
  </style>
</head>
<body>
  <div id="editor"></div>

  <script src="https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs/loader.js"></script>
  <script src="lib/xql-lang.js"></script>
  <script>
    var VS = "https://cdn.jsdelivr.net/npm/monaco-editor@0.52.2/min/vs";

    require.config({ paths: { vs: VS } });
    require(["vs/editor/editor.main"], function () {
      fetch("lib/xql-data.json").then(function (r) { return r.json(); }).then(function (data) {

        // Registers the XQL language, the Monarch tokenizer, both themes, completion and hover.
        var xql = XQLLang.register(monaco, data);

        var editor = monaco.editor.create(document.getElementById("editor"), {
          value: "dataset = xdr_data\n| filter action_process_image_name contains \"powershell\"\n| limit 100",
          language: xql.languageId,
          theme: xql.themes.dark,          // or xql.themes.light
          automaticLayout: true
        });

        // Validation runs the real ANTLR grammar in a Web Worker, so the ~2 MB parser never
        // blocks typing. Drop this block and you still get highlighting, completion and hover.
        var model = editor.getModel();
        var worker = new Worker("lib/xql-validator.js");
        var seq = 0, timer = null;

        worker.onmessage = function (ev) {
          var d = ev.data || {};
          if (d.ready) return validate();
          if (d.id !== seq) return;                       // a stale reply; a newer edit is in flight
          monaco.editor.setModelMarkers(model, "XQL", (d.markers || []).map(function (m) {
            m.severity = m.severity === "warning"
              ? monaco.MarkerSeverity.Warning
              : monaco.MarkerSeverity.Error;
            return m;
          }));
        };

        function validate() { worker.postMessage({ id: ++seq, text: model.getValue() }); }
        model.onDidChangeContent(function () {
          clearTimeout(timer);
          timer = setTimeout(validate, 250);
        });
      });
    });
  </script>
</body>
</html>

This is the whole integration. What the demo above adds on top is presentation: a problems panel, a theme toggle, and the completion bridge that routes suggestions through the worker for caret-aware results — all of it in xql-editor.js, which ships in the same zip.

The worker fetches lib/xql-intellisense.json at runtime, so swapping in your own tenant's schema is a file copy — no rebuild. Without it you still get syntax validation.