Skip to content

Commit 984db81

Browse files
authored
Merge pull request #598 from witheve/npm-package
Npm package
2 parents 8128f37 + 6b24a5d commit 984db81

17 files changed

+519
-184
lines changed

.npmignore

Whitespace-only changes.

README.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,20 @@ or you can [download](https://github.com/witheve/Eve/archive/master.zip) the Eve
2323

2424
```
2525
npm install
26+
npm run build
2627
npm start
2728
```
2829

2930
Then open `http://localhost:8080/` in your browser.
3031

32+
### From npm
33+
34+
Alternatively, you can download Eve directly from npm with the following command:
35+
36+
```
37+
npm install witheve
38+
```
39+
3140
### From Docker
3241

3342
First, [download](https://www.docker.com/products/docker) and install Docker for your platform. To download and install the Eve container, run the following command:
@@ -46,10 +55,9 @@ You can learn about Eve with the following resources:
4655

4756
*Please let us know what kind of documents would be the most helpful as you begin your journey with Eve*. We want our documentation to be a highlight of the Eve experience, so any suggestions are greatly appreciated.
4857

49-
### Running programs on Node.js
58+
### Running Eve Programs in Server Mode
5059

51-
By default, Eve serves the IDE with the browser as the runtime (executing the program).
52-
To instead have the program execute on the server-side, in Node.js use:
60+
By default, Eve executes on the client browser. To instead execute your program on the server, launch Eve with the `--server` flag:
5361

5462
```
5563
npm start -- --server

bin/eve.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env node
2+
3+
var path = require("path");
4+
var fs = require("fs");
5+
var minimist = require("minimist");
6+
7+
var config = require("../build/src/config");
8+
var Owner = config.Owner;
9+
var server = require("../build/src/runtime/server");
10+
11+
const argv = minimist(process.argv.slice(2), {boolean: ["server", "editor"]});
12+
13+
// Since our current development pattern uses npm as its package repository, we treat the nearest ancestor directory with a package.json (inclusive) as the directory's "root".
14+
function findRoot(root) {
15+
var pkg;
16+
root = root.split(path.sep);
17+
while(!pkg && root.length > 1) {
18+
var cur = root.join(path.sep);
19+
if(fs.existsSync(path.join(cur, "package.json"))) {
20+
return cur;
21+
}
22+
root.pop();
23+
}
24+
}
25+
26+
27+
var port = argv["port"] || process.env.PORT || 8080;
28+
var runtimeOwner = argv["server"] ? Owner.server : Owner.client;
29+
var controlOwner = argv["localControl"] ? Owner.client : Owner.server;
30+
var editor = argv["editor"] || false;
31+
var filepath = argv["_"][0];
32+
var internal = false;
33+
34+
var root = findRoot(process.cwd());
35+
var eveRoot = findRoot(__dirname);
36+
37+
38+
// If we're executing within the eve module/repo, we're running internally and should expose our examples, src, etc.
39+
// This should be handled down the road by some sort of a manifest in conjunction with the `root` rather than hardcoding.
40+
if(root === eveRoot) internal = true;
41+
else if(!root) {
42+
internal = true;
43+
// We shouldn't (and when globally installed, *can't*) taint the internal examples when running as an installed binary.
44+
// @TODO: In the future we should have a more flexible solution that can copy out the examples into your current workspace when edited.
45+
controlOwner = Owner.client;
46+
}
47+
48+
49+
// If we're not given an explicit filepath to run, assume the user wanted the editor (rather than a blank page).
50+
// Similarly, if we're running internally, send the user over to the quickstart, since they're likely testing the waters.
51+
if(!filepath) {
52+
editor = true;
53+
if(internal) filepath = eveRoot + "/" + "examples/quickstart.eve";
54+
} else {
55+
filepath = path.resolve(filepath);
56+
}
57+
58+
var opts = {internal: internal, runtimeOwner: runtimeOwner, controlOwner: controlOwner, editor: editor, port: port, path: filepath, internal: internal, root: root, eveRoot: eveRoot};
59+
config.init(opts);
60+
61+
server.run(opts);

index.html

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<link href="favicon.png" rel="icon" type="image/png" />
2020
</head>
2121
<body>
22-
<script type="text/javascript" src="build/examples.js"></script>
22+
<script type="text/javascript" src="build/workspaces.js"></script>
2323
<script type="text/javascript" src="build/src/uuid.js"></script>
2424
<script type="text/javascript" src="build/src/codemirror.js"></script>
2525
<script type="text/javascript" src="build/src/simplescrollbars.js"></script>
@@ -30,7 +30,8 @@
3030
<script>
3131
SystemJS.config({
3232
baseURL: "build/src",
33-
defaultJSExtensions: true,
33+
defaultJSExtensions: true,
34+
map: {fs: "@empty", path: "@empty", glob: "@empty", mkdirp: "@empty"},
3435
meta: {"build/src/codemirror.js": { format: "cjs" }}
3536
});
3637

package.json

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,33 @@
11
{
2+
"name": "witheve",
3+
"version": "0.2.1",
4+
"description": "Programming designed for humans",
5+
"keywords": ["language", "ide", "relational", "database", "dataflow"],
6+
"homepage": "http://witheve.com",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/witheve/Eve"
10+
},
11+
"bugs": {
12+
"url": "https://github.com/witheve/Eve/issues"
13+
},
14+
"license": "Apache-2.0",
15+
16+
"bin": {
17+
"eve": "./bin/eve.js"
18+
},
19+
20+
"scripts": {
21+
"build": "./node_modules/.bin/tsc && node ./build/scripts/build.js",
22+
"start": "./node_modules/.bin/tsc && node ./bin/eve.js",
23+
"server": "node ./bin/eve.js",
24+
25+
"prepublish": "./node_modules/.bin/tsc && node ./build/scripts/build.js",
26+
"build-dist": "node ./build/scripts/build-dist.js",
27+
28+
"test": "node ./build/test/all.js | faucet"
29+
},
30+
231
"dependencies": {
332
"@types/body-parser": "0.0.33",
433
"@types/commonmark": "^0.22.29",
@@ -25,19 +54,5 @@
2554
"devDependencies": {
2655
"faucet": "0.0.1",
2756
"tape": "^4.6.0"
28-
},
29-
"scripts": {
30-
"install": "./node_modules/.bin/tsc",
31-
"postinstall": "node ./build/scripts/build.js",
32-
"build": "node ./build/scripts/build.js",
33-
"build-dist": "node ./build/scripts/build-dist.js",
34-
"start": "node ./build/src/runtime/server.js",
35-
"server": "node ./build/src/runtime/server.js",
36-
"test": "node ./build/test/all.js | faucet"
37-
},
38-
"repository": {
39-
"type": "git",
40-
"url": "https://github.com/witheve/Eve.git"
41-
},
42-
"license": "Apache-2.0"
57+
}
4358
}

scripts/build-dist.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ function buildDist(callback:() => void) {
3131
fs.writeFileSync("./dist/index.html", index);
3232

3333
//copy("./index.html", "./dist/index.html", tracker.track("copy index"));
34-
copy("./build/examples.js", "./dist/build/examples.js", tracker.track("copy packaged examples"));
34+
copy("./build/workspaces.js", "./dist/build/workspaces.js", tracker.track("copy packaged workspaces"));
3535

3636

3737
for(let pattern of ["build/src/**/*.js", "build/src/**/*.js.map", "src/**/*.css", "css/**/*.css", "examples/**/*.css"]) {

scripts/build.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import * as path from "path";
12
import * as fs from "fs";
23
import * as glob from "glob";
3-
import {packageExamples} from "./package-examples";
4+
import {packageWorkspaces} from "./package-workspaces";
45

56
export function onError(err) {
67
throw err;
@@ -70,12 +71,13 @@ export function build(callback:() => void) {
7071
"node_modules/chevrotain/lib/chevrotain.js"
7172
];
7273
for(let dep of deps) {
74+
dep = path.resolve(dep);
7375
let base = dep.split("/").pop();
7476
copy(dep, "build/src/" + base, tracker.track("copy node module files"));
7577
}
7678

77-
// Package examples.
78-
packageExamples(tracker.track("package examples"));
79+
// Package workspaces.
80+
packageWorkspaces(tracker.track("package workspaces"));
7981

8082
tracker.finishedStartingTasks();
8183
}

scripts/package-examples.ts

Lines changed: 0 additions & 20 deletions
This file was deleted.

scripts/package-workspaces.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import * as fs from "fs";
2+
import * as path from "path";
3+
import * as eveSource from "../src/runtime/eveSource";
4+
5+
eveSource.add("eve", "./examples");
6+
eveSource.add("examples", "./examples");
7+
8+
export function packageWorkspaces(callback:() => void) {
9+
fs.writeFileSync("build/workspaces.js", eveSource.pack());
10+
callback();
11+
}
12+
13+
if(require.main === module) {
14+
console.log("Packaging...")
15+
packageWorkspaces(() => console.log("done."));
16+
}

src/client.ts

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {clone, debounce, uuid, sortComparator} from "./util";
2+
import {Owner} from "./config";
23
import {sentInputValues, activeIds, renderRecords, renderEve} from "./renderer"
34
import {IDE} from "./ide";
45
import * as browser from "./runtime/browser";
@@ -140,14 +141,13 @@ export class EveClient {
140141

141142
constructor(url?:string) {
142143
let loc = url ? url : this.getUrl();
143-
let self = this;
144144

145145
this.socket = new WebSocket(loc);
146146
this.socket.onerror = (event) => {
147-
self.onError();
147+
this.onError();
148148
}
149149
this.socket.onopen = (event) => {
150-
self.onOpen();
150+
this.onOpen();
151151
}
152152
this.socket.onmessage = (event) => {
153153
this.onMessage(event);
@@ -202,9 +202,12 @@ export class EveClient {
202202
onError() {
203203
this.localControl = true;
204204
this.localEve = true;
205-
if(this.showIDE) {
206-
this.ide = new IDE();
207-
this.ide.local = true;
205+
if(!this.ide) {
206+
this._initProgram({runtimeOwner: Owner.client, controlOwner: Owner.client, withIDE: true, path: (window.location.hash || "").slice(1) || "/examples/quickstart.eve"});
207+
} else if(this.showIDE) {
208+
this.ide.injectNotice("error", "Unexpectedly disconnected from the server. Please refresh the page.");
209+
} else {
210+
console.error("Unexpectedly disconnected from the server. Please refresh the page.");
208211
}
209212
}
210213

@@ -266,16 +269,27 @@ export class EveClient {
266269
}
267270

268271
_initProgram(data) {
269-
this.localEve = data.local;
272+
this.localEve = data.runtimeOwner === Owner.client;
273+
this.localControl = data.controlOwner === Owner.client;
270274
this.showIDE = data.withIDE;
271-
if(data.local) {
275+
if(this.localEve) {
272276
browser.init(data.code);
273277
}
274278
if(this.showIDE) {
279+
// Ensure the URL bar is in sync with the server.
280+
// @FIXME: This back and forth of control over where we are
281+
// is an Escherian nightmare.
282+
if(!data.path) {
283+
history.pushState({}, "", window.location.pathname);
284+
}
285+
275286
this.ide = new IDE();
287+
this.ide.local = this.localControl;
276288
initIDE(this);
277289
this.ide.render();
278-
this.ide.loadFile(data.path, data.code);
290+
if(data.path && data.path.length > 2) {
291+
this.ide.loadFile(data.path, data.code);
292+
}
279293
}
280294
onHashChange({});
281295
}
@@ -425,9 +439,6 @@ function initIDE(client:EveClient) {
425439
client.send({scope: "root", type: "parse", code})
426440
client.send({type: "eval", persist: false});
427441
let url = `${location.pathname}#${documentId}`;
428-
if(documentId.indexOf("/examples/") === -1) {
429-
url = `${location.pathname}#/examples/${documentId}`;
430-
}
431442
history.pushState({}, "", url + location.search);
432443
analyticsEvent("load-document", documentId);
433444
}
@@ -440,18 +451,21 @@ function initIDE(client:EveClient) {
440451
client.send({type: "tokenInfo", tokenId});
441452
}
442453

443-
ide.loadWorkspace("examples", window["examples"]);
454+
let cache = window["_workspaceCache"];
455+
for(let workspace in cache || {}) {
456+
ide.loadWorkspace(workspace, cache[workspace]);
457+
}
444458
}
445459

446460
function changeDocument() {
447461
if(!client.showIDE) return;
448462
let ide = client.ide;
449-
let docId = "quickstart.eve";
450-
let path = "/" + location.hash.split('?')[0].split("#/")[1];
451-
console.log("PATH", path, location.hash);
452-
if(path) {
463+
// @FIXME: This is not right in the non-internal case.
464+
let docId = "/examples/quickstart.eve";
465+
let path = location.hash && location.hash.split('?')[0].split("#/")[1];
466+
if(path && path.length > 2) {
453467
if(path[path.length - 1] === "/") path = path.slice(0, -1);
454-
docId = path;
468+
docId = "/" + path;
455469
}
456470
if(!docId) return;
457471
if(docId === ide.documentId) return;

0 commit comments

Comments
 (0)