From 5627721463bc72a7fe47cc70ff110ddf535f005b Mon Sep 17 00:00:00 2001 From: Jon Staab Date: Thu, 26 Sep 2024 15:36:01 -0700 Subject: [PATCH] Add negentropy support to executor --- package-lock.json | 439 ++++++++++++++++++++++++++-- packages/app/tsconfig.json | 2 +- packages/content/tsconfig.json | 2 +- packages/dvm/tsconfig.json | 2 +- packages/feeds/tsconfig.json | 2 +- packages/lib/src/Emitter.ts | 2 +- packages/lib/src/Worker.ts | 2 +- packages/lib/tsconfig.json | 2 +- packages/net/package.json | 4 +- packages/net/src/Executor.ts | 71 ++++- packages/net/src/Subscribe.ts | 4 +- packages/net/src/index.ts | 1 + packages/net/src/target/Echo.ts | 16 + packages/net/test/Executor.test.cjs | 37 +++ packages/net/tsconfig.json | 2 +- packages/signer/tsconfig.json | 2 +- packages/store/tsconfig.json | 2 +- packages/util/tsconfig.json | 2 +- 18 files changed, 548 insertions(+), 46 deletions(-) create mode 100644 packages/net/src/target/Echo.ts create mode 100644 packages/net/test/Executor.test.cjs diff --git a/package-lock.json b/package-lock.json index a9d9e28..d434a18 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,11 +29,12 @@ } }, "node_modules/@babel/code-frame": { - "version": "7.24.2", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/highlight": "^7.24.2", + "@babel/highlight": "^7.24.7", "picocolors": "^1.0.0" }, "engines": { @@ -41,19 +42,21 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.22.20", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, - "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.24.2", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, - "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.22.20", + "@babel/helper-validator-identifier": "^7.24.7", "chalk": "^2.4.2", "js-tokens": "^4.0.0", "picocolors": "^1.0.0" @@ -64,8 +67,9 @@ }, "node_modules/@babel/highlight/node_modules/ansi-styles": { "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, - "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -75,8 +79,9 @@ }, "node_modules/@babel/highlight/node_modules/chalk": { "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, - "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -88,37 +93,42 @@ }, "node_modules/@babel/highlight/node_modules/color-convert": { "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, - "license": "MIT", "dependencies": { "color-name": "1.1.3" } }, "node_modules/@babel/highlight/node_modules/color-name": { "version": "1.1.3", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, - "license": "MIT", "engines": { "node": ">=0.8.0" } }, "node_modules/@babel/highlight/node_modules/has-flag": { "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, - "license": "MIT", "engines": { "node": ">=4" } }, "node_modules/@babel/highlight/node_modules/supports-color": { "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, - "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -678,6 +688,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "dev": true, @@ -725,6 +744,19 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, "node_modules/argparse": { "version": "2.0.1", "dev": true, @@ -767,6 +799,18 @@ "dev": true, "license": "MIT" }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "dev": true, @@ -788,6 +832,12 @@ "node": ">=8" } }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "dev": true, @@ -840,6 +890,42 @@ "dev": true, "license": "MIT" }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/clean-stack": { "version": "2.2.0", "dev": true, @@ -939,11 +1025,12 @@ } }, "node_modules/debug": { - "version": "4.3.4", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, - "license": "MIT", "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -998,6 +1085,15 @@ "node": ">=6" } }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "dev": true, @@ -1493,6 +1589,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, "node_modules/flat-cache": { "version": "3.2.0", "dev": true, @@ -1516,6 +1621,20 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "dev": true, @@ -1688,6 +1807,15 @@ "node": ">= 0.4" } }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, "node_modules/hosted-git-info": { "version": "4.1.0", "dev": true, @@ -1804,6 +1932,18 @@ "dev": true, "license": "MIT" }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/is-core-module": { "version": "2.13.1", "dev": true, @@ -1886,6 +2026,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/isexe": { "version": "2.0.0", "dev": true, @@ -1900,8 +2052,9 @@ }, "node_modules/js-tokens": { "version": "4.0.0", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true }, "node_modules/js-yaml": { "version": "4.1.0", @@ -2007,6 +2160,22 @@ "dev": true, "license": "MIT" }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/lru-cache": { "version": "6.0.0", "dev": true, @@ -2143,10 +2312,131 @@ "node": ">= 6" } }, - "node_modules/ms": { - "version": "2.1.2", + "node_modules/mocha": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-10.7.3.tgz", + "integrity": "sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==", "dev": true, - "license": "MIT" + "dependencies": { + "ansi-colors": "^4.1.3", + "browser-stdout": "^1.3.1", + "chokidar": "^3.5.3", + "debug": "^4.3.5", + "diff": "^5.2.0", + "escape-string-regexp": "^4.0.0", + "find-up": "^5.0.0", + "glob": "^8.1.0", + "he": "^1.2.0", + "js-yaml": "^4.1.0", + "log-symbols": "^4.1.0", + "minimatch": "^5.1.6", + "ms": "^2.1.3", + "serialize-javascript": "^6.0.2", + "strip-json-comments": "^3.1.1", + "supports-color": "^8.1.1", + "workerpool": "^6.5.1", + "yargs": "^16.2.0", + "yargs-parser": "^20.2.9", + "yargs-unparser": "^2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha.js" + }, + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/mocha/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/mocha/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mocha/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/mocha/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/mocha/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true }, "node_modules/mute-stream": { "version": "0.0.8", @@ -2185,6 +2475,15 @@ "node": ">=10" } }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/nostr-tools": { "version": "2.7.2", "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.7.2.tgz", @@ -2411,9 +2710,10 @@ } }, "node_modules/picocolors": { - "version": "1.0.0", - "dev": true, - "license": "ISC" + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", + "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", + "dev": true }, "node_modules/picomatch": { "version": "2.3.1", @@ -2494,6 +2794,15 @@ "node": ">=8" } }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, "node_modules/read-pkg": { "version": "5.2.0", "dev": true, @@ -2625,6 +2934,18 @@ "node": ">= 6" } }, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, "node_modules/redent": { "version": "3.0.0", "dev": true, @@ -2794,6 +3115,15 @@ "node": ">=10" } }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "dev": true, @@ -3175,6 +3505,12 @@ "node": ">= 8" } }, + "node_modules/workerpool": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.5.1.tgz", + "integrity": "sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==", + "dev": true + }, "node_modules/wrap-ansi": { "version": "7.0.0", "dev": true, @@ -3266,6 +3602,54 @@ "node": ">=10" } }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs-unparser/node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/yargs/node_modules/yargs-parser": { "version": "21.1.1", "dev": true, @@ -3425,6 +3809,7 @@ }, "devDependencies": { "gts": "^5.0.1", + "mocha": "^10.7.3", "tsc-multi": "^1.1.0", "typescript": "~5.1.6" } diff --git a/packages/app/tsconfig.json b/packages/app/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/app/tsconfig.json +++ b/packages/app/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/content/tsconfig.json b/packages/content/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/content/tsconfig.json +++ b/packages/content/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/dvm/tsconfig.json b/packages/dvm/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/dvm/tsconfig.json +++ b/packages/dvm/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/feeds/tsconfig.json b/packages/feeds/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/feeds/tsconfig.json +++ b/packages/feeds/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/lib/src/Emitter.ts b/packages/lib/src/Emitter.ts index 925536a..64470fe 100644 --- a/packages/lib/src/Emitter.ts +++ b/packages/lib/src/Emitter.ts @@ -1,7 +1,7 @@ import {EventEmitter} from 'events' export class Emitter extends EventEmitter { - emit(type: string | number, ...args: any[]) { + emit(type: string, ...args: any[]) { const a = super.emit(type, ...args) const b = super.emit('*', type, ...args) diff --git a/packages/lib/src/Worker.ts b/packages/lib/src/Worker.ts index 81c705d..c0a62f0 100644 --- a/packages/lib/src/Worker.ts +++ b/packages/lib/src/Worker.ts @@ -44,7 +44,7 @@ export class Worker { #enqueueWork = () => { if (!this.timeout && this.buffer.length > 0) { - this.timeout = setTimeout(this.#doWork, 50) + this.timeout = setTimeout(this.#doWork, 50) as unknown as number } } diff --git a/packages/lib/tsconfig.json b/packages/lib/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/lib/tsconfig.json +++ b/packages/lib/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/net/package.json b/packages/net/package.json index e38b694..51e8485 100644 --- a/packages/net/package.json +++ b/packages/net/package.json @@ -23,10 +23,12 @@ "pub": "npm run lint && npm run build && npm publish", "build": "gts clean && tsc-multi", "lint": "gts lint", - "fix": "gts fix" + "fix": "gts fix", + "test": "mocha" }, "devDependencies": { "gts": "^5.0.1", + "mocha": "^10.7.3", "tsc-multi": "^1.1.0", "typescript": "~5.1.6" }, diff --git a/packages/net/src/Executor.ts b/packages/net/src/Executor.ts index ae08936..1ed0d21 100644 --- a/packages/net/src/Executor.ts +++ b/packages/net/src/Executor.ts @@ -3,6 +3,7 @@ import type {Emitter} from '@welshman/lib' import type {SignedEvent, Filter} from '@welshman/util' import type {Message} from './Socket' import type {Connection} from './Connection' +import {Negentropy, NegentropyStorageVector} from './Negentropy' export type Target = Emitter & { connections: Connection[] @@ -12,10 +13,13 @@ export type Target = Emitter & { type EventCallback = (url: string, event: SignedEvent) => void type EoseCallback = (url: string) => void +type CloseCallback = () => void type OkCallback = (url: string, id: string, ...extra: any[]) => void type ErrorCallback = (url: string, id: string, ...extra: any[]) => void +type DiffMessageCallback = (url: string, {have, need}: {have: string[], need: string[]}) => void type SubscribeOpts = {onEvent?: EventCallback, onEose?: EoseCallback} type PublishOpts = {verb?: string, onOk?: OkCallback, onError?: ErrorCallback} +type DiffOpts = {onError?: ErrorCallback, onMessage?: DiffMessageCallback, onClose?: CloseCallback} const createSubId = (prefix: string) => [prefix, Math.random().toString().slice(2, 10)].join('-') @@ -50,11 +54,11 @@ export class Executor { return { unsubscribe: () => { - if (!closed) { - this.target.send("CLOSE", id) - this.target.off('EVENT', eventListener) - this.target.off('EOSE', eoseListener) - } + if (closed) return + + this.target.send("CLOSE", id) + this.target.off('EVENT', eventListener) + this.target.off('EOSE', eoseListener) closed = true }, @@ -86,5 +90,60 @@ export class Executor { } } } -} + diff(filter: Filter, events: SignedEvent[], {onMessage, onError, onClose}: DiffOpts = {}) { + let closed = false + + const id = createSubId('NEG') + const storage = new NegentropyStorageVector() + const neg = new Negentropy(storage, 50_000) + + for (const event of events) { + storage.insert(event.created_at, event.id) + } + + storage.seal() + + const msgListener = async (url: string, negid: string, msg: string) => { + if (negid === id) { + const [newMsg, have, need] = await neg.reconcile(msg) + + onMessage?.(url, {have, need}) + + if (newMsg) { + this.target.send('NEG-MSG', id, newMsg) + } else { + close() + } + } + } + + const errListener = (url: string, negid: string, msg: string) => { + if (negid === id) { + onError?.(url, msg) + } + } + + const close = () => { + if (closed) return + + this.target.send('NEG-CLOSE', id) + this.target.off('NEG-MSG', msgListener) + this.target.off('NEG-ERR', errListener) + + closed = true + onClose?.() + } + + this.target.on('NEG-MSG', msgListener) + this.target.on('NEG-ERR', errListener) + + neg.initiate().then((msg: string) => { + this.target.send("NEG-OPEN", id, filter, msg) + }) + + return { + unsubscribe: close, + } + } +} diff --git a/packages/net/src/Subscribe.ts b/packages/net/src/Subscribe.ts index a23e44a..9074ec8 100644 --- a/packages/net/src/Subscribe.ts +++ b/packages/net/src/Subscribe.ts @@ -326,7 +326,9 @@ export const executeSubscriptionBatched = (() => { return (sub: Subscription) => { subs.push(sub) - timeouts.push(setTimeout(executeAll, Math.max(16, sub.request.delay!))) + timeouts.push( + setTimeout(executeAll, Math.max(16, sub.request.delay!)) as unknown as number + ) } })() diff --git a/packages/net/src/index.ts b/packages/net/src/index.ts index a605350..a1016c7 100644 --- a/packages/net/src/index.ts +++ b/packages/net/src/index.ts @@ -7,6 +7,7 @@ export * from "./Publish" export * from "./Socket" export * from "./Subscribe" export * from "./Tracker" +export * from "./target/Echo" export * from "./target/Multi" export * from "./target/Plex" export * from "./target/Relay" diff --git a/packages/net/src/target/Echo.ts b/packages/net/src/target/Echo.ts new file mode 100644 index 0000000..4a68c42 --- /dev/null +++ b/packages/net/src/target/Echo.ts @@ -0,0 +1,16 @@ +import {Emitter} from '@welshman/lib' +import type {Message} from '../Socket' + +export class Echo extends Emitter { + get connections() { + return [] + } + + send(...payload: Message) { + this.emit(...payload) + } + + cleanup = () => { + this.removeAllListeners() + } +} diff --git a/packages/net/test/Executor.test.cjs b/packages/net/test/Executor.test.cjs new file mode 100644 index 0000000..1e8ad1e --- /dev/null +++ b/packages/net/test/Executor.test.cjs @@ -0,0 +1,37 @@ +const assert = require('assert') +const {setContext} = require('@welshman/lib') +const {Executor, Echo, getDefaultNetContext} = require('@welshman/net') + +const event = { + "content": "👀", + "created_at":1727389659, + "id": "acaee505278bd8842ab6df906bf39bb143cf9905f36453c9bc13554cf5006e2d", + "kind": 1, + "pubkey": "6e468422dfb74a5738702a8823b9b28168abab8655faacb6853cd0ee15deee93", + "sig": "3aa512e2dbcd704bd287e6a35eaa8c4388606d553d385e482cc94d536eea25585731c36da6658c941c4668a473860a12d75ba588ca50470df09f8827e164e640", + "tags": [ + ["p","460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"], + ["e","d423aa132e5dc741ddecbac5e67515b6fd900c2559058397ec7fd860b3d77ea6","wss://nostr.mom","root"] + ] +} + +setContext({net: getDefaultNetContext()}) + +describe('myFunction', () => { + const target = new Echo() + const executor = new Executor(target) + + it('should return the correct result', done => { + const messages = [] + const neg = executor.diff({kinds: [1]}, [event], {}) + + target.on('*', (...message) => messages.push(message)) + + setTimeout(() => { + neg.unsubscribe() + assert.equal(messages[0][0], 'NEG-OPEN') + assert.equal(messages[1][0], 'NEG-CLOSE') + done() + }, 10) + }) +}) diff --git a/packages/net/tsconfig.json b/packages/net/tsconfig.json index 13631ba..669c5f4 100644 --- a/packages/net/tsconfig.json +++ b/packages/net/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/signer/tsconfig.json b/packages/signer/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/signer/tsconfig.json +++ b/packages/signer/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/store/tsconfig.json b/packages/store/tsconfig.json index 15d351a..8defcdc 100644 --- a/packages/store/tsconfig.json +++ b/packages/store/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom", "dom.iterable"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] } diff --git a/packages/util/tsconfig.json b/packages/util/tsconfig.json index 13631ba..669c5f4 100644 --- a/packages/util/tsconfig.json +++ b/packages/util/tsconfig.json @@ -7,5 +7,5 @@ "skipLibCheck": true, "lib": ["esnext", "dom"] }, - "include": ["**/*.ts"] + "include": ["src/**/*.ts"] }