diff --git a/package-lock.json b/package-lock.json index e9e903b..ac2f9a0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28,6 +28,8 @@ "mxgraph": "^4.2.2", "niceware": "^4.0.0", "p2p-data-channel": "^1.10.7", + "pouchdb": "^8.0.1", + "pouchdb-find": "^7.2.2", "query-string": "^8.1.0", "recordrtc": "^5.6.2", "ring-client-api": "11.7.7", @@ -1066,6 +1068,32 @@ "integrity": "sha512-U/4aVJ2mxI0aDNI8Uq0wEhMgY+u4CNtEb0om3+y3+niDAsoTCOB33UF0sxpzqzdqXLqmvc+vZyAt4O8pPdfkwA==", "optional": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, + "node_modules/abstract-leveldown": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-6.2.3.tgz", + "integrity": "sha512-BsLm5vFMRUrrLeCcRc+G0t2qOaTzpoJQLOubq2XM72eNpjF5UdU5o/5NvlNhx95XHcAvcl8OMXr4mlg/fRgUXQ==", + "dependencies": { + "buffer": "^5.5.0", + "immediate": "^3.2.3", + "level-concat-iterator": "~2.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/aes-js": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", @@ -1135,6 +1163,11 @@ "node": ">= 8" } }, + "node_modules/argsarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", + "integrity": "sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg==" + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -1339,6 +1372,11 @@ "node": "*" } }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "node_modules/cacheable-lookup": { "version": "5.0.4", "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", @@ -1495,6 +1533,14 @@ "node": ">=0.8" } }, + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/clone-response": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", @@ -1564,6 +1610,11 @@ "node": ">= 0.6" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -1666,6 +1717,18 @@ "node": ">=10" } }, + "node_modules/deferred-leveldown": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-5.3.0.tgz", + "integrity": "sha512-a59VOT+oDy7vtAbLRCZwWgxu2BaCfd5Hk7wxJd48ei7I+nsg8Orlb9CLG0PMZienk9BSUKgeAqkO2+Lw+1+Ukw==", + "dependencies": { + "abstract-leveldown": "~6.2.1", + "inherits": "^2.0.3" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1721,6 +1784,11 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/double-ended-queue": { + "version": "2.1.0-0", + "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", + "integrity": "sha512-+BNfZ+deCo8hMNpDqDnvT+c0XpJ5cUa6mqYq89bho2Ifze4URTqRkcwR399hWoTrTkbZ/XJYDgP6rc7pRgffEQ==" + }, "node_modules/earcut": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.4.tgz", @@ -1760,6 +1828,20 @@ "iconv-lite": "^0.6.2" } }, + "node_modules/encoding-down": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-6.3.0.tgz", + "integrity": "sha512-QKrV0iKR6MZVJV08QY0wp1e7vF6QbhnbQhb07bwpEyuz4uZiZgPlEGdkCROuFkUwdxlFaiPIhjyarH1ee/3vhw==", + "dependencies": { + "abstract-leveldown": "^6.2.1", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/encoding/node_modules/iconv-lite": { "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", @@ -1781,6 +1863,14 @@ "once": "^1.4.0" } }, + "node_modules/end-stream": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/end-stream/-/end-stream-0.1.0.tgz", + "integrity": "sha512-Brl10T8kYnc75IepKizW6Y9liyW8ikz1B7n/xoHrJxoVSSjoqPn30sb7XVFfQERK4QfUMYRGs9dhWwtt2eu6uA==", + "dependencies": { + "write-stream": "~0.4.3" + } + }, "node_modules/engine.io-client": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.5.3.tgz", @@ -1844,6 +1934,17 @@ "has-binary2": "~1.0.2" } }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, "node_modules/esbuild": { "version": "0.18.20", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.18.20.tgz", @@ -1897,6 +1998,14 @@ "node": ">=0.8.0" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -1970,6 +2079,17 @@ "reusify": "^1.0.4" } }, + "node_modules/fetch-cookie": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/fetch-cookie/-/fetch-cookie-0.11.0.tgz", + "integrity": "sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA==", + "dependencies": { + "tough-cookie": "^2.3.3 || ^3.0.1 || ^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ffmpeg-for-homebridge": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/ffmpeg-for-homebridge/-/ffmpeg-for-homebridge-0.1.4.tgz", @@ -2391,6 +2511,11 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", + "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==" + }, "node_modules/indexof": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", @@ -2686,6 +2811,142 @@ "json-buffer": "3.0.1" } }, + "node_modules/level": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/level/-/level-6.0.1.tgz", + "integrity": "sha512-psRSqJZCsC/irNhfHzrVZbmPYXDcEYhA5TVNwr+V92jF44rbf86hqGp8fiT702FyiArScYIlPSBTDUASCVNSpw==", + "dependencies": { + "level-js": "^5.0.0", + "level-packager": "^5.1.0", + "leveldown": "^5.4.0" + }, + "engines": { + "node": ">=8.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/level" + } + }, + "node_modules/level-codec": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.2.tgz", + "integrity": "sha512-UyIwNb1lJBChJnGfjmO0OR+ezh2iVu1Kas3nvBS/BzGnx79dv6g7unpKIDNPMhfdTEGoc7mC8uAu51XEtX+FHQ==", + "dependencies": { + "buffer": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-concat-iterator": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-concat-iterator/-/level-concat-iterator-2.0.1.tgz", + "integrity": "sha512-OTKKOqeav2QWcERMJR7IS9CUo1sHnke2C0gkSmcR7QuEtFNLLzHQAvnMw8ykvEcv0Qtkg0p7FOwP1v9e5Smdcw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/level-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.1.tgz", + "integrity": "sha512-UVprBJXite4gPS+3VznfgDSU8PTRuVX0NXwoWW50KLxd2yw4Y1t2JUR5In1itQnudZqRMT9DlAM3Q//9NCjCFw==", + "dependencies": { + "errno": "~0.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-4.0.2.tgz", + "integrity": "sha512-ZSthfEqzGSOMWoUGhTXdX9jv26d32XJuHz/5YnuHZzH6wldfWMOVwI9TBtKcya4BKTyTt3XVA0A3cF3q5CY30Q==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.4.0", + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-iterator-stream/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/level-js": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/level-js/-/level-js-5.0.2.tgz", + "integrity": "sha512-SnBIDo2pdO5VXh02ZmtAyPP6/+6YTJg2ibLtl9C34pWvmtMEmRTWpra+qO/hifkUtBTOtfx6S9vLDjBsBK4gRg==", + "dependencies": { + "abstract-leveldown": "~6.2.3", + "buffer": "^5.5.0", + "inherits": "^2.0.3", + "ltgt": "^2.1.2" + } + }, + "node_modules/level-packager": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-5.1.1.tgz", + "integrity": "sha512-HMwMaQPlTC1IlcwT3+swhqf/NUO+ZhXVz6TY1zZIIZlIR0YSn8GtAAWmIvKjNY16ZkEg/JcpAuQskxsXqC0yOQ==", + "dependencies": { + "encoding-down": "^6.3.0", + "levelup": "^4.3.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-supports": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/level-supports/-/level-supports-1.0.1.tgz", + "integrity": "sha512-rXM7GYnW8gsl1vedTJIbzOrRv85c/2uCMpiiCzO2fndd06U/kUXEEU9evYn4zFggBOg36IsBW8LzqIpETwwQzg==", + "dependencies": { + "xtend": "^4.0.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/level-write-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/level-write-stream/-/level-write-stream-1.0.0.tgz", + "integrity": "sha512-bBNKOEOMl8msO+uIM9YX/gUO6ckokZ/4pCwTm/lwvs46x6Xs8Zy0sn3Vh37eDqse4mhy4fOMIb/JsSM2nyQFtw==", + "dependencies": { + "end-stream": "~0.1.0" + } + }, + "node_modules/leveldown": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-5.6.0.tgz", + "integrity": "sha512-iB8O/7Db9lPaITU1aA2txU/cBEXAt4vWwKQRrrWuS6XDgbP4QZGj9BL2aNbwb002atoQ/lIotJkfyzz+ygQnUQ==", + "hasInstallScript": true, + "dependencies": { + "abstract-leveldown": "~6.2.1", + "napi-macros": "~2.0.0", + "node-gyp-build": "~4.1.0" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/levelup": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-4.4.0.tgz", + "integrity": "sha512-94++VFO3qN95cM/d6eBXvd894oJE0w3cInq9USsyQzzoJxmiYzPAocNcuGCPGGjoXqDVJcr3C1jzt1TSjyaiLQ==", + "dependencies": { + "deferred-leveldown": "~5.3.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~4.0.0", + "level-supports": "~1.0.0", + "xtend": "~4.0.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -2736,6 +2997,11 @@ "node": ">=8" } }, + "node_modules/ltgt": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.2.1.tgz", + "integrity": "sha512-AI2r85+4MquTw9ZYqabu4nMwy9Oftlfa/e/52t9IjtfG+mGBbTNdAoZ3RQKLHR6r0wQnwZnPIEh/Ya6XTWAKNA==" + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -2937,6 +3203,11 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/napi-macros": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-macros/-/napi-macros-2.0.0.tgz", + "integrity": "sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg==" + }, "node_modules/niceware": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/niceware/-/niceware-4.0.0.tgz", @@ -2965,6 +3236,16 @@ } } }, + "node_modules/node-gyp-build": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.1.1.tgz", + "integrity": "sha512-dSq1xmcPDKPZ2EED2S6zw/b9NKsqzXRE6dVr8TVQnI3FJOTteUMuqF3Qqs6LZg+mLGYJWqQzMbIjMtJqTv87nQ==", + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -3203,6 +3484,230 @@ "node": "^10 || ^12 || >=14" } }, + "node_modules/pouchdb": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/pouchdb/-/pouchdb-8.0.1.tgz", + "integrity": "sha512-xp5S83JOQn2NAL0ZQ5CU+DI26V9/YrYuVtkXnbGEIDrYiFfj5A8gAcfbxefXb/9O+Qn4n5RaT/19+8UBSZ42sw==", + "dependencies": { + "abort-controller": "3.0.0", + "buffer-from": "1.1.2", + "clone-buffer": "1.0.0", + "double-ended-queue": "2.1.0-0", + "fetch-cookie": "0.11.0", + "immediate": "3.3.0", + "level": "6.0.1", + "level-codec": "9.0.2", + "level-write-stream": "1.0.0", + "leveldown": "5.6.0", + "levelup": "4.4.0", + "ltgt": "2.2.1", + "node-fetch": "2.6.7", + "readable-stream": "1.1.14", + "spark-md5": "3.0.2", + "through2": "3.0.2", + "uuid": "8.3.2", + "vuvuzela": "1.0.3" + } + }, + "node_modules/pouchdb-abstract-mapreduce": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-abstract-mapreduce/-/pouchdb-abstract-mapreduce-7.3.1.tgz", + "integrity": "sha512-0zKXVFBvrfc1KnN0ggrB762JDmZnUpePHywo9Bq3Jy+L1FnoG7fXM5luFfvv5/T0gEw+ZTIwoocZECMnESBI9w==", + "dependencies": { + "pouchdb-binary-utils": "7.3.1", + "pouchdb-collate": "7.3.1", + "pouchdb-collections": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-fetch": "7.3.1", + "pouchdb-mapreduce-utils": "7.3.1", + "pouchdb-md5": "7.3.1", + "pouchdb-utils": "7.3.1" + } + }, + "node_modules/pouchdb-binary-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-binary-utils/-/pouchdb-binary-utils-7.3.1.tgz", + "integrity": "sha512-crZJNfAEOnUoRk977Qtmk4cxEv6sNKllQ6vDDKgQrQLFjMUXma35EHzNyIJr1s76J77Q4sqKQAmxz9Y40yHGtw==", + "dependencies": { + "buffer-from": "1.1.2" + } + }, + "node_modules/pouchdb-collate": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-collate/-/pouchdb-collate-7.3.1.tgz", + "integrity": "sha512-o4gyGqDMLMSNzf6EDTr3eHaH/JRMoqRhdc+eV+oA8u00nTBtr9wD+jypVe2LbgKLJ4NWqx2qVkXiTiQdUFtsLQ==" + }, + "node_modules/pouchdb-collections": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-collections/-/pouchdb-collections-7.3.1.tgz", + "integrity": "sha512-yUyDqR+OJmtwgExOSJegpBJXDLAEC84TWnbAYycyh+DZoA51Yw0+XVQF5Vh8Ii90/Ut2xo88fmrmp0t6kqom8w==" + }, + "node_modules/pouchdb-errors": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-errors/-/pouchdb-errors-7.3.1.tgz", + "integrity": "sha512-Zktz4gnXEUcZcty8FmyvtYUYsHskoST05m6H5/E2gg/0mCfEXq/XeyyLkZHaZmqD0ZPS9yNmASB1VaFWEKEaDw==", + "dependencies": { + "inherits": "2.0.4" + } + }, + "node_modules/pouchdb-errors/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/pouchdb-fetch": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-fetch/-/pouchdb-fetch-7.3.1.tgz", + "integrity": "sha512-205xAtvdHRPQ4fp1h9+RmT9oQabo9gafuPmWsS9aEl3ER54WbY8Vaj1JHZGbU4KtMTYvW7H5088zLS7Nrusuag==", + "dependencies": { + "abort-controller": "3.0.0", + "fetch-cookie": "0.11.0", + "node-fetch": "2.6.7" + } + }, + "node_modules/pouchdb-fetch/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/pouchdb-find": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-find/-/pouchdb-find-7.3.1.tgz", + "integrity": "sha512-AeqUfAVY1c7IFaY36BRT0vIz9r4VTKq/YOWTmiqndOZUQ/pDGxyO2fNFal6NN3PyYww0JijlD377cPvhnrhJVA==", + "dependencies": { + "pouchdb-abstract-mapreduce": "7.3.1", + "pouchdb-collate": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-fetch": "7.3.1", + "pouchdb-md5": "7.3.1", + "pouchdb-selector-core": "7.3.1", + "pouchdb-utils": "7.3.1" + } + }, + "node_modules/pouchdb-mapreduce-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-mapreduce-utils/-/pouchdb-mapreduce-utils-7.3.1.tgz", + "integrity": "sha512-oUMcq82+4pTGQ6dtrhgORHOVHZSr6w/5tFIUGlv7RABIDvJarL4snMawADjlpiEwPdiQ/ESG8Fqt8cxqvqsIgg==", + "dependencies": { + "argsarray": "0.0.1", + "inherits": "2.0.4", + "pouchdb-collections": "7.3.1", + "pouchdb-utils": "7.3.1" + } + }, + "node_modules/pouchdb-mapreduce-utils/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/pouchdb-md5": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-md5/-/pouchdb-md5-7.3.1.tgz", + "integrity": "sha512-aDV8ui/mprnL3xmt0gT/81DFtTtJiKyn+OxIAbwKPMfz/rDFdPYvF0BmDC9QxMMzGfkV+JJUjU6at0PPs2mRLg==", + "dependencies": { + "pouchdb-binary-utils": "7.3.1", + "spark-md5": "3.0.2" + } + }, + "node_modules/pouchdb-selector-core": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-selector-core/-/pouchdb-selector-core-7.3.1.tgz", + "integrity": "sha512-HBX+nNGXcaL9z0uNpwSMRq2GNZd3EZXW+fe9rJHS0hvJohjZL7aRJLoaXfEdHPRTNW+CpjM3Rny60eGekQdI/w==", + "dependencies": { + "pouchdb-collate": "7.3.1", + "pouchdb-utils": "7.3.1" + } + }, + "node_modules/pouchdb-utils": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/pouchdb-utils/-/pouchdb-utils-7.3.1.tgz", + "integrity": "sha512-R3hHBo1zTdTu/NFs3iqkcaQAPwhIH0gMIdfVKd5lbDYlmP26rCG5pdS+v7NuoSSFLJ4xxnaGV+Gjf4duYsJ8wQ==", + "dependencies": { + "argsarray": "0.0.1", + "clone-buffer": "1.0.0", + "immediate": "3.3.0", + "inherits": "2.0.4", + "pouchdb-collections": "7.3.1", + "pouchdb-errors": "7.3.1", + "pouchdb-md5": "7.3.1", + "uuid": "8.3.2" + } + }, + "node_modules/pouchdb-utils/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "node_modules/pouchdb-utils/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/pouchdb/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==" + }, + "node_modules/pouchdb/node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/pouchdb/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/pouchdb/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==" + }, + "node_modules/pouchdb/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/precision": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/precision/-/precision-1.0.1.tgz", @@ -3252,6 +3757,16 @@ "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -3261,6 +3776,14 @@ "once": "^1.3.1" } }, + "node_modules/punycode": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", + "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", + "engines": { + "node": ">=6" + } + }, "node_modules/pvtsutils": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.2.tgz", @@ -3293,6 +3816,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3379,6 +3907,11 @@ "node": ">=0.10.0" } }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" + }, "node_modules/resolve-alpn": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", @@ -3724,6 +4257,11 @@ "node": ">=0.10.0" } }, + "node_modules/spark-md5": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spark-md5/-/spark-md5-3.0.2.tgz", + "integrity": "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==" + }, "node_modules/split-on-first": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", @@ -3837,6 +4375,20 @@ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==" }, + "node_modules/through2": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.2.tgz", + "integrity": "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ==", + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "2 || 3" + } + }, + "node_modules/through2/node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, "node_modules/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -3864,6 +4416,28 @@ "node": ">=8.0" } }, + "node_modules/tough-cookie": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.3.tgz", + "integrity": "sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==", + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.2.0", + "url-parse": "^1.5.3" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "engines": { + "node": ">= 4.0.0" + } + }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -3936,6 +4510,15 @@ "node": ">= 10.0.0" } }, + "node_modules/url-parse": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", + "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/urlsafe-base64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/urlsafe-base64/-/urlsafe-base64-1.0.0.tgz", @@ -4055,6 +4638,11 @@ "node": ">=12" } }, + "node_modules/vuvuzela": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vuvuzela/-/vuvuzela-1.0.3.tgz", + "integrity": "sha512-Tm7jR1xTzBbPW+6y1tknKiEhz04Wf/1iZkcTJjSFcpNko43+dFW6+OOeQe9taJIug3NdfUAjFKgUSyQrIKaDvQ==" + }, "node_modules/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", @@ -4209,6 +4797,19 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/write-stream": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/write-stream/-/write-stream-0.4.3.tgz", + "integrity": "sha512-IJrvkhbAnj89W/GAVdVgbnPiVw5Ntg/B4tc/MUCIEwj/g6JIww1DWJyB/yBMT3yw2/TkT6IUZ0+IYef3flEw8A==", + "dependencies": { + "readable-stream": "~0.0.2" + } + }, + "node_modules/write-stream/node_modules/readable-stream": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-0.0.4.tgz", + "integrity": "sha512-azrivNydKRYt7zwLV5wWUK7YzKTWs3q87xSmY6DlHapPrCvaT6ZrukvM5erV+yCSSPmZT8zkSdttOHQpWWm9zw==" + }, "node_modules/ws": { "version": "8.13.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", @@ -4237,6 +4838,14 @@ "node": ">=0.4.0" } }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", diff --git a/package.json b/package.json index d172677..e2681bf 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,8 @@ "mxgraph": "^4.2.2", "niceware": "^4.0.0", "p2p-data-channel": "^1.10.7", + "pouchdb": "^8.0.1", + "pouchdb-find": "^7.2.2", "query-string": "^8.1.0", "recordrtc": "^5.6.2", "ring-client-api": "11.7.7", diff --git a/src/app.ts b/src/app.ts index e0a05aa..367bb46 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,6 +1,6 @@ import { - ArcRotateCamera, Engine, + FreeCamera, HemisphericLight, Scene, Vector3, @@ -20,8 +20,9 @@ import workerUrl from "./worker?worker&url"; import {DiagramEventType} from "./diagram/diagramEntity"; import {PeerjsNetworkConnection} from "./integration/peerjsNetworkConnection"; import {DiagramExporter} from "./util/diagramExporter"; -import {Introduction} from "./tutorial/introduction"; import {Spinner} from "./util/spinner"; +import {WebController} from "./controllers/webController"; +import {PouchdbPersistenceManager} from "./integration/pouchdbPersistenceManager"; export class App { @@ -57,23 +58,67 @@ export class App { } const scene = new Scene(engine); + + const spinner = new Spinner(scene); spinner.show(); const config = new AppConfig(); const peerjsNetworkConnection = new PeerjsNetworkConnection(); //const persistenceManager = new IndexdbPersistenceManager("diagram"); - const worker = new Worker(workerUrl, {type: 'module'}); + /*const worker = new Worker(workerUrl, {type: 'module'}); peerjsNetworkConnection.connectionObservable.add((peerId) => { this.logger.debug('App', 'peerjs network connected', peerId); worker.postMessage({type: 'sync'}); }); + + */ const controllers = new Controllers(); const toolbox = new Toolbox(scene, controllers); const diagramManager = new DiagramManager(scene, controllers, toolbox, config); + const db = new PouchdbPersistenceManager("diagram"); - peerjsNetworkConnection.diagramEventObservable.add((evt) => { + db.configObserver.add((newConfig) => { + config.onConfigChangedObservable.notifyObservers(newConfig, 1); + }); + config.onConfigChangedObservable.add((newConfig) => { + db.setConfig(newConfig); + }, 2, false, this); + + diagramManager.onDiagramEventObservable.add((evt) => { + switch (evt.type) { + case DiagramEventType.CHANGECOLOR: + db.changeColor(evt.oldColor, evt.newColor); + break; + case DiagramEventType.ADD: + db.add(evt.entity); + break; + case DiagramEventType.REMOVE: + db.remove(evt.entity.id); + break; + case DiagramEventType.MODIFY: + case DiagramEventType.DROP: + db.modify(evt.entity); + break; + default: + this.logger.warn('App', 'unknown diagram event type', evt); + } + }, 2); + db.updateObserver.add((evt) => { + diagramManager.onDiagramEventObservable.notifyObservers({ + type: DiagramEventType.ADD, + entity: evt + }, 1); + }); + db.removeObserver.add((entity) => { + diagramManager.onDiagramEventObservable.notifyObservers( + {type: DiagramEventType.REMOVE, entity: entity}, 1); + }); + + await db.initialize(); + + /*peerjsNetworkConnection.diagramEventObservable.add((evt) => { this.logger.debug('App', 'peerjs network event', evt); diagramManager.onDiagramEventObservable.notifyObservers(evt, 1); }); @@ -111,7 +156,7 @@ export class App { } worker.postMessage({type: 'init'}); - +*/ //diagramManager.setPersistenceManager(persistenceManager); const environment = new CustomEnvironment(scene, "default", config); @@ -122,13 +167,13 @@ export class App { } }); */ - const camera: ArcRotateCamera = new ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 4, - new Vector3(0, 1.6, 0), scene); + const camera: FreeCamera = new FreeCamera("Camera", + new Vector3(0, 1.6, 3), scene); + camera.setTarget(new Vector3(0, 1.6, 0)); +// camera.attachControl(canvas, true); - camera.attachControl(canvas, true); new HemisphericLight("light1", new Vector3(1, 1, 0), scene); - - + new HemisphericLight("light1", new Vector3(-1, 1, 0), scene); environment.groundMeshObservable.add(async (ground) => { const xr = await WebXRDefaultExperience.CreateAsync(scene, { floorMeshes: [ground], @@ -168,6 +213,9 @@ export class App { }); import('./controllers/rigplatform').then((rigmodule) => { const rig = new rigmodule.Rigplatform(scene, xr, diagramManager, controllers); + + const webController = new WebController(scene, rig, diagramManager, controllers); + // const deckMenu = new DeckMenu(scene, xr, controllers); /*setTimeout(() => { const soccerMenu = new SoccerMenu(scene, xr, controllers); }, 5000); diff --git a/src/controllers/base.ts b/src/controllers/base.ts index 7e5b63b..a0b61c9 100644 --- a/src/controllers/base.ts +++ b/src/controllers/base.ts @@ -4,7 +4,6 @@ import { Mesh, PhysicsMotionType, Scene, - TransformNode, Vector3, WebXRControllerComponent, WebXRDefaultExperience, @@ -19,6 +18,7 @@ import {setupTransformNode} from "./functions/setupTransformNode"; import {reparent} from "./functions/reparent"; import {snapGridVal} from "../util/functions/snapGridVal"; import {snapRotateVal} from "../util/functions/snapRotateVal"; +import {grabAndClone} from "./functions/grab"; export class Base { static stickVector = Vector3.Zero(); @@ -153,23 +153,13 @@ export class Base { this.grabbedMesh = mesh; } else { - const newMesh = this.diagramManager.createCopy(mesh); - const transformNode = new TransformNode("grabAnchor, this.scene"); - transformNode.id = "grabAnchor"; - transformNode.position = newMesh.position.clone(); - if (newMesh.rotationQuaternion) { - transformNode.rotationQuaternion = newMesh.rotationQuaternion.clone(); - } else { - transformNode.rotation = newMesh.rotation.clone(); - } - transformNode.setParent(this.controller.motionController.rootMesh); - newMesh.setParent(transformNode); - this.grabbedMeshParentId = transformNode.id; - this.grabbedMesh = newMesh; + const clone = grabAndClone(this.diagramManager, mesh, this.controller.motionController.rootMesh); + this.grabbedMeshParentId = clone.transformNode.id; + this.grabbedMesh = clone.newMesh; this.previousParentId = null; const event: DiagramEvent = { type: DiagramEventType.ADD, - entity: toDiagramEntity(newMesh) + entity: toDiagramEntity(clone.newMesh) } this.diagramManager.onDiagramEventObservable.notifyObservers(event, -1); } diff --git a/src/controllers/functions/grab.ts b/src/controllers/functions/grab.ts new file mode 100644 index 0000000..9851638 --- /dev/null +++ b/src/controllers/functions/grab.ts @@ -0,0 +1,17 @@ +import {AbstractMesh, TransformNode} from "@babylonjs/core"; +import {DiagramManager} from "../../diagram/diagramManager"; + +export function grabAndClone(diagramManager: DiagramManager, mesh: AbstractMesh, parent: AbstractMesh) { + const newMesh = diagramManager.createCopy(mesh); + const transformNode = new TransformNode("grabAnchor, this.scene"); + transformNode.id = "grabAnchor"; + transformNode.position = newMesh.position.clone(); + if (newMesh.rotationQuaternion) { + transformNode.rotationQuaternion = newMesh.rotationQuaternion.clone(); + } else { + transformNode.rotation = newMesh.rotation.clone(); + } + transformNode.setParent(parent); + newMesh.setParent(transformNode); + return {transformNode: transformNode, newMesh: newMesh}; +} \ No newline at end of file diff --git a/src/controllers/webController.ts b/src/controllers/webController.ts new file mode 100644 index 0000000..15ec302 --- /dev/null +++ b/src/controllers/webController.ts @@ -0,0 +1,149 @@ +import {AbstractMesh, MeshBuilder, Scene, Vector3} from "@babylonjs/core"; +import {Rigplatform} from "./rigplatform"; +import {ControllerEventType, Controllers} from "./controllers"; +import {DiagramManager} from "../diagram/diagramManager"; +import {GridMaterial} from "@babylonjs/materials"; +import {setMenuPosition} from "../util/functions/setMenuPosition"; + +export class WebController { + private scene: Scene; + private readonly referencePlane: AbstractMesh; + private grabbedMesh: AbstractMesh; + private pickedMesh: AbstractMesh; + private rig: Rigplatform; + private diagramManager: DiagramManager; + private mouseDown: boolean = false; + private controllers: Controllers; + + constructor(scene: Scene, rig: Rigplatform, diagramManager: DiagramManager, controllers: Controllers) { + this.scene = scene; + this.rig = rig; + this.diagramManager = diagramManager; + this.controllers = controllers; + + this.referencePlane = MeshBuilder.CreatePlane('referencePlane', {size: 10}, this.scene); + this.referencePlane.setEnabled(false); + this.referencePlane.visibility = 0.5; + const material = new GridMaterial('grid', this.scene); + material.gridRatio = 1; + material.backFaceCulling = false; + material.antialias = true; + this.referencePlane.material = material; + + + this.scene.onKeyboardObservable.add((kbInfo) => { + console.log(kbInfo); + if (kbInfo.type == 1) { + switch (kbInfo.event.key) { + case "ArrowUp": + this.rig.forwardback(-1); + break; + case "ArrowDown": + this.rig.forwardback(1); + break; + case "ArrowLeft": + this.rig.leftright(-1); + break; + case "ArrowRight": + this.rig.leftright(1); + break; + case " ": + if (kbInfo.event.ctrlKey) { + if (this.controllers) { + this.controllers.controllerObserver.notifyObservers( + {type: ControllerEventType.X_BUTTON, value: 1} + ) + } + } + default: + console.log(kbInfo.event); + } + + } else { + this.rig.leftright(0); + this.rig.forwardback(0); + } + if (kbInfo.event.key == "Shift") { + if (kbInfo.type == 1) { + //this.referencePlane.setEnabled(true); + } else { + this.referencePlane.setEnabled(false); + if (this.pickedMesh) { + this.pickedMesh.showBoundingBox = false; + this.pickedMesh = null; + } + } + } + }); + + this.scene.onPointerUp = () => { + this.mouseDown = false; + this.rig.turn(0); + }; + + this.scene.onPointerDown = (evt, state, type) => { + if (evt.pointerType == "mouse") { + if (evt.shiftKey) { + setMenuPosition(this.referencePlane, this.scene, new Vector3(0, 0, 5)); + //this.referencePlane.rotation = scene.activeCamera.absoluteRotation.toEulerAngles(); + this.pickedMesh = state.pickedMesh.clone('pickedMesh', null, true); + this.pickedMesh.rotation = scene.activeCamera.absoluteRotation.toEulerAngles(); + this.referencePlane.setEnabled(true); + } else { + this.mouseDown = true; + } + } + }; + this.scene.onPointerMove = (evt) => { + if (this.mouseDown) { + //this.rig.leftright(evt.movementX); + this.rig.turn(evt.movementX); + } + const meshPickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { + return mesh.metadata?.template != undefined; + }); + const planePickInfo = scene.pick(this.scene.pointerX, this.scene.pointerY, (mesh) => { + return mesh.id == this.referencePlane.id; + }); + + if (meshPickInfo.hit) { + if (!this._mesh) { + this.mesh = meshPickInfo.pickedMesh; + } else { + if (this._mesh.id != meshPickInfo.pickedMesh.id) { + //const clone = grabAndClone() + this.mesh = meshPickInfo.pickedMesh; + } + } + } else { + this.mesh = null; + } + if (this.pickedMesh && planePickInfo.hit) { + this.pickedMesh.position = planePickInfo.pickedPoint; + } + } + } + + _mesh: AbstractMesh; + + get mesh(): AbstractMesh { + return this._mesh; + } + + set mesh(mesh: AbstractMesh) { + if (mesh) { + mesh.showBoundingBox = true; + mesh.outlineWidth = 0.08; + } else { + if (this._mesh) { + this._mesh.showBoundingBox = false; + } + } + this._mesh = mesh; + } + + private handlePointer(info, state) { + console.log(info); + console.log(state); + } +} \ No newline at end of file diff --git a/src/diagram/diagramEventHandler.ts b/src/diagram/diagramEventHandler.ts index fa21e33..20107c6 100644 --- a/src/diagram/diagramEventHandler.ts +++ b/src/diagram/diagramEventHandler.ts @@ -17,20 +17,25 @@ export function diagramEventHandler(event: DiagramEvent, sounds: DiaSounds) { const entity = event.entity; let mesh; - if (event?.entity?.template) { - const toolMesh = scene.getMeshById("tool-" + event.entity.template + "-" + event.entity.color); - if (!toolMesh && event.type != DiagramEventType.CHANGECOLOR) { - log.debug('no mesh found for ' + event.entity.template + "-" + event.entity.color, 'adding it'); - toolbox.updateToolbox(event.entity.color); - } - mesh = fromDiagramEntity(event.entity, scene); - if (mesh) { - mesh.actionManager = actionManager; - if (physicsEnabled) { - applyPhysics(sounds, mesh, scene, PhysicsMotionType.DYNAMIC); + if (event.type == DiagramEventType.REMOVE) { + mesh = scene.getMeshById(entity.id); + } else { + if (event?.entity?.template) { + const toolMesh = scene.getMeshById("tool-" + event.entity.template + "-" + event.entity.color); + if (!toolMesh && event.type != DiagramEventType.CHANGECOLOR) { + log.debug('no mesh found for ' + event.entity.template + "-" + event.entity.color, 'adding it'); + toolbox.updateToolbox(event.entity.color); + } + mesh = fromDiagramEntity(event.entity, scene); + if (mesh) { + mesh.actionManager = actionManager; + if (physicsEnabled) { + applyPhysics(sounds, mesh, scene, PhysicsMotionType.DYNAMIC); + } } } } + switch (event.type) { case DiagramEventType.CLEAR: break; diff --git a/src/diagram/diagramManager.ts b/src/diagram/diagramManager.ts index fe19db2..fd47382 100644 --- a/src/diagram/diagramManager.ts +++ b/src/diagram/diagramManager.ts @@ -1,4 +1,4 @@ -import {AbstractMesh, InstancedMesh, Mesh, Observable, Scene} from "@babylonjs/core"; +import {AbstractMesh, Color3, InstancedMesh, Mesh, Observable, Scene} from "@babylonjs/core"; import {DiagramEvent, DiagramEventType} from "./diagramEntity"; import log from "loglevel"; import {Controllers} from "../controllers/controllers"; @@ -40,7 +40,10 @@ export class DiagramManager { } this.toolbox.colorChangeObservable.add((evt) => { this.logger.debug(evt); - this.onDiagramEventObservable.notifyObservers({type: DiagramEventType.CHANGECOLOR}, 2); + this.onDiagramEventObservable.notifyObservers({ + type: DiagramEventType.CHANGECOLOR, + oldColor: Color3.FromHexString(evt.oldColor), newColor: Color3.FromHexString(evt.newColor) + }, 2); }, -1, true, this, false); this.onDiagramEventObservable.add(this.onDiagramEvent, 1, true, this); this.logger.debug("DiagramManager constructed"); diff --git a/src/integration/pouchdbPersistenceManager.ts b/src/integration/pouchdbPersistenceManager.ts new file mode 100644 index 0000000..399bc4b --- /dev/null +++ b/src/integration/pouchdbPersistenceManager.ts @@ -0,0 +1,228 @@ +import {DiagramListing, DiagramListingEvent, IPersistenceManager} from "./iPersistenceManager"; +import PouchDB from 'pouchdb'; +import {DiagramEntity} from "../diagram/diagramEntity"; +import {Color3, Observable} from "@babylonjs/core"; +import {AppConfigType} from "../util/appConfigType"; +import {v4 as uuidv4} from 'uuid'; +import axios from "axios"; + +export class PouchdbPersistenceManager implements IPersistenceManager { + configObserver: Observable = new Observable(); + diagramListingObserver: Observable = new Observable(); + updateObserver: Observable = new Observable(); + removeObserver: Observable = new Observable(); + //implement IPersistenceManager interface with pouchdb apis + private db: PouchDB; + private remote: PouchDB; + private config: PouchDB; + private diagramListings: PouchDB; + + constructor(name: string) { + console.log(name); + this.config = new PouchDB("config"); + this.diagramListings = new PouchDB("diagramListings"); + + } + + private _currentDiagramId: string; + + public get currentDiagramId(): string { + return this._currentDiagramId; + } + + public set currentDiagramId(value: string) { + this._currentDiagramId = value; + try { + const listing = this.diagramListings.get(value); + } catch (err) { + this.diagramListings.put({_id: value, name: "New Diagram"}); + } + this.db = new PouchDB(value); + + this.db.sync(this.remote, {live: true}); + } + + public async add(entity: DiagramEntity) { + if (!entity) { + return; + } + const newEntity = {...entity, _id: entity.id}; + try { + this.db.put(newEntity); + } catch (err) { + console.log(err); + } + } + + public async remove(id: string) { + if (!id) { + return; + } + try { + const doc = await this.db.get(id); + this.db.remove(doc); + } catch (err) { + console.log(err); + } + } + + public async modify(entity: DiagramEntity) { + if (!entity) { + return; + } + try { + const doc = await this.db.get(entity.id); + const newDoc = {...doc, ...entity}; + this.db.put(newDoc); + + } catch (err) { + console.log(err); + } + } + + public async addDiagram(diagram: DiagramListing) { + try { + const doc = await this.diagramListings.get(diagram.id); + + } catch (err) { + this.diagramListings.put({...diagram, _id: diagram.id}); + } + } + + public async removeDiagram(diagram: DiagramListing) { + try { + this.diagramListings.delete(diagram.id); + } catch (err) { + console.log(err); + } + } + + public async modifyDiagram(diagram: DiagramListing) { + try { + const doc = await this.db.get(diagram.id); + this.db.put({...doc, ...diagram}); + } catch (err) { + console.log(err); + } + + } + + public async getNewRelicData(): Promise { + + } + + public async setNewRelicData(data: any[]): Promise { + + } + + public async setConfig(config: any): Promise { + const doc = await this.config.get('1'); + const newConf = {...config, _id: '1', _rev: doc._rev}; + return this.config.put(newConf); + } + + public async getConfig(): Promise { + return this.config.get('1'); + } + + public async initialize() { + try { + const config = await this.config.get('1'); + if (config.currentDiagramId) { + this.db = new PouchDB(config.currentDiagramId); + this.beginSync(); + } else { + config.currentDiagramId = uuidv4(); + this.db = new PouchDB(config.currentDiagramId); + this.beginSync(); + await this.config.put(config); + } + this.configObserver.notifyObservers(config); + } catch (err) { + const defaultConfig = { + _id: '1', + demoCompleted: false, + gridSnap: 1, + rotateSnap: 0, + createSnap: 0, + turnSnap: 0, + flyMode: true, + currentDiagramId: uuidv4() + } + try { + await this.setConfig(defaultConfig); + } catch (err) { + console.log(err); + } + + this.diagramListings.put({_id: defaultConfig.currentDiagramId, name: "New Diagram"}); + this.db = new PouchDB(defaultConfig.currentDiagramId); + this.beginSync(); + this.configObserver.notifyObservers(defaultConfig); + } + try { + const all = await this.db.allDocs({include_docs: true}); + for (const entity of all.rows) { + this.updateObserver.notifyObservers(entity.doc, 1); + } + } catch (err) { + + } + + } + + syncDoc = function (info) { + console.log(info); + if (info.direction == 'pull') { + const docs = info.change.docs; + for (const doc of docs) { + if (doc._deleted) { + this.removeObserver.notifyObservers({id: doc._id, template: doc.template}, 1); + + } else { + this.updateObserver.notifyObservers(doc, 1); + } + + } + } + + } + + async changeColor(oldColor: Color3, newColor: Color3) { + const all = await this.db.allDocs({include_docs: true}); + for (const entity of all.rows) { + console.log(`comparing ${entity.doc.color} to ${oldColor.toHexString()}`); + if (entity.doc.color == oldColor.toHexString()) { + entity.doc.color = newColor.toHexString(); + this.db.put({...entity.doc, _rev: entity.doc._rev}); + } + } + } + + setCurrentDiagram(diagram: DiagramListing) { + this.currentDiagramId = diagram.id; + } + + sync() { + + } + + private async beginSync() { + try { + + const syncTarget = "mike"; + const dbs = await axios.get('https://syncdb-service-d3f974de56ef.herokuapp.com/_all_dbs'); + if (dbs.data.indexOf(syncTarget) == -1) { + console.log('sync target missing'); + return; + } + console.log(dbs); + this.remote = new PouchDB('https://syncdb-service-d3f974de56ef.herokuapp.com/' + syncTarget); + this.syncDoc = this.syncDoc.bind(this); + this.db.sync(this.remote, {live: true, retry: true}) + .on('change', this.syncDoc); + } catch (err) { + console.log(err); + } + } +} \ No newline at end of file diff --git a/src/menus/abstractMenu.ts b/src/menus/abstractMenu.ts index 7b9ba01..ba8198f 100644 --- a/src/menus/abstractMenu.ts +++ b/src/menus/abstractMenu.ts @@ -9,7 +9,7 @@ export abstract class AbstractMenu { protected xr: WebXRDefaultExperience; protected controllers: Controllers; - constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { + protected constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { this.scene = scene; this.xr = xr; this.controllers = controllers; diff --git a/src/menus/configMenu.ts b/src/menus/configMenu.ts index eaf4ccc..358aeee 100644 --- a/src/menus/configMenu.ts +++ b/src/menus/configMenu.ts @@ -79,12 +79,11 @@ export class ConfigMenu extends AbstractMenu { const selectionPanel3 = new SelectionPanel("selectionPanel3"); selectionPanel3.width = .3; columnPanel.addControl(selectionPanel3); - //this.buildRotationSnapControl(selectionPanel3); - //this.buildTurnSnapControl(selectionPanel3); + this.buildFlyModeControl(selectionPanel3); configPlane.position.set(0, .2, 0); - setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0)); + setMenuPosition(this.handle.mesh, this.scene, new Vector3(.6, .4, 0)); } private adjustRadio(radio: RadioGroup | CheckboxGroup) { diff --git a/src/menus/deckMenu.ts b/src/menus/deckMenu.ts new file mode 100644 index 0000000..0e9bbf1 --- /dev/null +++ b/src/menus/deckMenu.ts @@ -0,0 +1,46 @@ +import {AbstractMenu} from "./abstractMenu"; +import {Color3, MeshBuilder, Scene, StandardMaterial, Vector2, WebXRDefaultExperience} from "@babylonjs/core"; +import {Controllers} from "../controllers/controllers"; + +export class DeckMenu extends AbstractMenu { + private static instance: DeckMenu; + + public constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { + super(scene, xr, controllers); + this.buildMenu(); + } + + private feetToMeters(feet: number, inches: number) { + return (feet * 12 + inches) * .0254; + } + + private buildMenu() { + const base = MeshBuilder.CreateBox("base", { + width: this.feetToMeters(14, 6), + height: this.feetToMeters(0, .75), + depth: this.feetToMeters(14, 6) + }, this.scene); + base.position.y = this.feetToMeters(0, .375); + this.buildPost(new Vector2(7, 3), new Vector2(7, 3)); + this.buildPost(new Vector2(-7, -3), new Vector2(7, 3)); + this.buildPost(new Vector2(-4, -0), new Vector2(7, 3)); + this.buildPost(new Vector2(7 - 4, 3), new Vector2(7, 3)); + this.buildPost(new Vector2(-7, -3), new Vector2(7, 3 - 16)); + this.buildPost(new Vector2(7, 3), new Vector2(7, 3 - 16)); + + } + + private buildPost(x: Vector2, y: Vector2) { + const material = new StandardMaterial("material", this.scene); + material.diffuseColor = new Color3(.02, .02, .02); + const base = MeshBuilder.CreateBox("base", { + width: this.feetToMeters(0, 2.5), + height: this.feetToMeters(0, 38), + depth: this.feetToMeters(0, 2.5) + }, this.scene); + base.position.y = this.feetToMeters(0, 38 / 2); + base.position.x = this.feetToMeters(x.x, x.y); + base.position.z = this.feetToMeters(y.x, y.y); + base.material = material; + } +} \ No newline at end of file diff --git a/src/menus/editMenu.ts b/src/menus/editMenu.ts index 59721e5..f63d733 100644 --- a/src/menus/editMenu.ts +++ b/src/menus/editMenu.ts @@ -76,7 +76,7 @@ export class EditMenu extends AbstractMenu { } else { this.sounds.enter.play(); - setMenuPosition(this.handle.mesh, this.scene, new Vector3(0, .4, 0)); + setMenuPosition(this.handle.mesh, this.scene, new Vector3(-.6, .4, 0)); this.isVisible = true; } } @@ -223,7 +223,6 @@ export class EditMenu extends AbstractMenu { constructor(scene: Scene, xr: WebXRDefaultExperience, diagramManager: DiagramManager, controllers: Controllers) { super(scene, xr, controllers); - this.scene = scene; this.sounds = new DiaSounds(scene); this.diagramManager = diagramManager; this.gizmoManager = new GizmoManager(scene); diff --git a/src/menus/sequenceMenu.ts b/src/menus/sequenceMenu.ts new file mode 100644 index 0000000..14e089f --- /dev/null +++ b/src/menus/sequenceMenu.ts @@ -0,0 +1,20 @@ +import {AbstractMenu} from "./abstractMenu"; +import {Scene, WebXRDefaultExperience} from "@babylonjs/core"; +import {Controllers} from "../controllers/controllers"; + +//a class called SequenceMenu that extends AbstraceMenu and has three buttons labeled '1', '2', and '3' +export class SequenceMenu extends AbstractMenu { + constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { + super(scene, xr, controllers); + this.buildMenu(); + } + + private buildMenu() { + const button1 = this.makeButton("1", "1"); + const button2 = this.makeButton("2", "1"); + const button3 = this.makeButton("3", "1"); + + } +} + + diff --git a/src/newrelic/newRelicMenu.ts b/src/newrelic/newRelicMenu.ts index 24ba84a..dcc4eba 100644 --- a/src/newrelic/newRelicMenu.ts +++ b/src/newrelic/newRelicMenu.ts @@ -2,17 +2,23 @@ import {AbstractMenu} from "../menus/abstractMenu"; import {Scene, WebXRDefaultExperience} from "@babylonjs/core"; import {Controllers} from "../controllers/controllers"; import log, {Logger} from "loglevel"; +import {Grid} from "@babylonjs/gui"; export class NewRelicMenu extends AbstractMenu { private logger: Logger = log.getLogger('NewRelicMenu'); constructor(scene: Scene, xr: WebXRDefaultExperience, controllers: Controllers) { super(scene, xr, controllers); + this.buildMenu(); } buildMenu() { this.logger.debug('buildMenu'); this.makeButton("credentials", "credentials"); + const grid = new Grid("grid"); + grid.addColumnDefinition(.5); + grid.addColumnDefinition(.5); + grid.addRowDefinition(.5); } diff --git a/src/toolbox/toolbox.ts b/src/toolbox/toolbox.ts index 03e51e3..bdee5dc 100644 --- a/src/toolbox/toolbox.ts +++ b/src/toolbox/toolbox.ts @@ -72,8 +72,11 @@ export class Toolbox { addButton.onPointerClickObservable.add(() => { buildColor(Color3.Random(), this.scene, this.node, this.index++, this.colorChangeObservable); }); - + //this.node.parent this.node.parent.setEnabled(false); + setMenuPosition(this.node.parent as Mesh, this.scene, + Vector3.Zero()); + } } diff --git a/src/util/functions/setMenuPosition.ts b/src/util/functions/setMenuPosition.ts index f114148..2c1e37c 100644 --- a/src/util/functions/setMenuPosition.ts +++ b/src/util/functions/setMenuPosition.ts @@ -2,12 +2,64 @@ import {Scene, TransformNode, Vector3} from "@babylonjs/core"; import {getFrontPosition} from "./getFrontPosition"; export function setMenuPosition(node: TransformNode, scene: Scene, offset: Vector3 = Vector3.Zero()) { - const front = getFrontPosition(.8, scene); - //front.y = scene.activeCamera.globalPosition.y; - node.position = front; - node.position.addInPlace(offset); - node.position.y -= .5; + /* + scene.onActiveCameraChanged.add(() => { - node.lookAt(scene.activeCamera.globalPosition); - node.rotation.y = node.rotation.y + Math.PI; -} \ No newline at end of file + if (scene.activeCamera) { + switch (scene.activeCamera.getClassName()) { + case "WebXRCamera": + node.parent = null; + const front = getFrontPosition(.8, scene); + //front.y = scene.activeCamera.globalPosition.y; + node.position = front; + node.position.addInPlace(offset); + node.position.y -= .5; + + node.lookAt(scene.activeCamera.globalPosition); + node.rotation.y = node.rotation.y + Math.PI; + break; + case "FreeCamera": + case "DeviceOrientationCamera": + case "ArcRotateCamera": + case "UniversalCamera": + node.parent = scene.activeCamera; + const width = scene.getEngine().getRenderWidth(); + const height = scene.getEngine().getRenderHeight(); + node.position.z = 3; + node.position.y = -.8; + break; + + } + + } + }); + + */ + if (scene.activeCamera) { + switch (scene.activeCamera.getClassName()) { + case "WebXRCamera": + node.parent = null; + const front = getFrontPosition(.8, scene); + //front.y = scene.activeCamera.globalPosition.y; + node.position = front; + node.position.addInPlace(offset); + node.position.y -= .5; + + node.lookAt(scene.activeCamera.globalPosition); + node.rotation.y = node.rotation.y + Math.PI; + break; + case "FreeCamera": + case "DeviceOrientationCamera": + case "ArcRotateCamera": + case "UniversalCamera": + node.parent = scene.activeCamera; + const width = scene.getEngine().getRenderWidth(); + const height = scene.getEngine().getRenderHeight(); + node.position.z = 2; + node.position.y = -.8; + break; + + } + + } +} diff --git a/tsconfig.json b/tsconfig.json index e7b4750..41762fe 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,13 +1,21 @@ { "compilerOptions": { - "target": "es6", // choose our ECMA/JavaScript version (all modern browsers support ES6 so it's your best bet) - "lib": [ // choose our default ECMA/libraries to import - "dom", // mandatory for all browser-based apps - "es6" // mandatory for targeting ES6 + "target": "es6", + // choose our ECMA/JavaScript version (all modern browsers support ES6 so it's your best bet) + "allowSyntheticDefaultImports": true, + "lib": [ + // choose our default ECMA/libraries to import + "dom", + // mandatory for all browser-based apps + "es6" + // mandatory for targeting ES6 ], - "useDefineForClassFields": true, // enable latest ECMA runtime behavior with older ECMA/JavaScript versions (delete this line if target: "ESNext" or "ES2022"+) - "module": "ESNext", // use the latest ECMA/JavaScript syntax for our import statements and such - "moduleResolution": "node", // ensures we are using CommonJS for our npm packages + "useDefineForClassFields": true, + // enable latest ECMA runtime behavior with older ECMA/JavaScript versions (delete this line if target: "ESNext" or "ES2022"+) + "module": "ESNext", + // use the latest ECMA/JavaScript syntax for our import statements and such + "moduleResolution": "node", + // ensures we are using CommonJS for our npm packages "noResolve": false, // disable TypeScript from automatically detecting/adding files based on import statements and etc (it's less helpful than you think) "isolatedModules": true, diff --git a/vite.config.ts b/vite.config.ts index d9ec451..200b361 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -2,8 +2,12 @@ import {defineConfig} from "vite"; /** @type {import('vite').UserConfig} */ export default defineConfig({ + define: { + "global": {} + }, server: { port: 3001, + proxy: { '/.netlify': { target: 'http://localhost:9999/',