From 397b71875ecdf407d8353f4d596ac87d3aff046d Mon Sep 17 00:00:00 2001 From: yuhj Date: Sun, 3 Oct 2021 13:46:27 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E6=B3=A8=E5=86=8C=20-=20?= =?UTF-8?q?=E5=89=8D=E5=90=8E=E7=AB=AF=20=E6=88=BF=E9=97=B4=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E3=80=81=E5=8A=A0=E5=85=A5=E3=80=81=E9=80=80=E5=87=BA?= =?UTF-8?q?=E5=92=8C=E6=B6=88=E6=81=AF=E5=8F=91=E5=B8=83=20-=20=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E7=AB=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 - .hbuilderx/launch.json | 16 + App.vue | 103 ++ index.html | 14 + main.js | 21 + manifest.json | 72 ++ meteor/.gitignore | 3 + meteor/package-lock.json | 1002 +++++++++++++++ meteor/package.json | 29 + meteor/server/main.ts | 90 ++ meteor/tests/main.js | 20 + meteor/tsconfig.json | 48 + modules/core/ddp.js | 13 + modules/user/login/login.vue | 93 ++ modules/user/service/index.js | 40 + modules/user/signup/signup.vue | 110 ++ pages.json | 34 + pages/index/index.vue | 43 + static/logo.png | Bin 0 -> 4023 bytes uni.scss | 76 ++ uni_modules/hj-core/changelog.md | 2 + uni_modules/hj-core/js_sdk/hj-core.es.js | 865 +++++++++++++ uni_modules/hj-core/js_sdk/index.js | 1 + uni_modules/hj-core/package.json | 89 ++ uni_modules/hj-core/readme.md | 1 + uni_modules/hj-ddp/changelog.md | 28 + uni_modules/hj-ddp/js_sdk/hj-ddp.es.js | 1100 +++++++++++++++++ uni_modules/hj-ddp/js_sdk/index.d.ts | 107 ++ uni_modules/hj-ddp/js_sdk/index.js | 1 + uni_modules/hj-ddp/package.json | 86 ++ uni_modules/hj-ddp/readme.md | 145 +++ uni_modules/hj-meteor-account/changelog.md | 0 .../hj-meteor-account/js_sdk/index.d.ts | 11 + uni_modules/hj-meteor-account/js_sdk/index.js | 107 ++ uni_modules/hj-meteor-account/package.json | 80 ++ uni_modules/hj-meteor-account/readme.md | 1 + 36 files changed, 4451 insertions(+), 1 deletion(-) create mode 100644 .hbuilderx/launch.json create mode 100644 App.vue create mode 100644 index.html create mode 100644 main.js create mode 100644 manifest.json create mode 100644 meteor/.gitignore create mode 100644 meteor/package-lock.json create mode 100644 meteor/package.json create mode 100644 meteor/server/main.ts create mode 100644 meteor/tests/main.js create mode 100644 meteor/tsconfig.json create mode 100644 modules/core/ddp.js create mode 100644 modules/user/login/login.vue create mode 100644 modules/user/service/index.js create mode 100644 modules/user/signup/signup.vue create mode 100644 pages.json create mode 100644 pages/index/index.vue create mode 100644 static/logo.png create mode 100644 uni.scss create mode 100644 uni_modules/hj-core/changelog.md create mode 100644 uni_modules/hj-core/js_sdk/hj-core.es.js create mode 100644 uni_modules/hj-core/js_sdk/index.js create mode 100644 uni_modules/hj-core/package.json create mode 100644 uni_modules/hj-core/readme.md create mode 100644 uni_modules/hj-ddp/changelog.md create mode 100644 uni_modules/hj-ddp/js_sdk/hj-ddp.es.js create mode 100644 uni_modules/hj-ddp/js_sdk/index.d.ts create mode 100644 uni_modules/hj-ddp/js_sdk/index.js create mode 100644 uni_modules/hj-ddp/package.json create mode 100644 uni_modules/hj-ddp/readme.md create mode 100644 uni_modules/hj-meteor-account/changelog.md create mode 100644 uni_modules/hj-meteor-account/js_sdk/index.d.ts create mode 100644 uni_modules/hj-meteor-account/js_sdk/index.js create mode 100644 uni_modules/hj-meteor-account/package.json create mode 100644 uni_modules/hj-meteor-account/readme.md diff --git a/.gitignore b/.gitignore index ed87e18..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -" " diff --git a/.hbuilderx/launch.json b/.hbuilderx/launch.json new file mode 100644 index 0000000..07c1d5f --- /dev/null +++ b/.hbuilderx/launch.json @@ -0,0 +1,16 @@ +{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/ + // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数 + "version": "0.0", + "configurations": [{ + "default" : + { + "launchtype" : "local" + }, + "h5" : + { + "launchtype" : "local" + }, + "type" : "uniCloud" + } + ] +} diff --git a/App.vue b/App.vue new file mode 100644 index 0000000..94607d3 --- /dev/null +++ b/App.vue @@ -0,0 +1,103 @@ + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..b61f63e --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + + + + + + + +
+ + + diff --git a/main.js b/main.js new file mode 100644 index 0000000..afc6b08 --- /dev/null +++ b/main.js @@ -0,0 +1,21 @@ +import App from './App' + +// #ifndef VUE3 +import Vue from 'vue' +Vue.config.productionTip = false +App.mpType = 'app' +const app = new Vue({ + ...App +}) +app.$mount() +// #endif + +// #ifdef VUE3 +import { createSSRApp } from 'vue' +export function createApp() { + const app = createSSRApp(App) + return { + app + } +} +// #endif \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..779447e --- /dev/null +++ b/manifest.json @@ -0,0 +1,72 @@ +{ + "name" : "dpp-demo", + "appid" : "__UNI__FB8BA41", + "description" : "", + "versionName" : "1.0.0", + "versionCode" : "100", + "transformPx" : false, + /* 5+App特有相关 */ + "app-plus" : { + "usingComponents" : true, + "nvueStyleCompiler" : "uni-app", + "compilerVersion" : 3, + "splashscreen" : { + "alwaysShowBeforeRender" : true, + "waiting" : true, + "autoclose" : true, + "delay" : 0 + }, + /* 模块配置 */ + "modules" : {}, + /* 应用发布信息 */ + "distribute" : { + /* android打包配置 */ + "android" : { + "permissions" : [ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "" + ] + }, + /* ios打包配置 */ + "ios" : {}, + /* SDK配置 */ + "sdkConfigs" : {} + } + }, + /* 快应用特有相关 */ + "quickapp" : {}, + /* 小程序特有相关 */ + "mp-weixin" : { + "appid" : "", + "setting" : { + "urlCheck" : false + }, + "usingComponents" : true + }, + "mp-alipay" : { + "usingComponents" : true + }, + "mp-baidu" : { + "usingComponents" : true + }, + "mp-toutiao" : { + "usingComponents" : true + }, + "uniStatistics" : { + "enable" : false + }, + "vueVersion" : "3" +} diff --git a/meteor/.gitignore b/meteor/.gitignore new file mode 100644 index 0000000..7696398 --- /dev/null +++ b/meteor/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +bundle/ +.meteor/* \ No newline at end of file diff --git a/meteor/package-lock.json b/meteor/package-lock.json new file mode 100644 index 0000000..e2ce2df --- /dev/null +++ b/meteor/package-lock.json @@ -0,0 +1,1002 @@ +{ + "name": "app", + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@types/bson": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.2.0.tgz", + "integrity": "sha512-ELCPqAdroMdcuxqwMgUpifQyRoTpyYCNr1V9xKyF40VsBobsj+BbWNRvwGchMgBPGqkw655ypkjj2MEF5ywVwg==", + "dev": true, + "requires": { + "bson": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/jquery": { + "version": "3.5.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.6.tgz", + "integrity": "sha512-SmgCQRzGPId4MZQKDj9Hqc6kSXFNWZFHpELkyK8AQhf8Zr6HKfCzFv9ZC1Fv3FyQttJZOlap3qYb12h61iZAIg==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/meteor": { + "version": "1.4.78", + "resolved": "https://registry.npmjs.org/@types/meteor/-/meteor-1.4.78.tgz", + "integrity": "sha512-0OaRaRDZlM1pERRzaRubg63Iu/OUWd6Ygwd7oF47OtnhK9uYcZhkiZ2ElZVyqg2HZWlbU0oedVdeD80Ro8yiBg==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/jquery": "*", + "@types/mongodb": "^3.6.20", + "@types/react": "*", + "@types/underscore": "*" + } + }, + "@types/meteor-publish-composite": { + "version": "0.0.37", + "resolved": "https://registry.npmjs.org/@types/meteor-publish-composite/-/meteor-publish-composite-0.0.37.tgz", + "integrity": "sha512-L0LtMWj26Jfv6vBywGAi+iaXfB/cHoLRsaV0mhOPA1KcVdQgRwGSSk9QgDZob2fxl3RCry0uwQ+GMi+/CvS0sg==", + "dev": true, + "requires": { + "@types/meteor": "*" + } + }, + "@types/mocha": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.0.0.tgz", + "integrity": "sha512-scN0hAWyLVAvLR9AyW7HoFF5sJZglyBsbPuHO4fv7JRvfmPBMfp1ozWqOf/e4wwPNxezBZXRfWzMb6iFLgEVRA==", + "dev": true + }, + "@types/mongodb": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", + "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "dev": true, + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "@types/node": { + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.9.0.tgz", + "integrity": "sha512-nmP+VR4oT0pJUPFbKE4SXj3Yb4Q/kz3M9dSAO1GGMebRKWHQxLfDNmU/yh3xxCJha3N60nQ/JwXWwOE/ZSEVag==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "dev": true + }, + "@types/react": { + "version": "17.0.20", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.20.tgz", + "integrity": "sha512-wWZrPlihslrPpcKyCSlmIlruakxr57/buQN1RjlIeaaTWDLtJkTtRW429MoQJergvVKc4IWBpRhWw7YNh/7GVA==", + "dev": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "dev": true + }, + "@types/sizzle": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.3.tgz", + "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ==", + "dev": true + }, + "@types/underscore": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/@types/underscore/-/underscore-1.11.3.tgz", + "integrity": "sha512-Fl1TX1dapfXyDqFg2ic9M+vlXRktcPJrc4PR7sRc7sdVrjavg/JHlbUXBt8qWWqhJrmSqg3RNAkAPRiOYw6Ahw==", + "dev": true + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "bson": { + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-4.5.1.tgz", + "integrity": "sha512-XqFP74pbTVLyLy5KFxVfTUyRrC1mgOlmu/iXHfXqfCKT59jyP9lwbotGfbN59cHBRbJSamZNkrSopjv+N0SqAA==", + "dev": true, + "requires": { + "buffer": "^5.6.0" + } + }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "csstype": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.8.tgz", + "integrity": "sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==", + "dev": true + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "meteor-node-stubs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-1.1.0.tgz", + "integrity": "sha512-YvMQb4zcfWA82wFdRVTyxq28GO+Us7GSdtP+bTtC/mV35yipKnWo4W4665O57AmLVFnz4zR+WIZW11b4sfCtJw==", + "requires": { + "assert": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.19.0", + "elliptic": "^6.5.4", + "events": "^3.3.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.0", + "process": "^0.11.10", + "punycode": "^2.1.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^3.6.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "0.0.1", + "url": "^0.11.0", + "util": "^0.12.4", + "vm-browserify": "^1.1.2" + }, + "dependencies": { + "asn1.js": { + "version": "5.4.1", + "bundled": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "assert": { + "version": "2.0.0", + "bundled": true, + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, + "available-typed-arrays": { + "version": "1.0.4", + "bundled": true + }, + "base64-js": { + "version": "1.5.1", + "bundled": true + }, + "bn.js": { + "version": "5.2.0", + "bundled": true + }, + "brorand": { + "version": "1.1.0", + "bundled": true + }, + "browserify-aes": { + "version": "1.2.0", + "bundled": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "bundled": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "bundled": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "bundled": true, + "requires": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "browserify-sign": { + "version": "4.2.1", + "bundled": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "bundled": true, + "requires": { + "pako": "~1.0.5" + } + }, + "buffer": { + "version": "6.0.3", + "bundled": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "buffer-xor": { + "version": "1.0.3", + "bundled": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "bundled": true + }, + "call-bind": { + "version": "1.0.2", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "cipher-base": { + "version": "1.0.4", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "console-browserify": { + "version": "1.2.0", + "bundled": true + }, + "constants-browserify": { + "version": "1.0.0", + "bundled": true + }, + "create-ecdh": { + "version": "4.0.4", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "bundled": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "bundled": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "bundled": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "define-properties": { + "version": "1.1.3", + "bundled": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "des.js": { + "version": "1.0.1", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "diffie-hellman": { + "version": "5.0.3", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "domain-browser": { + "version": "4.19.0", + "bundled": true + }, + "elliptic": { + "version": "6.5.4", + "bundled": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "es-abstract": { + "version": "1.18.3", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.3", + "is-string": "^1.0.6", + "object-inspect": "^1.10.3", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "bundled": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-object-assign": { + "version": "1.1.0", + "bundled": true + }, + "events": { + "version": "3.3.0", + "bundled": true + }, + "evp_bytestokey": { + "version": "1.0.3", + "bundled": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "foreach": { + "version": "2.0.5", + "bundled": true + }, + "function-bind": { + "version": "1.1.1", + "bundled": true + }, + "get-intrinsic": { + "version": "1.1.1", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "has": { + "version": "1.0.3", + "bundled": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "bundled": true + }, + "has-symbols": { + "version": "1.0.2", + "bundled": true + }, + "hash-base": { + "version": "3.1.0", + "bundled": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "hmac-drbg": { + "version": "1.0.1", + "bundled": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "https-browserify": { + "version": "1.0.0", + "bundled": true + }, + "ieee754": { + "version": "1.2.1", + "bundled": true + }, + "inherits": { + "version": "2.0.4", + "bundled": true + }, + "is-arguments": { + "version": "1.1.0", + "bundled": true, + "requires": { + "call-bind": "^1.0.0" + } + }, + "is-bigint": { + "version": "1.0.2", + "bundled": true + }, + "is-boolean-object": { + "version": "1.1.1", + "bundled": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "bundled": true + }, + "is-date-object": { + "version": "1.0.4", + "bundled": true + }, + "is-generator-function": { + "version": "1.0.9", + "bundled": true + }, + "is-nan": { + "version": "1.3.2", + "bundled": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "bundled": true + }, + "is-number-object": { + "version": "1.0.5", + "bundled": true + }, + "is-regex": { + "version": "1.1.3", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.6", + "bundled": true + }, + "is-symbol": { + "version": "1.0.4", + "bundled": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typed-array": { + "version": "1.1.5", + "bundled": true, + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.2", + "es-abstract": "^1.18.0-next.2", + "foreach": "^2.0.5", + "has-symbols": "^1.0.1" + } + }, + "md5.js": { + "version": "1.3.5", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "bundled": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "bundled": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "bundled": true + }, + "object-inspect": { + "version": "1.10.3", + "bundled": true + }, + "object-is": { + "version": "1.1.5", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "object-keys": { + "version": "1.1.1", + "bundled": true + }, + "object.assign": { + "version": "4.1.2", + "bundled": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "os-browserify": { + "version": "0.3.0", + "bundled": true + }, + "pako": { + "version": "1.0.11", + "bundled": true + }, + "parse-asn1": { + "version": "5.1.6", + "bundled": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "1.0.1", + "bundled": true + }, + "pbkdf2": { + "version": "3.1.2", + "bundled": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "process": { + "version": "0.11.10", + "bundled": true + }, + "public-encrypt": { + "version": "4.0.3", + "bundled": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "bundled": true + } + } + }, + "punycode": { + "version": "2.1.1", + "bundled": true + }, + "querystring": { + "version": "0.2.0", + "bundled": true + }, + "querystring-es3": { + "version": "0.2.1", + "bundled": true + }, + "randombytes": { + "version": "2.1.0", + "bundled": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "bundled": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "ripemd160": { + "version": "2.0.2", + "bundled": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "bundled": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true + }, + "setimmediate": { + "version": "1.0.5", + "bundled": true + }, + "sha.js": { + "version": "2.4.11", + "bundled": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "stream-browserify": { + "version": "3.0.0", + "bundled": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "bundled": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "bundled": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string_decoder": { + "version": "1.3.0", + "bundled": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, + "timers-browserify": { + "version": "2.0.12", + "bundled": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "tty-browserify": { + "version": "0.0.1", + "bundled": true + }, + "unbox-primitive": { + "version": "1.0.1", + "bundled": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "url": { + "version": "0.11.0", + "bundled": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "bundled": true + } + } + }, + "util": { + "version": "0.12.4", + "bundled": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "safe-buffer": "^5.1.2", + "which-typed-array": "^1.1.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true + }, + "vm-browserify": { + "version": "1.1.2", + "bundled": true + }, + "which-boxed-primitive": { + "version": "1.0.2", + "bundled": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-typed-array": { + "version": "1.1.4", + "bundled": true, + "requires": { + "available-typed-arrays": "^1.0.2", + "call-bind": "^1.0.0", + "es-abstract": "^1.18.0-next.1", + "foreach": "^2.0.5", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.1", + "is-typed-array": "^1.1.3" + } + }, + "xtend": { + "version": "4.0.2", + "bundled": true + } + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "typescript": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.2.tgz", + "integrity": "sha512-gzP+t5W4hdy4c+68bfcv0t400HVJMMd2+H9B7gae1nQlBzCqvrXX+6GL/b3GAgyTH966pzrZ70/fRjwAtZksSQ==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } +} diff --git a/meteor/package.json b/meteor/package.json new file mode 100644 index 0000000..d9bbab0 --- /dev/null +++ b/meteor/package.json @@ -0,0 +1,29 @@ +{ + "name": "app", + "private": true, + "scripts": { + "start": "meteor run --port 0.0.0.0:3002", + "test": "meteor test --once --driver-package meteortesting:mocha", + "test-app": "TEST_WATCH=1 meteor test --full-app --driver-package meteortesting:mocha", + "visualize": "meteor --production --extra-packages bundle-visualizer", + "build": "cross-env NODE_ENV=development meteor build --debug --directory ../ --platforms web.browser", + "remote-db": "SET MONGO_URL=mongodb://xxxxx && npm run start" + }, + "dependencies": { + "@babel/runtime": "^7.14.8", + "meteor-node-stubs": "^1.1.0" + }, + "meteor": { + "mainModule": { + "server": "server/main.ts" + }, + "testModule": "tests/main.js" + }, + "devDependencies": { + "@types/meteor": "^1.4.78", + "@types/meteor-publish-composite": "0.0.37", + "@types/mocha": "^9.0.0", + "cross-env": "^7.0.3", + "typescript": "^4.4.2" + } +} diff --git a/meteor/server/main.ts b/meteor/server/main.ts new file mode 100644 index 0000000..cdef223 --- /dev/null +++ b/meteor/server/main.ts @@ -0,0 +1,90 @@ +import { Meteor } from "meteor/meteor"; +import { Mongo } from "meteor/mongo"; +import { publishComposite } from "meteor/reywood:publish-composite"; + + +Meteor.startup(() => { + console.log(`Hi boot! -- ddp demo -- oh yeah -`); +}); +const Users = Meteor.users; +const Rooms = new Mongo.Collection("rooms"); +const Messages = new Mongo.Collection("messages"); + +Meteor.methods({ + "message.add": function (data: any) { + if (!this.userId || !data.room) + throw new Meteor.Error("仅有登录用户能那啥"); + return Messages.insert({ + ...data, + user: this.userId, + }); + }, + "room.create": function (name: string) { + if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); + return Rooms.insert({ + name, + createdBy: this.userId, + createdAt: Date.now(), + members: [this.userId], + }); + }, + "room.join": function (id: string) { + if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); + const room = Rooms.findOne(id); + if (!room) throw new Meteor.Error("没房间不能那啥"); + return Rooms.update(id, { + $addToSet: { + members: this.userId, + }, + }); + }, + "room.left": function (id: string) { + if (!this.userId) throw new Meteor.Error("仅有登录用户能那啥"); + const room = Rooms.findOne(id); + if (!room) throw new Meteor.Error("没房间不能那啥"); + return Rooms.update(id, { + $pull: { + members: this.userId, + }, + }); + } +}); + +Meteor.publish("rooms.all", function () { + return Rooms.find({}, { fields: { name: 1, _id: 1 } }); +}); + +publishComposite("rooms.mine", function () { + const userId = this.userId; + return { + find() { + return Rooms.find( + { members: userId }, + { fields: { name: 1, members: 1 } } + ); + }, + collectionName: `rooms-mine`, + children: [ + { + find(room) { + return Users.find( + { id: { $in: room.membsers } }, + { fields: { profile: 1 } } + ); + }, + }, + { + find(room) { + return Messages.find({ roomId: room._id }); + }, + }, + ], + }; +}); + +Meteor.onConnection((con) => { + console.log(`${con.id} connected`); + con.onClose(() => { + console.log(`${con.id} closed`); + }); +}); diff --git a/meteor/tests/main.js b/meteor/tests/main.js new file mode 100644 index 0000000..785f15c --- /dev/null +++ b/meteor/tests/main.js @@ -0,0 +1,20 @@ +import assert from "assert"; + +describe("app", function () { + it("package.json has correct name", async function () { + const { name } = await import("../package.json"); + assert.strictEqual(name, "app"); + }); + + if (Meteor.isClient) { + it("client is not server", function () { + assert.strictEqual(Meteor.isServer, false); + }); + } + + if (Meteor.isServer) { + it("server is not client", function () { + assert.strictEqual(Meteor.isClient, false); + }); + } +}); diff --git a/meteor/tsconfig.json b/meteor/tsconfig.json new file mode 100644 index 0000000..146af95 --- /dev/null +++ b/meteor/tsconfig.json @@ -0,0 +1,48 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "es2018", + "module": "esNext", + "lib": ["esnext", "dom"], + "allowJs": true, + "checkJs": false, + "jsx": "preserve", + "incremental": true, + "noEmit": true, + + /* Strict Type-Checking Options */ + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + + /* Additional Checks */ + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": false, + "noFallthroughCasesInSwitch": false, + + /* Module Resolution Options */ + "baseUrl": ".", + "paths": { + /* Support absolute /imports/* with a leading '/' */ + "/*": ["*"] + }, + "moduleResolution": "node", + "resolveJsonModule": true, + "types": ["node", "mocha","meteor","meteor-publish-composite",], + "esModuleInterop": true, + "preserveSymlinks": true + }, + "exclude": [ + "./.meteor/**", + "./packages/**" + ], + "include": [ + "server/**/*.ts", + "server/**/*.d.ts", + "imports/**/*.ts", + "imports/**/*.d.ts", + "../shared/**/*.ts", + "../shared/**/*.d.ts" + ] +} diff --git a/modules/core/ddp.js b/modules/core/ddp.js new file mode 100644 index 0000000..511ea91 --- /dev/null +++ b/modules/core/ddp.js @@ -0,0 +1,13 @@ + +import { init } from "../../uni_modules/hj-ddp/js_sdk"; +import { hjMeteorAccount } from "../../uni_modules/hj-meteor-account/js_sdk"; + +// #ifdef H5 +export const ddp = init('ws://localhost:3002') +// #endif + +// #ifndef H5 +export const ddp = init('ws://10.0.2.2:3002') +// #endif + +ddp.use(hjMeteorAccount) \ No newline at end of file diff --git a/modules/user/login/login.vue b/modules/user/login/login.vue new file mode 100644 index 0000000..8f2191a --- /dev/null +++ b/modules/user/login/login.vue @@ -0,0 +1,93 @@ + + + + + diff --git a/modules/user/service/index.js b/modules/user/service/index.js new file mode 100644 index 0000000..db66c23 --- /dev/null +++ b/modules/user/service/index.js @@ -0,0 +1,40 @@ + +import { + reactive +} from "vue"; +import { + ddp +} from "../../core/ddp"; + +export const user = reactive({}) +export const myRooms = reactive([]) + +ddp.user.onChange((info) => { + if (info) { + for (const key in info) { + user[key] = info[key] + } + } else { + for (const key in user) { + delete user[key] + } + } +}) + +export const signin = async (data) => { + if (!data.username || !data.password) return + ddp.loginWithPassword(data.username, data.password).catch(err => { + uni.showToast({ + title: '密码或者用户名错误' + }) + }); +}; + +export const signup = async (data) => { + if (!data.username || !data.password || data.password !== data.password1) return + ddp.createAccount(data.username, data.password).catch(err => { + uni.showToast({ + title: '注册失败' + }) + }); +}; \ No newline at end of file diff --git a/modules/user/signup/signup.vue b/modules/user/signup/signup.vue new file mode 100644 index 0000000..7731862 --- /dev/null +++ b/modules/user/signup/signup.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/pages.json b/pages.json new file mode 100644 index 0000000..416cf7b --- /dev/null +++ b/pages.json @@ -0,0 +1,34 @@ +{ + "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages + { + "path": "pages/index/index", + "style": { + "navigationBarTitleText": "DDP Demo" + } + } + ,{ + "path" : "modules/user/login/login", + "style" : + { + "navigationBarTitleText": "登录", + "enablePullDownRefresh": false + } + + } + ,{ + "path" : "modules/user/signup/signup", + "style" : + { + "navigationBarTitleText": "", + "enablePullDownRefresh": false + } + + } + ], + "globalStyle": { + "navigationBarTextStyle": "black", + "navigationBarTitleText": "uni-app", + "navigationBarBackgroundColor": "#F8F8F8", + "backgroundColor": "#F8F8F8" + } +} diff --git a/pages/index/index.vue b/pages/index/index.vue new file mode 100644 index 0000000..650b5db --- /dev/null +++ b/pages/index/index.vue @@ -0,0 +1,43 @@ + + + + + diff --git a/static/logo.png b/static/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..b5771e209bb677e2ebd5ff766ad5ee11790f305a GIT binary patch literal 4023 zcmaJ^c|25Y`#+XyC`+5OUafkYqmlSEl)+V zC53EJB$S8m@9Vz4*Y&-Yb3W(3Y;(d~fM1#)0003Cvn<7K1}HtM`$d{YenwQ;C^-S(Bw!dKGPRQ{5d$=<+Bb^=&62=9 zyT3g7ffNAnXPh^N0JjBz*>4v5+kn2(URc+5KlGCVF`&OikMw zfqqB8XK2+;V}LL3B>(G>)mVo1y5YXue4A!H*}eQbcg`t##g9HFply&`y$2%Ui`qzhj;o^=JbnXrW48s;xu1fDr z0))La)fp=QkX*N#V0eTJXiqO11AyvJlBY^iBrIQo0Kg>g;^BKnJ9a%2Wz`F2Ka;Jl zm*B>3H!<9`zg|z+c>6eWFMqydnvs-!J))2I(LEmNyxo~2!VjOpv<0SyMNVCup-60Z zm&|RDtd8R2HEIU!!OA0Ic6-G4K{`MZ8S%UjEL!s#vj{vLBWeqI(M&DkE;aT|aziV8 zRiTRN#GNwykvPx{R==`-rP>^pa`AyJ&s**Q!zU$j(pO&Q(YolGLT=2o0>3Wlhx?Gs z#|6b*$3F$ofzT`QIA#}2(Cg}Z?5V5KrtX)WrInh*aTCsP#{@V|*7<0lm`r^xmJQm^ z9n0J^3p#yCxWPX>G11)F(iv5vIIHkbqzdH37jX&JZ~&5AV*OAtL}axw*aLAt(b-!Vf)wRw=S8((e`~WLqlDBobRbj)NXB zS>W`fibSDA>uYN*&&Ml75iep!E%^%eV~SElj=}K;6TCNXs2gYG-L`En&3y~H9fP=W z(t?;5Xalv2F5ROUkg3?7C5~z>QYq|tok{Q}toT5u=~a9mBKDc4zfSM=`?OF-lS(V+pE1(m&x$HE_9vj;Cy)b@OiPMS0bs1 zRL9h?)T!I{4m1aY9>(pR_IDhF?wocEy=CU`m(5ry-&^rJJ*Bb^PfNARJ1{|*1e;FV zGljKhHo|}41Rg|1n&m~I3+-_gFQww-#b2u97o3fIsg67|%6`|aJX{~F&RPa;TayWd zp0l(=(QbROypp_fCeOBW3BJ5PJg@UU`&fs3hd{?U6&@7>mHWNEWnN`rWk>r%`fK|= z=BRVxb2I(y07{Nwj&jZtf{0iN;H%QAvaO1&8VKn8tp5f#! zN#ZlRm)#|IR8144l_=#8)5guWCE`B$T_;p_&0iWR+1=_>mDK1{*kw_8pi=2ewD%Z1 zSVG^6Mc(Vd()@@Y^wYz75Yz{X8jD_x*B)w5@yqn8>U#Kw-qzNvJjm)}wamur^knR_o)EvaGVkz%1gB=%{GIq3%OVcBFpT?D{PKZ079tIh|$fvf?svxl^`nuZV1~ zE?xILl^)O*=ufGhDH_pyUfNjteA>xd#yg*uvj~^Cbv&_EBt0-)!j4#crI>Uhq&0Oy z`b$;!qc=;1Sx>VD%ia^;erQ9!2)(mrrJ5zv;`SWLHu^Td;yik`Z7ioatGHn?aSD1m z@U+Y6wVHj_e`PD>_Noz^2O3?6Yg*5_BlMB@A05*?`Y-jlZ-m^4uDw+Y8A8@7g!P7H zgzZ?*UDN&1x{>g`ZiMkweBs14cdln#6I?YHr7!-)nyY$73 zckv0h$WfEY^%7rYR&g4G-pZL>Vy{3sVkc#OsI@6s?(5whAJqvO5)LEZTD6>Rdkl&h zHusOIlp{!GNUVm69y+XkTlKT;Lp%Ce`igQdYushcyC!}iq4eq#-2van)Ie{RuRq2g zH=9+-th`-$F*y3W=|Z{)eb0Wrxy$2?eT~S=V>Iq5|4fbS@l5+PI<90O)5aZFv- z{-7I*`r#90Z5HrSgU=dsgpnk5?TNyom7_`TM^@+iv+q@OQnFLB3o!zOw1-FDsZ|`T zu=YA~Bw1jbF-d$SlN|kOWn5vEwm2Z>A8FZD_z+WWBPebOEjbeGD(MZ=TPSr~@YnLZU)h_#alQiZu;syu@U^WCAXKCKVZHf%!^8wGMR7*MP@UWP13nuk#~M$mU% z$uszs);TA=a{4!`8Qm`Sn+rdD>w9SLzQ0p-yTPboznqn+ASr#=Td7#J^gVESP9li^ zi{+qONJ8-4_1gZ8&pUnyeZKH;^FF?wIQ-qc-o5j=ix69oFFJQK<>#B|k#6%g^Bx5= zg}8(qIXM{t>6)*e9mylb4~qA6z6x{v$(W(tnHt&{T|3_Cyxupzb2YZJuAEW2NM+wC zy^Cm4Xp*b$U?3N6t(SESgt9ByRYOfRav2BL4L5BTyMExBieFo==ue&BT!*e)T3lo5 zDDLL`TT0PQo#}RDFM1G`iU*85$sTyH1rh6w$KbJ^jI%9xJpkZ2Ot5#RJ6l;IaAcw? zc1uS!m`LHE0YJ|nn1aRm;pt!xyf=Y_gs`91LBIr0B*Y1BrDjDz;e80`5Gvj-jfh?28eh%7933UC(#hWNXRd{2+nv*426JysnGq9kiSVeTiJk7WGWsE zSJhI%!8FvtM|D(Ta2<7RO=YmU8cYkSrU`}VsK7K3oKsT`{QH1#yiq;95Ev7)-@Z6A zB*ceKry!uvpr9btAPrSA)tiIW(SfR|L)Fz)I2tN628oUhRw2<8{#Y=<({NM*g-#%o zz*`ov9^?Qz62f8ncL+p^mDN9nNwnXI;-m~3jHN(fs%lUoaVxH0+B7-_|6dyas!g+J zQ1DO;o<-jJ7|Hhj9zgQ@T40Nl&|EJ)8M4T?#8vfJ1oXI~g0G`C@dMc;A zjqo=rI2*RN7A8ja!Tlbd0QX!*+E1x@K*^ZD{)%J_pe^QRp=+j?jCO1cZN?ryPlN&29$7&Ac>xMM*DwQ*NxtIV%NlmI`lJr2JVZ!|SUM)s{m5-r-hrCim zGEunpTX?76P{|0K32-Ym!wnJFjcNAROWZ-AL8+J1F_-(QHNzMCON{8s2|iO0D*vNr zQhflINtwvCi<$Z|n(_I*HbSmD?h6-!bQZ5=hQ8L&m)|I~)%u)gyCW_QRg`w5P~OC1 z%uCbu%`2nB5zR=>{took!+yKEDi`b>pzAf)^KDGtUM8R*t#G@mH2=PKe4(Ipz-y*c zc~Kzl;GA)s+53_RGg-}F1`$4QjX29!BLu$pn{&KmMu86HO}Y2@q{Jb7v=N}{+PQWx zHF2LIb9qiO+DI~r+eb9ubK7oh6KFdUL6e;9wKv_RvXh$HuqHw)inh2kQGM>}%G4V% zmjkEYsw}?{m%gW>#P7wTXwk}cZO--qydYul`!3w~l(JgX@=yG7|6z{6kO^>c^P;zI zAmO}-iEA~6%U7@PbJN4EXW!v;|5owjl2$w4ZZqafWPCshmRxS}7Zwlg(*rDz;hg}s SYs}WS&%*SCNx89m_ key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; +}; +var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); +const helper = { + maxStack: function maxStack(msgError) { + return new RegExp("Maximum call stack size exceeded", "g").test(msgError); + }, + isFunction(fn) { + return typeof fn === "function"; + }, + isObject(fn) { + return typeof fn === "object"; + }, + keysOf(obj) { + return Object.keys(obj); + }, + lengthOf(obj) { + return Object.keys(obj).length; + }, + hasOwn(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + }, + convertMapToObject(map) { + return Array.from(map).reduce(function(acc, _ref) { + var key = _ref[0], value = _ref[1]; + acc[key] = value; + return acc; + }, {}); + }, + isArguments(obj) { + return obj != null && this.hasOwn(obj, "callee"); + }, + isInfOrNaN(obj) { + return Number.isNaN(obj) || obj === Infinity || obj === -Infinity; + }, + handleError(fn) { + return function(...args) { + try { + return fn.apply(this, args); + } catch (error) { + var isMaxStack = this.maxStack(error.message); + if (isMaxStack) { + throw new Error("Converting circular structure to JSON"); + } + throw error; + } + }; + } +}; +const BASE_64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +const BASE_64_VALS = Object.create(null); +function getChar(val) { + return BASE_64_CHARS.charAt(val); +} +function getVal(ch) { + return ch === "=" ? -1 : BASE_64_VALS[ch]; +} +for (let i = 0; i < BASE_64_CHARS.length; i++) { + BASE_64_VALS[getChar(i)] = i; +} +function encode(array) { + if (typeof array === "string") { + var str2 = array; + array = newBinary(str2.length); + for (var _i = 0; _i < str2.length; _i++) { + var ch = str2.charCodeAt(_i); + if (ch > 255) { + throw new Error("Not ascii. Base64.encode can only take ascii strings."); + } + array[_i] = ch; + } + } + var answer = []; + var a = null; + var b = null; + var c = null; + var d = null; + for (var _i2 = 0; _i2 < array.length; _i2++) { + switch (_i2 % 3) { + case 0: + a = array[_i2] >> 2 & 63; + b = (array[_i2] & 3) << 4; + break; + case 1: + b = b | array[_i2] >> 4 & 15; + c = (array[_i2] & 15) << 2; + break; + case 2: + c = c | array[_i2] >> 6 & 3; + d = array[_i2] & 63; + answer.push(getChar(a)); + answer.push(getChar(b)); + answer.push(getChar(c)); + answer.push(getChar(d)); + a = null; + b = null; + c = null; + d = null; + break; + } + } + if (a != null) { + answer.push(getChar(a)); + answer.push(getChar(b)); + if (c == null) { + answer.push("="); + } else { + answer.push(getChar(c)); + } + if (d == null) { + answer.push("="); + } + } + return answer.join(""); +} +function newBinary(len) { + if (typeof Uint8Array === "undefined" || typeof ArrayBuffer === "undefined") { + const ret = []; + for (let i = 0; i < len; i++) { + ret.push(0); + } + ret.$Uint8ArrayPolyfill = true; + return ret; + } + return new Uint8Array(new ArrayBuffer(len)); +} +function decode(str2) { + var len = Math.floor(str2.length * 3 / 4); + if (str2.charAt(str2.length - 1) == "=") { + len--; + if (str2.charAt(str2.length - 2) == "=") { + len--; + } + } + let arr = newBinary(len); + let one = null; + let two = null; + let three = null; + let j = 0; + for (let i = 0; i < str2.length; i++) { + var c = str2.charAt(i); + var v = getVal(c); + switch (i % 4) { + case 0: + if (v < 0) { + throw new Error("invalid base64 string"); + } + one = v << 2; + break; + case 1: + if (v < 0) { + throw new Error("invalid base64 string"); + } + one = one | v >> 4; + arr[j++] = one; + two = (v & 15) << 4; + break; + case 2: + if (v >= 0) { + two = two | v >> 2; + arr[j++] = two; + three = (v & 3) << 6; + } + break; + case 3: + if (v >= 0) { + arr[j++] = three | v; + } + break; + } + } + return arr; +} +const Base64 = { + encode, + decode, + newBinary +}; +function quote(string) { + return JSON.stringify(string); +} +function str(key, holder, singleIndent, outerIndent, canonical) { + var value = holder == null ? void 0 : holder[key]; + switch (typeof value) { + case "string": + return quote(value); + case "number": + return isFinite(value) ? String(value) : "null"; + case "boolean": + return String(value); + case "object": { + if (!value) { + return "null"; + } + let innerIndent = outerIndent + singleIndent; + let partial = []; + let v; + if (Array.isArray(value) || {}.hasOwnProperty.call(value, "callee")) { + let length = value.length; + for (var i = 0; i < length; i += 1) { + partial[i] = str(i, value, singleIndent, innerIndent, canonical) || "null"; + } + if (partial.length === 0) { + v = "[]"; + } else if (innerIndent) { + v = "[\n" + innerIndent + partial.join(",\n" + innerIndent) + "\n" + outerIndent + "]"; + } else { + v = "[" + partial.join(",") + "]"; + } + return v; + } + let keys = helper.keysOf(value); + if (canonical) { + keys = keys.sort(); + } + keys.forEach(function(k) { + v = str(k, value, singleIndent, innerIndent, canonical); + if (v) { + partial.push(quote(k) + (innerIndent ? ": " : ":") + v); + } + }); + if (partial.length === 0) { + v = "{}"; + } else if (innerIndent) { + v = "{\n" + innerIndent + partial.join(",\n" + innerIndent) + "\n" + outerIndent + "}"; + } else { + v = "{" + partial.join(",") + "}"; + } + return v; + } + } +} +function canonicalStringify(value, options) { + const allOptions = Object.assign({ + indent: "", + canonical: false + }, options); + if (allOptions.indent === true) { + allOptions.indent = " "; + } else if (typeof allOptions.indent === "number") { + var newIndent = ""; + for (var i = 0; i < allOptions.indent; i++) { + newIndent += " "; + } + allOptions.indent = newIndent; + } + return str("", { + "": value + }, allOptions.indent, "", allOptions.canonical); +} +const EJSON = { + addType(name, factory) { + if (customTypes.has(name)) { + throw new Error("Type ".concat(name, " already present")); + } + customTypes.set(name, factory); + }, + toJSONValue(item) { + var changed = toJSONValueHelper(item); + if (changed !== void 0) { + return changed; + } + var newItem = item; + if (helper.isObject(item)) { + newItem = EJSON.clone(item); + adjustTypesToJSONValue(newItem); + } + return newItem; + }, + fromJSONValue(item, ...args) { + var changed = fromJSONValueHelper(item); + if (changed === item && helper.isObject(item)) { + changed = EJSON.clone(item); + adjustTypesFromJSONValue(changed); + } + return changed; + }, + stringify: helper.handleError(function(item, options) { + var serialized; + var json = EJSON.toJSONValue(item); + if (options && (options.canonical || options.indent)) { + serialized = canonicalStringify(json, options); + } else { + serialized = JSON.stringify(json); + } + return serialized; + }), + parse(item) { + if (typeof item !== "string") { + throw new Error("EJSON.parse argument should be a string"); + } + return EJSON.fromJSONValue(JSON.parse(item)); + }, + isBinary(obj) { + return !!(typeof Uint8Array !== "undefined" && obj instanceof Uint8Array || obj && obj.$Uint8ArrayPolyfill); + }, + equals(a, b, options) { + var i; + var keyOrderSensitive = !!(options && options.keyOrderSensitive); + if (a === b) { + return true; + } + if (Number.isNaN(a) && Number.isNaN(b)) { + return true; + } + if (!a || !b) { + return false; + } + if (!(helper.isObject(a) && helper.isObject(b))) { + return false; + } + if (a instanceof Date && b instanceof Date) { + return a.valueOf() === b.valueOf(); + } + if (EJSON.isBinary(a) && EJSON.isBinary(b)) { + if (a.length !== b.length) { + return false; + } + for (i = 0; i < a.length; i++) { + if (a[i] !== b[i]) { + return false; + } + } + return true; + } + if (helper.isFunction(a.equals)) { + return a.equals(b, options); + } + if (helper.isFunction(b.equals)) { + return b.equals(a, options); + } + if (a instanceof Array) { + if (!(b instanceof Array)) { + return false; + } + if (a.length !== b.length) { + return false; + } + for (i = 0; i < a.length; i++) { + if (!EJSON.equals(a[i], b[i], options)) { + return false; + } + } + return true; + } + switch (Number(_isCustomType(a)) + Number(_isCustomType(b))) { + case 1: + return false; + case 2: + return EJSON.equals(EJSON.toJSONValue(a), EJSON.toJSONValue(b)); + } + var ret; + var aKeys = helper.keysOf(a); + var bKeys = helper.keysOf(b); + if (keyOrderSensitive) { + i = 0; + ret = aKeys.every(function(key) { + if (i >= bKeys.length) { + return false; + } + if (key !== bKeys[i]) { + return false; + } + if (!EJSON.equals(a[key], b[bKeys[i]], options)) { + return false; + } + i++; + return true; + }); + } else { + i = 0; + ret = aKeys.every(function(key) { + if (!helper.hasOwn(b, key)) { + return false; + } + if (!EJSON.equals(a[key], b[key], options)) { + return false; + } + i++; + return true; + }); + } + return ret && i === bKeys.length; + }, + clone(v) { + var ret; + if (!helper.isObject(v)) { + return v; + } + if (v === null) { + return null; + } + if (v instanceof Date) { + return new Date(v.getTime()); + } + if (v instanceof RegExp) { + return v; + } + if (EJSON.isBinary(v)) { + ret = newBinary(v.length); + for (var i = 0; i < v.length; i++) { + ret[i] = v[i]; + } + return ret; + } + if (Array.isArray(v)) { + return v.map(EJSON.clone); + } + if (helper.isArguments(v)) { + return Array.from(v).map(EJSON.clone); + } + if (helper.isFunction(v.clone)) { + return v.clone(); + } + if (_isCustomType(v)) { + return EJSON.fromJSONValue(EJSON.clone(EJSON.toJSONValue(v)), true); + } + ret = {}; + helper.keysOf(v).forEach(function(key) { + ret[key] = EJSON.clone(v[key]); + }); + return ret; + }, + newBinary: Base64.newBinary +}; +const customTypes = new Map(); +const builtinConverters = [{ + matchJSONValue: function matchJSONValue(obj) { + return helper.hasOwn(obj, "$date") && helper.lengthOf(obj) === 1; + }, + matchObject: function matchObject(obj) { + return obj instanceof Date; + }, + toJSONValue: function toJSONValue(obj) { + return { + $date: obj.getTime() + }; + }, + fromJSONValue: function fromJSONValue(obj) { + return new Date(obj.$date); + } +}, { + matchJSONValue: function matchJSONValue2(obj) { + return helper.hasOwn(obj, "$regexp") && helper.hasOwn(obj, "$flags") && helper.lengthOf(obj) === 2; + }, + matchObject: function matchObject2(obj) { + return obj instanceof RegExp; + }, + toJSONValue: function toJSONValue2(regexp) { + return { + $regexp: regexp.source, + $flags: regexp.flags + }; + }, + fromJSONValue: function fromJSONValue2(obj) { + return new RegExp(obj.$regexp, obj.$flags.slice(0, 50).replace(/[^gimuy]/g, "").replace(/(.)(?=.*\1)/g, "")); + } +}, { + matchJSONValue: function matchJSONValue3(obj) { + return helper.hasOwn(obj, "$InfNaN") && helper.lengthOf(obj) === 1; + }, + matchObject: helper.isInfOrNaN, + toJSONValue: function toJSONValue3(obj) { + var sign; + if (Number.isNaN(obj)) { + sign = 0; + } else if (obj === Infinity) { + sign = 1; + } else { + sign = -1; + } + return { + $InfNaN: sign + }; + }, + fromJSONValue: function fromJSONValue3(obj) { + return obj.$InfNaN / 0; + } +}, { + matchJSONValue: function matchJSONValue4(obj) { + return helper.hasOwn(obj, "$binary") && helper.lengthOf(obj) === 1; + }, + matchObject: function matchObject3(obj) { + return typeof Uint8Array !== "undefined" && obj instanceof Uint8Array || obj && helper.hasOwn(obj, "$Uint8ArrayPolyfill"); + }, + toJSONValue: function toJSONValue4(obj) { + return { + $binary: Base64.encode(obj) + }; + }, + fromJSONValue: function fromJSONValue4(obj) { + return Base64.decode(obj.$binary); + } +}, { + matchJSONValue: function matchJSONValue5(obj) { + return helper.hasOwn(obj, "$escape") && helper.lengthOf(obj) === 1; + }, + matchObject: function matchObject4(obj) { + var match = false; + if (obj) { + var keyCount = helper.lengthOf(obj); + if (keyCount === 1 || keyCount === 2) { + match = builtinConverters.some(function(converter) { + return converter.matchJSONValue(obj); + }); + } + } + return match; + }, + toJSONValue: function toJSONValue5(obj) { + var newObj = {}; + helper.keysOf(obj).forEach(function(key) { + newObj[key] = EJSON.toJSONValue(obj[key]); + }); + return { + $escape: newObj + }; + }, + fromJSONValue: function fromJSONValue5(obj) { + var newObj = {}; + helper.keysOf(obj.$escape).forEach(function(key) { + newObj[key] = EJSON.fromJSONValue(obj.$escape[key]); + }); + return newObj; + } +}, { + matchJSONValue: function matchJSONValue6(obj) { + return helper.hasOwn(obj, "$type") && helper.hasOwn(obj, "$value") && helper.lengthOf(obj) === 2; + }, + matchObject: function matchObject5(obj) { + return _isCustomType(obj); + }, + toJSONValue: function toJSONValue6(obj) { + var jsonValue = _noYieldsAllowed(function() { + return obj.toJSONValue(); + }); + return { + $type: obj.typeName(), + $value: jsonValue + }; + }, + fromJSONValue: function fromJSONValue6(obj) { + var typeName = obj.$type; + if (!customTypes.has(typeName)) { + throw new Error("Custom EJSON type ".concat(typeName, " is not defined")); + } + var converter = customTypes.get(typeName); + return _noYieldsAllowed(function() { + return converter(obj.$value); + }); + } +}]; +function _noYieldsAllowed(f) { + return f(); +} +function _isCustomType(obj) { + return obj && helper.isFunction(obj.toJSONValue) && helper.isFunction(obj.typeName) && customTypes.has(obj.typeName()); +} +function toJSONValueHelper(item) { + for (var i = 0; i < builtinConverters.length; i++) { + var converter = builtinConverters[i]; + if (converter.matchObject(item)) { + return converter.toJSONValue(item); + } + } + return void 0; +} +function adjustTypesToJSONValue(obj) { + if (obj === null) { + return null; + } + var maybeChanged = toJSONValueHelper(obj); + if (maybeChanged !== void 0) { + return maybeChanged; + } + if (!helper.isObject(obj)) { + return obj; + } + helper.keysOf(obj).forEach(function(key) { + var value = obj[key]; + if (!helper.isObject(value) && value !== void 0 && !helper.isInfOrNaN(value)) { + return; + } + var changed = toJSONValueHelper(value); + if (changed) { + obj[key] = changed; + return; + } + adjustTypesToJSONValue(value); + }); + return obj; +} +function fromJSONValueHelper(value) { + if (helper.isObject(value) && value !== null) { + var keys = helper.keysOf(value); + if (keys.length <= 2 && keys.every(function(k) { + return typeof k === "string" && k.substr(0, 1) === "$"; + })) { + for (var i = 0; i < builtinConverters.length; i++) { + var converter = builtinConverters[i]; + if (converter.matchJSONValue(value)) { + return converter.fromJSONValue(value); + } + } + } + } + return value; +} +function adjustTypesFromJSONValue(obj) { + if (obj === null) { + return null; + } + var maybeChanged = fromJSONValueHelper(obj); + if (maybeChanged !== obj) { + return maybeChanged; + } + if (!helper.isObject(obj)) { + return obj; + } + helper.keysOf(obj).forEach(function(key) { + var value = obj[key]; + if (helper.isObject(value)) { + var changed = fromJSONValueHelper(value); + if (value !== changed) { + obj[key] = changed; + return; + } + adjustTypesFromJSONValue(value); + } + }); + return obj; +} +function ProcessEmitWarning(warning) { + if (console && console.warn) + console.warn(warning); +} +class ExtError extends Error { +} +var defaultMaxListeners = 10; +const _EventEmitter = class { + constructor() { + this._events = Object.create(null); + this._eventsCount = 0; + this._maxListeners = void 0; + } + static get defaultMaxListeners() { + return defaultMaxListeners; + } + get maxListeners() { + if (this._maxListeners === void 0) + return _EventEmitter.defaultMaxListeners; + return this._maxListeners; + } + set maxListeners(v) { + if (v < 0 || !Number.isSafeInteger(v)) { + throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + v + "."); + } + this._maxListeners = v; + } + set defaultMaxListeners(v) { + if (v < 0 || !Number.isSafeInteger(v)) { + throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + v + "."); + } + defaultMaxListeners = v; + } + emit(type, ...args) { + var doError = type === "error"; + var events = this._events; + if (events !== void 0) { + doError = doError && events.error === void 0; + } else if (!doError) + return false; + if (doError) { + var er; + if (args.length > 0) + er = args[0]; + if (er instanceof Error) { + throw er; + } + var err = new ExtError("Unhandled error." + (er ? " (" + er.message + ")" : "")); + err.context = er; + throw err; + } + var handlers = events[type]; + if (handlers === void 0) + return false; + for (const el of handlers) { + el.apply(this, args); + } + return true; + } + on(type, listener, prepend = false) { + checkListener(listener); + const events = this._events; + if (events.newListener !== void 0) { + this.emit("newListener", type, listener.listener ? listener.listener : listener); + } + let list = events[type]; + if (!list) { + events[type] = [listener]; + ++this._eventsCount; + } else { + if (prepend) { + list.unshift(listener); + } else { + list.push(listener); + } + const m = this.maxListeners; + if (m > 0 && list.length > m && !list.warned) { + list.warned = true; + var w = new ExtError("Possible EventEmitter memory leak detected. " + list.length + " " + String(type) + " listeners added. Use emitter.setMaxListeners() to increase limit"); + w.name = "MaxListenersExceededWarning"; + w.emitter = this; + w.type = type; + w.count = list.length; + ProcessEmitWarning(w); + } + } + return this; + } + once(type, listener, prepend = false) { + checkListener(listener); + const nf = (...args) => { + listener.apply(null, args); + this.off(type, nf); + }; + this.on(type, nf, prepend); + return this; + } + off(type, listener) { + if (!type) { + this._events = Object.create(null); + this._eventsCount = 0; + return this; + } + const list = this._events[type]; + if (!(list == null ? void 0 : list.length)) + return this; + if (!listener) { + this._eventsCount -= list.length; + delete this._events[type]; + } else { + const i = list.indexOf(listener); + if (i > -1) { + list.splice(i, 1); + this._eventsCount--; + } + } + return this; + } + listenerCount(type) { + var _a; + return ((_a = this._events[type]) == null ? void 0 : _a.length) || 0; + } + eventNames() { + return this._eventsCount > 0 ? Object.keys(this._events) : []; + } +}; +let EventEmitter = _EventEmitter; +EventEmitter.EventEmitter = _EventEmitter; +function checkListener(listener) { + if (typeof listener !== "function") { + throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); + } +} +class UniSocket { + constructor(url, protocols, ops) { + this.onmessage = null; + this.onclose = null; + this.onerror = null; + this.onopen = null; + const task = uni.connectSocket(__spreadProps(__spreadValues({ + url, + protocols + }, ops), { + success: () => { + } + })); + task.onClose(() => { + var _a; + (_a = this.onclose) == null ? void 0 : _a.call(this); + }); + task.onError((err) => { + var _a; + (_a = this.onerror) == null ? void 0 : _a.call(this, err); + }); + task.onOpen(() => { + var _a; + (_a = this.onopen) == null ? void 0 : _a.call(this); + }); + task.onMessage((ev) => { + var _a; + (_a = this.onmessage) == null ? void 0 : _a.call(this, ev); + }); + this.instance = task; + } + send(e) { + this.instance.send({ data: e }); + } + close() { + var _a; + (_a = this.instance) == null ? void 0 : _a.close(); + } +} +const _UniDB = class { + constructor(name, prefix = "db") { + this.name = name; + this.prefix = prefix; + if (_UniDB.dbs.has(name)) { + return _UniDB.dbs.get(name); + } + _UniDB.dbs.set(name, this); + } + static info() { + return uni.getStorageInfoSync(); + } + sk(key) { + return `${this.prefix}.${this.name}.${key}`; + } + get(key) { + return uni.getStorageSync(this.sk(key)); + } + set(key, val) { + return uni.setStorageSync(this.sk(key), val); + } + remove(key) { + return uni.removeStorageSync(this.sk(key)); + } +}; +let UniDB = _UniDB; +UniDB.dbs = new Map(); +const invariant = function(condition, format, a, b, c, d, e, f) { + if (!condition) { + var error; + if (format === void 0) { + error = new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings."); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error(format.replace(/%s/g, function() { + return args[argIndex++]; + })); + error.name = "Invariant Violation"; + } + error.framesToPop = 1; + throw error; + } +}; +export { Base64, EJSON, EventEmitter, UniDB, UniSocket, helper, invariant }; diff --git a/uni_modules/hj-core/js_sdk/index.js b/uni_modules/hj-core/js_sdk/index.js new file mode 100644 index 0000000..0b267c0 --- /dev/null +++ b/uni_modules/hj-core/js_sdk/index.js @@ -0,0 +1 @@ +export * from "./hj-core.es.js" \ No newline at end of file diff --git a/uni_modules/hj-core/package.json b/uni_modules/hj-core/package.json new file mode 100644 index 0000000..a651375 --- /dev/null +++ b/uni_modules/hj-core/package.json @@ -0,0 +1,89 @@ +{ + "id": "hj-core", + "displayName": "hj-core", + "version": "1.0.0", + "description": "hj-x 系列公共依赖的存放点", + "keywords": [ + "hj-core", + "hj-*" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "y" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "y", + "字节跳动": "y", + "QQ": "y" + }, + "快应用": { + "华为": "y", + "联盟": "y" + } + } + } + }, + "main": "./js_sdk/hj-core.umd.js", + "module": "./js_sdk/hj-core.es.js", + "exports": { + ".": { + "import": "./js_sdk/hj-core.es.js", + "require": "./js_sdk/hj-core.umd.js" + } + } +} \ No newline at end of file diff --git a/uni_modules/hj-core/readme.md b/uni_modules/hj-core/readme.md new file mode 100644 index 0000000..90590ab --- /dev/null +++ b/uni_modules/hj-core/readme.md @@ -0,0 +1 @@ +# hj-utils \ No newline at end of file diff --git a/uni_modules/hj-ddp/changelog.md b/uni_modules/hj-ddp/changelog.md new file mode 100644 index 0000000..0b21707 --- /dev/null +++ b/uni_modules/hj-ddp/changelog.md @@ -0,0 +1,28 @@ +## 1.0.1(2021-10-03) +1. 新增利用use 注册插件 +## 1.0.0(2021-10-02) +[1.0.0] +2021.10.2 再不发一个,我觉得自己会一直拖下去了,凑合能用,后面补文档和优化,我在想要不要在某个博客写 - demo最近这两天发 +###已完成 + +>1. 使用websocket协议连接ddp服务器 [例如meteor] +>2. 订阅数据 +>3. 调用方法 +>4. 映射数据至vue响应式数组数据源 +>5. 简化的Mininongo,使用它的selector进行的重写 + +###暂不支持 +>1. 账号服务 - 在研究中,计划绑定在实例 +>2. Autorun - 不计划写,vue有足够的响应式支持了,当订阅参数变化时,取消上次订阅进行重新订阅即可 +>3. 本地数据库操作直接反应到远程数据库 - 感觉有点风险,还是建议调用方法,改完后影响的数据如果有订阅,结果会挺快推到前台的。 +>4. 文件传输,呃,这个不打算适配了,大文件建议直接upload吧 + +###想做但不好做的 +>1. 本地数据缓存: 因为取消订阅会触发删除数据操作,本地缓存就有点难,因为无法区分删除操作是取消订阅引起的还是真正的删除数据操作 - 但因为发布的数据往往只是文档的一部分,所以想追踪其实有点不太好弄 + +###避坑指南 +>1. 发布源的名称并不是数据集的名称 +>2. 方法和发布可以取名为 a_b_c,或者 'a.b.c' 或者 'a/b/c' 而不是函数命名的驼峰形式 + + + diff --git a/uni_modules/hj-ddp/js_sdk/hj-ddp.es.js b/uni_modules/hj-ddp/js_sdk/hj-ddp.es.js new file mode 100644 index 0000000..ea04168 --- /dev/null +++ b/uni_modules/hj-ddp/js_sdk/hj-ddp.es.js @@ -0,0 +1,1100 @@ +var __defProp = Object.defineProperty; +var __defProps = Object.defineProperties; +var __getOwnPropDescs = Object.getOwnPropertyDescriptors; +var __getOwnPropSymbols = Object.getOwnPropertySymbols; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __propIsEnum = Object.prototype.propertyIsEnumerable; +var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; +var __spreadValues = (a, b) => { + for (var prop in b || (b = {})) + if (__hasOwnProp.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + if (__getOwnPropSymbols) + for (var prop of __getOwnPropSymbols(b)) { + if (__propIsEnum.call(b, prop)) + __defNormalProp(a, prop, b[prop]); + } + return a; +}; +var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); +import { EventEmitter, UniSocket, EJSON, UniDB } from "../../hj-core/js_sdk"; +function deepCopy(d) { + return JSON.parse(JSON.stringify(d)); +} +const uuid = { + id: 1, + next() { + return (this.id++).toString(); + } +}; +const DDPConnectionState = { + CLOSED: 0, + CONNECTING: 1, + CONNECTED: 2, + READY: 3, + FAIL: 4, + CLOSING: 5, + RECONNECTING: 6 +}; +const DDPConnectionEvent = { + STATE_CHANGE: "state-change" +}; +const supportedDdpVersions = ["1", "pre2", "pre1"]; +class DDPConnection extends EventEmitter { + constructor(opts) { + super(); + this.supportedDdpVersions = supportedDdpVersions; + this.state = DDPConnectionState.CLOSED; + this.messages = []; + this.checkTick = null; + this.tlsOpts = (opts == null ? void 0 : opts.tlsOpts) || {}; + this.autoReconnect = "autoReconnect" in opts ? !!(opts == null ? void 0 : opts.autoReconnect) : true; + this.autoReconnectTimer = (opts == null ? void 0 : opts.autoReconnectTimer) || 1e4; + this.url = opts == null ? void 0 : opts.url; + this.socketConstructor = opts.socketConstructor || UniSocket; + this.ddpVersion = (opts == null ? void 0 : opts.ddpVersion) || "1"; + this.db = opts.db; + this._callbacks = {}; + this._updatedCallbacks = {}; + this._pendingMethods = {}; + this.on("connected", () => { + this._clearReconnectTimeout(); + this.changeState(DDPConnectionState.READY); + this.checkMessage(); + }); + this.on("failed", (error) => { + this.changeState(DDPConnectionState.FAIL, error); + }); + if ("autoConnect" in opts ? opts.autoConnect : true) { + this.connect(); + } + } + get isSocketBusy() { + return this.state === DDPConnectionState.CLOSING || this.state === DDPConnectionState.CONNECTING || this.state === DDPConnectionState.RECONNECTING; + } + changeState(state, data) { + this.state = state; + this.emit(DDPConnectionEvent.STATE_CHANGE, { + state, + data + }); + } + connect(url, protos, data) { + if (this.state !== DDPConnectionState.CLOSED && this.state !== DDPConnectionState.RECONNECTING) { + return; + } + this.changeState(DDPConnectionState.CONNECTING); + this.url = this.parseUrl(url || this.url); + this.socket = new this.socketConstructor(this.url + "/websocket", protos, data); + this._prepareHandlers(); + } + parseUrl(url = "") { + if (url.endsWith("/")) + url = url.slice(0, -1); + if (url.endsWith("/websocket")) + url = url.slice(0, -10); + return url; + } + _prepareHandlers() { + const socket = this.socket; + socket.onopen = () => { + this.changeState(DDPConnectionState.CONNECTED); + this.send({ + msg: "connect", + version: this.ddpVersion, + support: this.supportedDdpVersions + }, true); + }; + socket.onerror = (error) => { + if (this.state === DDPConnectionState.CONNECTING) { + this.emit("failed", error.message); + this.changeState(DDPConnectionState.FAIL); + } + this.emit("socket-error", error); + }; + socket.onclose = (ev) => { + this.changeState(DDPConnectionState.CLOSED, ev); + this.emit("socket-close", ev == null ? void 0 : ev.code, ev == null ? void 0 : ev.reason); + this._endPendingMethodCalls(); + this.reconnect(); + }; + socket.onmessage = (event) => { + this.ddpMessageHandler(event.data); + this.emit("message", event.data); + }; + } + close() { + this.changeState(DDPConnectionState.CLOSING); + this.socket.close(); + } + call(name, params, callback, updatedCallback) { + var id = this._getNextId(); + if (typeof callback === "function") { + this._pendingMethods[id] = true; + this._callbacks[id] = (...args) => { + delete this._pendingMethods[id]; + if (callback) { + callback.apply(this, args); + } + }; + } + if (typeof updatedCallback === "function") { + this._pendingMethods[id] = true; + this._updatedCallbacks[id] = (...args) => { + delete this._pendingMethods[id]; + if (updatedCallback) { + updatedCallback.apply(this, args); + } + }; + } + this.send({ + msg: "method", + id, + method: name, + params + }); + } + callWithRandomSeed(method, params, randomSeed, callback, updatedCallback) { + var id = this._getNextId(); + if (callback) { + this._callbacks[id] = callback; + } + if (updatedCallback) { + this._updatedCallbacks[id] = updatedCallback; + } + this.send({ + msg: "method", + id, + method, + randomSeed, + params + }); + } + subscribe(name, params, callback) { + const id = uuid.next(); + const data = { + msg: "sub", + id, + name, + params + }; + if (typeof callback === "function") + this._callbacks[id] = () => { + callback({ + id, + name, + params, + stop: () => this.unsubscribe(id) + }); + }; + this.send(data); + return id; + } + unsubscribe(id) { + this.send({ + msg: "unsub", + id + }); + } + _clearReconnectTimeout() { + if (this.reconnectTimeout) { + clearTimeout(this.reconnectTimeout); + this.reconnectTimeout = null; + } + } + reconnect() { + if (!this.autoReconnect || this.isSocketBusy) + return; + this._clearReconnectTimeout(); + this.reconnectTimeout = setTimeout(() => { + this.connect(); + }, this.autoReconnectTimer); + this.changeState(DDPConnectionState.RECONNECTING); + } + send(data, force = false) { + if (force) { + if (this.state === DDPConnectionState.CONNECTED) + this.socket.send(EJSON.stringify(data)); + else + this.messages.unshift(data); + return; + } + if (data.id) { + const oldIndex = this.messages.findIndex((el) => { + return el.method&&el.method === data.method && JSON.stringify(el.params) === JSON.stringify(data.params); + }); + if (oldIndex > -1) { + const oo = this.messages.splice(oldIndex, 1)[0]; + this.revokeCallBack(oo.id, [1, "ignored"]); + } + } + this.messages.push(data); + this.checkMessage(); + } + checkMessage() { + if (this.state !== DDPConnectionState.READY || this.messages.length === 0) + return; + clearTimeout(this.checkTick); + this.socket.send(JSON.stringify(this.messages.shift())); + this.checkTick = setTimeout(() => { + this.checkMessage(); + }, 0); + } + ddpMessageHandler(data) { + data = EJSON.parse(data); + const type = data == null ? void 0 : data.msg; + console.log(data); + switch (type) { + case "failed": { + if (this.supportedDdpVersions.indexOf(data.version) !== -1) { + this.ddpVersion = data.version; + this.connect(); + } else { + this.autoReconnect = false; + this.emit("failed", "Cannot negotiate DDP version"); + } + break; + } + case "connected": { + this.session = data.session; + this.emit("connected"); + break; + } + case "result": { + this.revokeCallBack(data.id, data.error, data.result); + break; + } + case "updated": { + Array.from(data.methods).forEach((method) => { + var cb = this._updatedCallbacks[method]; + if (cb) { + cb(); + delete this._updatedCallbacks[method]; + } + }); + break; + } + case "nosub": { + this.revokeCallBack(data.id, data.error); + break; + } + case "added": { + this.db.update(data.collection, "added", data.id, data.fields); + break; + } + case "removed": { + this.db.update(data.collection, "removed", data.id); + break; + } + case "changed": { + this.db.update(data.collection, "changed", data.id, data.fields, data.cleared); + break; + } + case "addedBefore ": { + this.db.update(data.collection, "addedBefore", data.id, data.fields, data.before); + break; + } + case "movedBefore": { + this.db.update(data.collection, "movedBefore", data.id, data.before); + break; + } + case "ready": { + Array.from(data.subs).forEach((id) => { + this.revokeCallBack(id); + }); + break; + } + case "ping": { + this.send(Object.prototype.hasOwnProperty.call(data, "id") ? { msg: "pong", id: data.id } : { msg: "pong" }); + } + } + } + _getNextId() { + return uuid.next(); + } + _endPendingMethodCalls() { + var ids = Object.keys(this._pendingMethods); + this._pendingMethods = {}; + ids.forEach((id) => { + if (this._callbacks[id]) { + this._callbacks[id](new Error("DDPClient: Disconnected from DDP server")); + delete this._callbacks[id]; + } + if (this._updatedCallbacks[id]) { + this._updatedCallbacks[id](); + delete this._updatedCallbacks[id]; + } + }); + } + revokeCallBack(id, ...args) { + const cb = this._callbacks[id]; + typeof cb === "function" && cb(...args); + delete this._callbacks[id]; + } +} +const _CollectionObserver = class { + constructor(name, handler, id = null) { + this.name = name; + this.handler = handler; + this.id = id; + if (!_CollectionObserver.observers.has(name)) { + _CollectionObserver.observers.set(name, [this]); + } else { + const observers = _CollectionObserver.observers.get(name); + if (id) { + const sameObserver = observers.find((el) => el.id === id); + if (sameObserver) + return sameObserver; + } else + observers.push(this); + } + } + static getObservers(name) { + if (!_CollectionObserver.observers.has(name)) { + return []; + } else { + return _CollectionObserver.observers.get(name); + } + } + static notify(name, type, ...args) { + const observers = this.getObservers(name); + if (!observers.length) + return; + observers.forEach((observer) => { + var _a, _b; + try { + const handler = observer.handler[type]; + handler && handler.apply(observer, args); + } catch (error) { + (_b = (_a = observer.handler) == null ? void 0 : _a.error) == null ? void 0 : _b.call(observer, error); + } + }); + } + get brothers() { + return _CollectionObserver.observers.get(this.name); + } + stop() { + const index = this.brothers.findIndex((e) => e === this); + if (index) { + this.brothers.splice(index, 1); + } + } +}; +let CollectionObserver = _CollectionObserver; +CollectionObserver.observers = new Map(); +var LocalCollection = {}; +var isArray = function isArray2(x) { + return Array.isArray(x) && !EJSON.isBinary(x); +}; +var _anyIfArray = function _anyIfArray2(x, f) { + if (isArray(x)) + return x.some((e) => f(e)); + return f(x); +}; +var _anyIfArrayPlus = function _anyIfArrayPlus2(x, f) { + if (f(x)) + return true; + return isArray(x) && x.some((e) => f(e)); +}; +var hasOperators = function hasOperators2(valueSelector) { + var theseAreOperators = void 0; + for (var selKey in valueSelector) { + var thisIsOperator = selKey.substr(0, 1) === "$"; + if (theseAreOperators === void 0) { + theseAreOperators = thisIsOperator; + } else if (theseAreOperators !== thisIsOperator) { + throw new Error("Inconsistent selector: " + valueSelector); + } + } + return !!theseAreOperators; +}; +var isObject = (v) => Object.prototype.toString.call(v).slice(8, -1) === "Object"; +var compileValueSelector = function compileValueSelector2(valueSelector) { + if (valueSelector == null) { + return function(value) { + return _anyIfArray(value, function(x) { + return x == null; + }); + }; + } + if (!isObject(valueSelector)) { + return function(value) { + return _anyIfArray(value, function(x) { + return x === valueSelector; + }); + }; + } + if (valueSelector instanceof RegExp) { + return function(value) { + if (value === void 0) + return false; + return _anyIfArray(value, function(x) { + return valueSelector.test(x); + }); + }; + } + if (isArray(valueSelector)) { + return function(value) { + if (!isArray(value)) + return false; + return _anyIfArrayPlus(value, function(x) { + return LocalCollection._f._equal(valueSelector, x); + }); + }; + } + if (hasOperators(valueSelector)) { + var operatorFunctions = []; + Object.keys(valueSelector).forEach((operator) => { + const operand = valueSelector[operator]; + if (!VALUE_OPERATORS[operator]) + throw new Error("Unrecognized operator: " + operator); + operatorFunctions.push(VALUE_OPERATORS[operator](operand, valueSelector.$options)); + }); + return function(value) { + return operatorFunctions.every(function(f) { + return f(value); + }); + }; + } + return function(value) { + return _anyIfArray(value, function(x) { + return LocalCollection._f._equal(valueSelector, x); + }); + }; +}; +var LOGICAL_OPERATORS = { + $and(subSelector) { + if (!isArray(subSelector) || !subSelector) + throw Error("$and/$or/$nor must be nonempty array"); + var subSelectorFunctions = subSelector.map(_compileDocumentSelector); + return function(doc) { + return subSelectorFunctions.every(function(f) { + return f(doc); + }); + }; + }, + $or(subSelector) { + if (!isArray(subSelector) || !subSelector) + throw Error("$and/$or/$nor must be nonempty array"); + var subSelectorFunctions = subSelector.map((v) => _compileDocumentSelector(v)); + return function(doc) { + return subSelectorFunctions.some(function(f) { + return f(doc); + }); + }; + }, + $nor(subSelector) { + if (!isArray(subSelector) || !subSelector) + throw Error("$and/$or/$nor must be nonempty array"); + var subSelectorFunctions = subSelector.map((v) => _compileDocumentSelector(v)); + return function(doc) { + return subSelectorFunctions.some(function(f) { + return !f(doc); + }); + }; + }, + $where(selectorValue) { + if (!(selectorValue instanceof Function)) { + selectorValue = Function("return " + selectorValue); + } + return function(doc) { + return selectorValue.call(doc); + }; + } +}; +var VALUE_OPERATORS = { + $in(operand) { + if (!isArray(operand)) + throw new Error("Argument to $in must be array"); + return function(value) { + return _anyIfArrayPlus(value, function(x) { + return operand.some(function(operandElt) { + return LocalCollection._f._equal(operandElt, x); + }); + }); + }; + }, + $all(operand) { + if (!isArray(operand)) + throw new Error("Argument to $all must be array"); + return function(value) { + if (!isArray(value)) + return false; + return operand.every(function(operandElt) { + return value.some(function(valueElt) { + return LocalCollection._f._equal(operandElt, valueElt); + }); + }); + }; + }, + $lt(operand) { + return function(value) { + return _anyIfArray(value, function(x) { + return LocalCollection._f._cmp(x, operand) < 0; + }); + }; + }, + $lte(operand) { + return function(value) { + return _anyIfArray(value, function(x) { + return LocalCollection._f._cmp(x, operand) <= 0; + }); + }; + }, + $gt(operand) { + return function(value) { + return _anyIfArray(value, function(x) { + return LocalCollection._f._cmp(x, operand) > 0; + }); + }; + }, + $gte(operand) { + return function(value) { + return _anyIfArray(value, function(x) { + return LocalCollection._f._cmp(x, operand) >= 0; + }); + }; + }, + $ne(operand) { + return function(value) { + return !_anyIfArrayPlus(value, function(x) { + return LocalCollection._f._equal(x, operand); + }); + }; + }, + $nin(operand) { + if (!isArray(operand)) + throw new Error("Argument to $nin must be array"); + var inFunction = VALUE_OPERATORS.$in(operand); + return function(value) { + if (value === void 0) + return true; + return !inFunction(value); + }; + }, + $exists(operand) { + return function(value) { + return operand === (value !== void 0); + }; + }, + $mod(operand) { + var divisor = operand[0], remainder = operand[1]; + return function(value) { + return _anyIfArray(value, function(x) { + return x % divisor === remainder; + }); + }; + }, + $size(operand) { + return function(value) { + return isArray(value) && operand === value.length; + }; + }, + $type(operand) { + return function(value) { + if (value === void 0) + return false; + return _anyIfArray(value, function(x) { + return LocalCollection._f._type(x) === operand; + }); + }; + }, + $regex(operand, options) { + if (options !== void 0) { + if (/[^gim]/.test(options)) + throw new Error("Only the i, m, and g regexp options are supported"); + var regexSource = operand instanceof RegExp ? operand.source : operand; + operand = new RegExp(regexSource, options); + } else if (!(operand instanceof RegExp)) { + operand = new RegExp(operand); + } + return function(value) { + if (value === void 0) + return false; + return _anyIfArray(value, function(x) { + return operand.test(x); + }); + }; + }, + $options(operand) { + return function(value) { + return true; + }; + }, + $elemMatch(operand) { + var matcher = _compileDocumentSelector(operand); + return function(value) { + if (!isArray(value)) + return false; + return value.some(function(x) { + return matcher(x); + }); + }; + }, + $not(operand) { + var matcher = compileValueSelector(operand); + return function(value) { + return !matcher(value); + }; + }, + $near(operand) { + return function(value) { + return true; + }; + }, + $geoIntersects(operand) { + return function(value) { + return true; + }; + } +}; +LocalCollection._f = { + _type: function _type(v) { + if (typeof v === "number") + return 1; + if (typeof v === "string") + return 2; + if (typeof v === "boolean") + return 8; + if (isArray(v)) + return 4; + if (v === null) + return 10; + if (v instanceof RegExp) + return 11; + if (typeof v === "function") + return 13; + if (v instanceof Date) + return 9; + if (EJSON.isBinary(v)) + return 5; + return 3; + }, + _equal: function _equal(a, b) { + return EJSON.equals(a, b, { keyOrderSensitive: true }); + }, + _typeorder: function _typeorder(t) { + return [ + -1, + 1, + 2, + 3, + 4, + 5, + -1, + 6, + 7, + 8, + 0, + 9, + -1, + 100, + 2, + 100, + 1, + 8, + 1 + ][t]; + }, + _cmp: function _cmp(a, b) { + if (a === void 0) + return b === void 0 ? 0 : -1; + if (b === void 0) + return 1; + var ta = LocalCollection._f._type(a); + var tb = LocalCollection._f._type(b); + var oa = LocalCollection._f._typeorder(ta); + var ob = LocalCollection._f._typeorder(tb); + if (oa !== ob) + return oa < ob ? -1 : 1; + if (ta !== tb) + throw Error("Missing type coercion logic in _cmp"); + if (ta === 7) { + ta = tb = 2; + a = a.toHexString(); + b = b.toHexString(); + } + if (ta === 9) { + ta = tb = 1; + a = a.getTime(); + b = b.getTime(); + } + if (ta === 1) + return a - b; + if (tb === 2) + return a < b ? -1 : a === b ? 0 : 1; + if (ta === 3) { + var to_array = function to_array2(obj) { + var ret = []; + for (var key in obj) { + ret.push(key); + ret.push(obj[key]); + } + return ret; + }; + return LocalCollection._f._cmp(to_array(a), to_array(b)); + } + if (ta === 4) { + for (var i = 0; ; i++) { + if (i === a.length) + return i === b.length ? 0 : -1; + if (i === b.length) + return 1; + var s = LocalCollection._f._cmp(a[i], b[i]); + if (s !== 0) + return s; + } + } + if (ta === 5) { + if (a.length !== b.length) + return a.length - b.length; + for (i = 0; i < a.length; i++) { + if (a[i] < b[i]) + return -1; + if (a[i] > b[i]) + return 1; + } + return 0; + } + if (ta === 8) { + if (a) + return b ? 0 : 1; + return b ? -1 : 0; + } + if (ta === 10) + return 0; + if (ta === 11) + throw Error("Sorting not supported on regular expression"); + if (ta === 13) + throw Error("Sorting not supported on Javascript code"); + throw Error("Unknown type to sort"); + } +}; +LocalCollection._matches = function(selector, doc) { + return LocalCollection._compileSelector(selector)(doc); +}; +LocalCollection._makeLookupFunction = function(key) { + var dotLocation = key.indexOf("."); + var first, lookupRest, nextIsNumeric; + if (dotLocation === -1) { + first = key; + } else { + first = key.substr(0, dotLocation); + var rest = key.substr(dotLocation + 1); + lookupRest = LocalCollection._makeLookupFunction(rest); + nextIsNumeric = /^\d+(\.|$)/.test(rest); + } + return function(doc) { + if (doc == null) + return [void 0]; + var firstLevel = doc[first]; + if (!lookupRest) + return [firstLevel]; + if (isArray(firstLevel) && firstLevel.length === 0) + return [void 0]; + if (!isArray(firstLevel) || nextIsNumeric) + firstLevel = [firstLevel]; + return Array.prototype.concat.apply([], firstLevel.map((v) => lookupRest(v))); + }; +}; +function _compileDocumentSelector(docSelector) { + var perKeySelectors = []; + Object.keys(docSelector).forEach(function(key) { + const subSelector = docSelector[key]; + if (key.substr(0, 1) === "$") { + if (!LOGICAL_OPERATORS[key]) + throw new Error("Unrecognized logical operator: " + key); + perKeySelectors.push(LOGICAL_OPERATORS[key](subSelector)); + } else { + var lookUpByIndex = LocalCollection._makeLookupFunction(key); + var valueSelectorFunc = compileValueSelector(subSelector); + perKeySelectors.push(function(doc) { + var branchValues = lookUpByIndex(doc); + return branchValues.some((v) => valueSelectorFunc(v)); + }); + } + }); + return function(doc) { + return perKeySelectors.every(function(f) { + return f(doc); + }); + }; +} +LocalCollection._compileSelector = function(selector) { + if (!selector) { + return () => true; + } + if (selector instanceof Function) + return selector; + if (typeof selector === "string" || typeof selector === "number") { + return function(doc) { + return doc._id === selector; + }; + } + if ("_id" in selector && !selector._id) + return function(doc) { + return false; + }; + if (typeof selector === "boolean" || isArray(selector) || EJSON.isBinary(selector)) + throw new Error("Invalid selector: " + selector); + return _compileDocumentSelector(selector); +}; +const compileSelector = LocalCollection._compileSelector; +class Collection { + constructor(name, db, observeKey = name + "-" + db.name) { + this.name = name; + this.db = db; + this.observeKey = observeKey; + this.sources = []; + this.sources[0]; + } + find(selector, options) { + const filter = compileSelector(selector); + const result = []; + const transform = (options == null ? void 0 : options.transform) || ((doc) => doc); + for (const doc of this.sources) { + if (filter(doc)) { + result.push(transform(doc)); + } + } + return result; + } + findOne(selector, options) { + const filter = compileSelector(selector); + let result = null; + const transform = (options == null ? void 0 : options.transform) || ((doc) => doc); + for (const doc of this.sources) { + if (filter(doc)) { + result = transform(doc); + break; + } + } + return result; + } + insert(data) { + if (!(data == null ? void 0 : data._id)) + return console.warn("remote doc need _id"); + const index = this.sources.findIndex((el) => el._id === data._id); + if (index > -1) { + this.sources.splice(index, 1, data); + CollectionObserver.notify(this.observeKey, "changed", data._id, data); + } else { + this.sources.push(data); + CollectionObserver.notify(this.observeKey, "added", data._id, deepCopy(data)); + } + } + upsert(selector, data) { + if (!selector) + return; + const filter = compileSelector(selector); + let count = 0; + this.sources.forEach((doc) => { + if (!filter(doc)) + return; + Object.assign(doc, data); + count++; + for (const key of Object.keys(doc)) { + if (doc[key] === void 0) + delete doc[key]; + } + CollectionObserver.notify(this.observeKey, "changed", doc.id, deepCopy(doc)); + }); + if (count === 0 && data.id) { + this.insert(data); + count++; + } + return count; + } + remove(id) { + if (!id) + return; + const index = this.sources.findIndex((el) => el.id === id); + if (index > -1) + this.sources.splice(index, 1); + CollectionObserver.notify(this.observeKey, "removed", id); + } + observe(handler) { + return new CollectionObserver(this.observeKey, handler); + } +} +function removeKeys(source, keys) { + keys = keys || Object.keys(source); + keys.forEach((key) => delete source[key]); +} +const _MiniMongo = class { + constructor(name, cache) { + this.name = name; + this.cache = cache; + this.collections = new Map(); + } + static connect(name, cache = true) { + if (cache) { + const sysDb = new UniDB("sys"); + let list = sysDb.get("mongodbs"); + if (!Array.isArray(list)) { + list = [name]; + sysDb.set("mongodbs", list); + } + } + if (_MiniMongo.dbs.has(name)) + return _MiniMongo.dbs.get(name); + return new _MiniMongo(name, cache); + } + collection(name) { + let col = this.collections.get(name); + if (!col) + this.collections.set(name, col = new Collection(name, this)); + return col; + } + observe(name, handler) { + return this.collection(name).observe(handler); + } + update(name, type, ...args) { + const collection = this.collection(name); + switch (type) { + case "added": { + const [_id, item] = args; + collection.insert(__spreadValues({ + _id + }, item)); + break; + } + case "removed": { + const [_id] = args; + collection.remove(_id); + break; + } + case "changed": { + const [_id, fields = {}, cleard] = args; + if (Array.isArray(cleard)) + cleard.forEach((key) => { + fields[key] = void 0; + }); + fields._id = _id; + collection.upsert(_id, fields); + break; + } + } + } +}; +let MiniMongo = _MiniMongo; +MiniMongo.dbs = new Map(); +var IDDPConnectionState; +(function(IDDPConnectionState2) { + IDDPConnectionState2[IDDPConnectionState2["CLOSED"] = 0] = "CLOSED"; + IDDPConnectionState2[IDDPConnectionState2["CONNECTING"] = 1] = "CONNECTING"; + IDDPConnectionState2[IDDPConnectionState2["CONNECTED"] = 2] = "CONNECTED"; + IDDPConnectionState2[IDDPConnectionState2["READY"] = 3] = "READY"; + IDDPConnectionState2[IDDPConnectionState2["FAIL"] = 4] = "FAIL"; + IDDPConnectionState2[IDDPConnectionState2["CLOSING"] = 5] = "CLOSING"; + IDDPConnectionState2[IDDPConnectionState2["RECONNECTING"] = 6] = "RECONNECTING"; +})(IDDPConnectionState || (IDDPConnectionState = {})); +const _Client = class { + constructor({ + url = "ws://localhost:3000/websocket", + storageKey = "u" + }) { + this.plugins = {}; + if (_Client.clients.has(url)) + return _Client.clients.get(url); + _Client.clients.set(url, this); + this.db = MiniMongo.connect(storageKey); + this.connection = new DDPConnection({ + url, + db: this.db + }); + } + use(plugin, opts) { + const pluginName = plugin.name; + if (!pluginName) + return console.warn("need name"); + if (this[pluginName]) + return console.warn(`\u51B2\u7A81\u7684${pluginName}`); + const setupFunction = plugin.setup || plugin; + let pluginObj = null; + if (typeof setupFunction === "function") { + pluginObj = setupFunction(this, opts); + } else { + pluginObj = plugin; + } + if (pluginObj) { + this.plugins[pluginName] = pluginObj; + Object.defineProperty(this, pluginName, { + get() { + return this.plugins[pluginName]; + } + }); + } + } + map(source, listHolder, selector, options) { + const collection = typeof source === "string" ? this.db.collection(source) : source; + const filter = compileSelector(selector); + const inits = collection.find(filter, options); + if (inits.length !== 0) + listHolder.push(...inits); + const transform = (options == null ? void 0 : options.transform) || ((doc) => doc); + const ob = new CollectionObserver(collection.observeKey, { + added(_id, item) { + const doc = __spreadProps(__spreadValues({}, item), { _id, id: _id }); + if (!filter(doc)) + return; + listHolder.push(transform(doc)); + }, + changed(_id, fields, removed = []) { + const index = listHolder.findIndex((e) => e._id = _id); + if (index > -1) { + const no = __spreadValues(__spreadValues({}, listHolder[index]), fields); + removeKeys(no, removed); + if (filter(no)) { + listHolder.splice(index, 1, transform(no)); + } else { + listHolder.splice(index, 1); + } + } else { + this.added(_id, fields); + } + }, + removed(_id) { + const index = listHolder.findIndex((e) => e._id = _id); + if (index > -1) { + listHolder.splice(index, 1); + } + } + }, options == null ? void 0 : options.id); + return { + stop() { + ob.stop(); + } + }; + } + call(name, ...args) { + const callArgs = args.filter((el) => typeof el !== "function"); + const callback = args.filter((el) => typeof el === "function"); + return this.connection.call(name, callArgs, callback[0], callback[1]); + } + subscribe(name, ...args) { + const callArgs = args.filter((el) => typeof el !== "function"); + const callback = args.filter((el) => typeof el === "function"); + return this.connection.subscribe(name, callArgs, callback[0]); + } + unsubscribe(id) { + this.connection.unsubscribe(id); + } + destroy() { + this.connection.close(); + } +}; +let Client = _Client; +Client.clients = new Map(); +const buildedClients = new Map(); +function init(opt) { + if (!opt) + opt = "ws://localhost:3000/websocket"; + const userOpt = typeof opt === "string" ? { + url: opt + } : opt; + if (buildedClients.has(userOpt.url)) + return buildedClients.get(userOpt.url); + return new Client(__spreadValues({ socketConstructor: UniSocket }, userOpt)); +} +export { IDDPConnectionState, init }; diff --git a/uni_modules/hj-ddp/js_sdk/index.d.ts b/uni_modules/hj-ddp/js_sdk/index.d.ts new file mode 100644 index 0000000..afecd95 --- /dev/null +++ b/uni_modules/hj-ddp/js_sdk/index.d.ts @@ -0,0 +1,107 @@ +export interface IDDPClientOption { + socketConstructor?: Socket; + tlsOpts?: any; + autoReconnect?: boolean; + autoReconnectTimer?: number; + maintainCollections?: boolean; + url?: string; + ddpVersion?: string; + storageKey?: string; +} +export interface Socket { + send: (msg: string | ArrayBuffer) => any; + onclose: (ev: { code?: number; reason?: string }) => void; + onopen: () => void; + onmessage: (msg: { data: any }) => void; + close: () => void; + onerror: (err: any) => void; +} +export interface SocketConstructor { + new (url: string, protos?: string | string[], confs?: any): Socket; +} +export interface IDDPOption { + socketConstructor?: SocketConstructor; + tlsOpts?: any; + autoConnect?: boolean; + autoReconnect?: boolean; + autoReconnectTimer?: number; + maintainCollections?: boolean; + url?: string; + ddpVersion?: string; + db: IMongo; +} +export interface IDDPClient { + connection: IDDPConnection; + db: IMongo; + use(plugin:any,options?:any):any + call(name: string, arg?: any, ready?: Function, updated?: Function): void; + subscribe(name: string, arg?: any, ready?: Function): string; + unsubscribe(id: string): void; + destroy(): void; + map( + collectionName: string | ICollection, + holder: any[], + selector: any, + options?: { id?: string; transform: (doc: any) => any } + ): { + stop: () => void; + }; +} +export interface IMongo { + collection(name: string): ICollection; + name: string; +} +export interface IDocument { + _id: string; + [key: string]: any; +} + +export interface ICollection { + find(selector?: any, opt?: { transform: (doc: any) => any }): Partial[]; + findOne(selector?: any, opt?: { transform: (doc: any) => any }): Partial; + observe(handler:ICollectionObserverHandler):void +} +export interface ICollectionObserverHandler { + added: (id: string, data: T) => any; + changed?: (id: string, fields: Partial, removeFields: string[]) => any; + removed?: (id: string) => any; + error?: (err: any) => any; + addedBefore?: (id: string, fields: any, before: any) => any; + movedBefore?: (id: string, before: any) => any; +} +export interface IEventEmitter { + maxListeners: number; + emit(type, ...args): boolean; + on(type, listener, prepend?: boolean); + once(type, listener, prepend?: boolean): IEventEmitter; + off(type, listener): IEventEmitter; + listenerCount(type): number; + eventNames(): string[]; +} +export enum IDDPConnectionState { + CLOSED = 0, + CONNECTING = 1, + CONNECTED = 2, + READY = 3, + FAIL = 4, + CLOSING = 5, + RECONNECTING = 6, +} +export interface IDDPConnection extends IEventEmitter { + tlsOpts: any; + autoReconnect: boolean; + autoReconnectTimer: number; + url: string; + socketConstructor: SocketConstructor; + ddpVersion: string; + db: IMongo; + socket: Socket; + session: any; + state: IDDPConnectionState; + isSocketBusy: boolean; + connect(url?: string, protos?: any, data?: any): void; + close(): void; + call(name, params, callback?: any, updatedCallback?: any): void; + subscribe(name: string, params: any, callback?: any): string; + unsubscribe(id: string): void; +} diff --git a/uni_modules/hj-ddp/js_sdk/index.js b/uni_modules/hj-ddp/js_sdk/index.js new file mode 100644 index 0000000..f6fd0e1 --- /dev/null +++ b/uni_modules/hj-ddp/js_sdk/index.js @@ -0,0 +1 @@ +export * from "./hj-ddp.es.js" \ No newline at end of file diff --git a/uni_modules/hj-ddp/package.json b/uni_modules/hj-ddp/package.json new file mode 100644 index 0000000..c99e5c6 --- /dev/null +++ b/uni_modules/hj-ddp/package.json @@ -0,0 +1,86 @@ +{ + "id": "hj-ddp", + "displayName": "hj-ddp", + "version": "1.0.1", + "description": "一个uniapp的DDP客户端实现,助你成为全栈工程师,哈哈~", + "keywords": [ + "hj-ddp", + "DDP", + "Meteor", + "数据同步", + "响应式数据" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "通用 SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "暂无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [ + "hj-core" + ], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "y" + }, + "App": { + "app-vue": "y", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "y", + "IE": "y", + "Edge": "y", + "Firefox": "y", + "Safari": "y" + }, + "小程序": { + "微信": "y", + "阿里": "y", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/hj-ddp/readme.md b/uni_modules/hj-ddp/readme.md new file mode 100644 index 0000000..7dc9675 --- /dev/null +++ b/uni_modules/hj-ddp/readme.md @@ -0,0 +1,145 @@ +# hj-ddp + +## 一个Uniapp的DDP实现,助你成为全栈工程师 + +>DDP是什么 +>>DDP是一个 分布式数据协议,主要是为了解决不同终端数据同步的问题,使用简单的协议来实现多个终端的数据一致性。由Meteor提出和维护。Vue创造者当时就是从Meteor离职然后全职维护vue的。 + +>它有什么好处 +>>DDP是一个异步的数据推送,而且做到订阅了的数据会直接推送,所以: +>>>小明改了个自己的昵称、另一个人会很快看到改动; + +>>>订单状态变了,所在的列表会自动刷新,而不需要进行一次请求 + +>它的原理和不足、使用建议 +>>【推荐使用Meteor作为服务端,参考demo】 基于Mongodb以及订阅发布模式,在ddp服务器端自定义个发布源:可以参考MongoDB的watch API或者冒出来的大量livequery服务(它们都收费的),如果改动的数据集满足定义的选择器(例如{age:{$gt:30}这种选择30岁以上的},就会把这个改动推送给所有的订阅者 + +>>基于Websocket实现双工通讯,因为要维护连接,所以可能更耗资源?但有点不能认同,因为websocket建立起来后就不需要多次握手,以及重复的身份验证 + +>>>1.高频更新的数据很合适! +>>>2.大文件(100k)和长音频等媒体文件,别用! +>>>3.静态资源文件,别用! + +## 使用指南 -【typescript】 + +### 1. 建立连接 - 确保安装了hj-core + +``` +import { init, IDDPClient } from "../../uni_modules/hj-ddp/js_sdk" +// ts +export const ddp: IDDPClient = init("ws://localhost:3002"); +// js +export const ddp = init("ws://localhost:3002"); +``` +####1. init : 参数 string | undefined | IDDPClientOption + +``` +interface IDDPClientOption { + socketConstructor?: Socket; + tlsOpts?: any; + autoReconnect?: boolean; + autoReconnectTimer?: number; + url?: string; + ddpVersion?: string; + storageKey?: string; +} +``` +>>说明: 缺省值为ws://localhost:3000 - meteor默认地址,Mongodb为meteor端口+1或者自己传入 ;同一个ddp服务地址只会建立一个客户端 +>>>IDDPClientOption.socketConstructor: 自定义的socket构造函数,已经封装了个uniapp的,所以不需要传入,自己可以封装个http的只要实现Socket的方法即可 + +>>>IDDPClientOption.tlsOpts: 暂时没用到,后面可能作为连接参数 + +>>>IDDPClientOption.autoReconnect: 自动重连-默认true + +>>>IDDPClientOption.autoReconnectTimer: 自动重连间隔-默认10000ms = 10s + +>>>IDDPClientOption.url: ddp服务地址,同字符串方式的 + +>>>IDDPClientOption.ddpVersion: ddp协议版本,默认 1,当前版本,协议挺稳定,基本没改过 + +>>>IDDPClientOption.storageKey: 可以传个表示client数据缓存的key,但因为这个不好做【见changelog说明】所以意义不大 + +>>返回:IDDPClient + +### 2. IDDPClient说明 - 简单的看接口定义 + +``` +interface IDDPClient { + db: IMongo; + call(name: string, arg?: any, ready?: Function, updated?: Function): void; + subscribe(name: string, arg?: any, ready?: Function): string; + unsubscribe(id: string): void; + destroy(): void; + map( + collection: string | ICollection, + holder: any[], + selector: any, + options?: { id?: string; transform: (doc: any) => any } + ): { + stop: () => void; + }; +} +``` +> 1. call: 调用远程定义的方法,只支持一个参数传送给远端*,ready回调会传入远程方法的返回值,updated会在call方法修改了文档+订阅了这个文档,且本地更新完后调用 - (例如你新增一个订单,成功后会返回订单id,但不一定已经入库了,updated会晚一点执行,但是如果一个方法修改了文档然后做了些其它耗时的操作updated会早于ready) + +> 2. subscribe: 订阅一个发布源,可以传入一个参数,ready方法在订阅源的所有文档都在本地后调用 + +> 3. map : 第一个参数可以是数据集的名称或者已经创建的数据集,第二个参数是一个响应式数组例如传入一个reactive([])-vue3构建的引用或者this.list-vue2,然后第三个参数是一个选择器或者过滤器: 支持 string | Function | MongoSelector- 后面更新再详细说,用来过于文档,第四个传输让你可以传入一个独一无二的id避免重复订阅或者一个transform函数转化每个文档为新数据 + +> 4. unsubscribe: 将subscribe返回的id传入即可取消订阅,订阅相关的数据会被清除~ + +> 5. 属性 db- 本链接绑定的数据库对象Mongo + + +### 3. Mongo/Collection 说明 + +>除了使用ddp.map方法映射数据到一个响应式数组,你还可以 直接观察某个数据集的数据 +``` +// 订阅数据 +const id = ddp.subscribe("todos",{userId:'233'}) +// 创建数据集 - 单例模式,也就是不会重复创建同名的数据集 +const Todos = ddp.db.collection("todos"); +// 查找所有数据: +const todos = Todos.find() +// 查找一条数据: +const todos = Todos.find({due:{$gt:1}}) +// 映射数据: +const todos = reactive([]) +const {stop} = ddp.map(Todos, list, { + + }, { + transform: doc => ({ + ...doc, + time: Date.now() + }) + }) +``` +接口说明: +``` +interface IMongo { + collection(name: string): ICollection; + name: string; +} +ICollection { + find(): Partial[]; + findOne(): Partial; + observe(handler:ICollectionObserverHandler):void +} +ICollectionObserverHandler { + added: (id: string, data: T) => any; + changed?: (id: string, fields: Partial, removeFields: string[]) => any; + removed?: (id: string) => any; + error?: (err: any) => any; + addedBefore?: (id: string, fields: any, before: any) => any; + movedBefore?: (id: string, before: any) => any; +} +``` + + + + + + + + + diff --git a/uni_modules/hj-meteor-account/changelog.md b/uni_modules/hj-meteor-account/changelog.md new file mode 100644 index 0000000..e69de29 diff --git a/uni_modules/hj-meteor-account/js_sdk/index.d.ts b/uni_modules/hj-meteor-account/js_sdk/index.d.ts new file mode 100644 index 0000000..dd2d86b --- /dev/null +++ b/uni_modules/hj-meteor-account/js_sdk/index.d.ts @@ -0,0 +1,11 @@ + +declare interface IDDPClient { + loginWithPassword(u: string, password: string): Promise; + user: { + state: 0 | 1 | 2; // offline logined loging + info: any; + onChange(cb: Function): void; + }; + logout(): Promise; + createAccount(u: string, password: string): Promise; +} diff --git a/uni_modules/hj-meteor-account/js_sdk/index.js b/uni_modules/hj-meteor-account/js_sdk/index.js new file mode 100644 index 0000000..72a1c58 --- /dev/null +++ b/uni_modules/hj-meteor-account/js_sdk/index.js @@ -0,0 +1,107 @@ +import { UniDB } from "../../hj-core/js_sdk"; + +export function hjMeteorAccount(client, opts) { + const users = client.db.collection("users"); + const cacher = opts?.cacher || new UniDB("hj-meteor-user"); + const od = cacher.get("login"); + const ucs = []; + client.user = { + state: 0, + info: null, + onChange(cb) { + ucs.push(cb); + }, + }; + function notify() { + ucs.forEach((cb) => { + if (typeof cb === "function") cb(client.user.info); + }); + } + if (od) { + if (new Date(od.tokenExpires).getTime() > Date.now()) { + // relogin + client.user.state = 2; + client.call("login", { resume: od.token }, (err, result) => { + if (err) { + client.user.state = 0; + cacher.set("login", ""); + client.user.info = null; + return; + } else { + client.user.state = 1; + cacher.set("login", result); + client.user.info = users.findOne(result.id); + } + notify(); + }); + } else cacher.set("login", ""); + } + client.loginWithPassword = (selector, password) => + new Promise((resolve, reject) => { + const request = {}; + client.user.state = 2; + if (typeof selector === "string") { + if (selector.indexOf("@") === -1) request.username = selector; + else request.email = selector; + } + request.password = password; + client.call( + "login", + request, + (err, result) => { + if (err) { + client.user.state = 0; + cacher.set("login", ""); + client.user.info = null; + return reject(err); + } + client.user.state = 1; + cacher.set("login", result); + client.user.info = users.findOne(result.id); + notify(); + resolve(client.user.info); + } + ); + }); + client.logout = () => + new Promise((resolve) => + client.call("logout", (err, res) => { + let os = client.user.state; + client.user.state = 0; + cacher.set("login", ""); + client.user.info = null; + if (os) notify(); + resolve(true); + }) + ); + client.createAccount = (selector, password) => + new Promise((resolve, reject) => { + const request = {}; + client.user.state = 2; + if (typeof selector === "string") { + if (selector.indexOf("@") === -1) request.username = selector; + else request.email = selector; + } + request.password = password; + request.profile = { + name: "用户-" + selector.slice(0, 10) + } + client.call( + "createUser", + request, + (err, result) => { + if (err) { + client.user.state = 0; + cacher.set("login", ""); + client.user.info = null; + return reject(err); + } + client.user.state = 1; + cacher.set("login", result); + client.user.info = users.findOne(result.id); + notify(); + resolve(client.user.info); + } + ); + }); +} diff --git a/uni_modules/hj-meteor-account/package.json b/uni_modules/hj-meteor-account/package.json new file mode 100644 index 0000000..8d2c439 --- /dev/null +++ b/uni_modules/hj-meteor-account/package.json @@ -0,0 +1,80 @@ +{ + "id": "hj-meteor-account", + "displayName": "hj-meteor-account", + "version": "1.0.0", + "description": "hj-meteor-account", + "keywords": [ + "hj-meteor-account" +], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "category": [ + "JS SDK", + "JS SDK" + ], + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "", + "data": "", + "permissions": "" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "u", + "aliyun": "u" + }, + "client": { + "Vue": { + "vue2": "u", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "u", + "Android Browser": "u", + "微信浏览器(Android)": "u", + "QQ浏览器(Android)": "u" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "u", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} \ No newline at end of file diff --git a/uni_modules/hj-meteor-account/readme.md b/uni_modules/hj-meteor-account/readme.md new file mode 100644 index 0000000..246b7ee --- /dev/null +++ b/uni_modules/hj-meteor-account/readme.md @@ -0,0 +1 @@ +# hj-meteor-account \ No newline at end of file -- GitLab