Skip to content

✨ feat(playground): add type checking and inlay hints support#1398

Merged
harehare merged 3 commits intomainfrom
feat/playground-type-check
Mar 12, 2026
Merged

✨ feat(playground): add type checking and inlay hints support#1398
harehare merged 3 commits intomainfrom
feat/playground-type-check

Conversation

@harehare
Copy link
Copy Markdown
Owner

@harehare harehare commented Mar 6, 2026

No description provided.

Copilot AI review requested due to automatic review settings March 6, 2026 12:53
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds type-checking-related UX in the web playground by extending the mq-web wrapper API and wiring Monaco diagnostics + inlay hints to new WASM-facing functions.

Changes:

  • Expose inlayHints (and InlayHint type) from mq-web, and extend diagnostics with an enableTypeCheck flag.
  • Add a “Type Check” toggle in the playground, pass the toggle into diagnostics, and register a Monaco inlay-hints provider.
  • Point the playground’s mq-web dependency at the local package to consume these new APIs.

Reviewed changes

Copilot reviewed 4 out of 5 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
packages/mq-web/src/index.ts Re-export inlayHints and InlayHint type from the WASM bindings.
packages/mq-web/src/core.ts Add wrapper methods/signatures for inlayHints and diagnostics(..., enableTypeCheck?).
packages/mq-playground/src/Playground.tsx Add UI toggle, pass flag into diagnostics, and register inlay hints provider.
packages/mq-playground/package.json Use local mq-web package to pick up new APIs.
packages/mq-playground/package-lock.json Lockfile updates for local linked mq-web.
Files not reviewed (1)
  • packages/mq-playground/package-lock.json: Language not supported

