Skip to content
Draft
14 changes: 0 additions & 14 deletions apps/hash-frontend/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,6 @@ export default withSentryConfig(
// eslint-disable-next-line no-param-reassign
webpackConfig.resolve.alias.canvas = false;

if (!isServer) {
// Stub Node.js built-ins for browser β€” needed by `typescript` (used by
// @hashintel/petrinaut's in-browser language service)
// eslint-disable-next-line no-param-reassign
webpackConfig.resolve.fallback = {
...webpackConfig.resolve.fallback,
module: false,
fs: false,
path: false,
os: false,
perf_hooks: false,
};
}

webpackConfig.plugins.push(
new DefinePlugin({
__SENTRY_DEBUG__: false,
Expand Down
13 changes: 1 addition & 12 deletions apps/hash-frontend/src/lib/csp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,13 @@ export const buildCspHeader = (nonce: string): string => {
"https://apis.google.com",
// Vercel toolbar / live preview widget
"https://vercel.live",
// @todo FE-488 will make this unnecessary
// Monaco Editor loaded from CDN by @monaco-editor/react (used by petrinaut)
"https://cdn.jsdelivr.net",
],

"style-src": [
"'self'",
// Required for Emotion/MUI CSS-in-JS inline style injection.
// @todo Use nonce-based approach via Emotion's cache `nonce` option.
"'unsafe-inline'",
// @todo FE-488 will make this unnecessary
// Monaco Editor stylesheet loaded from CDN by @monaco-editor/react (used by petrinaut)
"https://cdn.jsdelivr.net",
],

"img-src": [
Expand All @@ -51,12 +45,7 @@ export const buildCspHeader = (nonce: string): string => {
...(process.env.NODE_ENV === "development" ? ["http:"] : []),
],

"font-src": [
"'self'",
// @todo FE-488 will make this unnecessary
// Monaco Editor CSS embeds the Codicon icon font as an inline base64 data URI
"data:",
],
"font-src": ["'self'"],

"connect-src": [
"'self'",
Expand Down
49 changes: 49 additions & 0 deletions libs/@hashintel/petrinaut/src/checker/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { createContext } from "react";

import type {
CheckerCompletionResult,
CheckerItemDiagnostics,
CheckerQuickInfoResult,
CheckerResult,
CheckerSignatureHelpResult,
} from "./worker/protocol";

export interface CheckerContextValue {
/** Result of the last SDCPN validation run. */
checkResult: CheckerResult;
/** Total number of diagnostics across all items. */
totalDiagnosticsCount: number;
/** Request completions at a position within an SDCPN item. */
getCompletions: (
itemType: CheckerItemDiagnostics["itemType"],
itemId: string,
offset: number,
) => Promise<CheckerCompletionResult>;
/** Request quick info (hover) at a position within an SDCPN item. */
getQuickInfo: (
itemType: CheckerItemDiagnostics["itemType"],
itemId: string,
offset: number,
) => Promise<CheckerQuickInfoResult>;
/** Request signature help at a position within an SDCPN item. */
getSignatureHelp: (
itemType: CheckerItemDiagnostics["itemType"],
itemId: string,
offset: number,
) => Promise<CheckerSignatureHelpResult>;
}

const DEFAULT_CONTEXT_VALUE: CheckerContextValue = {
checkResult: {
isValid: true,
itemDiagnostics: [],
},
totalDiagnosticsCount: 0,
getCompletions: () => Promise.resolve({ items: [] }),
getQuickInfo: () => Promise.resolve(null),
getSignatureHelp: () => Promise.resolve(null),
};

export const CheckerContext = createContext<CheckerContextValue>(
DEFAULT_CONTEXT_VALUE,
);
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import type ts from "typescript";

import type { SDCPN } from "../types/sdcpn";
import { createSDCPNLanguageService } from "./create-sdcpn-language-service";
import type { SDCPN } from "../../core/types/sdcpn";
import {
createSDCPNLanguageService,
type SDCPNLanguageService,
} from "./create-sdcpn-language-service";
import { getItemFilePath } from "./file-paths";

export type SDCPNDiagnostic = {
Expand Down Expand Up @@ -29,8 +32,12 @@ export type SDCPNCheckResult = {
* @param sdcpn - The SDCPN to check
* @returns A result object indicating validity and any diagnostics
*/
export function checkSDCPN(sdcpn: SDCPN): SDCPNCheckResult {
const languageService = createSDCPNLanguageService(sdcpn);
export function checkSDCPN(
sdcpn: SDCPN,
existingLanguageService?: SDCPNLanguageService,
): SDCPNCheckResult {
const languageService =
existingLanguageService ?? createSDCPNLanguageService(sdcpn);
const itemDiagnostics: SDCPNDiagnostic[] = [];

// Check all differential equations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,12 @@ export type VirtualFile = {
*
* Creates a TypeScript LanguageServiceHost for virtual SDCPN files
*/
export function createLanguageServiceHost(
files: Map<string, VirtualFile>,
): ts.LanguageServiceHost {
export function createLanguageServiceHost(files: Map<string, VirtualFile>): {
host: ts.LanguageServiceHost;
updateFileContent: (fileName: string, content: string) => void;
} {
const versions = new Map<string, number>();

const getFileContent = (fileName: string): string | undefined => {
const entry = files.get(fileName);
if (entry) {
Expand All @@ -62,10 +65,18 @@ export function createLanguageServiceHost(
return undefined;
};

return {
const updateFileContent = (fileName: string, content: string) => {
const entry = files.get(fileName);
if (entry) {
entry.content = content;
versions.set(fileName, (versions.get(fileName) ?? 0) + 1);
}
};

const host: ts.LanguageServiceHost = {
getScriptFileNames: () => [...files.keys()],
getCompilationSettings: () => COMPILER_OPTIONS,
getScriptVersion: () => "0",
getScriptVersion: (fileName) => String(versions.get(fileName) ?? 0),
getCurrentDirectory: () => "/",
getDefaultLibFileName: () => "/lib.es2015.core.d.ts",

Expand All @@ -82,4 +93,6 @@ export function createLanguageServiceHost(
return getFileContent(path);
},
};

return { host, updateFileContent };
}
Loading
Loading