webxdc-dev
Advanced tools
Comparing version 0.10.0 to 0.11.0
@@ -6,10 +6,8 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Instances = exports.Instance = exports.createPeer = exports.createFrontend = void 0; | ||
exports.createPeer = exports.createFrontend = void 0; | ||
const express_1 = __importDefault(require("express")); | ||
const express_ws_1 = __importDefault(require("express-ws")); | ||
const ws_1 = require("ws"); | ||
const http_proxy_middleware_1 = require("http-proxy-middleware"); | ||
const message_1 = require("./message"); | ||
const SIMULATOR_PATHS = ["/webxdc.js", "/webxdc", "/webxdc/.websocket"]; | ||
function createFrontend(appInfo, instances, injectFrontend, getIndexHtml) { | ||
function createFrontend(appInfo, instances, injectFrontend, getIndexHtml, autoOpen) { | ||
const expressApp = (0, express_1.default)(); | ||
@@ -27,2 +25,3 @@ const wsInstance = (0, express_ws_1.default)(expressApp); | ||
manifestFound: appInfo.manifest.manifestFound, | ||
toolVersion: appInfo.toolVersion, | ||
}); | ||
@@ -46,2 +45,5 @@ }); | ||
instance.start(); | ||
if (autoOpen) { | ||
instance.open(); | ||
} | ||
res.json({ | ||
@@ -94,93 +96,1 @@ status: "ok", | ||
exports.createPeer = createPeer; | ||
class Instance { | ||
constructor(app, port, webXdc) { | ||
this.app = app; | ||
this.port = port; | ||
this.webXdc = webXdc; | ||
this.id = port.toString(); | ||
} | ||
start() { | ||
this.app.listen(this.port, () => { | ||
console.log(`Starting Webxdc instance at port ${this.port}`); | ||
}); | ||
} | ||
} | ||
exports.Instance = Instance; | ||
class Instances { | ||
constructor(location, injectSim, basePort) { | ||
this._onMessage = null; | ||
this.location = location; | ||
this.basePort = basePort; | ||
this.currentPort = basePort; | ||
this.instances = new Map(); | ||
this.injectSim = injectSim; | ||
this.processor = (0, message_1.createProcessor)((message) => { | ||
if (this._onMessage == null) { | ||
return; | ||
} | ||
this._onMessage(message); | ||
}); | ||
} | ||
add() { | ||
this.currentPort++; | ||
const port = this.currentPort; | ||
if (this.instances.has(port)) { | ||
throw new Error(`Already have Webxdc instance at port: ${port}`); | ||
} | ||
const wsInstance = createPeer(this.location, this.injectSim); | ||
const app = wsInstance.app; | ||
const wss = wsInstance.getWss(); | ||
const instance = new Instance(app, port, this.processor.createClient(port.toString())); | ||
app.ws("/webxdc", (ws, req) => { | ||
// when receiving an update from this peer | ||
ws.on("message", (msg) => { | ||
if (typeof msg !== "string") { | ||
console.error("webxdc: Don't know how to handle unexpected non-string data"); | ||
return; | ||
} | ||
const parsed = JSON.parse(msg); | ||
// XXX should validate parsed | ||
if (isSendUpdateMessage(parsed)) { | ||
instance.webXdc.sendUpdate(parsed.update, parsed.descr); | ||
} | ||
else if (isSetUpdateListenerMessage(parsed)) { | ||
instance.webXdc.connect((updates) => { | ||
console.info("gossip", updates); | ||
broadcast(wss, JSON.stringify({ | ||
type: "updates", | ||
updates: updates.map(([update]) => update), | ||
})); | ||
}, parsed.serial, () => { | ||
console.info("clear"); | ||
broadcast(wss, JSON.stringify({ type: "clear" })); | ||
}); | ||
} | ||
else { | ||
throw new Error(`Unknown message: ${JSON.stringify(parsed)}`); | ||
} | ||
}); | ||
}); | ||
this.instances.set(port, instance); | ||
return instance; | ||
} | ||
clear() { | ||
this.processor.clear(); | ||
} | ||
onMessage(onMessage) { | ||
this._onMessage = onMessage; | ||
} | ||
} | ||
exports.Instances = Instances; | ||
function broadcast(wss, data) { | ||
wss.clients.forEach((client) => { | ||
if (client.readyState === ws_1.WebSocket.OPEN) { | ||
client.send(data); | ||
} | ||
}); | ||
} | ||
function isSendUpdateMessage(value) { | ||
return value.type === "sendUpdate"; | ||
} | ||
function isSetUpdateListenerMessage(value) { | ||
return value.type === "setUpdateListener"; | ||
} |
@@ -15,3 +15,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getAppInfoUrl = exports.getAppInfo = exports.AppInfoError = void 0; | ||
exports.getToolVersion = exports.getAppInfoUrl = exports.getAppInfo = exports.AppInfoError = void 0; | ||
const path_1 = __importDefault(require("path")); | ||
@@ -22,3 +22,4 @@ const fs_1 = __importDefault(require("fs")); | ||
const node_fetch_1 = __importDefault(require("node-fetch")); | ||
const wait_on_1 = __importDefault(require("wait-on")); | ||
const waitOn_1 = require("./waitOn"); | ||
const APP_INFO_TIMEOUT = 5000; | ||
class AppInfoError extends Error { | ||
@@ -31,11 +32,3 @@ } | ||
try { | ||
yield (0, wait_on_1.default)({ | ||
// we don't want to do a HEAD check, just a GET check | ||
resources: [location.url.replace("http:", "http-get:")], | ||
// workaround https://github.com/jeffbski/wait-on/issues/78#issuecomment-867813529 | ||
headers: { | ||
accept: "text/html", | ||
}, | ||
timeout: 5000, | ||
}); | ||
yield (0, waitOn_1.waitOnUrl)(location.url, APP_INFO_TIMEOUT); | ||
} | ||
@@ -51,2 +44,3 @@ catch (e) { | ||
icon: getIconInfoFromDir(location.path), | ||
toolVersion: getToolVersion(), | ||
}; | ||
@@ -62,2 +56,3 @@ }); | ||
icon: yield getIconInfoFromUrl(location.url, fetch), | ||
toolVersion: getToolVersion(), | ||
}; | ||
@@ -67,2 +62,6 @@ }); | ||
exports.getAppInfoUrl = getAppInfoUrl; | ||
function getToolVersion() { | ||
return process.env.npm_package_version || "Unknown"; | ||
} | ||
exports.getToolVersion = getToolVersion; | ||
function getManifestInfoFromUrl(url, fetch) { | ||
@@ -69,0 +68,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -6,20 +6,30 @@ "use strict"; | ||
const run_1 = require("./run"); | ||
const appInfo_1 = require("./appInfo"); | ||
function parsePort(value) { | ||
const result = Number(value); | ||
if (isNaN(result)) { | ||
throw new commander_1.InvalidArgumentError("not a number"); | ||
} | ||
if (result < 0 || result > 65535) { | ||
throw new commander_1.InvalidArgumentError("port number out of range"); | ||
} | ||
return result; | ||
} | ||
function createProgram(inject) { | ||
const program = new commander_1.Command(); | ||
program.name("webxdc-dev").description("Tool simulate Webxdc in the browser"); | ||
program | ||
.name("webxdc-dev") | ||
.description("Tool simulate Webxdc in the browser") | ||
.version((0, appInfo_1.getToolVersion)()); | ||
program | ||
.command("run") | ||
.argument("<location>", "URL with dev server, path to .xdc file, or path to webxdc dist directory") | ||
.option("-p, --port <port>", "start port for webxdc-dev UI, instance ports are incremented by one each", "7000") | ||
.option("-p, --port <port>", "start port for webxdc-dev UI, instance ports are incremented by one each", parsePort, 7000) | ||
.option("-o, --open", "Automatically open instance tabs", false) | ||
.description("Run webxdc-dev simulator with webxdc from dev server URL, .xdc file or dist directory") | ||
.action((location, portString) => { | ||
const port = Number(portString.port); | ||
if (isNaN(port) || port < 0 || port > 65535) { | ||
throw new Error("provided port is invalid: " + JSON.stringify(portString)); | ||
} | ||
(0, run_1.run)(location, Number(port), inject); | ||
.action((location, options) => { | ||
(0, run_1.run)(location, options.port, inject, options.open); | ||
}); | ||
program.showHelpAfterError(); | ||
return program; | ||
} | ||
exports.createProgram = createProgram; |
@@ -10,18 +10,23 @@ "use strict"; | ||
const app_1 = require("./app"); | ||
const instance_1 = require("./instance"); | ||
const location_1 = require("./location"); | ||
const appInfo_1 = require("./appInfo"); | ||
function actualRun(appInfo, basePort, inject) { | ||
function actualRun(appInfo, basePort, inject, autoOpen) { | ||
const { injectFrontend, injectSim, getIndexHtml } = inject; | ||
const instances = new app_1.Instances(appInfo.location, injectSim, basePort); | ||
const peer0 = instances.add(); | ||
const peer1 = instances.add(); | ||
const frontend = (0, app_1.createFrontend)(appInfo, instances, injectFrontend, getIndexHtml); | ||
const instances = new instance_1.Instances(appInfo.location, injectSim, basePort); | ||
const numberOfInstances = 2; | ||
for (let i = 0; i < numberOfInstances; i++) { | ||
instances.add(); | ||
} | ||
const frontend = (0, app_1.createFrontend)(appInfo, instances, injectFrontend, getIndexHtml, autoOpen); | ||
frontend.listen(basePort, () => { | ||
console.log("Starting webxdc-dev frontend"); | ||
}); | ||
peer0.start(); | ||
peer1.start(); | ||
instances.start(); | ||
(0, open_1.default)("http://localhost:" + basePort); | ||
if (autoOpen) { | ||
instances.open(); | ||
} | ||
} | ||
function run(locationStr, basePort, inject) { | ||
function run(locationStr, basePort, inject, autoOpen) { | ||
let location; | ||
@@ -46,3 +51,3 @@ try { | ||
.then((appInfo) => { | ||
actualRun(appInfo, basePort, inject); | ||
actualRun(appInfo, basePort, inject, autoOpen); | ||
}) | ||
@@ -49,0 +54,0 @@ .catch((e) => { |
@@ -1,1 +0,1 @@ | ||
(()=>{"use strict";const e=`ws://${document.location.host}/webxdc`;window.webxdc=function(e,s=(()=>{})){let t=null;return{sendUpdate:(t,n)=>{e.send({type:"sendUpdate",update:t,descr:n}),s("send",{update:t,descr:n})},setUpdateListener:(n,o=0)=>(e.onMessage((o=>{if("updates"===o.type){s("recv",o.updates);for(const e of o.updates)n(e);null!=t&&(t(),t=null)}else"clear"===o.type&&e.clear()})),e.onConnect((()=>{e.send({type:"setUpdateListener",serial:o})})),new Promise((e=>{t=e}))),selfAddr:e.address(),selfName:e.name()}}(new class{messageListener=null;constructor(e){this.socket=new WebSocket(e)}send(e){this.socket.send(JSON.stringify(e))}onMessage(e){null!=this.messageListener&&this.socket.removeEventListener("message",this.messageListener);const s=s=>{e(JSON.parse(s.data))};this.messageListener=s,this.socket.addEventListener("message",s)}onConnect(e){const s=this.socket.readyState;if(0===s)this.socket.addEventListener("open",e);else{if(1!==s)throw new Error(`SocketTransport: socket not ready: ${s}`);e()}}clear(){window.localStorage.clear(),window.sessionStorage.clear(),window.location.reload()}address(){return`instance@${document.location.port}`}name(){return`Instance ${document.location.port}`}}(e),((...e)=>{console.info(...e)}))})(); | ||
(()=>{"use strict";const e=`ws://${document.location.host}/webxdc`;window.webxdc=function(e,t=(()=>{})){let s=null;return{sendUpdate:(s,n)=>{e.send({type:"sendUpdate",update:s,descr:n}),t("send",{update:s,descr:n})},setUpdateListener:(n,o=0)=>(e.onMessage((o=>{if("updates"===o.type){t("recv",o.updates);for(const e of o.updates)n(e);null!=s&&(s(),s=null)}else"clear"===o.type&&(t("clear"),e.clear())})),e.onConnect((()=>{e.send({type:"setUpdateListener",serial:o})})),new Promise((e=>{s=e}))),selfAddr:e.address(),selfName:e.name()}}(new class{messageListener=null;constructor(e){this.socket=new WebSocket(e)}send(e){this.socket.send(JSON.stringify(e))}onMessage(e){null!=this.messageListener&&this.socket.removeEventListener("message",this.messageListener);const t=t=>{e(JSON.parse(t.data))};this.messageListener=t,this.socket.addEventListener("message",t)}onConnect(e){const t=this.socket.readyState;if(0===t)this.socket.addEventListener("open",e);else{if(1!==t)throw new Error(`SocketTransport: socket not ready: ${t}`);e()}}clear(){window.localStorage.clear(),window.sessionStorage.clear(),window.location.reload()}address(){return`instance@${document.location.port}`}name(){return`Instance ${document.location.port}`}}(e),((...e)=>{console.info(...e)})),window.addEventListener("load",(function(){let e=document.getElementsByTagName("title")[0];null==e&&(e=document.createElement("title"),document.getElementsByTagName("head")[0].append(e)),e.innerText=window.webxdc.selfName}))})(); |
{ | ||
"name": "webxdc-dev", | ||
"version": "0.10.0", | ||
"version": "0.11.0", | ||
"description": "A dev tool for Webxdc", | ||
@@ -57,2 +57,3 @@ "homepage": "https://github.com/webxdc/webxdc-dev#readme", | ||
"concurrently": "^7.2.2", | ||
"copy-webpack-plugin": "^11.0.0", | ||
"eslint": "^8.17.0", | ||
@@ -59,0 +60,0 @@ "eslint-config-prettier": "^8.5.0", |
@@ -87,2 +87,4 @@ # webxdc-dev | ||
### Command-line options | ||
### Controlling the port number | ||
@@ -97,2 +99,11 @@ | ||
### Automatically opening tabs. | ||
By using the `--open` command line option you can cause `webxdc-dev` to | ||
automatically open tabs for each instance upon startup and when you add one. | ||
```shell | ||
webxdc-dev run --open /path/to/webxdc/project | ||
``` | ||
## `webxdc` as a `package.json` script | ||
@@ -99,0 +110,0 @@ |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
319963
23
1659
238
30
7