Skip to content

Commit ad97a9e

Browse files
vegegokuniloc132
andauthored
Package JS API to be an ES6 module (#2733)
Both dh-core and dh-internal here have been changed, through the use of a custom GWT linker. Also updates html samples and web-client-ui to use the new module packaging. Note that the web-client-ui build is an alpha release, but will switch to a stable release soon. --------- Fixes #2735 Co-authored-by: Colin Alworth <colinalworth@deephaven.io>
1 parent f68e872 commit ad97a9e

28 files changed

Lines changed: 250 additions & 189 deletions

proto/raw-js-openapi/webpack.config.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ module.exports = {
88
output: {
99
path: __dirname+'/build/js-out/',
1010
filename: 'dh-internal.js',
11-
libraryTarget: "umd",
11+
libraryTarget: 'module',
12+
module:true,
13+
},
14+
experiments: {
15+
outputModule:true
1216
},
1317
resolve : {
1418
modules: ['node_modules', __dirname + '/build/js-src'],

web/client-api/src/main/java/io/deephaven/web/DeephavenJsApiLinker.java

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
import com.google.gwt.core.ext.linker.*;
1010
import com.google.gwt.dev.About;
1111
import com.google.gwt.dev.util.DefaultTextOutput;
12+
import com.google.gwt.util.tools.Utility;
1213

14+
import java.io.IOException;
1315
import java.util.Set;
1416

1517
/**
@@ -35,8 +37,6 @@ public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet ar
3537

3638
ArtifactSet toReturn = new ArtifactSet(artifacts);
3739
DefaultTextOutput out = new DefaultTextOutput(true);
38-
out.print("(function(){");
39-
out.newline();
4040

4141
// get compilation result
4242
Set<CompilationResult> results = artifacts.find(CompilationResult.class);
@@ -54,23 +54,41 @@ public ArtifactSet link(TreeLogger logger, LinkerContext context, ArtifactSet ar
5454

5555
// get the generated javascript
5656
String[] javaScript = result.getJavaScript();
57-
out.print("self.dh = {}");
58-
out.newline();
59-
out.print("var $wnd = self, $doc, $entry, $moduleName, $moduleBase;");
60-
out.newline();
61-
out.print("var $gwt_version = \"" + About.getGwtVersionNum() + "\";");
62-
out.newlineOpt();
63-
out.print(javaScript[0]);
64-
out.newline();
65-
66-
out.print("gwtOnLoad(null,'" + context.getModuleName() + "',null);");
67-
out.newline();
68-
out.print("})();");
69-
out.newline();
57+
58+
StringBuffer buffer = readFileToStringBuffer(getSelectionScriptTemplate(), logger);
59+
replaceAll(buffer, "__GWT_VERSION__", About.getGwtVersionNum());
60+
replaceAll(buffer, "__JAVASCRIPT_RESULT__", javaScript[0]);
61+
replaceAll(buffer, "__MODULE_NAME__", context.getModuleName());
62+
63+
out.print(buffer.toString());
7064

7165
toReturn.add(emitString(logger, out.toString(), "dh-core.js"));
7266

7367
return toReturn;
7468
}
7569

70+
protected StringBuffer readFileToStringBuffer(String filename,
71+
TreeLogger logger) throws UnableToCompleteException {
72+
StringBuffer buffer;
73+
try {
74+
buffer = new StringBuffer(Utility.getFileFromClassPath(filename));
75+
} catch (IOException e) {
76+
logger.log(TreeLogger.ERROR, "Unable to read file: " + filename, e);
77+
throw new UnableToCompleteException();
78+
}
79+
return buffer;
80+
}
81+
82+
protected String getSelectionScriptTemplate() {
83+
return "io/deephaven/web/DeephavenJsApiLinkerTemplate.js";
84+
}
85+
86+
protected static void replaceAll(StringBuffer buf, String search,
87+
String replace) {
88+
int len = search.length();
89+
for (int pos = buf.indexOf(search); pos >= 0; pos = buf.indexOf(search,
90+
pos + replace.length())) {
91+
buf.replace(pos, pos + len, replace);
92+
}
93+
}
7694
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
function bindTo(target, source) {
2+
var descriptors = Object.getOwnPropertyDescriptors(source);
3+
for (var key in descriptors) {
4+
if (!(key[0].toUpperCase() === key[0])) {
5+
var descriptor = descriptors[key];
6+
if (typeof (descriptor.value) === 'function') {
7+
descriptor.value = descriptor.value.bind(source)
8+
} else if (typeof (descriptor.get) === 'function') {
9+
descriptor.get = descriptor.get.bind(source);
10+
}
11+
}
12+
}
13+
Object.defineProperties(target, descriptors);
14+
}
15+
16+
var Scope = function () {
17+
};
18+
Scope.prototype = self;
19+
var $doc, $entry, $moduleName, $moduleBase;
20+
var $wnd = new Scope();
21+
bindTo($wnd, self);
22+
var dh = {}
23+
$wnd.dh = dh;
24+
import {dhinternal} from './dh-internal.js';
25+
$wnd.dhinternal = dhinternal;
26+
var $gwt_version = "__GWT_VERSION__";
27+
__JAVASCRIPT_RESULT__
28+
gwtOnLoad(null, '__MODULE_NAME__', null);
29+
export default dh;

web/client-api/src/main/java/io/deephaven/web/public/console.html

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,24 +4,25 @@
44
<meta charset="utf-8" />
55

66
<title>Deephaven JS API Console Interaction</title>
7-
<script src="dh-internal.js" type="text/javascript"></script>
8-
<script src="dh-core.js" type="text/javascript"></script>
97
</head>
108
<body>
119
<div id="logs"></div>
1210
<div id="tools">
1311
<textarea id="command" placeholder="waiting for connection..." rows="1" cols="80" autofocus="autofocus" disabled="disabled" style="resize:vertical"></textarea><button id="run">Run</button>
1412
</div>
15-
<script type="text/javascript">
13+
<script type="module">
14+
import dh from './dh-core.js';
15+
16+
const {CoreClient} = dh;
1617
var client;
1718
var connection;
1819
var ide;
1920
var table;
2021
(async () => {
2122
var url = new URL(window.location);
2223
// create a connection to the server
23-
client = new dh.CoreClient(url.protocol + "//" + url.host);
24-
await client.login({type:dh.CoreClient.LOGIN_TYPE_ANONYMOUS});
24+
client = new CoreClient(url.protocol + "//" + url.host);
25+
await client.login({type:CoreClient.LOGIN_TYPE_ANONYMOUS});
2526
connection = await client.getAsIdeConnection();
2627

2728
// check if a language was specified

web/client-api/src/main/java/io/deephaven/web/public/format.html

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
<head>
44
<meta charset="UTF-8">
55
<title>Deephaven Web API Formatting examples</title>
6-
<script src="dh-internal.js" type="text/javascript"></script>
7-
<script src="dh-core.js" type="text/javascript"></script>
86
<style>
97
.console {
108
max-height: 200px;
@@ -73,8 +71,8 @@ <h4>Sample format strings (click to replace the current format)</h4>
7371
</ul>
7472
</div>
7573
</div>
76-
<script>
77-
74+
<script type="module">
75+
import dh from './dh-core.js';
7876

7977
document.querySelectorAll(".section").forEach(section => {
8078
var patternInput = section.querySelector('.pattern');

web/client-api/src/main/java/io/deephaven/web/public/freeze.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
<head>
44
<meta charset="utf-8" />
55
<title>Deephaven Web API table freeze</title>
6-
<script src="dh-internal.js" type="text/javascript"></script>
7-
<script src="dh-core.js" type="text/javascript"></script>
86
<link href="basic.css" rel="stylesheet" type="text/css" />
97
<style>
108
li.open ul { display:block; }
@@ -40,16 +38,18 @@ <h3>Selected table data</h3>
4038
<button id="next_frozen">&gt;</button>
4139
<button id="end_frozen">&gt;&gt;</button>
4240

43-
<script>
41+
<script type="module">
42+
import dh from './dh-core.js';
4443

44+
const {Client} = dh;
4545
var url = new URL('/socket', window.location);
4646
if (url.protocol === 'http:') {
4747
url.protocol = 'ws:';
4848
} else {
4949
url.protocol = 'wss:';
5050
}
5151

52-
window.c = new dh.Client(url.href);
52+
window.c = new Client(url.href);
5353
c.addEventListener(dh.Client.EVENT_CONNECT, () => {
5454
connected();
5555
c.login({username:'dh',token:'dh',type:'password'}).then(result => {

web/client-api/src/main/java/io/deephaven/web/public/grpc.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
<meta charset="utf-8" />
55

66
<title>Deephaven gRPC test page</title>
7-
<script src="dh-internal.js" type="text/javascript"></script>
87
</head>
98
<body>
109
<h3>Simple test page to verify that gRPC is working</h3>

web/client-api/src/main/java/io/deephaven/web/public/index.html

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
<meta charset="utf-8" />
55

66
<title>Deephaven JS API samples</title>
7-
<script src="dh-internal.js" type="text/javascript"></script>
8-
<script src="dh-core.js" type="text/javascript"></script>
97
</head>
108
<body>
119
Welcome to the Deephaven JS API. This page has the api loaded, open the browser console to interact with the server.

web/client-api/src/main/java/io/deephaven/web/public/input_table.html

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
<head>
44
<meta charset="utf-8" />
55
<title>Deephaven Web API table viewport and updates</title>
6-
<script src="dh-internal.js" type="text/javascript"></script>
7-
<script src="dh-core.js" type="text/javascript"></script>
86
<script src="input_tables.js" type="text/javascript"></script>
97
<link href="basic.css" rel="stylesheet" type="text/css" />
108
<style>
@@ -34,7 +32,10 @@ <h3>Table data (bold headers are keys)</h3>
3432
<button id="next">&gt;</button>
3533
<button id="end">&gt;&gt;</button>
3634

37-
<script>
35+
<script type="module">
36+
import dh from './dh-core.js'
37+
38+
const {CoreClient, Table} = dh;
3839
var table, inputTable;
3940
var connection;
4041
var ide;
@@ -43,8 +44,8 @@ <h3>Table data (bold headers are keys)</h3>
4344
var currentOffset;
4445
var PAGE_SIZE = 20;
4546
(async () => {
46-
var client = new dh.CoreClient(window.location.protocol + "//" + window.location.host);
47-
await client.login({type:dh.CoreClient.LOGIN_TYPE_ANONYMOUS});
47+
var client = new CoreClient(window.location.protocol + "//" + window.location.host);
48+
await client.login({type:CoreClient.LOGIN_TYPE_ANONYMOUS});
4849
connection = await client.getAsIdeConnection();
4950

5051
var types = await connection.getConsoleTypes();
@@ -137,7 +138,7 @@ <h3>Table data (bold headers are keys)</h3>
137138
simplePagingTable.appendChild(header);
138139

139140
// listen for items to be added, populate the table body
140-
oldTableHandlerCleanup = t.addEventListener(dh.Table.EVENT_UPDATED, function handleTableUpdate(event) {
141+
oldTableHandlerCleanup = t.addEventListener(Table.EVENT_UPDATED, function handleTableUpdate(event) {
141142
console.log("update event received, time to redraw data");
142143
// rebuild the current tbody from scratch
143144
var tbody = simplePagingTable.querySelector('tbody');

web/client-api/src/main/java/io/deephaven/web/public/linked/child.html

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
<head>
44
<meta charset="utf-8" />
55
<title>Deephaven Web API linked table example: child window</title>
6-
<script src="../dh-internal.js" type="text/javascript"></script>
7-
<script src="../dh-core.js" type="text/javascript"></script>
86
<link href="../basic.css" rel="stylesheet" type="text/css" />
97
</head>
108
<body>
@@ -26,7 +24,10 @@ <h3>Outgoing link summary</h3>
2624

2725
</ul>
2826

29-
<script>
27+
<script type="module">
28+
import dh from '../dh-core.js';
29+
30+
const {Client, FilterValue, Table} = dh;
3031
if (!window.opener) {
3132
alert("This page only works correctly when opened by another window.");
3233
throw "This page only works correctly when opened by another window.";
@@ -43,14 +44,14 @@ <h3>Outgoing link summary</h3>
4344
url.protocol = 'wss:';
4445
}
4546

46-
window.c = new dh.Client(url.href);
47-
c.addEventListener(dh.Client.EVENT_CONNECT, () => {
47+
window.c = new Client(url.href);
48+
c.addEventListener(Client.EVENT_CONNECT, () => {
4849
c.login({username:'dh',token:'dh',type:'password'}).then(result => {
4950
console.log("login successful");
5051
});
5152
});
5253
//wait for the named config to load
53-
c.addEventListener(dh.Client.EVENT_CONFIG_ADDED, event => {
54+
c.addEventListener(Client.EVENT_CONFIG_ADDED, event => {
5455
var config = event.detail;
5556
if (config.name === configName) {
5657
if (config.status !== 'Running') {
@@ -136,9 +137,9 @@ <h3>Outgoing link summary</h3>
136137

137138
// wrap the data so that we can handle it as a filter value
138139
if (typeof valueToFilterOn === 'string') {
139-
valueToFilterOn = dh.FilterValue.ofString(valueToFilterOn);
140+
valueToFilterOn = FilterValue.ofString(valueToFilterOn);
140141
} else {
141-
valueToFilterOn = dh.FilterValue.ofNumber(valueToFilterOn);
142+
valueToFilterOn = FilterValue.ofNumber(valueToFilterOn);
142143
}
143144

144145
// apply a new filter (could also present a menu at this point to ask which filter to use)
@@ -166,7 +167,7 @@ <h3>Outgoing link summary</h3>
166167
simpleLinkedTable.appendChild(header);
167168

168169
// listen for items to be added, populate the table body
169-
oldTableHandlerCleanup = table.addEventListener(dh.Table.EVENT_UPDATED, function handleTableUpdate(event) {
170+
oldTableHandlerCleanup = table.addEventListener(Table.EVENT_UPDATED, function handleTableUpdate(event) {
170171
console.log("update event received, time to redraw data");
171172
// rebuild the current tbody from scratch
172173
var tbody = simpleLinkedTable.querySelector('tbody');

0 commit comments

Comments
 (0)