diff --git a/.gitignore b/.gitignore index 3ffb186252..a1243acede 100644 --- a/.gitignore +++ b/.gitignore @@ -84,4 +84,6 @@ typings/ !.yarn/sdks !.yarn/versions -fakeNodes.json \ No newline at end of file +fakeNodes.json + +/build/ \ No newline at end of file diff --git a/api/lib/ZwaveClient.ts b/api/lib/ZwaveClient.ts index 7004d643a0..9580f4e86a 100644 --- a/api/lib/ZwaveClient.ts +++ b/api/lib/ZwaveClient.ts @@ -4400,7 +4400,7 @@ class ZwaveClient extends TypedEventEmitter { controllerNode.statistics as ControllerStatistics controllerNode.statistics = stats - if (stats.messagesRX > oldStatistics?.messagesRX ?? 0) { + if (stats.messagesRX > (oldStatistics?.messagesRX ?? 0)) { // no need to emit `lastActive` event. That would cause useless traffic controllerNode.lastActive = Date.now() } diff --git a/esbuild.js b/esbuild.js new file mode 100644 index 0000000000..2e3823bf5c --- /dev/null +++ b/esbuild.js @@ -0,0 +1,79 @@ +const esbuild = require('esbuild') +const { cp } = require('fs/promises') +const pkgJson = require('./package.json') +const { exists, removeSync } = require('fs-extra') + +const outputDir = 'build' + +// from https://github.com/evanw/esbuild/issues/1051#issuecomment-806325487 +const nativeNodeModulesPlugin = { + name: 'native-node-modules', + setup(build) { + // If a ".node" file is imported within a module in the "file" namespace, resolve + // it to an absolute path and put it into the "node-file" virtual namespace. + build.onResolve({ filter: /\.node$/, namespace: 'file' }, (args) => ({ + path: require.resolve(args.path, { paths: [args.resolveDir] }), + namespace: 'node-file', + })) + + // Files in the "node-file" virtual namespace call "require()" on the + // path from esbuild of the ".node" file in the output directory. + build.onLoad({ filter: /.*/, namespace: 'node-file' }, (args) => ({ + contents: ` + import path from ${JSON.stringify(args.path)} + try { module.exports = require(path) } + catch {} + `, + })) + + // If a ".node" file is imported within a module in the "node-file" namespace, put + // it in the "file" namespace where esbuild's default loading behavior will handle + // it. It is already an absolute path since we resolved it to one above. + build.onResolve( + { filter: /\.node$/, namespace: 'node-file' }, + (args) => ({ + path: args.path, + namespace: 'file', + }), + ) + + // Tell esbuild's default loading behavior to use the "file" loader for + // these ".node" files. + let opts = build.initialOptions + opts.loader = opts.loader || {} + opts.loader['.node'] = 'file' + }, +} + +// clean build folder +removeSync(outputDir) + +esbuild + .build({ + entryPoints: ['api/bin/www.ts'], + plugins: [nativeNodeModulesPlugin], + bundle: true, + + platform: 'node', + target: 'node18', + outfile: `${outputDir}/code/index.js`, + external: ['serialport'], + }) + .then(async () => { + // copy assets to build folder + for (let asset of pkgJson.pkg.assets) { + console.log(`copying ${asset} to ${outputDir} folder`) + // resolve glob assets + asset = asset.replace('/**/*', '').replace('/**', '') + + if (await exists(asset)) { + await cp(asset, `${outputDir}/${asset}`, { recursive: true }) + } else { + console.log(`asset ${asset} does not exist`) + } + } + }) + .catch((err) => { + console.error(err) + process.exit(1) + })