export type {
Options,
Diagnostic,
InlayHint,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

InlayHint is exported from ../mq-wasm/mq_wasm.js, but the current WASM bindings (crates/mq-wasm) don't define an InlayHint type in the generated TypeScript section. This will fail type-check/build for mq-web unless the WASM bindings are updated and regenerated. Either add InlayHint to crates/mq-wasm's TS custom section (and regenerate packages/mq-web/mq-wasm/*) or remove this export until the WASM layer provides it.

Suggested change
InlayHint,

Copilot uses AI. Check for mistakes.
Comment on lines +5 to 8
InlayHint,
ConversionOptions,
} from "./mq_wasm";

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

core.ts now imports InlayHint from ./mq_wasm, but the current WASM bindings in this repo (crates/mq-wasm) only define DefinedValue, Diagnostic, and Options in their TypeScript custom section. Unless the WASM bindings are updated/regenerated to export InlayHint, this import will break the mq-web build.

Suggested change
InlayHint,
ConversionOptions,
} from "./mq_wasm";
} from "./mq_wasm";
type InlayHint = unknown;
type ConversionOptions = unknown;

Copilot uses AI. Check for mistakes.
toAst: wasmImport.toAst,
format: wasmImport.format,
diagnostics: wasmImport.diagnostics,
inlayHints: wasmImport.inlayHints,
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

initWasm() wires inlayHints: wasmImport.inlayHints, but the current WASM exports (crates/mq-wasm/src/script.rs) do not define or export an inlayHints function. As-is, wasm.inlayHints(...) will be undefined at runtime and the first call will throw. Implement and export inlayHints in the WASM crate (and regenerate bindings into packages/mq-web/mq-wasm) or add a defensive fallback in mq-web that returns an empty list when the export is missing.

Suggested change
inlayHints: wasmImport.inlayHints,
inlayHints:
wasmImport.inlayHints ??
(async (_code: string): Promise<readonly InlayHint[]> => []),

Copilot uses AI. Check for mistakes.
): Promise<ReadonlyArray<Diagnostic>> {
const wasm = await initWasm();
return await wasm.diagnostics(code);
return await wasm.diagnostics(code, enableTypeCheck);
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

diagnostics(code, enableTypeCheck?) suggests the WASM layer can optionally run type checking, but the current WASM diagnostics export only accepts code: string and only returns parse errors. Passing this flag is ignored today, which makes the new Playground toggle misleading. Either extend the WASM diagnostics export to accept the flag and run type checking, or expose a separate typeDiagnostics(...)/check(...) API so callers can reliably request type errors.

Suggested change
return await wasm.diagnostics(code, enableTypeCheck);
return await wasm.diagnostics(code);

Copilot uses AI. Check for mistakes.
Comment on lines +1147 to +1163
monaco.languages.registerInlayHintsProvider("mq", {
provideInlayHints: async (model: editor.ITextModel) => {
if (!enableTypeCheckRef.current) {
return { hints: [], dispose: () => {} };
}
const hints = await mq.inlayHints(model.getValue());
return {
hints: hints.map((hint: mq.InlayHint) => ({
position: {
lineNumber: hint.line,
column: hint.column,
},
label: hint.label,
kind: monaco.languages.InlayHintKind.Type,
})),
dispose: () => {},
};
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The new inlay hints provider calls mq.inlayHints(...), but mq-web's wrapper currently points at a WASM export that doesn't exist in this repo (crates/mq-wasm doesn't export inlayHints). This will throw/reject during Monaco's inlay-hints requests. Either implement/regenerate the WASM export, or guard the provider with a feature-detection check (e.g., return no hints when mq.inlayHints is undefined) to avoid runtime failures.

Copilot uses AI. Check for mistakes.
@harehare harehare force-pushed the feat/playground-type-check branch 2 times, most recently from 00abd47 to 8e71666 Compare March 12, 2026 12:59
Copilot AI review requested due to automatic review settings March 12, 2026 12:59
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 1 out of 2 changed files in this pull request and generated 3 comments.

Files not reviewed (1)
  • packages/mq-playground/package-lock.json: Language not supported
Comments suppressed due to low confidence (1)

packages/mq-playground/package-lock.json:36

  • This lockfile update removes resolved and integrity fields for many registry packages (e.g. @babel/code-frame). That can reduce supply-chain protections (no integrity pinning) and may make installs less reproducible across environments/tools. If this wasn’t intentional, regenerate package-lock.json with standard npm settings; if it is intentional, consider adding a repo-level note/config documenting the npm setting that strips these fields so future installs don’t reintroduce them.

Comment on lines +909 to 913
const errors = await mq.diagnostics(
model.getValue(),
enableTypeCheckRef.current,
);
monaco.editor.setModelMarkers(
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

The diagnostics update is async but not tied to a specific model version. With type checking enabled (potentially slower), results can arrive out of order and apply markers for stale code. Consider capturing model.getVersionId() (or similar) before awaiting and skipping setModelMarkers if the model version has changed, or canceling/serializing in-flight diagnostics calls.

Copilot uses AI. Check for mistakes.
Comment on lines +909 to +912
const errors = await mq.diagnostics(
model.getValue(),
enableTypeCheckRef.current,
);
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

When enableTypeCheckRef.current is true, mq.diagnostics can return type-check diagnostics whose startLine/endLine are 0-based (see crates/mq-wasm/src/script.rs where type error lines are line.saturating_sub(1)), while parse diagnostics appear to be 1-based. Monaco markers are 1-based, so type-check errors may be rendered on the wrong line or not at all. Normalize diagnostic line numbers before calling setModelMarkers (or fix the wasm side to consistently return 1-based positions).

Copilot uses AI. Check for mistakes.
<input
type="checkbox"
checked={enableTypeCheck}
onChange={(e) => setEnableTypeCheck(e.target.checked)}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

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

Toggling the Type Check checkbox only updates state/localStorage; it doesn’t trigger a diagnostics recompute or an inlay-hints refresh, so users may keep seeing stale markers/hints until they type again. Consider triggering a markers refresh + inlay-hints refresh when enableTypeCheck changes (e.g., keep a Monaco editor/model ref and re-run diagnostics / call Monaco’s inlay hints refresh action).

Suggested change
onChange={(e) => setEnableTypeCheck(e.target.checked)}
onChange={(e) => {
const enabled = e.target.checked;
setEnableTypeCheck(enabled);
// Force diagnostics and inlay hints to refresh immediately
// when the type-checking setting changes. This avoids
// stale markers/hints persisting until the next edit.
const editors = (editor as typeof editor & {
getEditors?: () => editor.IStandaloneCodeEditor[];
}).getEditors
? (editor as typeof editor & {
getEditors: () => editor.IStandaloneCodeEditor[];
}).getEditors()
: [];
editors.forEach((instance) => {
const model = instance.getModel();
if (!model) {
return;
}
const value = model.getValue();
// Writing the same value back triggers Monaco's
// validation / diagnostics pipeline without changing
// the visible content.
model.setValue(value);
const action =
instance.getAction?.("editor.action.inlineHints");
action?.run();
});
}}

Copilot uses AI. Check for mistakes.
@harehare harehare force-pushed the feat/playground-type-check branch from 8e71666 to 76bebe9 Compare March 12, 2026 13:31
@harehare harehare merged commit 1acad36 into main Mar 12, 2026
6 checks passed
@harehare harehare deleted the feat/playground-type-check branch March 12, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants