Skip to content

Commit 125f35b

Browse files
Merge pull request #120 from Watts-Lab/schema-fall-fixes
Schema fall fixes
2 parents 46a9275 + f3bf620 commit 125f35b

34 files changed

Lines changed: 2959 additions & 257 deletions

deliberation-empirica

esbuild.js

Lines changed: 78 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ filesToCopy.forEach((filePath) => {
3030
});
3131

3232
/**
33-
* This plugin hooks into the build process to print errors in a format that the problem matcher in
34-
* Visual Studio Code can understand.
35-
* @type {import('esbuild').Plugin}
33+
* Plugin to display errors nicely in VS Code's problem matcher format
3634
*/
3735
const esbuildProblemMatcherPlugin = {
3836
name: "esbuild-problem-matcher",
@@ -44,20 +42,19 @@ const esbuildProblemMatcherPlugin = {
4442
build.onEnd((result) => {
4543
result.errors.forEach(({ text, location }) => {
4644
console.error(`✘ [ERROR] ${text}`);
47-
console.error(
48-
` ${location.file}:${location.line}:${location.column}:`
49-
);
45+
if (location) {
46+
console.error(
47+
` ${location.file}:${location.line}:${location.column}:`
48+
);
49+
}
5050
});
5151
console.log("[watch] build finished");
5252
});
5353
},
5454
};
5555

5656
/**
57-
* For web extension, all tests, including the test runner, need to be bundled into
58-
* a single module that has a exported `run` function .
59-
* This plugin bundles implements a virtual file extensionTests.ts that bundles all these together.
60-
* @type {import('esbuild').Plugin}
57+
* Plugin for bundling all test files into a single entry (used for VS Code extension tests)
6158
*/
6259
const testBundlePlugin = {
6360
name: "testBundlePlugin",
@@ -67,7 +64,7 @@ const testBundlePlugin = {
6764
return { path: path.resolve(args.path) };
6865
}
6966
});
70-
build.onLoad({ filter: /[\/\\]extensionTests\.ts$/ }, async (args) => {
67+
build.onLoad({ filter: /[\/\\]extensionTests\.ts$/ }, async () => {
7168
const testsRoot = path.join(__dirname, "src/test/suite");
7269
const files = await glob.glob("*.test.{ts,tsx}", {
7370
cwd: testsRoot,
@@ -84,25 +81,27 @@ const testBundlePlugin = {
8481
},
8582
};
8683

87-
// Points hooks.js from deliberation-empirica to the mock hooks.js file in src/views
88-
// Needed for rendering
84+
/**
85+
* Alias plugin to handle ../components/hooks imports
86+
* Used in deliberation-empirica code
87+
*/
8988
const aliasHooksImport = {
9089
name: "alias-hooks-imports",
9190
setup(build) {
92-
build.onResolve({ filter: /^\.\.\/components\/hooks$/ }, args => {
91+
build.onResolve({ filter: /^\.\.\/components\/hooks$/ }, () => {
9392
return {
9493
path: path.resolve(__dirname, "src/views/hooks.js"),
9594
};
9695
});
9796
},
9897
};
9998

100-
99+
/**
100+
* Build VS Code extension backend
101+
*/
101102
async function buildExtension() {
102103
const ctx = await esbuild.context({
103-
entryPoints: [
104-
"src/extension.ts"
105-
],
104+
entryPoints: ["src/extension.ts"],
106105
bundle: true,
107106
format: "cjs",
108107
minify: production,
@@ -112,34 +111,47 @@ async function buildExtension() {
112111
outdir: "dist/",
113112
external: ["vscode", "path", "assert"],
114113
logLevel: "silent",
115-
// Node.js global to browser globalThis
116-
define: {
117-
global: "globalThis",
118-
},
119-
alias: { // Aliases of empirica modules to mocks for rendering
120-
'@empirica/core/player/react': path.resolve(__dirname, 'src/views/mocks.js'),
121-
'@empirica/core/player/classic/react': path.resolve(__dirname, 'src/views/mocks.js'),
122-
'deliberation-empirica/client/src/components/hooks': path.resolve(__dirname, 'src/views/hooks.js')
114+
define: { global: "globalThis" },
115+
alias: {
116+
"@empirica/core/player/react": path.resolve(__dirname, "src/views/mocks.js"),
117+
"@empirica/core/player/classic/react": path.resolve(__dirname, "src/views/mocks.js"),
118+
"components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
119+
"components/hooks.js": path.resolve(__dirname, "src/views/hooks.js"),
120+
"deliberation-empirica/client/src/components/hooks": path.resolve(
121+
__dirname,
122+
"src/views/hooks.js"
123+
),
124+
"deliberation-empirica/client/src/components/hooks.js": path.resolve(
125+
__dirname,
126+
"src/views/hooks.js"
127+
),
123128
},
124129

125130
plugins: [
126131
polyfill.NodeGlobalsPolyfillPlugin({
127132
process: true,
128133
buffer: true,
129134
}),
130-
131135
alias({
132136
aliases: {
133-
"../components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
137+
"components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
138+
"components/hooks.js": path.resolve(__dirname, "src/views/hooks.js"),
139+
"deliberation-empirica/client/src/components/hooks": path.resolve(
140+
__dirname,
141+
"src/views/hooks.js"
142+
),
143+
"deliberation-empirica/client/src/components/hooks.js": path.resolve(
144+
__dirname,
145+
"src/views/hooks.js"
146+
),
134147
},
135148
resolve: [".js", ".jsx"],
136149
}),
137-
138150
aliasHooksImport,
139-
140-
esbuildProblemMatcherPlugin /* add to the end of plugins array */,
151+
esbuildProblemMatcherPlugin,
141152
],
142153
});
154+
143155
if (watch) {
144156
await ctx.watch();
145157
} else {
@@ -148,15 +160,17 @@ async function buildExtension() {
148160
}
149161
}
150162

151-
// Builds index.jsx for prompt file rendering and CSS style files
163+
/**
164+
* Build webview frontend (prompt preview, styles)
165+
*/
152166
async function buildPrompt() {
153167
const ctx = await esbuild.context({
154168
entryPoints: [
155169
"src/views/index.jsx",
156170
"src/views/styles.css",
157171
"src/views/playerStyles.css",
158172
"src/views/layout.css",
159-
"src/views/baseStyles.css"
173+
"src/views/baseStyles.css",
160174
],
161175
bundle: true,
162176
format: "esm",
@@ -167,22 +181,40 @@ async function buildPrompt() {
167181
outdir: "dist/views/",
168182
logLevel: "silent",
169183
external: ["vscode", "path", "assert"],
170-
alias: { // Aliasing empirica module methods to point to mocks
171-
'@empirica/core/player/react': path.resolve(__dirname, 'src/views/mocks.js'),
172-
'@empirica/core/player/classic/react': path.resolve(__dirname, 'src/views/mocks.js'),
173-
'deliberation-empirica/client/src/components/hooks': path.resolve(__dirname, 'src/views/hooks.js')
184+
alias: {
185+
"@empirica/core/player/react": path.resolve(__dirname, "src/views/mocks.js"),
186+
"@empirica/core/player/classic/react": path.resolve(__dirname, "src/views/mocks.js"),
187+
"components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
188+
"components/hooks.js": path.resolve(__dirname, "src/views/hooks.js"),
189+
"deliberation-empirica/client/src/components/hooks": path.resolve(
190+
__dirname,
191+
"src/views/hooks.js"
192+
),
193+
"deliberation-empirica/client/src/components/hooks.js": path.resolve(
194+
__dirname,
195+
"src/views/hooks.js"
196+
),
174197
},
175198
plugins: [
176199
alias({
177200
aliases: {
178-
"../components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
201+
"components/hooks": path.resolve(__dirname, "src/views/hooks.js"),
202+
"components/hooks.js": path.resolve(__dirname, "src/views/hooks.js"),
203+
"deliberation-empirica/client/src/components/hooks": path.resolve(
204+
__dirname,
205+
"src/views/hooks.js"
206+
),
207+
"deliberation-empirica/client/src/components/hooks.js": path.resolve(
208+
__dirname,
209+
"src/views/hooks.js"
210+
),
179211
},
180212
resolve: [".js", ".jsx"],
181213
}),
182-
183-
aliasHooksImport
184-
]
214+
aliasHooksImport,
215+
],
185216
});
217+
186218
if (watch) {
187219
await ctx.watch();
188220
} else {
@@ -191,6 +223,9 @@ async function buildPrompt() {
191223
}
192224
}
193225

226+
/**
227+
* Run both builds
228+
*/
194229
async function main() {
195230
await buildExtension();
196231
await buildPrompt();
@@ -200,3 +235,5 @@ main().catch((e) => {
200235
console.error(e);
201236
process.exit(1);
202237
});
238+
239+

package-lock.json

Lines changed: 3 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
"Other"
2222
],
2323
"activationEvents": [
24-
"onLanguage:treatmentsYaml",
25-
"onLanguage:markdown"
24+
"onLanguage:treatmentsYaml"
2625
],
2726
"contributes": {
2827
"configurationDefaults": {
@@ -91,7 +90,7 @@
9190
"compile-web": "npm run prepare-web && tsc -p tsconfig.json && npm run lint && node esbuild.js",
9291
"package-web": "npm run prepare-web && npm run check-types && npm run lint && node esbuild.js --production",
9392
"compile-test": "npm run build:css && tsc -p tsconfig.test.json",
94-
"test": "npm run compile-test && ELECTRON_DISABLE_GPU=1 xvfb-run -a node runExtensionTests.js $TEST_FILES",
93+
"test": "npm run compile-test && ELECTRON_DISABLE_GPU=1 node -e \"const { spawnSync } = require('child_process'); const run = (cmd) => spawnSync(cmd, { shell: true, stdio: 'inherit' }); const check = spawnSync('command -v xvfb-run', { shell: true, stdio: 'pipe' }); if (check.status === 0) { console.log('🖥️ Using xvfb virtual display'); const xvfb = run('xvfb-run -a node runExtensionTests.js'); process.exit(xvfb.status ?? 0); } else { console.log('⚠️ xvfb not found, running tests without virtual display'); const plain = run('node runExtensionTests.js'); process.exit(plain.status ?? 1); }\"",
9594
"test:electron": "vscode-test --extensionDevelopmentPath=. --extensionTestsPath=out/test/suite/extensionTests.js",
9695
"vscode:prepublish": "npm run package-web",
9796
"check-types": "tsc --noEmit",
@@ -140,9 +139,9 @@
140139
"axios": "^1.9.0",
141140
"cp": "^0.2.0",
142141
"daisyui": "^5.0.43",
142+
"detect-browser": "^5.3.0",
143143
"fastest-levenshtein": "^1.0.16",
144144
"json-to-ast": "^2.1.0",
145-
"detect-browser": "^5.3.0",
146145
"react": "18.2.0",
147146
"react-debounce-input": "^3.3.0",
148147
"react-device-detect": "^2.2.3",
@@ -163,4 +162,3 @@
163162
}
164163
}
165164
}
166-

src/detectFile.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import * as path from "path";
66

77
// Detects if file is prompt Markdown format by parsing metadata with YAML
88
export function detectPromptMarkdown(document: vscode.TextDocument) {
9-
if (document.languageId === "markdown") {
9+
if (document.languageId === "markdown" || document.languageId === "promptMarkdown") {
1010
// console.log("Markdown file");
1111

1212
// define interface for metadata
@@ -39,7 +39,11 @@ export function detectPromptMarkdown(document: vscode.TextDocument) {
3939
// Function to detect if document is treatmentsYaml format - mostly for unit tests
4040
export function detectTreatmentsYaml(document: vscode.TextDocument) {
4141
// console.log("Document languageId:", document.languageId);
42-
return document.languageId === "treatmentsYaml";
42+
if (document.languageId === "treatmentsYaml") return true;
43+
// Fallback: detect by file name suffix in case languageId isn't set to the contributed language
44+
const fileName = document.fileName || "";
45+
if (fileName.endsWith(".treatments.yaml") || fileName.endsWith(".treatments.yml")) return true;
46+
return false;
4347
}
4448

4549
export function detectdlConfig(document: vscode.TextDocument) {

src/errorPosition.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ export function findPositionFromPathJson(
129129
}
130130

131131
// Helper function to find the position of a node in the AST based on the path
132-
function findPositionFromPath(
132+
export function findPositionFromPath(
133133
path: (string | number)[],
134134
astNode: any,
135135
document: vscode.TextDocument // Pass the document as an additional parameter

src/extension.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ async function parseDocument(document: vscode.TextDocument) {
1717
if (detectTreatmentsYaml(document)) {
1818
await parseYaml(document);
1919
} else if (detectPromptMarkdown(document)) {
20+
console.log(detectPromptMarkdown(document));
2021
parseMarkdown(document);
2122
} else if (detectdlConfig(document)) {
2223
await parseDlConfig(document);
@@ -50,13 +51,12 @@ export async function activate(context: vscode.ExtensionContext) {
5051
await parseDocument(event);
5152
}
5253
}),
53-
54-
// for changing document
55-
vscode.workspace.onDidChangeTextDocument(async (event) => {
56-
if (event?.document !== undefined) {
57-
parseDocument(event?.document);
58-
};
59-
}),
54+
// for changing document
55+
vscode.workspace.onDidChangeTextDocument(async (event) => {
56+
if (event?.document !== undefined) {
57+
parseDocument(event?.document);
58+
};
59+
}),
6060

6161
// When we switch to a document open in another tab
6262
vscode.window.onDidChangeActiveTextEditor(async (event) => {

0 commit comments

Comments
 (0)