From 6a404d9fb3ca865e7f413f0aaa837a07ec9f2315 Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Tue, 28 Nov 2023 00:40:50 +0100 Subject: [PATCH] Refactor and port plugin web code to TypeScript Clean up the configuration for compiling TypeScript for the Web interface to us its own tsconfig.web.json config files and reference the TypeScript source files directly in the configuration and imports instead of files compiled to dist. To properly support recompliation with TypeScript's projects feature each package's tsconfig.web.json file is set to output the build to dist/web_build which is then ignored in .npmignore. Webpack is still used to create the proper build in dist/web, so this is mainly to make TypeScipt's compiler happy but it also allows the root tsconfig.json file to include the web interface code, meaning running the build script now also checks the typing of the web interface. Final part of #491. --- .eslintrc.js | 6 ++- packages/controller/.npmignore | 1 + packages/controller/tsconfig.web.json | 12 ++++++ .../controller/web/{index.jsx => index.tsx} | 1 + packages/controller/webpack.config.js | 2 +- packages/lib/browser.js | 17 --------- packages/lib/browser.ts | 17 +++++++++ packages/lib/package.json | 2 +- packages/web_ui/package.json | 1 + packages/web_ui/tsconfig.json | 20 ---------- packages/web_ui/tsconfig.web.json | 10 +++++ packages/web_ui/webpack.common.js | 4 ++ plugins/global_chat/.npmignore | 1 + plugins/global_chat/package.json | 1 + plugins/global_chat/tsconfig.web.json | 11 ++++++ .../global_chat/web/{index.jsx => index.tsx} | 0 plugins/global_chat/webpack.config.js | 4 +- plugins/inventory_sync/.npmignore | 1 + plugins/inventory_sync/package.json | 1 + plugins/inventory_sync/tsconfig.web.json | 11 ++++++ .../web/{index.jsx => index.tsx} | 10 +---- plugins/inventory_sync/webpack.config.js | 6 +-- plugins/player_auth/.npmignore | 1 + plugins/player_auth/package.json | 1 + plugins/player_auth/tsconfig.web.json | 11 ++++++ .../player_auth/web/{index.jsx => index.tsx} | 17 +++++---- plugins/player_auth/webpack.config.js | 6 +-- plugins/research_sync/.npmignore | 1 + plugins/research_sync/package.json | 3 +- plugins/research_sync/tsconfig.web.json | 11 ++++++ .../web/{index.jsx => index.tsx} | 0 plugins/research_sync/webpack.config.js | 4 +- plugins/statistics_exporter/.npmignore | 1 + plugins/statistics_exporter/package.json | 1 + plugins/statistics_exporter/tsconfig.web.json | 11 ++++++ .../web/{index.jsx => index.tsx} | 0 plugins/statistics_exporter/webpack.config.js | 4 +- plugins/subspace_storage/.npmignore | 1 + plugins/subspace_storage/package.json | 1 + plugins/subspace_storage/tsconfig.web.json | 11 ++++++ .../web/{index.jsx => index.tsx} | 38 ++++++++++--------- plugins/subspace_storage/webpack.config.js | 6 +-- tsconfig.base.json | 1 + tsconfig.json | 9 ++++- tsconfig.node.json | 2 - tsconfig.web.json | 11 ++++++ 46 files changed, 199 insertions(+), 92 deletions(-) create mode 100644 packages/controller/tsconfig.web.json rename packages/controller/web/{index.jsx => index.tsx} (65%) delete mode 100644 packages/lib/browser.js create mode 100644 packages/lib/browser.ts delete mode 100644 packages/web_ui/tsconfig.json create mode 100644 packages/web_ui/tsconfig.web.json create mode 100644 plugins/global_chat/tsconfig.web.json rename plugins/global_chat/web/{index.jsx => index.tsx} (100%) create mode 100644 plugins/inventory_sync/tsconfig.web.json rename plugins/inventory_sync/web/{index.jsx => index.tsx} (83%) create mode 100644 plugins/player_auth/tsconfig.web.json rename plugins/player_auth/web/{index.jsx => index.tsx} (87%) create mode 100644 plugins/research_sync/tsconfig.web.json rename plugins/research_sync/web/{index.jsx => index.tsx} (100%) create mode 100644 plugins/statistics_exporter/tsconfig.web.json rename plugins/statistics_exporter/web/{index.jsx => index.tsx} (100%) create mode 100644 plugins/subspace_storage/tsconfig.web.json rename plugins/subspace_storage/web/{index.jsx => index.tsx} (78%) create mode 100644 tsconfig.web.json diff --git a/.eslintrc.js b/.eslintrc.js index 2cee77d9..e3b50a27 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -40,7 +40,11 @@ module.exports = { }, }, { - "files": ["packages/web_ui/src/**/*.ts?(x)", "packages/lib/browser.js", "plugins/*/web/**/*.ts?(x)"], + "files": [ + "packages/web_ui/src/**/*.ts?(x)", + "packages/lib/browser.ts", + "{packages,plugins}/*/web/**/*.ts?(x)", + ], "env": { "browser": true, }, diff --git a/packages/controller/.npmignore b/packages/controller/.npmignore index 6de001d8..e31e7410 100644 --- a/packages/controller/.npmignore +++ b/packages/controller/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/packages/controller/tsconfig.web.json b/packages/controller/tsconfig.web.json new file mode 100644 index 00000000..4f57c7a7 --- /dev/null +++ b/packages/controller/tsconfig.web.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../lib" }, + { "path": "../web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], + "compilerOptions": { + "rootDir": "..", + "outDir": "dist/web_build", + } +} diff --git a/packages/controller/web/index.jsx b/packages/controller/web/index.tsx similarity index 65% rename from packages/controller/web/index.jsx rename to packages/controller/web/index.tsx index 64be3a06..da298e39 100644 --- a/packages/controller/web/index.jsx +++ b/packages/controller/web/index.tsx @@ -1,3 +1,4 @@ +/* eslint-disable arrow-body-style, no-console */ import("@clusterio/web_ui").then(webUi => { return webUi.bootstrap(); }).catch(console.error); diff --git a/packages/controller/webpack.config.js b/packages/controller/webpack.config.js index cd0155c4..25182879 100644 --- a/packages/controller/webpack.config.js +++ b/packages/controller/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", devServer: { contentBase: "./dist/web", }, diff --git a/packages/lib/browser.js b/packages/lib/browser.js deleted file mode 100644 index 15cd95d5..00000000 --- a/packages/lib/browser.js +++ /dev/null @@ -1,17 +0,0 @@ -export * from "./dist/src/api"; -export * from "./dist/src/config"; -export * from "./dist/src/data"; -export * from "./dist/src/errors"; -export * from "./dist/src/factorio/exchange_string"; -export * from "./dist/src/helpers"; -export * from "./dist/src/ini"; -export * from "./dist/src/link"; -export * from "./dist/src/logging"; -export * from "./dist/src/plugin"; -export * from "./dist/src/schema"; -export * from "./dist/src/users"; -export * from "./dist/src/subscriptions"; - -export { default as ExponentialBackoff } from "./dist/src/ExponentialBackoff"; -export { default as PlayerStats } from "./dist/src/PlayerStats"; -export { default as RateLimiter } from "./dist/src/RateLimiter"; diff --git a/packages/lib/browser.ts b/packages/lib/browser.ts new file mode 100644 index 00000000..18cbc868 --- /dev/null +++ b/packages/lib/browser.ts @@ -0,0 +1,17 @@ +export * from "./src/api"; +export * from "./src/config"; +export * from "./src/data"; +export * from "./src/errors"; +export * from "./src/factorio/exchange_string"; +export * from "./src/helpers"; +export * from "./src/ini"; +export * from "./src/link"; +export * from "./src/logging"; +export * from "./src/plugin"; +export * from "./src/schema"; +export * from "./src/users"; +export * from "./src/subscriptions"; + +export { default as ExponentialBackoff } from "./src/ExponentialBackoff"; +export { default as PlayerStats } from "./src/PlayerStats"; +export { default as RateLimiter } from "./src/RateLimiter"; diff --git a/packages/lib/package.json b/packages/lib/package.json index 68b4bf52..dc981417 100644 --- a/packages/lib/package.json +++ b/packages/lib/package.json @@ -9,7 +9,7 @@ "compile_validator": "node scripts/compile_validator.js" }, "main": "dist/index.js", - "browser": "browser.js", + "browser": "browser.ts", "keywords": [ "factorio" ], diff --git a/packages/web_ui/package.json b/packages/web_ui/package.json index fec64b31..87f93b92 100644 --- a/packages/web_ui/package.json +++ b/packages/web_ui/package.json @@ -5,6 +5,7 @@ "license": "MIT", "version": "2.0.0-alpha.13", "browser": "src/index.ts", + "main": "dist/src/index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, diff --git a/packages/web_ui/tsconfig.json b/packages/web_ui/tsconfig.json deleted file mode 100644 index 9c7d97f9..00000000 --- a/packages/web_ui/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "include": [ "src/**/*.tsx", "src/**/*.ts", "package.json", "global.d.ts" ], - "compilerOptions": { - "jsx": "react", - "lib": ["dom", "es2023"], - "module": "commonjs", - "target": "es2022", - "rootDir": "./", - "outDir": "dist", - "composite": true, - "sourceMap": true, - "strict": true, - "alwaysStrict": true, - "noImplicitAny": true, - "esModuleInterop": true, - "skipLibCheck": true, - "resolveJsonModule": true, - "noEmitOnError": true - } -} diff --git a/packages/web_ui/tsconfig.web.json b/packages/web_ui/tsconfig.web.json new file mode 100644 index 00000000..3beee793 --- /dev/null +++ b/packages/web_ui/tsconfig.web.json @@ -0,0 +1,10 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../lib" }, + ], + "include": [ "src/**/*.tsx", "src/**/*.ts", "package.json", "global.d.ts" ], + "compilerOptions": { + "outDir": "dist", + } +} diff --git a/packages/web_ui/webpack.common.js b/packages/web_ui/webpack.common.js index 3648acaf..e8a5d8b7 100644 --- a/packages/web_ui/webpack.common.js +++ b/packages/web_ui/webpack.common.js @@ -78,6 +78,10 @@ module.exports = (env = {}) => ({ exclude: /node_modules/, use: { loader: require.resolve("ts-loader"), + options: { + configFile: "tsconfig.web.json", + projectReferences: true, + }, }, }, { diff --git a/plugins/global_chat/.npmignore b/plugins/global_chat/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/global_chat/.npmignore +++ b/plugins/global_chat/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/global_chat/package.json b/plugins/global_chat/package.json index 6c1f9e5c..240af799 100644 --- a/plugins/global_chat/package.json +++ b/plugins/global_chat/package.json @@ -24,6 +24,7 @@ "@clusterio/lib": "^2.0.0-alpha.13", "@clusterio/web_ui": "^2.0.0-alpha.13", "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "typescript": "^5.1.6", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", diff --git a/plugins/global_chat/tsconfig.web.json b/plugins/global_chat/tsconfig.web.json new file mode 100644 index 00000000..b3a7914b --- /dev/null +++ b/plugins/global_chat/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/global_chat/web/index.jsx b/plugins/global_chat/web/index.tsx similarity index 100% rename from plugins/global_chat/web/index.jsx rename to plugins/global_chat/web/index.tsx diff --git a/plugins/global_chat/webpack.config.js b/plugins/global_chat/webpack.config.js index 4f084bda..6870a94b 100644 --- a/plugins/global_chat/webpack.config.js +++ b/plugins/global_chat/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,7 +16,7 @@ module.exports = (env = {}) => merge(common(env), { name: "global_chat", library: { type: "var", name: "plugin_global_chat" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", }, shared: { diff --git a/plugins/inventory_sync/.npmignore b/plugins/inventory_sync/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/inventory_sync/.npmignore +++ b/plugins/inventory_sync/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/inventory_sync/package.json b/plugins/inventory_sync/package.json index b4ad895a..28cc8055 100644 --- a/plugins/inventory_sync/package.json +++ b/plugins/inventory_sync/package.json @@ -29,6 +29,7 @@ "@clusterio/web_ui": "^2.0.0-alpha.13", "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "antd": "^5.7.3", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/plugins/inventory_sync/tsconfig.web.json b/plugins/inventory_sync/tsconfig.web.json new file mode 100644 index 00000000..8c702166 --- /dev/null +++ b/plugins/inventory_sync/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "instance.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/inventory_sync/web/index.jsx b/plugins/inventory_sync/web/index.tsx similarity index 83% rename from plugins/inventory_sync/web/index.jsx rename to plugins/inventory_sync/web/index.tsx index 25b405c3..61450ff1 100644 --- a/plugins/inventory_sync/web/index.jsx +++ b/plugins/inventory_sync/web/index.tsx @@ -1,14 +1,14 @@ import React, { useContext, useEffect, useState } from "react"; import { BaseWebPlugin, PageLayout, ControlContext } from "@clusterio/web_ui"; -import { DatabaseStatsRequest } from "../dist/plugin/messages"; +import { DatabaseStatsRequest, DatabaseStatsResponse } from "../messages"; import "./index.css"; function InventoryPage() { let control = useContext(ControlContext); - let [statsData, updateStatsData] = useState(); + let [statsData, updateStatsData] = useState(); useEffect(() => { (async () => { @@ -38,10 +38,4 @@ export class WebPlugin extends BaseWebPlugin { }, ]; } - - onControllerConnectionEvent(event) { - if (event === "connect") { - - } - } } diff --git a/plugins/inventory_sync/webpack.config.js b/plugins/inventory_sync/webpack.config.js index 857e098b..90f35fef 100644 --- a/plugins/inventory_sync/webpack.config.js +++ b/plugins/inventory_sync/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,9 +16,9 @@ module.exports = (env = {}) => merge(common(env), { name: "inventory_sync", library: { type: "var", name: "plugin_inventory_sync" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", - "./web": "./web/index.jsx", + "./web": "./web/index.tsx", }, shared: { "@clusterio/lib": { import: false }, diff --git a/plugins/player_auth/.npmignore b/plugins/player_auth/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/player_auth/.npmignore +++ b/plugins/player_auth/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/player_auth/package.json b/plugins/player_auth/package.json index 32025629..0a497811 100644 --- a/plugins/player_auth/package.json +++ b/plugins/player_auth/package.json @@ -31,6 +31,7 @@ "@types/express": "^4.17.17", "@types/jsonwebtoken": "^9.0.2", "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "antd": "^5.7.3", "phin": "^3.7.0", "react": "^18.2.0", diff --git a/plugins/player_auth/tsconfig.web.json b/plugins/player_auth/tsconfig.web.json new file mode 100644 index 00000000..b3a7914b --- /dev/null +++ b/plugins/player_auth/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/player_auth/web/index.jsx b/plugins/player_auth/web/index.tsx similarity index 87% rename from plugins/player_auth/web/index.jsx rename to plugins/player_auth/web/index.tsx index 266450ef..eb86ae0e 100644 --- a/plugins/player_auth/web/index.jsx +++ b/plugins/player_auth/web/index.tsx @@ -7,13 +7,16 @@ import "./index.css"; const { Paragraph, Text } = Typography; +interface LoginFormProps { + setToken(token: string): void, +} -function LoginForm(props) { - let [servers, setServers] = useState(null); - let [playerCode, setPlayerCode] = useState(null); - let [playerCodeError, setPlayerCodeError] = useState(null); - let [verifyCode, setVerifyCode] = useState(null); - let [verifyToken, setVerifyToken] = useState(null); +function LoginForm(props: LoginFormProps) { + let [servers, setServers] = useState(null); + let [playerCode, setPlayerCode] = useState(null); + let [playerCodeError, setPlayerCodeError] = useState(null); + let [verifyCode, setVerifyCode] = useState(); + let [verifyToken, setVerifyToken] = useState(null); useEffect(() => { (async () => { @@ -137,7 +140,7 @@ function LoginForm(props) {
  • Enter this code into the in-game dialog: - +
  • diff --git a/plugins/player_auth/webpack.config.js b/plugins/player_auth/webpack.config.js index 04c092d2..6a3fc528 100644 --- a/plugins/player_auth/webpack.config.js +++ b/plugins/player_auth/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,9 +16,9 @@ module.exports = (env = {}) => merge(common(env), { name: "player_auth", library: { type: "var", name: "plugin_player_auth" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", - "./web": "./web/index.jsx", + "./web": "./web/index.tsx", }, shared: { "@clusterio/lib": { import: false }, diff --git a/plugins/research_sync/.npmignore b/plugins/research_sync/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/research_sync/.npmignore +++ b/plugins/research_sync/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/research_sync/package.json b/plugins/research_sync/package.json index 099fd3a5..eeaa70a3 100644 --- a/plugins/research_sync/package.json +++ b/plugins/research_sync/package.json @@ -27,8 +27,9 @@ "devDependencies": { "@clusterio/lib": "^2.0.0-alpha.13", "@clusterio/web_ui": "^2.0.0-alpha.13", - "@types/node": "^20.4.5", "@types/fs-extra": "^11.0.1", + "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "typescript": "^5.1.6", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", diff --git a/plugins/research_sync/tsconfig.web.json b/plugins/research_sync/tsconfig.web.json new file mode 100644 index 00000000..b3a7914b --- /dev/null +++ b/plugins/research_sync/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/research_sync/web/index.jsx b/plugins/research_sync/web/index.tsx similarity index 100% rename from plugins/research_sync/web/index.jsx rename to plugins/research_sync/web/index.tsx diff --git a/plugins/research_sync/webpack.config.js b/plugins/research_sync/webpack.config.js index 069b6dac..6c04b3d1 100644 --- a/plugins/research_sync/webpack.config.js +++ b/plugins/research_sync/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,7 +16,7 @@ module.exports = (env = {}) => merge(common(env), { name: "research_sync", library: { type: "var", name: "plugin_research_sync" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", }, shared: { diff --git a/plugins/statistics_exporter/.npmignore b/plugins/statistics_exporter/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/statistics_exporter/.npmignore +++ b/plugins/statistics_exporter/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/statistics_exporter/package.json b/plugins/statistics_exporter/package.json index 1e3c1a81..50a09732 100644 --- a/plugins/statistics_exporter/package.json +++ b/plugins/statistics_exporter/package.json @@ -24,6 +24,7 @@ "@clusterio/lib": "^2.0.0-alpha.13", "@clusterio/web_ui": "^2.0.0-alpha.13", "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "typescript": "^5.1.6", "webpack": "^5.88.2", "webpack-cli": "^5.1.4", diff --git a/plugins/statistics_exporter/tsconfig.web.json b/plugins/statistics_exporter/tsconfig.web.json new file mode 100644 index 00000000..be3879f6 --- /dev/null +++ b/plugins/statistics_exporter/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/statistics_exporter/web/index.jsx b/plugins/statistics_exporter/web/index.tsx similarity index 100% rename from plugins/statistics_exporter/web/index.jsx rename to plugins/statistics_exporter/web/index.tsx diff --git a/plugins/statistics_exporter/webpack.config.js b/plugins/statistics_exporter/webpack.config.js index 515da3ef..3f768eaa 100644 --- a/plugins/statistics_exporter/webpack.config.js +++ b/plugins/statistics_exporter/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,7 +16,7 @@ module.exports = (env = {}) => merge(common(env), { name: "statistics_exporter", library: { type: "var", name: "plugin_statistics_exporter" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", }, shared: { diff --git a/plugins/subspace_storage/.npmignore b/plugins/subspace_storage/.npmignore index 6de001d8..e31e7410 100644 --- a/plugins/subspace_storage/.npmignore +++ b/plugins/subspace_storage/.npmignore @@ -1 +1,2 @@ webpack.config.js +dist/web_build diff --git a/plugins/subspace_storage/package.json b/plugins/subspace_storage/package.json index 6d7581a0..258668c7 100644 --- a/plugins/subspace_storage/package.json +++ b/plugins/subspace_storage/package.json @@ -30,6 +30,7 @@ "@types/express": "^4.17.17", "@types/fs-extra": "^11.0.1", "@types/node": "^20.4.5", + "@types/react": "^18.2.21", "antd": "^5.7.3", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/plugins/subspace_storage/tsconfig.web.json b/plugins/subspace_storage/tsconfig.web.json new file mode 100644 index 00000000..b3a7914b --- /dev/null +++ b/plugins/subspace_storage/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.web.json", + "references": [ + { "path": "../../packages/lib" }, + { "path": "../../packages/web_ui/tsconfig.web.json" }, + ], + "include": [ "web/**/*.tsx", "web/**/*.ts", "messages.ts", "package.json" ], + "compilerOptions": { + "outDir": "dist/web_build", + } +} diff --git a/plugins/subspace_storage/web/index.jsx b/plugins/subspace_storage/web/index.tsx similarity index 78% rename from plugins/subspace_storage/web/index.jsx rename to plugins/subspace_storage/web/index.tsx index 04cd6b76..40809242 100644 --- a/plugins/subspace_storage/web/index.jsx +++ b/plugins/subspace_storage/web/index.tsx @@ -3,18 +3,18 @@ import { Input, Table, Typography } from "antd"; import * as lib from "@clusterio/lib"; import { - BaseWebPlugin, PageLayout, ControlContext, + BaseWebPlugin, PageLayout, Control, ControlContext, notifyErrorHandler, useItemMetadata, useLocale, } from "@clusterio/web_ui"; -import { GetStorageRequest, SetStorageSubscriptionRequest } from "../dist/plugin/messages"; +import { GetStorageRequest, Item, SetStorageSubscriptionRequest, UpdateStorageEvent } from "../messages"; import "./index.css"; const { Paragraph } = Typography; -function useStorage(control) { - let plugin = control.plugins.get("subspace_storage"); +function useStorage(control: Control) { + let plugin = control.plugins.get("subspace_storage") as WebPlugin; let [storage, setStorage] = useState([...plugin.storage]); useEffect(() => { @@ -35,14 +35,15 @@ function StoragePage() { let locale = useLocale(); let itemMetadata = useItemMetadata(); let storage = useStorage(control); - let [filter, setFilter] = useState(null); + type ItemFilter = ([name, count]: [string, number]) => boolean; + let [filter, setFilter] = useState(null); - function getLocaleName(itemName) { + function getLocaleName(itemName: string) { let localeName = itemName; let meta = itemMetadata.get(itemName); - if (meta && meta.localized_name) { + if (meta && meta.localised_name) { // TODO: implement the locale to name conversion. - localeName = locale.get(meta.localized_name[0]); + localeName = locale.get(meta.localised_name[0])!; } else { for (let section of ["item-name", "entity-name", "fluid-name", "equipment-name"]) { let name = locale.get(`${section}.${itemName}`); @@ -72,7 +73,7 @@ function StoragePage() { search = search.replace(/(^| )(\w)/g, "$1\\b$2"); search = search.replace(/ +/g, ".*"); let filterExpr = new RegExp(search, "i"); - setFilter(() => (item => { + setFilter(() => ((item: [string, number]) => { let name = getLocaleName(item[0]); return filterExpr.test(name) || filterExpr.test(item[0]); })); @@ -118,6 +119,9 @@ function StoragePage() { } export class WebPlugin extends BaseWebPlugin { + storage = new Map(); + callbacks: (() => void)[] = []; + async init() { this.pages = [ { @@ -127,29 +131,27 @@ export class WebPlugin extends BaseWebPlugin { content: , }, ]; - - this.storage = new Map(); - this.callbacks = []; + this.control.handle(UpdateStorageEvent, this.handleUpdateStorageEvent.bind(this)); } - onControllerConnectionEvent(event) { + onControllerConnectionEvent(event: "connect" | "drop" | "resume" | "close") { if (event === "connect") { this.updateSubscription(); } } - async updateStorageEventHandler(event) { + async handleUpdateStorageEvent(event: UpdateStorageEvent) { this.updateStorage(event.items); } - onUpdate(callback) { + onUpdate(callback: () => void) { this.callbacks.push(callback); if (this.callbacks.length) { this.updateSubscription(); } } - offUpdate(callback) { + offUpdate(callback: () => void) { let index = this.callbacks.lastIndexOf(callback); if (index === -1) { throw new Error("callback is not registered"); @@ -161,7 +163,7 @@ export class WebPlugin extends BaseWebPlugin { } } - updateStorage(items) { + updateStorage(items: Item[]) { for (let item of items) { this.storage.set(item.name, item.count); } @@ -180,7 +182,7 @@ export class WebPlugin extends BaseWebPlugin { ).catch(notifyErrorHandler("Error subscribing to storage")); if (this.callbacks.length) { - this.control.send(new GetStorageRequest()).then( + this.control!.send(new GetStorageRequest()).then( items => { this.updateStorage(items); } diff --git a/plugins/subspace_storage/webpack.config.js b/plugins/subspace_storage/webpack.config.js index 87a02824..a2669ef6 100644 --- a/plugins/subspace_storage/webpack.config.js +++ b/plugins/subspace_storage/webpack.config.js @@ -7,7 +7,7 @@ const common = require("@clusterio/web_ui/webpack.common"); module.exports = (env = {}) => merge(common(env), { context: __dirname, - entry: "./web/index.jsx", + entry: "./web/index.tsx", output: { path: path.resolve(__dirname, "dist", "web"), }, @@ -16,9 +16,9 @@ module.exports = (env = {}) => merge(common(env), { name: "subspace_storage", library: { type: "var", name: "plugin_subspace_storage" }, exposes: { - "./info": "./dist/plugin/info.js", + "./info": "./info.ts", "./package.json": "./package.json", - "./web": "./web/index.jsx", + "./web": "./web/index.tsx", }, shared: { "@clusterio/lib": { import: false }, diff --git a/tsconfig.base.json b/tsconfig.base.json index 02016d99..dd597d2d 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -6,6 +6,7 @@ "incremental": true, "sourceMap": true, "strict": true, + "esModuleInterop": true, "resolveJsonModule": true, "skipLibCheck": true, }, diff --git a/tsconfig.json b/tsconfig.json index 35abcdb1..f2af308f 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,14 +3,21 @@ "references": [ { "path": "./packages/lib" }, { "path": "./packages/controller" }, + { "path": "./packages/controller/tsconfig.web.json" }, { "path": "./packages/host" }, { "path": "./packages/ctl" }, - { "path": "./packages/web_ui" }, + { "path": "./packages/web_ui/tsconfig.web.json" }, { "path": "./plugins/global_chat" }, + { "path": "./plugins/global_chat/tsconfig.web.json" }, { "path": "./plugins/inventory_sync" }, + { "path": "./plugins/inventory_sync/tsconfig.web.json" }, { "path": "./plugins/player_auth" }, + { "path": "./plugins/player_auth/tsconfig.web.json" }, { "path": "./plugins/research_sync" }, + { "path": "./plugins/research_sync/tsconfig.web.json" }, { "path": "./plugins/statistics_exporter" }, + { "path": "./plugins/statistics_exporter/tsconfig.web.json" }, { "path": "./plugins/subspace_storage" }, + { "path": "./plugins/subspace_storage/tsconfig.web.json" }, ], } diff --git a/tsconfig.node.json b/tsconfig.node.json index daa42608..700d02da 100644 --- a/tsconfig.node.json +++ b/tsconfig.node.json @@ -5,8 +5,6 @@ "module": "node16", "moduleResolution": "node16", "target": "es2022", - "esModuleInterop": true, - "alwaysStrict": true, "forceConsistentCasingInFileNames": true, }, } diff --git a/tsconfig.web.json b/tsconfig.web.json new file mode 100644 index 00000000..7edb5691 --- /dev/null +++ b/tsconfig.web.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "lib": ["dom", "es2023"], + "module": "es2022", + "moduleResolution": "bundler", + "target": "es2022", + "jsx": "react", + "noEmitOnError": true, + }, +}