From c9dacbd1523aff700040ac21328e7415ea9b33c4 Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Fri, 10 Sep 2021 21:21:54 -0400 Subject: [PATCH] remove old build server --- server/README.md | 8 -- server/build.js | 270 -------------------------------------------- server/build.log | 13 --- server/changelog.js | 59 ---------- server/https.crt | 31 ----- server/https.key | 52 --------- server/lint.js | 23 ---- server/serve.js | 194 ------------------------------- server/signature.js | 99 ---------------- server/typedoc.js | 35 ------ server/typings.js | 37 ------ 11 files changed, 821 deletions(-) delete mode 100644 server/README.md delete mode 100644 server/build.js delete mode 100644 server/build.log delete mode 100644 server/changelog.js delete mode 100644 server/https.crt delete mode 100644 server/https.key delete mode 100644 server/lint.js delete mode 100644 server/serve.js delete mode 100644 server/signature.js delete mode 100644 server/typedoc.js delete mode 100644 server/typings.js diff --git a/server/README.md b/server/README.md deleted file mode 100644 index 39312447..00000000 --- a/server/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Human Library: Dev Server & Build Scripts - -For details see Wiki: - -- [**Build Process**](https://github.com/vladmandic/human/wiki/Build-Process) -- [**Development Server**](https://github.com/vladmandic/human/wiki/Development-Server) - -Not required for normal funcioning of library diff --git a/server/build.js b/server/build.js deleted file mode 100644 index 2d94dd54..00000000 --- a/server/build.js +++ /dev/null @@ -1,270 +0,0 @@ -/** - * Implements Human build process - * Used to generate prod builds for releases or by dev server to generate on-the-fly debug builds - */ - -const fs = require('fs'); -const path = require('path'); -const log = require('@vladmandic/pilogger'); -const esbuild = require('esbuild'); -const rimraf = require('rimraf'); -const tfjs = require('@tensorflow/tfjs/package.json'); -const changelog = require('./changelog.js'); -const lint = require('./lint.js'); -const typedoc = require('./typedoc.js'); -const typings = require('./typings.js'); - -let busy = false; - -const config = { - build: { - banner: { js: ` - /* - Human library - homepage: - author: ' - */` }, - tsconfig: './tsconfig.json', - logLevel: 'error', - bundle: true, - metafile: true, - target: 'es2018', - }, - debug: { - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - production: { - minifyWhitespace: true, - minifyIdentifiers: true, - minifySyntax: true, - }, - buildLog: 'build.log', - changelog: '../CHANGELOG.md', - lintLocations: ['server/', 'src/', 'tfjs/', 'test/', 'demo/'], - cleanLocations: ['dist/*', 'types/*', 'typedoc/*'], -}; - -const targets = { - node: { - tfjs: { - platform: 'node', - format: 'cjs', - entryPoints: ['tfjs/tf-node.ts'], - outfile: 'dist/tfjs.esm.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - node: { - platform: 'node', - format: 'cjs', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.node.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - }, - nodeGPU: { - tfjs: { - platform: 'node', - format: 'cjs', - entryPoints: ['tfjs/tf-node-gpu.ts'], - outfile: 'dist/tfjs.esm.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - node: { - platform: 'node', - format: 'cjs', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.node-gpu.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - }, - nodeWASM: { - tfjs: { - platform: 'node', - format: 'cjs', - entryPoints: ['tfjs/tf-node-wasm.ts'], - outfile: 'dist/tfjs.esm.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - node: { - platform: 'node', - format: 'cjs', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.node-wasm.js', - external: ['@tensorflow'], - sourcemap: false, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - }, - - browserNoBundle: { - tfjs: { - platform: 'browser', - format: 'esm', - entryPoints: ['tfjs/tf-browser.ts'], - outfile: 'dist/tfjs.esm.js', - external: ['fs', 'buffer', 'util', 'os', '@tensorflow'], - sourcemap: true, - }, - esm: { - platform: 'browser', - format: 'esm', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.esm-nobundle.js', - external: ['fs', 'buffer', 'util', 'os', '@tensorflow'], - sourcemap: true, - }, - }, - browserBundle: { - tfjs: { - banner: { js: '/* TFJS custom ESM bundle in ES2018 */' }, - platform: 'browser', - format: 'esm', - entryPoints: ['tfjs/tf-browser.ts'], - outfile: 'dist/tfjs.esm.js', - external: ['fs', 'buffer', 'util', 'os'], - // treeShaking: 'ignore-annotations', - sourcemap: true, - minifyWhitespace: false, - minifyIdentifiers: false, - minifySyntax: false, - }, - iife: { - platform: 'browser', - format: 'iife', - globalName: 'Human', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.js', - external: ['fs', 'buffer', 'util', 'os'], - sourcemap: false, - }, - esm: { - platform: 'browser', - format: 'esm', - entryPoints: ['src/human.ts'], - outfile: 'dist/human.esm.js', - external: ['fs', 'buffer', 'util', 'os'], - sourcemap: true, - }, - /* - demo: { - platform: 'browser', - format: 'esm', - entryPoints: ['demo/browser.js'], - outfile: 'dist/demo-browser-index.js', - external: ['fs', 'buffer', 'util', 'os'], - }, - */ - }, -}; - -async function getStats(json) { - const stats = {}; - if (json && json.metafile?.inputs && json.metafile?.outputs) { - for (const [key, val] of Object.entries(json.metafile.inputs)) { - if (key.startsWith('node_modules')) { - stats.modules = (stats.modules || 0) + 1; - stats.moduleBytes = (stats.moduleBytes || 0) + val.bytes; - } else { - stats.imports = (stats.imports || 0) + 1; - stats.importBytes = (stats.importBytes || 0) + val.bytes; - } - } - const files = []; - for (const [key, val] of Object.entries(json.metafile.outputs)) { - if (!key.endsWith('.map')) { - files.push(key); - stats.outputBytes = (stats.outputBytes || 0) + val.bytes; - } - } - stats.outputFiles = files.join(', '); - } - return stats; -} - -// rebuild typings - -// rebuild on file change -async function build(f, msg, dev = false) { - if (busy) { - log.state('Build: busy...'); - setTimeout(() => build(f, msg, dev), 500); - return; - } - busy = true; - log.info('Build: file', msg, f, 'type:', dev ? 'debug' : 'production', 'config:', dev ? config.debug : config.production); - // common build options - try { - // rebuild all target groups and types - for (const [targetGroupName, targetGroup] of Object.entries(targets)) { - for (const [targetName, targetOptions] of Object.entries(targetGroup)) { - // if triggered from watch mode, rebuild only browser bundle - // if ((require.main !== module) && ((targetGroupName === 'browserNoBundle') || (targetGroupName === 'nodeGPU'))) continue; - const opt = dev ? config.debug : config.production; - // @ts-ignore // eslint-typescript complains about string enums used in js code - const meta = await esbuild.build({ ...config.build, ...opt, ...targetOptions }); - const stats = await getStats(meta); - log.state(` target: ${targetGroupName} type: ${targetName}:`, stats); - } - } - } catch (err) { - // catch errors and print where it occured - log.error('Build error', JSON.stringify(err.errors || err, null, 2)); - if (require.main === module) process.exit(1); - } - if (!dev) { // only for prod builds, skipped for dev build - await lint.run(config.lintLocations); // run linter - await changelog.update(config.changelog); // generate changelog - await typings.run(targets.browserBundle.esm.entryPoints); // generate typings - await typedoc.run(targets.browserBundle.esm.entryPoints); // generate typedoc - } - if (require.main === module) process.exit(0); - busy = false; -} - -function clean() { - log.info('Clean:', config.cleanLocations); - for (const loc of config.cleanLocations) rimraf.sync(loc); -} - -if (require.main === module) { - config.buildLog = path.join(__dirname, config.buildLog); - if (fs.existsSync(config.buildLog)) fs.unlinkSync(config.buildLog); - log.logFile(config.buildLog); - log.header(); - const toolchain = { - tfjs: tfjs.version, - esbuild: esbuild.version, - typescript: typings.version, - typedoc: typedoc.version, - eslint: lint.version, - }; - log.info('Toolchain: ', toolchain); - clean(); - build('all', 'startup'); -} else { - exports.build = build; -} diff --git a/server/build.log b/server/build.log deleted file mode 100644 index 5f80eae1..00000000 --- a/server/build.log +++ /dev/null @@ -1,13 +0,0 @@ -2021-09-10 19:34:11 INFO:  @vladmandic/human version 2.1.5 -2021-09-10 19:34:11 INFO:  User: vlado Platform: linux Arch: x64 Node: v16.5.0 -2021-09-10 19:34:11 INFO:  Toolchain: {"tfjs":"3.9.0","esbuild":"0.12.26","typescript":"4.4.3","typedoc":"0.22.1","eslint":"7.32.0"} -2021-09-10 19:34:11 INFO:  Clean: ["dist/*","types/*","typedoc/*"] -2021-09-10 19:34:11 INFO:  Build: file startup all type: production config: {"minifyWhitespace":true,"minifyIdentifiers":true,"minifySyntax":true} -2021-09-10 19:34:11 STATE: target: node type: tfjs: {"imports":1,"importBytes":102,"outputBytes":1444,"outputFiles":"dist/tfjs.esm.js"} -2021-09-10 19:34:11 STATE: target: node type: node: {"imports":47,"importBytes":456903,"outputBytes":396607,"outputFiles":"dist/human.node.js"} -2021-09-10 19:34:11 STATE: target: nodeGPU type: tfjs: {"imports":1,"importBytes":110,"outputBytes":1452,"outputFiles":"dist/tfjs.esm.js"} -2021-09-10 19:34:11 STATE: target: nodeGPU type: node: {"imports":47,"importBytes":456911,"outputBytes":396611,"outputFiles":"dist/human.node-gpu.js"} -2021-09-10 19:34:11 STATE: target: nodeWASM type: tfjs: {"imports":1,"importBytes":149,"outputBytes":1519,"outputFiles":"dist/tfjs.esm.js"} -2021-09-10 19:34:11 STATE: target: nodeWASM type: node: {"imports":47,"importBytes":456978,"outputBytes":396683,"outputFiles":"dist/human.node-wasm.js"} -2021-09-10 19:34:11 STATE: target: browserNoBundle type: tfjs: {"imports":1,"importBytes":2168,"outputBytes":1242,"outputFiles":"dist/tfjs.esm.js"} -2021-09-10 19:34:11 STATE: target: browserNoBundle type: esm: {"imports":47,"importBytes":456701,"outputBytes":255452,"outputFiles":"dist/human.esm-nobundle.js"} diff --git a/server/changelog.js b/server/changelog.js deleted file mode 100644 index a2453ffb..00000000 --- a/server/changelog.js +++ /dev/null @@ -1,59 +0,0 @@ -/** - * Creates changelog in markdown format from git log as part of the build process - */ - -const fs = require('fs'); -const path = require('path'); -const dayjs = require('dayjs'); -const simpleGit = require('simple-git/promise'); -const logger = require('@vladmandic/pilogger'); -const app = require('../package.json'); - -const git = simpleGit(); - -let text = `# ${app.name} - -Version: **${app.version}** -Description: **${app.description}** - -Author: **${app.author}** -License: **${app.license}** -Repository: **<${app.repository.url}>** - -## Changelog -`; - -async function update(f) { - const gitLog = await git.log(); - const entries = [...gitLog.all]; - const log = entries.sort((a, b) => (new Date(b.date).getTime() - new Date(a.date).getTime())); - - let previous = ''; - const headings = []; - for (const l of log) { - const msg = l.message.toLowerCase(); - if ((l.refs !== '') || msg.match(/^[0-99].[0-99].[0-99]/)) { - const dt = dayjs(l.date).format('YYYY/MM/DD'); - let ver = msg.match(/[0-99].[0-99].[0-99]/) ? msg : l.refs; - ver = ver.replace('tag: v', '').replace('tag: ', 'release: ').split(',')[0]; - const heading = `\n### **${ver}** ${dt} ${l.author_email}\n\n`; - if (!headings.includes(heading) && !ver.startsWith('tag')) { - headings.push(heading); - text += heading; - } - } else if ((msg.length > 2) && !msg.startsWith('update') && (previous !== msg)) { - previous = msg; - text += `- ${msg}\n`; - } - } - - const name = path.join(__dirname, f); - fs.writeFileSync(name, text); - logger.info('Generate ChangeLog:', [name]); -} - -if (require.main === module) { - update('../CHANGELOG.md'); -} else { - exports.update = update; -} diff --git a/server/https.crt b/server/https.crt deleted file mode 100644 index 1cc22286..00000000 --- a/server/https.crt +++ /dev/null @@ -1,31 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIUKQKodDBJnuweJs5IcTyL4NIp3vgwDQYJKoZIhvcNAQEL -BQAwRTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB0Zsb3JpZGExDjAMBgNVBAcMBU1p -YW1pMRQwEgYDVQQKDAtAdmxhZG1hbmRpYzAeFw0yMDExMDcxNTE3NDNaFw0yMTEx -MDcxNTE3NDNaMEUxCzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdGbG9yaWRhMQ4wDAYD -VQQHDAVNaWFtaTEUMBIGA1UECgwLQHZsYWRtYW5kaWMwggIiMA0GCSqGSIb3DQEB -AQUAA4ICDwAwggIKAoICAQDSC88PF8NyLkagK5mAZ/d739SOU16l2Cx3zE35zZQh -O29+1L4L+oMksLYipo+FMgtGO+MSzFsvGgKCs2sDSdfyoNSTZ3QaN4BAZ0sbq+wL -cke7yRBTM/XIGOQfhqq8yC2q8/zXwUbZg0UsCAxDGNwUr0Qlm829laIU/UN1KcYS -57Nebl1z05wMEvYmyl4JBAl9ozne7KS9DyW7jbrAXE8TaEy3+pY66kx5GG6v2+up -ScITGm4YPmPPlpOF1UjQloosgxdVa+fVp8aNCa/rf0JNO0Uhb3OKOZ+4kYmpfPn/ -trwoKWAa6CV1uAJ+3zDkLMq1JNlrV4OMp1QvX0wzA47a/n466JMN9SFb0Ng5wf19 -VOtT5Zu7chDStBudVjxlMDfUixvhvn4sjbaLNYR1fyWPoNXwr0KX2lpTP1QOzp9/ -Sd0iiJ8RPfXn8Xo26MStu4I52CZjS7yEMgJGCLH/mgPuSbrHHYYrrrCPJgmQOZG2 -TNMI+EqOwQvHh2ghdv7t7EEk4IslBk0QzufMXQ2WFXQ20nvj74mrmmiMuBcmonpR -0egA5/M18ZPLQxYu0Q86NUr4XHtAG1fq+n8pseQ7Avy6Gk6HRiezCbB7TJ9rnNeu -jie1TDajC6W7rx0VF7hcxkIrDgNgnYcjXUV2hMx1lo4fIoWkL3nJJVEthMVIcJOX -EwIDAQABo1MwUTAdBgNVHQ4EFgQUHawIRAo1bW8Xy7l4oKfM+ESjhs0wHwYDVR0j -BBgwFoAUHawIRAo1bW8Xy7l4oKfM+ESjhs0wDwYDVR0TAQH/BAUwAwEB/zANBgkq -hkiG9w0BAQsFAAOCAgEAozQJk5Ahx7rDn/aMXLdZFxR81VfkmHDm7NhlJsdVKUx5 -o/iegXnvwc1PoeKsz2S504QiuL8l7jqZoU2WPIm7Vlr+oxBgiKqjo1EqBsUgNCZ7 -qxMD84TVp/KBGjKUh1TXhjJwGGfNNr+R/fJGw+36UeuY3fSckjaYTuNuVElp+DoZ -/pGyu1qpcybLfiR8mpQkCeU/iBq5gIjWddbVjlYoTKfqULZrpsAF2AeqELEgyshl -p3PNhW/54TJSn4mWK+39BibYHPkvx8orEuWKyjjRk82hEXi7J3hsGKX29qC3oO40 -67DKDWmZdMCz+E1ERf10V0bSp6iJnnlwknHJloZUETV1NY/DdoSC6e8CN0+0cQqL -aJefJ483O3sXyN3v3+DaEFBLPFgRFGZB7eaBwR2xAv/KfjT5dSyi+wA4LZAxsQMC -Q7UYGNAfHLNHJo/bsj12+JDhJaFZ/KoBKzyMUuEXmvjxXNDMCfm+gVQFoLyXkGq3 -491W/O7LjR6pkD+ce0qeTFMu3nfUubyfbONVDEfuH4GC1e+FAggCRaBnFsVzCzXj -jxOOLoQ9nwLk8v17mx0BSwX4iuqvXFntfJbzfcnzQfx/qqPFheIbGnmKw1lrRML8 -87ZbN6t01+v2YyYe6Mc7p80s1R3jc8aVX8ca2KcYwsJAkg/xz0q5RJwsE1is5UY= ------END CERTIFICATE----- diff --git a/server/https.key b/server/https.key deleted file mode 100644 index e1217117..00000000 --- a/server/https.key +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN PRIVATE KEY----- -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 -qIRta3H9KNw2Mhpkm77TtUSV/W5aOmY= ------END PRIVATE KEY----- diff --git a/server/lint.js b/server/lint.js deleted file mode 100644 index 7864709f..00000000 --- a/server/lint.js +++ /dev/null @@ -1,23 +0,0 @@ -const log = require('@vladmandic/pilogger'); - -let eslint = null; -const { ESLint } = require('eslint'); - -const version = ESLint.version; - -async function lint(lintLocations) { - log.info('Running Linter:', lintLocations); - if (!eslint) eslint = new ESLint(); - const results = await eslint.lintFiles(lintLocations); - const errors = results.reduce((prev, curr) => prev += curr.errorCount, 0); - const warnings = results.reduce((prev, curr) => prev += curr.warningCount, 0); - log.info('Linter complete: files:', results.length, 'errors:', errors, 'warnings:', warnings); - if (errors > 0 || warnings > 0) { - const formatter = await eslint.loadFormatter('stylish'); - const text = formatter.format(results); - log.warn(text); - } -} - -exports.run = lint; -exports.version = version; diff --git a/server/serve.js b/server/serve.js deleted file mode 100644 index 46769b5b..00000000 --- a/server/serve.js +++ /dev/null @@ -1,194 +0,0 @@ -/** - Micro http/http2 server with file monitoring and automatic app rebuild - - can process concurrent http requests - - monitors specified filed and folders for changes - - triggers library and application rebuild - - any build errors are immediately displayed and can be corrected without need for restart - - passthrough data compression -*/ - -const fs = require('fs'); -const zlib = require('zlib'); -const http = require('http'); -const http2 = require('http2'); -const path = require('path'); -const chokidar = require('chokidar'); -const log = require('@vladmandic/pilogger'); -const build = require('./build.js'); - -// app configuration -// you can provide your server key and certificate or use provided self-signed ones -// self-signed certificate generated using: -// openssl req -x509 -newkey rsa:4096 -nodes -keyout https.key -out https.crt -days 365 -subj "/C=US/ST=Florida/L=Miami/O=@vladmandic" -// client app does not work without secure server since browsers enforce https for webcam access -const options = { - key: fs.readFileSync('server/https.key'), - cert: fs.readFileSync('server/https.crt'), - defaultFolder: 'demo', - defaultFile: 'index.html', - httpPort: 10030, - httpsPort: 10031, - insecureHTTPParser: false, - minElapsed: 2, - monitor: ['package.json', 'config.ts', 'demo/*.js', 'demo/*.html', 'src'], -}; - -// just some predefined mime types -const mime = { - '.html': 'text/html; charset=utf-8', - '.js': 'text/javascript; charset=utf-8', - '.css': 'text/css; charset=utf-8', - '.json': 'application/json; charset=utf-8', - '.png': 'image/png', - '.jpg': 'image/jpg', - '.gif': 'image/gif', - '.ico': 'image/x-icon', - '.svg': 'image/svg+xml', - '.wav': 'audio/wav', - '.mp4': 'video/mp4', - '.woff': 'font/woff', - '.woff2': 'font/woff2', - '.ttf': 'font/ttf', - '.wasm': 'application/wasm', -}; - -let last = Date.now(); -async function buildAll(evt, msg) { - const now = Date.now(); - if ((now - last) > options.minElapsed) build.build(evt, msg, true); - else log.state('Build: merge event file', msg, evt); - last = now; -} - -// watch filesystem for any changes and notify build when needed -async function watch() { - const watcher = chokidar.watch(options.monitor, { - persistent: true, - ignorePermissionErrors: false, - alwaysStat: false, - ignoreInitial: true, - followSymlinks: true, - usePolling: false, - useFsEvents: false, - atomic: true, - }); - // single event handler for file add/change/delete - watcher - .on('add', (evt) => buildAll(evt, 'add')) - .on('change', (evt) => buildAll(evt, 'modify')) - .on('unlink', (evt) => buildAll(evt, 'remove')) - .on('error', (err) => log.error(`Client watcher error: ${err}`)) - .on('ready', () => log.state('Monitoring:', options.monitor)); -} - -function handle(url) { - url = url.split(/[?#]/)[0]; - const result = { ok: false, stat: {}, file: '' }; - const checkFile = (f) => { - result.file = f; - if (fs.existsSync(f)) { - result.stat = fs.statSync(f); - if (result.stat.isFile()) { - result.ok = true; - return true; - } - } - return false; - }; - const checkFolder = (f) => { - result.file = f; - if (fs.existsSync(f)) { - result.stat = fs.statSync(f); - if (result.stat.isDirectory()) { - result.ok = true; - return true; - } - } - return false; - }; - return new Promise((resolve) => { - if (checkFile(path.join(process.cwd(), url))) resolve(result); - else if (checkFile(path.join(process.cwd(), url, options.defaultFile))) resolve(result); - else if (checkFile(path.join(process.cwd(), options.defaultFolder, url))) resolve(result); - else if (checkFile(path.join(process.cwd(), options.defaultFolder, url, options.defaultFile))) resolve(result); - else if (checkFolder(path.join(process.cwd(), url))) resolve(result); - else if (checkFolder(path.join(process.cwd(), options.defaultFolder, url))) resolve(result); - else resolve(result); - }); -} - -// process http requests -async function httpRequest(req, res) { - handle(decodeURI(req.url)).then((result) => { - // get original ip of requestor, regardless if it's behind proxy or not - const forwarded = (req.headers['forwarded'] || '').match(/for="\[(.*)\]:/); - const ip = (Array.isArray(forwarded) ? forwarded[1] : null) || req.headers['x-forwarded-for'] || req.ip || req.socket.remoteAddress; - if (!result || !result.ok || !result.stat) { - res.writeHead(404, { 'Content-Type': 'text/html; charset=utf-8' }); - res.end('Error 404: Not Found\n', 'utf-8'); - log.warn(`${req.method}/${req.httpVersion}`, res.statusCode, decodeURI(req.url), ip); - } else { - const input = encodeURIComponent(result.file).replace(/\*/g, '').replace(/\?/g, '').replace(/%2F/g, '/').replace(/%40/g, '@').replace(/%20/g, ' '); - if (result?.stat?.isFile()) { - const ext = String(path.extname(input)).toLowerCase(); - const contentType = mime[ext] || 'application/octet-stream'; - const accept = req.headers['accept-encoding'] ? req.headers['accept-encoding'].includes('br') : false; // does target accept brotli compressed data - res.writeHead(200, { - // 'Content-Length': result.stat.size, // not using as it's misleading for compressed streams - 'Content-Language': 'en', - 'Content-Type': contentType, - 'Content-Encoding': accept ? 'br' : '', - 'Last-Modified': result.stat.mtime, - 'Cache-Control': 'no-cache', - 'X-Content-Type-Options': 'nosniff', - 'Cross-Origin-Embedder-Policy': 'require-corp', - 'Cross-Origin-Opener-Policy': 'same-origin', - 'Content-Security-Policy': "media-src 'self' http: https: data:", - }); - const compress = zlib.createBrotliCompress({ params: { [zlib.constants.BROTLI_PARAM_QUALITY]: 5 } }); // instance of brotli compression with level 5 - const stream = fs.createReadStream(input); - if (!accept) stream.pipe(res); // don't compress data - else stream.pipe(compress).pipe(res); // compress data - - /// alternative #2 read stream and send by chunk - // const stream = fs.createReadStream(result.file); - // stream.on('data', (chunk) => res.write(chunk)); - // stream.on('end', () => res.end()); - - // alternative #3 read entire file and send it as blob - // const data = fs.readFileSync(result.file); - // res.write(data); - log.data(`${req.method}/${req.httpVersion}`, res.statusCode, contentType, result.stat.size, req.url, ip); - } - if (result?.stat?.isDirectory()) { - res.writeHead(200, { 'Content-Language': 'en', 'Content-Type': 'application/json; charset=utf-8', 'Last-Modified': result.stat.mtime, 'Cache-Control': 'no-cache', 'X-Content-Type-Options': 'nosniff' }); - let dir = fs.readdirSync(input); - dir = dir.map((f) => path.join(decodeURI(req.url), f)); - res.end(JSON.stringify(dir), 'utf-8'); - log.data(`${req.method}/${req.httpVersion}`, res.statusCode, 'directory/json', result.stat.size, req.url, ip); - } - } - }); -} - -// app main entry point -async function main() { - log.header(); - await watch(); - process.chdir(path.join(__dirname, '..')); - if (options.httpPort && options.httpPort > 0) { - const server1 = http.createServer(options, httpRequest); - server1.on('listening', () => log.state('HTTP server listening:', options.httpPort)); - server1.on('error', (err) => log.error('HTTP server:', err.message || err)); - server1.listen(options.httpPort); - } - if (options.httpsPort && options.httpsPort > 0) { - const server2 = http2.createSecureServer(options, httpRequest); - server2.on('listening', () => log.state('HTTP2 server listening:', options.httpsPort)); - server2.on('error', (err) => log.error('HTTP2 server:', err.message || err)); - server2.listen(options.httpsPort); - } - await build.build('all', 'startup', true); -} - -main(); diff --git a/server/signature.js b/server/signature.js deleted file mode 100644 index 73f4dd40..00000000 --- a/server/signature.js +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/env -S node --no-deprecation --trace-warnings - -/** - * Helper app that analyzes any TensorFlow SavedModel or GraphModel for inputs and outputs - */ - -const fs = require('fs'); -const path = require('path'); -const log = require('@vladmandic/pilogger'); -const tf = require('@tensorflow/tfjs-node'); - -async function analyzeGraph(modelPath) { - const model = await tf.loadGraphModel(`file://${modelPath}`); - log.info('graph model:', path.resolve(modelPath)); - log.info('size:', tf.engine().memory()); - - const inputs = []; - if (model.modelSignature && model.modelSignature['inputs']) { - log.info('model inputs based on signature'); - for (const [key, val] of Object.entries(model.modelSignature['inputs'])) { - const shape = val.tensorShape.dim.map((a) => parseInt(a.size)); - inputs.push({ name: key, dtype: val.dtype, shape }); - } - // @ts-ignore accessing private property - } else if (model.executor.graph['inputs']) { - log.info('model inputs based on executor'); - // @ts-ignore accessing private property - for (const t of model.executor.graph['inputs']) { - inputs.push({ name: t.name, dtype: t.attrParams.dtype.value, shape: t.attrParams.shape.value }); - } - } else { - log.warn('model inputs: cannot determine'); - } - - const outputs = []; - let i = 0; - if (model.modelSignature && model.modelSignature['outputs'] && Object.values(model.modelSignature['outputs'])[0].dtype) { - log.info('model outputs based on signature'); - for (const [key, val] of Object.entries(model.modelSignature['outputs'])) { - const shape = val.tensorShape?.dim.map((a) => parseInt(a.size)); - outputs.push({ id: i++, name: key, dytpe: val.dtype, shape }); - } - // @ts-ignore accessing private property - } else if (model.executor.graph['outputs']) { - log.info('model outputs based on executor'); - // @ts-ignore accessing private property - for (const t of model.executor.graph['outputs']) { - outputs.push({ id: i++, name: t.name, dtype: t.attrParams.dtype?.value || t.rawAttrs.T.type, shape: t.attrParams.shape?.value }); - } - } else { - log.warn('model outputs: cannot determine'); - } - - log.data('inputs:', inputs); - log.data('outputs:', outputs); -} - -async function analyzeSaved(modelPath) { - const meta = await tf.node.getMetaGraphsFromSavedModel(modelPath); - log.info('saved model:', path.resolve(modelPath)); - const sign = Object.values(meta[0].signatureDefs)[0]; - log.data('tags:', meta[0].tags); - log.data('signature:', Object.keys(meta[0].signatureDefs)); - const inputs = Object.values(sign.inputs)[0]; - // @ts-ignore a is array - const inputShape = inputs.shape?.map((a) => a.array[0]); - log.data('inputs:', { name: inputs.name, dtype: inputs.dtype, shape: inputShape }); - const outputs = []; - let i = 0; - for (const [key, val] of Object.entries(sign.outputs)) { - // @ts-ignore a is array - const shape = val.shape?.map((a) => a.array[0]); - outputs.push({ id: i++, name: key, dytpe: val.dtype, shape }); - } - log.data('outputs:', outputs); -} - -async function main() { - log.header(); - const param = process.argv[2]; - if (process.argv.length !== 3) { - log.error('path required'); - process.exit(0); - } else if (!fs.existsSync(param)) { - log.error(`path does not exist: ${param}`); - process.exit(0); - } - const stat = fs.statSync(param); - log.data('created on:', stat.birthtime); - if (stat.isFile()) { - if (param.endsWith('.json')) analyzeGraph(param); - } - if (stat.isDirectory()) { - if (fs.existsSync(path.join(param, '/saved_model.pb'))) analyzeSaved(param); - if (fs.existsSync(path.join(param, '/model.json'))) analyzeGraph(path.join(param, '/model.json')); - } -} - -main(); diff --git a/server/typedoc.js b/server/typedoc.js deleted file mode 100644 index c2e2ced6..00000000 --- a/server/typedoc.js +++ /dev/null @@ -1,35 +0,0 @@ -const log = require('@vladmandic/pilogger'); -const TypeDoc = require('typedoc'); -const tsconfig = require('../tsconfig.json'); - -let td = null; - -const version = TypeDoc.Application.VERSION; - -async function typedoc(entryPoints) { - if (!td) { - td = new TypeDoc.Application(); - td.options.addReader(new TypeDoc.TSConfigReader()); - td.bootstrap({ entryPoints }); - td.logger.warn = log.warn; - td.logger.error = log.error; - td.logger.verbose = () => { /***/ }; - // td.logger.verbose = log.data; // remove extra logging - td.logger.log = log.info; - // td.converter = converter; - } - log.info('Generate TypeDocs:', entryPoints, 'outDir:', [tsconfig.typedocOptions.out]); - const project = td.convert(); - if (!project) log.warn('TypeDoc: convert returned empty project'); - if (td.logger.hasErrors() || td.logger.hasWarnings()) log.warn('TypeDoc:', 'errors:', td.logger.errorCount, 'warnings:', td.logger.warningCount); - const result = project ? await td.generateDocs(project, 'typedoc') : null; - if (result) log.warn('TypeDoc:', result); -} - -if (require.main === module) { - log.header(); - typedoc(['src/human.ts']); // generate typedoc -} else { - exports.run = typedoc; - exports.version = version; -} diff --git a/server/typings.js b/server/typings.js deleted file mode 100644 index 86bc5e5d..00000000 --- a/server/typings.js +++ /dev/null @@ -1,37 +0,0 @@ -const ts = require('typescript'); -const log = require('@vladmandic/pilogger'); - -const version = ts.version; - -async function typings(entryPoint) { - const configFileName = ts.findConfigFile('./', ts.sys.fileExists, 'tsconfig.json') || ''; - const configFile = ts.readConfigFile(configFileName, ts.sys.readFile); - const compilerOptions = ts.parseJsonConfigFileContent(configFile.config, ts.sys, './'); - // add explicitly to avoid generating compiled js files - compilerOptions.options.emitDeclarationOnly = true; - log.info('Generate Typings:', entryPoint, 'outDir:', [compilerOptions.options.outDir]); - const compilerHost = ts.createCompilerHost(compilerOptions.options); - const program = ts.createProgram(entryPoint, compilerOptions.options, compilerHost); - const emit = program.emit(); - const diag = ts - .getPreEmitDiagnostics(program) - .concat(emit.diagnostics); - for (const info of diag) { - const msg = info.messageText['messageText'] || info.messageText; - if (msg.includes('package.json')) continue; - if (info.file) { - const pos = info.file.getLineAndCharacterOfPosition(info.start || 0); - log.error(`TSC: ${info.file.fileName} [${pos.line + 1},${pos.character + 1}]:`, msg); - } else { - log.error('TSC:', msg); - } - } -} - -if (require.main === module) { - log.header(); - typings(['src/human.ts']); // generate typedoc -} else { - exports.run = typings; - exports.version = version; -}