Browse Source

garbage

update-deps
Alex Mikhalev 7 years ago
parent
commit
d4164b9050
  1. 2
      app/components/ProgramTable.tsx
  2. 6
      app/components/SectionRunnerView.tsx
  3. 50
      app/sprinklers/websocket.ts
  4. 70
      app/webpack.config.js
  5. 2
      common/sprinklers/ErrorCode.ts
  6. 1
      common/tsconfig.json
  7. 19
      package.json
  8. 18
      paths.js
  9. 2
      server/state.ts
  10. 1244
      yarn.lock

2
app/components/ProgramTable.tsx

@ -1,4 +1,4 @@
import { flatMap } from "lodash"; import flatMap from "lodash-es/flatMap";
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import * as moment from "moment"; import * as moment from "moment";
import * as React from "react"; import * as React from "react";

6
app/components/SectionRunnerView.tsx

@ -87,7 +87,7 @@ class SectionRunView extends React.Component<{
const duration = Duration.fromSeconds(run.duration); const duration = Duration.fromSeconds(run.duration);
const cancel = run.cancel; const cancel = run.cancel;
const description = `'${section.name}' for ${duration.toString()}`; const description = `'${section.name}' for ${duration.toString()}`;
let running: boolean = false; let running: boolean = false; // tslint:disable-line:no-unused-variable
let paused: boolean = false; let paused: boolean = false;
let progressBar: React.ReactNode | undefined; let progressBar: React.ReactNode | undefined;
if (run.startTime != null) { if (run.startTime != null) {
@ -123,10 +123,10 @@ export default class SectionRunnerView extends React.Component<{
const queueView = queue.map((run) => const queueView = queue.map((run) =>
<SectionRunView key={run.id} run={run} sections={sections}/>); <SectionRunView key={run.id} run={run} sections={sections}/>);
if (current) { if (current) {
queueView.unshift(<SectionRunView run={current} sections={sections}/>); queueView.unshift(<SectionRunView key={-1} run={current} sections={sections}/>);
} }
if (queueView.length === 0) { if (queueView.length === 0) {
queueView.push(<Segment>No items in queue</Segment>); queueView.push(<Segment key={0}>No items in queue</Segment>);
} }
return ( return (
<Segment className="sectionRunner"> <Segment className="sectionRunner">

50
app/sprinklers/websocket.ts

@ -12,6 +12,7 @@ import { action, autorun, observable } from "mobx";
const log = logger.child({ source: "websocket" }); const log = logger.child({ source: "websocket" });
const TIMEOUT_MS = 5000; const TIMEOUT_MS = 5000;
const RECONNECT_TIMEOUT_MS = 5000;
export class WSSprinklersDevice extends s.SprinklersDevice { export class WSSprinklersDevice extends s.SprinklersDevice {
readonly api: WebSocketApiClient; readonly api: WebSocketApiClient;
@ -39,7 +40,6 @@ export class WSSprinklersDevice extends s.SprinklersDevice {
export class WebSocketApiClient implements s.ISprinklersApi { export class WebSocketApiClient implements s.ISprinklersApi {
readonly webSocketUrl: string; readonly webSocketUrl: string;
socket!: WebSocket;
device: WSSprinklersDevice; device: WSSprinklersDevice;
nextDeviceRequestId = Math.round(Math.random() * 1000000); nextDeviceRequestId = Math.round(Math.random() * 1000000);
@ -47,6 +47,9 @@ export class WebSocketApiClient implements s.ISprinklersApi {
@observable connectionState: s.ConnectionState = new s.ConnectionState(); @observable connectionState: s.ConnectionState = new s.ConnectionState();
private socket: WebSocket | null = null;
private reconnectTimer: number | null = null;
get connected(): boolean { get connected(): boolean {
return this.connectionState.isConnected; return this.connectionState.isConnected;
} }
@ -60,11 +63,18 @@ export class WebSocketApiClient implements s.ISprinklersApi {
start() { start() {
log.debug({ url: this.webSocketUrl }, "connecting to websocket"); log.debug({ url: this.webSocketUrl }, "connecting to websocket");
this.socket = new WebSocket(this.webSocketUrl); this._connect();
this.socket.onopen = this.onOpen.bind(this); }
this.socket.onclose = this.onClose.bind(this);
this.socket.onerror = this.onError.bind(this); stop() {
this.socket.onmessage = this.onMessage.bind(this); if (this.reconnectTimer != null) {
clearTimeout(this.reconnectTimer);
this.reconnectTimer = null;
}
if (this.socket != null) {
this.socket.close();
this.socket = null;
}
} }
getDevice(name: string): s.SprinklersDevice { getDevice(name: string): s.SprinklersDevice {
@ -80,6 +90,15 @@ export class WebSocketApiClient implements s.ISprinklersApi {
// args must all be JSON serializable // args must all be JSON serializable
makeDeviceCall(deviceName: string, request: requests.Request): Promise<requests.Response> { makeDeviceCall(deviceName: string, request: requests.Request): Promise<requests.Response> {
if (this.socket == null) {
const res: requests.Response = {
type: request.type,
result: "error",
code: ErrorCode.ServerDisconnected,
message: "the server is not connected",
};
throw res;
}
const requestData = seralizeRequest(request); const requestData = seralizeRequest(request);
const id = this.nextDeviceRequestId++; const id = this.nextDeviceRequestId++;
const data: ws.IDeviceCallRequest = { const data: ws.IDeviceCallRequest = {
@ -97,10 +116,10 @@ export class WebSocketApiClient implements s.ISprinklersApi {
reject(resData.data); reject(resData.data);
} }
}; };
timeoutHandle = setTimeout(() => { timeoutHandle = window.setTimeout(() => {
delete this.deviceResponseCallbacks[id]; delete this.deviceResponseCallbacks[id];
const res: requests.RunSectionResponse = { const res: requests.Response = {
type: "runSection", type: request.type,
result: "error", result: "error",
code: ErrorCode.Timeout, code: ErrorCode.Timeout,
message: "the request timed out", message: "the request timed out",
@ -112,6 +131,18 @@ export class WebSocketApiClient implements s.ISprinklersApi {
return promise; return promise;
} }
private _reconnect = () => {
this._connect();
}
private _connect() {
this.socket = new WebSocket(this.webSocketUrl);
this.socket.onopen = this.onOpen.bind(this);
this.socket.onclose = this.onClose.bind(this);
this.socket.onerror = this.onError.bind(this);
this.socket.onmessage = this.onMessage.bind(this);
}
private onOpen() { private onOpen() {
log.info("established websocket connection"); log.info("established websocket connection");
this.connectionState.clientToServer = true; this.connectionState.clientToServer = true;
@ -127,6 +158,7 @@ export class WebSocketApiClient implements s.ISprinklersApi {
log.info({ reason: event.reason, wasClean: event.wasClean }, log.info({ reason: event.reason, wasClean: event.wasClean },
"disconnected from websocket"); "disconnected from websocket");
this.onDisconnect(); this.onDisconnect();
this.reconnectTimer = window.setTimeout(this._reconnect, RECONNECT_TIMEOUT_MS);
} }
private onError(event: Event) { private onError(event: Event) {

70
app/webpack.config.js

@ -4,9 +4,13 @@ const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin");
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin"); const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
const cssnext = require("postcss-cssnext"); const DashboardPlugin = require("webpack-dashboard/plugin");
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HappyPack = require("happypack");
const ForkTsCheckerWebpackPlugin = require("fork-ts-checker-webpack-plugin");
const { getClientEnvironment } = require("../env"); const {getClientEnvironment} = require("../env");
const paths = require("../paths"); const paths = require("../paths");
// Webpack uses `publicPath` to determine where the app is being served from. // Webpack uses `publicPath` to determine where the app is being served from.
@ -35,14 +39,8 @@ const postCssConfig = {
ident: "postcss", ident: "postcss",
plugins: () => [ plugins: () => [
require("postcss-flexbugs-fixes"), require("postcss-flexbugs-fixes"),
cssnext({ require("postcss-preset-env")({
browsers: [ stage: 0,
">1%",
"last 4 versions",
"Firefox ESR",
"not ie < 9", // React doesn"t support IE8 anyway
],
flexbox: "no-2009",
}), }),
], ],
}, },
@ -59,10 +57,14 @@ const rules = (env) => {
// "style" loader turns CSS into JS modules that inject <style> tags. // "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use a plugin to extract that CSS to a file, but // In production, we use a plugin to extract that CSS to a file, but
// in development "style" loader enables hot editing of CSS. // in development "style" loader enables hot editing of CSS.
const styleLoader =
(env === "prod") ? {
loader: MiniCssExtractPlugin.loader
} : require.resolve("style-loader");
const cssRule = { const cssRule = {
test: /\.css$/, test: /\.css$/,
use: [ use: [
require.resolve("style-loader"), styleLoader,
{ {
loader: require.resolve("css-loader"), loader: require.resolve("css-loader"),
options: { options: {
@ -75,23 +77,18 @@ const rules = (env) => {
const sassRule = { const sassRule = {
test: /\.scss$/, test: /\.scss$/,
use: [ use: [
require.resolve("style-loader"), styleLoader,
{ {
loader: require.resolve("css-loader"), loader: require.resolve("css-loader"),
options: { options: {
importLoaders: 1, importLoaders: 1,
}, },
}, },
postCssConfig,
sassConfig, sassConfig,
], ],
}; };
return [ return [
{
test: /\.tsx?$/,
enforce: "pre",
loader: require.resolve("tslint-loader"),
options: { typeCheck: true, tsConfigFile: paths.appTsConfig },
},
{ {
// "oneOf" will traverse all following loaders until one will // "oneOf" will traverse all following loaders until one will
// match the requirements. when no loader matches it will fall // match the requirements. when no loader matches it will fall
@ -110,12 +107,10 @@ const rules = (env) => {
}, },
cssRule, cssRule,
sassRule, sassRule,
// Process TypeScript with TSC. // Process TypeScript with TSC through HappyPack.
{ {
test: /\.tsx?$/, use: { test: /\.tsx?$/, use: "happypack/loader?id=ts",
loader: "awesome-typescript-loader", include: [ paths.appDir, paths.commonDir ],
options: { configFileName: paths.appTsConfig }
},
}, },
// "file" loader makes sure those assets get served by WebpackDevServer. // "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename. // When you `import` an asset, you get its (virtual) filename.
@ -177,13 +172,40 @@ const getConfig = module.exports = (env) => {
}), }),
isDev && new webpack.HotModuleReplacementPlugin(), isDev && new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), new webpack.NamedModulesPlugin(),
new HappyPack({
id: "ts",
threads: 2,
loaders: [{
loader: "ts-loader",
options: {
configFile: paths.appTsConfig,
happyPackMode: true,
},
}],
}),
new ForkTsCheckerWebpackPlugin({
checkSyntacticErrors: true,
tsconfig: paths.appTsConfig,
tslint: paths.resolveRoot("tslint.json"),
}),
isDev && new DashboardPlugin(),
new BundleAnalyzerPlugin({
analyzerMode: "static",
openAnalyzer: false,
reportFilename: path.resolve(paths.serverBuildDir, "report.html"),
}),
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
isProd && new MiniCssExtractPlugin({
filename: "static/css/[name].[chunkhash:8].css",
chunkFilename: "static/css/[id].[chunkhash:8].css",
})
].filter(Boolean); ].filter(Boolean);
return { return {
mode: isProd ? "production" : "development", mode: isProd ? "production" : "development",
bail: isProd, bail: isProd,
devtool: shouldUseSourceMap ? devtool: shouldUseSourceMap ?
isProd ? "source-map" : "eval-source-map" : isProd ? "source-map" : "inline-source-map" :
false, false,
entry: [ entry: [
isDev && require.resolve("react-hot-loader/patch"), isDev && require.resolve("react-hot-loader/patch"),

2
common/sprinklers/ErrorCode.ts

@ -6,4 +6,6 @@ export enum ErrorCode {
InvalidData = 104, InvalidData = 104,
Internal = 200, Internal = 200,
Timeout = 300, Timeout = 300,
ServerDisconnected = 301,
BrokerDisconnected = 302,
} }

1
common/tsconfig.json

@ -12,6 +12,7 @@
"strict": true, "strict": true,
"allowJs": true, "allowJs": true,
"baseUrl": "..", "baseUrl": "..",
"sourceMap": true,
"paths": { "paths": {
"@common/*": [ "@common/*": [
"./common/*" "./common/*"

19
package.json

@ -35,18 +35,16 @@
}, },
"homepage": "https://github.com/amikhalev/sprinklers3#readme", "homepage": "https://github.com/amikhalev/sprinklers3#readme",
"dependencies": { "dependencies": {
"@types/react-router-dom": "^4.2.7",
"chalk": "^2.4.1", "chalk": "^2.4.1",
"express": "^4.16.3", "express": "^4.16.3",
"express-pino-logger": "^3.0.2", "express-pino-logger": "^3.0.2",
"fork-ts-checker-webpack-plugin": "^0.4.2",
"mobx": "^5.0.3", "mobx": "^5.0.3",
"module-alias": "^2.1.0", "module-alias": "^2.1.0",
"moment": "^2.22.2", "moment": "^2.22.2",
"mqtt": "^2.18.1", "mqtt": "^2.18.1",
"pino": "^4.17.3", "pino": "^4.17.3",
"postcss-cssnext": "^3.1.0", "rethinkdb": "^2.3.3",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"serializr": "^1.2.0", "serializr": "^1.2.0",
"uglify-es": "3.3.9", "uglify-es": "3.3.9",
"ws": "^5.2.1" "ws": "^5.2.1"
@ -57,6 +55,7 @@
"@types/core-js": "^2.5.0", "@types/core-js": "^2.5.0",
"@types/express": "^4.16.0", "@types/express": "^4.16.0",
"@types/lodash": "^4.14.110", "@types/lodash": "^4.14.110",
"@types/lodash-es": "^4.17.0",
"@types/node": "^10.3.5", "@types/node": "^10.3.5",
"@types/object-assign": "^4.0.30", "@types/object-assign": "^4.0.30",
"@types/pino": "^4.16.0", "@types/pino": "^4.16.0",
@ -64,19 +63,23 @@
"@types/react": "16.4.1", "@types/react": "16.4.1",
"@types/react-dom": "16.0.6", "@types/react-dom": "16.0.6",
"@types/react-hot-loader": "^4.1.0", "@types/react-hot-loader": "^4.1.0",
"@types/react-router-dom": "^4.2.7",
"@types/rethinkdb": "^2.3.11",
"@types/webpack-env": "^1.13.6", "@types/webpack-env": "^1.13.6",
"@types/ws": "^5.1.2", "@types/ws": "^5.1.2",
"async": "^2.6.1", "async": "^2.6.1",
"autoprefixer": "^8.6.3", "autoprefixer": "^8.6.3",
"awesome-typescript-loader": "^5.2.0",
"case-sensitive-paths-webpack-plugin": "^2.1.2", "case-sensitive-paths-webpack-plugin": "^2.1.2",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"css-loader": "^0.28.11", "css-loader": "^0.28.11",
"dotenv": "^6.0.0", "dotenv": "^6.0.0",
"file-loader": "^1.1.11", "file-loader": "^1.1.11",
"font-awesome": "^4.7.0", "font-awesome": "^4.7.0",
"happypack": "^5.0.0",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^3.2.0",
"lodash": "^4.17.10", "lodash": "^4.17.10",
"lodash-es": "^4.17.10",
"mini-css-extract-plugin": "^0.4.0",
"mobx-react": "^5.2.3", "mobx-react": "^5.2.3",
"mobx-react-devtools": "^5.0.1", "mobx-react-devtools": "^5.0.1",
"node-sass": "^4.8.3", "node-sass": "^4.8.3",
@ -85,12 +88,15 @@
"object-assign": "^4.1.1", "object-assign": "^4.1.1",
"postcss-flexbugs-fixes": "^3.3.1", "postcss-flexbugs-fixes": "^3.3.1",
"postcss-loader": "^2.1.5", "postcss-loader": "^2.1.5",
"postcss-preset-env": "^5.2.1",
"promise": "^8.0.1", "promise": "^8.0.1",
"prop-types": "^15.6.2", "prop-types": "^15.6.2",
"react": "16.4.1", "react": "16.4.1",
"react-dev-utils": "^5.0.1", "react-dev-utils": "^5.0.1",
"react-dom": "16.4.1", "react-dom": "16.4.1",
"react-hot-loader": "^4.3.3", "react-hot-loader": "^4.3.3",
"react-router": "^4.3.1",
"react-router-dom": "^4.3.1",
"sass-loader": "^7.0.3", "sass-loader": "^7.0.3",
"semantic-ui-css": "^2.3.2", "semantic-ui-css": "^2.3.2",
"semantic-ui-react": "^0.81.1", "semantic-ui-react": "^0.81.1",
@ -98,13 +104,14 @@
"style-loader": "^0.21.0", "style-loader": "^0.21.0",
"ts-loader": "^4.4.1", "ts-loader": "^4.4.1",
"tslint": "^5.10.0", "tslint": "^5.10.0",
"tslint-loader": "^3.6.0",
"tslint-react": "^3.6.0", "tslint-react": "^3.6.0",
"typescript": "^2.9.2", "typescript": "^2.9.2",
"uglifyjs-webpack-plugin": "^1.2.6", "uglifyjs-webpack-plugin": "^1.2.6",
"url-loader": "^1.0.1", "url-loader": "^1.0.1",
"webpack": "^4.12.0", "webpack": "^4.12.0",
"webpack-bundle-analyzer": "^2.13.1",
"webpack-cli": "^3.0.8", "webpack-cli": "^3.0.8",
"webpack-dashboard": "^2.0.0",
"webpack-dev-server": "^3.1.4" "webpack-dev-server": "^3.1.4"
}, },
"resolutions": { "resolutions": {

18
paths.js

@ -3,17 +3,17 @@ const fs = require("fs");
const url = require("url"); const url = require("url");
exports.rootDir = fs.realpathSync(process.cwd()); exports.rootDir = fs.realpathSync(process.cwd());
const resolveRoot = (p) => path.resolve(exports.rootDir, p); const resolveRoot = exports.resolveRoot = (p) => path.resolve(exports.rootDir, p);
function ensureSlash(p, needsSlash) { function ensureSlash(p, needsSlash) {
const hasSlash = p.endsWith("/"); const hasSlash = p.endsWith("/");
if (hasSlash && !needsSlash) { if (hasSlash && !needsSlash) {
return p.substr(p, p.length - 1); return p.substr(p, p.length - 1);
} else if (!hasSlash && needsSlash) { } else if (!hasSlash && needsSlash) {
return `${p}/`; return `${p}/`;
} else { } else {
return p; return p;
} }
} }
exports.dotenv = resolveRoot(".env"); exports.dotenv = resolveRoot(".env");

2
server/state.ts

@ -15,4 +15,4 @@ export class ServerState {
this.mqttClient.start(); this.mqttClient.start();
} }
} }

1244
yarn.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save