Skip to content

Commit dc64f02

Browse files
Merge branch 'main' into addPlaygroundService
2 parents bde4b9c + 4330879 commit dc64f02

36 files changed

+346
-290
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,3 +62,6 @@ apps/outreach/src/content/docs/en/runtime-core-docs/
6262
# docker dbs
6363
mongo/
6464
sqlite/
65+
66+
# runtime core intermediate build
67+
packages/runtime-core/lib/

.nvmrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
lts/iron
1+
lts/jod

apps/api/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:iron AS base
1+
FROM node:lts-jod AS base
22
WORKDIR /app
33
ARG RELEASE_VERSION
44
ENV GATEWAY_DATABASE_URL="file:/dev/null"

apps/gateway/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:iron AS base
1+
FROM node:lts-jod AS base
22
WORKDIR /app
33
ARG RELEASE_VERSION
44
ENV GATEWAY_DATABASE_URL=file:/app/sqlite/gateway.db

apps/outreach/astro.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export default defineConfig({
6262
},
6363
plugins: [
6464
starlightTypeDocPlugin({
65-
entryPoints: [path.resolve(runtimeCoreRoot, 'src/index.d.ts')],
65+
entryPoints: [path.resolve(runtimeCoreRoot, 'lib/index.d.ts')],
6666
locale: 'en',
6767
output: 'runtime-core-docs',
6868
sidebar: {

apps/web/Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM node:iron AS base
1+
FROM node:lts-jod AS base
22
ARG RELEASE_VERSION
33
WORKDIR /app
44
ENV PNPM_HOME="/pnpm"

apps/web/src/features/upload/pages/UploadPage.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Button, FileDropzone, Heading, Spinner } from '@douglasneuroinformatics
44
import { useDownload, useTranslation } from '@douglasneuroinformatics/libui/hooks';
55
import { useNotificationsStore } from '@douglasneuroinformatics/libui/hooks';
66
import type { AnyUnilingualFormInstrument } from '@opendatacapture/runtime-core';
7-
import { DownloadIcon } from 'lucide-react';
7+
import { BadgeHelpIcon, DownloadIcon } from 'lucide-react';
88
import { useParams } from 'react-router-dom';
99

1010
import { PageHeader } from '@/components/PageHeader';
@@ -121,13 +121,29 @@ export const UploadPage = () => {
121121
<Button disabled={!(file && instrument)} variant={'primary'} onClick={handleInstrumentCSV}>
122122
{t('core.submit')}
123123
</Button>
124-
<Button className="gap-1.5" disabled={!instrument} variant={'primary'} onClick={handleTemplateDownload}>
125-
<DownloadIcon />
126-
{t({
127-
en: 'Download Template',
128-
fr: 'Télécharger le modèle'
129-
})}
130-
</Button>
124+
<div className="flex justify-between space-x-1">
125+
<Button className="gap-1" disabled={!instrument} variant={'primary'} onClick={handleTemplateDownload}>
126+
<DownloadIcon />
127+
{t({
128+
en: 'Download Template',
129+
fr: 'Télécharger le modèle'
130+
})}
131+
</Button>
132+
<Button
133+
className="gap-1"
134+
disabled={!instrument}
135+
variant={'primary'}
136+
onClick={() => {
137+
window.open('https://opendatacapture.org/en/docs/guides/how-to-upload-data/');
138+
}}
139+
>
140+
<BadgeHelpIcon />
141+
{t({
142+
en: 'Help',
143+
fr: 'Aide'
144+
})}
145+
</Button>
146+
</div>
131147
</div>
132148
</div>
133149
) : (

apps/web/src/features/upload/utils.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,7 +534,7 @@ export async function processInstrumentCSV(
534534
if (!headers?.length) {
535535
return resolve({ message: 'headers is undefined or empty array', success: false });
536536
}
537-
537+
let rowNumber = 1;
538538
for (const elements of dataLines) {
539539
const jsonLine: { [key: string]: unknown } = {};
540540
for (let j = 0; j < headers.length; j++) {
@@ -577,7 +577,10 @@ export async function processInstrumentCSV(
577577
interpreterResult = interpretZodValue(rawValue, typeNameResult.typeName, typeNameResult.isOptional);
578578
}
579579
if (!interpreterResult.success) {
580-
return resolve({ message: `${interpreterResult.message} at column name: '${key}'`, success: false });
580+
return resolve({
581+
message: `${interpreterResult.message} at column name: '${key}' and row number ${rowNumber}`,
582+
success: false
583+
});
581584
}
582585
jsonLine[headers[j]!] = interpreterResult.value;
583586
}
@@ -591,6 +594,7 @@ export async function processInstrumentCSV(
591594
return resolve({ message: zodIssues.join(), success: false });
592595
}
593596
result.push(zodCheck.data);
597+
rowNumber++;
594598
}
595599
resolve({ success: true, value: result });
596600
};
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
---
2+
title: Runtime Execution Context
3+
slug: en/docs/concepts/runtime-execution-context
4+
sidebar:
5+
order: 3
6+
---
7+
8+
In JavaScript, the global object varies depending on the execution environment. In the browser, the global object is `window`, which includes properties like `document`. In Node.js, the global object is `global`. This object is specific to Node.js and is not available in browsers.
9+
10+
For example, you cannot access `process.env` in a browser environment because it is specific to Node.js. Similarly, calling `document.createElement` on a server does not work, as it is intended for the client-side. Attempting either will result in a runtime error.
11+
12+
In Open Data Capture, code runs on both the client and server. You should therefore not access browser-specific APIs, like `document` or `window` unless you are within functions named `render`, which execute exclusively on the client. For those familiar with Next.js, think of these functions as rendering a component with a "use client" directive within a React Server Component.
13+
14+
## Example of Problematic Instrument
15+
16+
```ts
17+
import { defineInstrument } from '/runtime/v1/@opendatacapture/runtime-core';
18+
import { z } from '/runtime/v1/[email protected]';
19+
20+
const button = document.createElement('button');
21+
button.textContent = 'Submit Instrument';
22+
document.body.appendChild(button);
23+
24+
export default defineInstrument({
25+
// ...
26+
kind: 'INTERACTIVE',
27+
content: {
28+
render(done) {
29+
button.addEventListener('click', () => {
30+
done({ message: 'Hello World' });
31+
});
32+
}
33+
}
34+
// ...
35+
});
36+
```
37+
38+
## Fixing This Instrument
39+
40+
To fix the instrument, there are two options:
41+
42+
1. Move the browser-specific code directly within the render function
43+
2. Wrap the browser-specific code in a function. This function can be defined outside the render function but must only be called within it.
44+
45+
**Example**
46+
47+
```ts
48+
import { defineInstrument } from '/runtime/v1/@opendatacapture/runtime-core';
49+
import { z } from '/runtime/v1/[email protected]';
50+
51+
function createButton() {
52+
const button = document.createElement('button');
53+
button.textContent = 'Submit Instrument';
54+
document.body.appendChild(button);
55+
return button;
56+
}
57+
58+
export default defineInstrument({
59+
// ...
60+
kind: 'INTERACTIVE',
61+
content: {
62+
render(done) {
63+
const button = createButton();
64+
button.addEventListener('click', () => {
65+
done({ message: 'Hello World' });
66+
});
67+
}
68+
}
69+
// ...
70+
});
71+
```

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"name": "opendatacapture",
33
"type": "module",
4-
"version": "1.8.5",
4+
"version": "1.8.6",
55
"private": true,
66
"packageManager": "[email protected]",
77
"license": "Apache-2.0",
88
"engines": {
9-
"node": ">=v20.17.0"
9+
"node": ">=v22.11.0"
1010
},
1111
"scripts": {
1212
"build": "env-cmd turbo run build",
@@ -53,7 +53,7 @@
5353
"@swc/helpers": "^0.5.15",
5454
"@types/github-script": "https://github.com/actions/github-script/archive/refs/tags/v7.0.1.tar.gz",
5555
"@types/js-yaml": "^4.0.9",
56-
"@types/node": "^20.14.2",
56+
"@types/node": "22.x",
5757
"@vitest/browser": "^2.0.5",
5858
"@vitest/coverage-v8": "^2.0.5",
5959
"dotenv": "^16.4.7",

0 commit comments

Comments
 (0)