Skip to content

Commit 295aff6

Browse files
authored
Merge pull request #1084 from joshunrau/docs
docs: document runtime execution context
2 parents 7ea5bc2 + 2440014 commit 295aff6

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed
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+
```

0 commit comments

Comments
 (0)