Skip to content

Commit 0bb3301

Browse files
committed
Added loadDhModules util to simplify standard usage (DH-19067)
1 parent 99dfcab commit 0bb3301

4 files changed

Lines changed: 72 additions & 11 deletions

File tree

package-lock.json

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

packages/jsapi-nodejs/README.md

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# @deephaven/jsapi-nodejs
22

3-
Deephaven utils for consuming Jsapi from a server from a nodejs app. It can
4-
optionally convert the server module format from `ESM` -> `CJS` or `CJS` -> `ESM`
5-
if the server and consumer don't use the same module format.
3+
Deephaven utils for consuming Jsapi from a server from a nodejs app. The jsapi
4+
can be downloaded as an `ESM` or `CJS` module.
65

76
## Install
87

@@ -16,17 +15,14 @@ npm install --save @deephaven/jsapi-nodejs
1615
import fs from 'node:fs';
1716
import path from 'node:path';
1817

19-
import { loadModules } from '@deephaven/jsapi-nodejs';
18+
import { loadDhModules } from '@deephaven/jsapi-nodejs';
2019

2120
const tmpDir = path.join(__dirname, 'tmp');
2221

23-
// Download jsapi `ESM` files from DH Community server and export as `CJS` module.
24-
const dhc = await loadModules({
22+
// Download jsapi from a Deephaven server
23+
const dhc = await loadDhModules({
2524
serverUrl: new URL('http://localhost:10000'),
26-
serverPaths: ['jsapi/dh-core.js', 'jsapi/dh-internal.js'],
27-
download: true,
2825
storageDir: tmpDir,
29-
sourceModuleType: 'esm',
30-
targetModuleType: 'cjs',
26+
targetModuleType: 'esm', // set to `cjs` to download as a CommonJS module
3127
});
3228
```

packages/jsapi-nodejs/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"build:babel": "babel ./src --out-dir ./dist --extensions \".ts,.tsx,.js,.jsx\" --source-maps --root-mode upward"
2222
},
2323
"dependencies": {
24+
"@deephaven/jsapi-types": "^1.0.0-dev0.37.2",
2425
"@deephaven/log": "file:../log",
2526
"@deephaven/utils": "file:../utils",
2627
"ws": "^8.18.0"

packages/jsapi-nodejs/src/loaderUtils.ts

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import fs from 'node:fs';
22
import path from 'node:path';
3+
import type { dh as DhType } from '@deephaven/jsapi-types';
34

45
import { downloadFromURL, urlToDirectoryName } from './serverUtils.js';
56
import { polyfillWs } from './polyfillWs.js';
@@ -84,4 +85,65 @@ export async function loadModules<TMainModule>({
8485
return require(mainModulePath);
8586
}
8687

87-
export default loadModules;
88+
/**
89+
* Load `jsapi/dh-core.js` and `jsapi/dh-internal.js` modules from a Core Server.
90+
* @param serverUrl The URL of the server to load from.
91+
* @param storageDir The directory to store the downloaded modules.
92+
* @param targetModuleType The type of module to load. Can be either 'esm' or 'cjs'.
93+
* @returns The default export the `jsapi/dh-core.js` module.
94+
*/
95+
export async function loadDhModules({
96+
serverUrl,
97+
storageDir,
98+
targetModuleType,
99+
}: Pick<
100+
LoadModuleOptions,
101+
'serverUrl' | 'storageDir' | 'targetModuleType'
102+
>): Promise<typeof DhType> {
103+
if (targetModuleType === 'esm') {
104+
// These will not be needed if we ever update the JSAPI to not rely on
105+
// `window` and `self`.
106+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
107+
// @ts-ignore
108+
globalThis.self = globalThis;
109+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
110+
// @ts-ignore
111+
globalThis.window = globalThis;
112+
}
113+
114+
const coreModule = await loadModules<
115+
typeof DhType & { default?: typeof DhType }
116+
>({
117+
serverUrl,
118+
serverPaths: ['jsapi/dh-core.js', 'jsapi/dh-internal.js'],
119+
storageDir,
120+
targetModuleType,
121+
download:
122+
targetModuleType === 'esm'
123+
? // ESM does not need any transformation since the server modules are already ESM.
124+
true
125+
: // CJS needs a post-download transform to convert the ESM modules to CJS.
126+
(serverPath, content) => {
127+
if (serverPath === 'jsapi/dh-core.js') {
128+
return content
129+
.replace(
130+
`import {dhinternal} from './dh-internal.js';`,
131+
`const {dhinternal} = require("./dh-internal.js");`
132+
)
133+
.replace(`export default dh;`, `module.exports = dh;`);
134+
}
135+
136+
if (serverPath === 'jsapi/dh-internal.js') {
137+
return content.replace(
138+
`export{__webpack_exports__dhinternal as dhinternal};`,
139+
`module.exports={dhinternal:__webpack_exports__dhinternal};`
140+
);
141+
}
142+
143+
return content;
144+
},
145+
});
146+
147+
// ESM uses `default` export. CJS does not.
148+
return coreModule.default ?? coreModule;
149+
}

0 commit comments

Comments
 (0)