From fd26b48ff66e35e1eaf7c19d9bf80ed0c08e3569 Mon Sep 17 00:00:00 2001 From: Philipp Kunz Date: Sat, 24 Feb 2024 12:20:13 +0100 Subject: [PATCH] fix(core): update --- package.json | 6 +- pnpm-lock.yaml | 130 +++++------ test/test.ts | 3 +- ts/00_commitinfo_data.ts | 2 +- ts/typedrequest.classes.typedrequest.ts | 9 +- ts/typedrequest.classes.typedrouter.ts | 12 +- ts/typedrequest.classes.virtualstream.ts | 276 +++++++++++++++++++++-- 7 files changed, 346 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index 4f9691d..f832223 100644 --- a/package.json +++ b/package.json @@ -21,12 +21,12 @@ "@git.zone/tstest": "^1.0.86", "@push.rocks/smartenv": "^5.0.12", "@push.rocks/tapbundle": "^5.0.15", - "@types/node": "^20.11.19" + "@types/node": "^20.11.20" }, "dependencies": { - "@api.global/typedrequest-interfaces": "^3.0.6", + "@api.global/typedrequest-interfaces": "^3.0.14", "@push.rocks/isounique": "^1.0.5", - "@push.rocks/lik": "^6.0.12", + "@push.rocks/lik": "^6.0.13", "@push.rocks/smartdelay": "^3.0.5", "@push.rocks/smartpromise": "^4.0.3", "@push.rocks/webrequest": "^3.0.34" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e731438..04a735c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,14 +6,14 @@ settings: dependencies: '@api.global/typedrequest-interfaces': - specifier: ^3.0.6 - version: 3.0.6 + specifier: ^3.0.14 + version: 3.0.14 '@push.rocks/isounique': specifier: ^1.0.5 version: 1.0.5 '@push.rocks/lik': - specifier: ^6.0.12 - version: 6.0.12 + specifier: ^6.0.13 + version: 6.0.13 '@push.rocks/smartdelay': specifier: ^3.0.5 version: 3.0.5 @@ -36,10 +36,10 @@ devDependencies: version: 2.0.15 '@git.zone/tsrun': specifier: ^1.2.44 - version: 1.2.46(@types/node@20.11.19) + version: 1.2.46(@types/node@20.11.20) '@git.zone/tstest': specifier: ^1.0.86 - version: 1.0.86(@types/node@20.11.19)(sinon@17.0.1) + version: 1.0.86(@types/node@20.11.20)(sinon@17.0.1) '@push.rocks/smartenv': specifier: ^5.0.12 version: 5.0.12 @@ -47,20 +47,20 @@ devDependencies: specifier: ^5.0.15 version: 5.0.15(sinon@17.0.1) '@types/node': - specifier: ^20.11.19 - version: 20.11.19 + specifier: ^20.11.20 + version: 20.11.20 packages: - /@api.global/typedrequest-interfaces@3.0.6: - resolution: {integrity: sha512-WnyJx1SobjK4NcOY4GXnqIhBEZ76BvvMKbGI/oh1lukS3WKYb6/b1ne4CzPlPnaFtAyETRbkphPhlzMIe3sTZA==} + /@api.global/typedrequest-interfaces@3.0.14: + resolution: {integrity: sha512-DvLKy1SrZYPxmt57ONH0hawJa2ZTF9tvyYdEn9bjy29hD3O/zOmtcWevtEHkOE5ifLGEpj6cwTyuNkBfsMoJ2w==} /@api.global/typedrequest@3.0.4: resolution: {integrity: sha512-8UThH9c3MxdSLiON8UN1CPXooU6Mp0eleFhVS3QB2OUsYqgEGn/EzuMt+cMIv/+ESSS6zcTpHvAhZ8ZMLfpL8A==} dependencies: - '@api.global/typedrequest-interfaces': 3.0.6 + '@api.global/typedrequest-interfaces': 3.0.14 '@push.rocks/isounique': 1.0.5 - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/webrequest': 3.0.34 @@ -70,9 +70,9 @@ packages: resolution: {integrity: sha512-8n84MXIJXUxjEu6JVQulzdwQ+JYwXjhWbpqQQTDDeMNlpmaz3QEoE83rwehL8AyTaY++VwwYpkJqSXPGWQ+5ww==} dependencies: '@api.global/typedrequest': 3.0.4 - '@api.global/typedrequest-interfaces': 3.0.6 + '@api.global/typedrequest-interfaces': 3.0.14 '@api.global/typedsocket': 3.0.0 - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartchok': 1.0.32 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartenv': 5.0.12 @@ -109,7 +109,7 @@ packages: resolution: {integrity: sha512-ui+6MLd99iTN/lC+iC/FKPRjzVyiZ4PrmlU6ptbCtbBj3cSOXHx+RRGF54+be2xHodf4FOgwFv/GZdW8LtO3vg==} dependencies: '@api.global/typedrequest': 3.0.4 - '@api.global/typedrequest-interfaces': 3.0.6 + '@api.global/typedrequest-interfaces': 3.0.14 '@push.rocks/isohash': 2.0.1 '@push.rocks/smartjson': 5.0.10 '@push.rocks/smartrx': 3.0.7 @@ -400,13 +400,13 @@ packages: - supports-color dev: true - /@git.zone/tsrun@1.2.46(@types/node@20.11.19): + /@git.zone/tsrun@1.2.46(@types/node@20.11.20): resolution: {integrity: sha512-8miFVBle9Mnjx+uPGI/P+EuWcIOXWjBAkdjN5IYbdp5Ytt4xQODCLh4JSnC9h56UeU1nUxCAxZeJs2e9TXrivA==} hasBin: true dependencies: '@push.rocks/smartfile': 10.0.33 '@push.rocks/smartshell': 3.0.3 - ts-node: 10.9.1(@types/node@20.11.19)(typescript@5.1.6) + ts-node: 10.9.1(@types/node@20.11.20)(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - '@swc/core' @@ -415,13 +415,13 @@ packages: - supports-color dev: true - /@git.zone/tstest@1.0.86(@types/node@20.11.19)(sinon@17.0.1): + /@git.zone/tstest@1.0.86(@types/node@20.11.20)(sinon@17.0.1): resolution: {integrity: sha512-ec95MNeA21L+ob+lvLVCmwPTTC1BY+v/JHLYZ9DOZ9+9buLgx+cJ7VkwGBJCnlWJtqEtJosUrFKTih36iNuT3g==} hasBin: true dependencies: '@api.global/typedserver': 3.0.23 '@git.zone/tsbundle': 2.0.15 - '@git.zone/tsrun': 1.2.46(@types/node@20.11.19) + '@git.zone/tsrun': 1.2.46(@types/node@20.11.20) '@push.rocks/consolecolor': 2.0.1 '@push.rocks/smartbrowser': 2.0.6 '@push.rocks/smartdelay': 3.0.5 @@ -600,8 +600,8 @@ packages: /@push.rocks/isounique@1.0.5: resolution: {integrity: sha512-Z0BVqZZOCif1THTbIKWMgg0wxCzt9CyBtBBqQJiZ+jJ0KlQFrQHNHrPt81/LXe/L4x0cxWsn0bpL6W5DNSvNLw==} - /@push.rocks/lik@6.0.12: - resolution: {integrity: sha512-/vzlOZ26gCmXZz67LeM2hJ+aNM49Jxvf3FKxLMXHhJwffd3LcV96MYbMfKzKR/za/bh5Itf3a6UjLL5mmN6Pew==} + /@push.rocks/lik@6.0.13: + resolution: {integrity: sha512-pfwcnWKQ56uuCjdw/NbY83e2MSFh9bu5Sxf38ZukzDH8+Athx83naVqt2pEENfUJrFWx7PcSC831GVwlWDt3oA==} dependencies: '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartmatch': 2.0.0 @@ -639,7 +639,7 @@ packages: /@push.rocks/smartchok@1.0.32: resolution: {integrity: sha512-bBJ4UX3jjItZo0mdDxQcDdRqbuIyCeDo4XXvkX2yLqkHJHFxQbL2lTDrX4l7cTaQ7361AYSsvOsBkZyPvCN6mg==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrx': 3.0.7 '@tempfix/watcher': 2.3.0 @@ -648,7 +648,7 @@ packages: /@push.rocks/smartcli@4.0.8: resolution: {integrity: sha512-B4F3nqq7ko8tev1wxGdFnh/zSDDP8Q9LpEOb3wTf0jayyhYetFQ7n6zi4J9fhXYBKPkJSyQEBoOfRmgJyeLHkA==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartlog': 3.0.3 '@push.rocks/smartparam': 1.1.10 '@push.rocks/smartpromise': 4.0.3 @@ -689,7 +689,7 @@ packages: /@push.rocks/smartfile@10.0.33: resolution: {integrity: sha512-mCvTWP32MCFtFcZVuGzvazyxQSrPhlaLkWTydz8IZ32/V41vvxieXDiPwoF64lcIYO37EZEXElYdBBjqCJ8MuA==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartfile-interfaces': 1.0.7 '@push.rocks/smarthash': 3.0.4 @@ -712,7 +712,7 @@ packages: /@push.rocks/smartfile@10.0.41: resolution: {integrity: sha512-xOOy0duI34M2qrJZggpk51EHGXmg9+mBL1Q55tNiQKXzfx89P3coY1EAZG8tvmep3qB712QEKe7T+u04t42Kjg==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartfile-interfaces': 1.0.7 '@push.rocks/smarthash': 3.0.4 @@ -733,7 +733,7 @@ packages: /@push.rocks/smartfile@11.0.4: resolution: {integrity: sha512-NXAyqYE5zNUJ9Mu/t2oWUKu21CRUI4Dvlm56rKBSczCq5xeC7EwmamTzL3Nyn6Tmu1jBpYktYL4zIx17JJOB7w==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartfile-interfaces': 1.0.7 '@push.rocks/smarthash': 3.0.4 @@ -939,11 +939,11 @@ packages: /@push.rocks/smartsocket@2.0.24: resolution: {integrity: sha512-Glqv1Zi5TXgD+04P8OvTpiytyfrQxTPv67qAwZizAVVQ2zWJJgKqnIuoHT1zKP8QiKRNer+D58LCxX0ZE2XfzQ==} dependencies: - '@api.global/typedrequest-interfaces': 3.0.6 + '@api.global/typedrequest-interfaces': 3.0.14 '@api.global/typedserver': 3.0.23 '@push.rocks/isohash': 2.0.1 '@push.rocks/isounique': 1.0.5 - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartenv': 5.0.12 '@push.rocks/smartjson': 5.0.10 @@ -996,7 +996,7 @@ packages: /@push.rocks/smartstream@3.0.30: resolution: {integrity: sha512-+izraXkILJJIy99PzP2LYahaW+g/35bTi/UxD7FeuOYbTaigode6Q3swvs0nrK6yu+A9x6RfoWV4JAJjd3Y87g==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartpromise': 4.0.3 '@push.rocks/smartrx': 3.0.7 dev: true @@ -1033,7 +1033,7 @@ packages: /@push.rocks/smarttime@4.0.6: resolution: {integrity: sha512-1whOow0YJw/TbN758TedRRxApoZbsvyxCVpoGjXh7DE/fEEgs7RCr4vVF5jYpyXNQuNMLpKJcTsSfyQ6RvH4Aw==} dependencies: - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartpromise': 4.0.3 croner: 7.0.3 @@ -1095,7 +1095,7 @@ packages: resolution: {integrity: sha512-w5Q3g1TT5SDIXukAAoYVuWud+Y5ysS8qiBqPU00/re895VVZhUOSNJMNU6jyneZigmbWtwSLsxDkZHlsHWpfuA==} dependencies: '@apiglobal/typedrequest-interfaces': 2.0.1 - '@push.rocks/lik': 6.0.12 + '@push.rocks/lik': 6.0.13 '@push.rocks/smartenv': 5.0.12 '@push.rocks/smartjson': 5.0.10 '@push.rocks/smartpromise': 4.0.3 @@ -1430,7 +1430,7 @@ packages: /@types/accepts@1.3.6: resolution: {integrity: sha512-6+qlUg57yfE9OO63wnsJXLeq9cG3gSHBBIxNMOjNrbDRlDnm/NaR7RctfYcVCPq+j7d+MwOxqVEludH5+FKrlg==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/babel__code-frame@7.0.5: @@ -1441,14 +1441,14 @@ packages: resolution: {integrity: sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA==} dependencies: '@types/connect': 3.4.37 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/body-parser@1.19.5: resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} dependencies: '@types/connect': 3.4.38 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/buffer-json@2.0.2: @@ -1471,27 +1471,27 @@ packages: /@types/clean-css@4.2.11: resolution: {integrity: sha512-Y8n81lQVTAfP2TOdtJJEsCoYl1AnOkqDqMvXb9/7pfgZZ7r8YrEyurrAvAoAjHOGXKRybay+5CsExqIH6liccw==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 source-map: 0.6.1 dev: true /@types/co-body@6.1.2: resolution: {integrity: sha512-eUqBFu8mNW56oZAP0aEmGm+4qFeYjkxVThQ1F/8jFOBiSNM+gib3pYFzjnQsQRUZ501Eg8qOc7Nn76GcZo6Uvg==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 '@types/qs': 6.9.9 dev: true /@types/connect@3.4.37: resolution: {integrity: sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/connect@3.4.38: resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/content-disposition@0.5.7: @@ -1512,13 +1512,13 @@ packages: '@types/connect': 3.4.37 '@types/express': 4.17.20 '@types/keygrip': 1.0.4 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/cors@2.8.17: resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/debounce@1.2.3: @@ -1532,7 +1532,7 @@ packages: /@types/express-serve-static-core@4.17.39: resolution: {integrity: sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 '@types/qs': 6.9.9 '@types/range-parser': 1.2.6 '@types/send': 0.17.3 @@ -1541,7 +1541,7 @@ packages: /@types/express-serve-static-core@4.17.43: resolution: {integrity: sha512-oaYtiBirUOPQGSWNGPWnzyAFJ0BP3cwvN4oWZQY+zUBwpVIGsKUkpBpSztp74drYcjavs7SKFZ4DX1V2QeN8rg==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 '@types/qs': 6.9.11 '@types/range-parser': 1.2.7 '@types/send': 0.17.4 @@ -1568,34 +1568,34 @@ packages: /@types/from2@2.3.2: resolution: {integrity: sha512-s1pdctxW2+CA4FOxxTBRxC3RKQL9Br1a2s2LngP4jh1BI84JBL3mDXj87EwcckN9z/IXp8o3ySmvZveGEAAwqw==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/from2@2.3.5: resolution: {integrity: sha512-giavnjf3kNlJnE+HpZA1CQ3UKHxgehzsTuIMGda8pGMbOiLYGVNADEskey44OZcADHm/HOoBany8IV+0x28XFw==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/fs-extra@11.0.3: resolution: {integrity: sha512-sF59BlXtUdzEAL1u0MSvuzWd7PdZvZEtnaVkzX5mjpdWTJ8brG0jUqve3jPCzSzvAKKMHTG8F8o/WMQLtleZdQ==} dependencies: '@types/jsonfile': 6.1.3 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/fs-extra@11.0.4: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/glob@8.1.0: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/html-minifier@4.0.5: @@ -1653,13 +1653,13 @@ packages: /@types/jsonfile@6.1.3: resolution: {integrity: sha512-/yqTk2SZ1wIezK0hiRZD7RuSf4B3whFxFamB1kGStv+8zlWScTMcHanzfc0XKWs5vA1TkHeckBlOyM8jxU8nHA==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/jsonfile@6.1.4: resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/keygrip@1.0.4: @@ -1682,7 +1682,7 @@ packages: '@types/http-errors': 2.0.3 '@types/keygrip': 1.0.4 '@types/koa-compose': 3.2.7 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/mime-types@2.1.1: @@ -1716,8 +1716,8 @@ packages: resolution: {integrity: sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==} dev: true - /@types/node@20.11.19: - resolution: {integrity: sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==} + /@types/node@20.11.20: + resolution: {integrity: sha512-7/rR21OS+fq8IyHTgtLkDK949uzsa6n8BkziAKtPVpugIkO6D+/ooXMvzXxDnZrmtXVfjb1bKQafYpb8s89LOg==} dependencies: undici-types: 5.26.5 dev: true @@ -1761,14 +1761,14 @@ packages: resolution: {integrity: sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug==} dependencies: '@types/mime': 1.3.4 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/send@0.17.4: resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} dependencies: '@types/mime': 1.3.5 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/serve-static@1.15.4: @@ -1776,7 +1776,7 @@ packages: dependencies: '@types/http-errors': 2.0.3 '@types/mime': 3.0.3 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/serve-static@1.15.5: @@ -1784,7 +1784,7 @@ packages: dependencies: '@types/http-errors': 2.0.4 '@types/mime': 3.0.4 - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/sinon-chai@3.2.11: @@ -1810,19 +1810,19 @@ packages: /@types/through2@2.0.38: resolution: {integrity: sha512-YFu+nHmjxMurkH1BSzA0Z1WrKDAY8jUKPZctNQn7mc+/KKtp2XxnclHFXxdB1m7Iqnzb5aywgP8TMK283LezGQ==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/through2@2.0.40: resolution: {integrity: sha512-QeEwyeGxvtKjP0I/SR8pHtKMgmqotWTI8V/rNMTjbF3arWZJV/kYtbZXtwQKxUuV/oPSGkUilSspFKkTgCPTpA==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/through2@2.0.41: resolution: {integrity: sha512-ryQ0tidWkb1O1JuYvWKyMLYEtOWDqF5mHerJzKz/gQpoAaJq2l/dsMPBF0B5BNVT34rbARYJ5/tsZwLfUi2kwQ==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/trusted-types@2.0.7: @@ -1850,20 +1850,20 @@ packages: /@types/ws@7.4.7: resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/ws@8.5.10: resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true /@types/yauzl@2.10.3: resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} requiresBuild: true dependencies: - '@types/node': 20.11.19 + '@types/node': 20.11.20 dev: true optional: true @@ -2831,7 +2831,7 @@ packages: dependencies: '@types/cookie': 0.4.1 '@types/cors': 2.8.17 - '@types/node': 20.11.19 + '@types/node': 20.11.20 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.4.2 @@ -5478,7 +5478,7 @@ packages: hasBin: true dev: true - /ts-node@10.9.1(@types/node@20.11.19)(typescript@5.1.6): + /ts-node@10.9.1(@types/node@20.11.20)(typescript@5.1.6): resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} hasBin: true peerDependencies: @@ -5497,7 +5497,7 @@ packages: '@tsconfig/node12': 1.0.11 '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 - '@types/node': 20.11.19 + '@types/node': 20.11.20 acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 diff --git a/test/test.ts b/test/test.ts index aa06527..adceae7 100644 --- a/test/test.ts +++ b/test/test.ts @@ -89,7 +89,8 @@ tap.test('should allow VirtualStreams', async () => { console.log(response.responseStream); }) -tap.test('should end the server', async () => { +tap.test('should end the server', async (toolsArg) => { + await toolsArg.delayFor(5000); await testServer.stop(); }); diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 1eece6c..9bc4c35 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@api.global/typedrequest', - version: '3.0.6', + version: '3.0.7', description: 'make typed requests towards apis' } diff --git a/ts/typedrequest.classes.typedrequest.ts b/ts/typedrequest.classes.typedrequest.ts index 5ef1024..98c8ff7 100644 --- a/ts/typedrequest.classes.typedrequest.ts +++ b/ts/typedrequest.classes.typedrequest.ts @@ -20,7 +20,6 @@ export class TypedRequest { - return this.postTrObject(payloadArg); + sendMethod: (payloadArg: plugins.typedRequestInterfaces.IStreamRequest) => { + return this.postTrObject(payloadArg) as Promise; } }); @@ -59,8 +58,8 @@ export class TypedRequest { - return this.postTrObject(payloadArg); + sendMethod: (payloadArg: plugins.typedRequestInterfaces.IStreamRequest) => { + return this.postTrObject(payloadArg) as Promise; } }); return payloadReceiving.response; diff --git a/ts/typedrequest.classes.typedrouter.ts b/ts/typedrequest.classes.typedrouter.ts index 585df0c..e209f36 100644 --- a/ts/typedrequest.classes.typedrouter.ts +++ b/ts/typedrequest.classes.typedrouter.ts @@ -14,7 +14,7 @@ export class TypedRouter { public handlerMap = new plugins.lik.ObjectMap< TypedHandler >(); - public registeredVirtualStreams = new plugins.lik.ObjectMap(); + public registeredVirtualStreams = new plugins.lik.ObjectMap>(); public fireEventInterestMap = new plugins.lik.InterestMap< string, @@ -102,7 +102,8 @@ export class TypedRouter { // lets do stream processing if (typedRequestArg.method === '##VirtualStream##') { - const result = await this.handleStreamTypedRequest(typedRequestArg as plugins.typedRequestInterfaces.IStreamRequest); + const result: any = await this.handleStreamTypedRequest(typedRequestArg as plugins.typedRequestInterfaces.IStreamRequest); + result.localData = null; return result as T; } @@ -152,6 +153,13 @@ export class TypedRouter { const relevantVirtualStream = await this.registeredVirtualStreams.find(async virtualStreamArg => { return virtualStreamArg.streamId === streamTrArg.request.streamId; }); + if (!relevantVirtualStream) { + console.log(`no relevant virtual stream found for stream with id ${streamTrArg.request.streamId}`); + console.log(this.registeredVirtualStreams.getArray()); + return streamTrArg; + } else { + console.log(`success: found relevant virtual stream with id ${streamTrArg.request.streamId}`); + } const result = await relevantVirtualStream.handleStreamTr(streamTrArg); return result; } diff --git a/ts/typedrequest.classes.virtualstream.ts b/ts/typedrequest.classes.virtualstream.ts index 507cd09..55a951b 100644 --- a/ts/typedrequest.classes.virtualstream.ts +++ b/ts/typedrequest.classes.virtualstream.ts @@ -3,16 +3,25 @@ import type { TypedRouter } from './typedrequest.classes.typedrouter.js'; export interface ICommFunctions { sendMethod?: ( - sendPayload: plugins.typedRequestInterfaces.ITypedRequest - ) => Promise; + sendPayload: plugins.typedRequestInterfaces.IStreamRequest + ) => Promise; typedrouter?: TypedRouter; } -export class VirtualStream { +/** + * 1. A VirtualStream connects over the network + * 2. It is always paired to one other VirtualStream + * on the other side with the same streamId. + * 3. It has a Readable and Writable side. + * 4. The Writable side is Readable on the other side and vice versa. + */ +export class VirtualStream { // STATIC public static encodePayloadForNetwork( objectPayload: any, - commFunctions: ICommFunctions + commFunctions: ICommFunctions, + originalPayload?: any, + path = [] ): any { if (objectPayload instanceof VirtualStream) { if (!objectPayload.side && commFunctions.sendMethod) { @@ -22,20 +31,41 @@ export class VirtualStream { if (!objectPayload.side && commFunctions.typedrouter) { objectPayload.side = 'responding'; objectPayload.typedrouter = commFunctions.typedrouter; + commFunctions.typedrouter.registeredVirtualStreams.add(objectPayload); + } + if (!originalPayload.response || path.includes('response')) { + return { + _isVirtualStream: true, + streamId: objectPayload.streamId, + }; + } else { + return { + _OBMITTED_VIRTUAL_STREAM: true, + reason: 'path is under .request: obmitted for deduplication reasons in response cycle.', + }; } - return { - _isVirtualStream: true, - streamId: objectPayload.streamId, - }; } else if (Array.isArray(objectPayload)) { const returnArray = []; for (const item of objectPayload) { - returnArray.push(VirtualStream.encodePayloadForNetwork(item, commFunctions)); + returnArray.push( + VirtualStream.encodePayloadForNetwork( + item, + commFunctions, + originalPayload || objectPayload, + path + ) + ); } return returnArray; } else if (objectPayload !== null && typeof objectPayload === 'object') { return Object.keys(objectPayload).reduce((acc, key) => { - acc[key] = VirtualStream.encodePayloadForNetwork(objectPayload[key], commFunctions); + path.push(key); + acc[key] = VirtualStream.encodePayloadForNetwork( + objectPayload[key], + commFunctions, + originalPayload || objectPayload, + path + ); return acc; }, {}); } else { @@ -55,6 +85,7 @@ export class VirtualStream { if (!virtualStream.side && commFunctions.typedrouter) { virtualStream.side = 'responding'; virtualStream.typedrouter = commFunctions.typedrouter; + commFunctions.typedrouter.registeredVirtualStreams.add(virtualStream); } return virtualStream; } else if (Array.isArray(objectPayload)) { @@ -78,23 +109,238 @@ export class VirtualStream { public side: 'requesting' | 'responding'; public streamId: string = plugins.isounique.uni(); + + // integration with typedrequest mechanics + public sendMethod: ICommFunctions['sendMethod']; public typedrouter: TypedRouter; - public sendMethod: ( - sendPayloadArg: plugins.typedRequestInterfaces.ITypedRequest - ) => Promise; - constructor() {} + // wether to keep the stream alive + private keepAlive = true; + private lastKeepAliveEvent = Date.now(); + // backpressured arrays + private sendBackpressuredArray = + new plugins.lik.BackpressuredArray( + 16 + ); + private receiveBackpressuredArray = + new plugins.lik.BackpressuredArray( + 16 + ); + + constructor() { + this.startKeepAliveLoop(); + } + + /** + * takes care of sending + */ + private async workOnQueue() { + if(this.side === 'requesting') { + // helper functions + const getFeedback = async () => { + const streamTr = await this.sendMethod({ + method: '##VirtualStream##', + request: { + streamId: this.streamId, + cycleId: plugins.isounique.uni(), + cycle: 'request', + mainPurpose: 'feedback', + next: this.sendBackpressuredArray.data.length > 0, + backpressure: this.receiveBackpressuredArray.checkSpaceAvailable(), + }, + response: null, + }).catch(() => { + console.log('stream ended immaturely'); + this.keepAlive = false; + }); + if (streamTr && streamTr.response) { + otherSideIsBackpressured = streamTr.response.backpressure + otherSideHasNext = streamTr.response.next; + } + } + + + // do work loop + let thisSideIsBackpressured = this.receiveBackpressuredArray.checkSpaceAvailable(); + let otherSideHasNext = false; + let otherSideIsBackpressured = false; + while (this.sendBackpressuredArray.data.length > 0 || otherSideHasNext) { + const dataArg = this.sendBackpressuredArray.shift(); + const streamTr = await this.sendMethod({ + method: '##VirtualStream##', + request: { + streamId: this.streamId, + cycleId: plugins.isounique.uni(), + cycle: 'request', + mainPurpose: 'chunk', + backpressure: thisSideIsBackpressured, + next: this.sendBackpressuredArray.data.length > 0, + chunkData: dataArg, + }, + response: null, + }).catch(() => { + console.log('stream ended immaturely'); + this.keepAlive = false; + }); + + if (streamTr && streamTr.response && streamTr.response.chunkData) { + this.receiveBackpressuredArray.push(streamTr.response.chunkData); + } + thisSideIsBackpressured = this.receiveBackpressuredArray.checkSpaceAvailable(); + + // lets care about looping + otherSideHasNext = streamTr && streamTr.response && streamTr.response.next; + } + + } + } + + /** + * This method handles the stream only on the responding side + * @param streamTrArg + * @returns + */ public async handleStreamTr(streamTrArg: plugins.typedRequestInterfaces.IStreamRequest) { + if (streamTrArg.request.keepAlive === true && this.keepAlive === true) { + this.lastKeepAliveEvent = Date.now(); + } else if (streamTrArg.request.keepAlive === false) { + this.keepAlive = false; + } + + // keepAlive handling + if (streamTrArg.request.mainPurpose === 'keepAlive') { + // if the main purpose is keepAlive, we answer with a keepAlive + streamTrArg.response = { + streamId: this.streamId, + cycleId: streamTrArg.request.cycleId, + cycle: 'response', + mainPurpose: 'keepAlive', + keepAlive: this.keepAlive, + next: this.sendBackpressuredArray.data.length > 0, + backpressure: this.receiveBackpressuredArray.checkSpaceAvailable(), + }; + } + + // feedback handling + if (streamTrArg.request.mainPurpose === 'feedback') { + streamTrArg.response = { + streamId: this.streamId, + cycleId: streamTrArg.request.cycleId, + cycle: 'response', + mainPurpose: 'feedback', + next: this.sendBackpressuredArray.data.length > 0, + backpressure: this.receiveBackpressuredArray.checkSpaceAvailable(), + }; + streamTrArg.request = null; + } + + // chunk handling + if (streamTrArg.request.mainPurpose === 'chunk') { + this.receiveBackpressuredArray.push(streamTrArg.request.chunkData); + if (this.sendBackpressuredArray.data.length > 0 && streamTrArg.response.backpressure === false) { + const dataArg = this.sendBackpressuredArray.shift(); + streamTrArg.response = { + streamId: this.streamId, + cycleId: streamTrArg.request.cycleId, + cycle: 'response', + mainPurpose: 'chunk', + next: this.sendBackpressuredArray.data.length > 1, + backpressure: this.receiveBackpressuredArray.checkSpaceAvailable(), + chunkData: this.sendBackpressuredArray.shift(), + }; + } else { + streamTrArg.response = { + streamId: this.streamId, + cycleId: streamTrArg.request.cycleId, + cycle: 'response', + mainPurpose: 'feedback', + next: this.sendBackpressuredArray.data.length > 0, + }; + } + streamTrArg.request = null; + } + return streamTrArg; } /** * closes the virtual stream */ - close() { + public async cleanup() { if (this.typedrouter) { this.typedrouter.registeredVirtualStreams.remove(this); } } + + /** + * a keepAlive loop that works across technologies + */ + private async startKeepAliveLoop() { + // initially wait for a second + await plugins.smartdelay.delayFor(0); + let counter = 0; + keepAliveLoop: while (this.keepAlive) { + const triggerResult = await this.triggerKeepAlive(); + await plugins.smartdelay.delayFor(1000); + } + await plugins.smartdelay.delayFor(1000); + await this.cleanup(); + console.log(`cleaned up for stream ${this.streamId}`); + } + + private async triggerKeepAlive() { + if (this.side === 'requesting') { + console.log(`keepalive sent.`); + const streamTr = await this.sendMethod({ + method: '##VirtualStream##', + request: { + streamId: this.streamId, + cycleId: plugins.isounique.uni(), + cycle: 'request', + mainPurpose: 'keepAlive', + keepAlive: true, + }, + response: null, + }).catch(() => { + this.keepAlive = false; + }); + + // lets handle keepAlive + if (streamTr && streamTr.response && streamTr.response.keepAlive === false) { + this.keepAlive = false; + } else { + this.lastKeepAliveEvent = Date.now(); + } + if (streamTr && streamTr.response && streamTr.response.next) { + this.workOnQueue(); + } + } + if (Date.now() - this.lastKeepAliveEvent > 10000) { + console.log(`closing stream for ${this.streamId}`); + this.keepAlive = false; + } + } + + // Data sending and receiving + public async sendData(dataArg: T): Promise { + this.sendBackpressuredArray.push(dataArg); + this.workOnQueue(); + await this.sendBackpressuredArray.waitForSpace(); + } + public async fetchData(): Promise { + if (this.receiveBackpressuredArray.hasSpace) { + // do something maybe? + } + await this.receiveBackpressuredArray.waitForItems(); + const dataPackage = this.receiveBackpressuredArray.shift(); + return dataPackage; + } + + public pipeWebStream(webStream: any) { + // lets do the piping + webStream.on('data', (data: any) => {}); + webStream.on('end', () => {}); + webStream.on('error', (error: any) => {}); + } }