{"_id":"@proximaone/stream-client-js","_rev":"46-b1082ab0eceb20191e694bba5c1005c2","name":"@proximaone/stream-client-js","dist-tags":{"latest":"1.3.1","preview":"1.3.1-preview.50.0"},"versions":{"0.1.1":{"name":"@proximaone/stream-client-js","version":"0.1.1","description":"## Installation","main":"dist/index.js","scripts":{"prepack":"yarn build","build":"yarn clean && yarn compile && yarn copy-content-files","clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo","copy-content-files":"copyfiles -u 1 src/**/*.proto dist/ && copyfiles -u 1 src/**/*.js dist/","compile":"tsc --build","push":"buf push ./src/proto","lint":"yarn run eslint","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"author":{"name":"proxima.one"},"license":"MIT","devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.4.0","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.1.1","dist":{"shasum":"3d6e24b25cc550ed10b1187f17e76de03efc9b1f","integrity":"sha512-amq04qZyjoPYwT07HpEHGQ/6AXHyaf7iWyseRBlYWWq+bdSIn8SonhVUQF2TrpzOrDOhc6IYPw126efC1SbAog==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.1.1.tgz","fileCount":37,"unpackedSize":1765070,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhxHjuCRA9TVsSAnZWagAA+TwP/Agq/4rcBYLTfKPHxAFP\nPs4WI01YxtyMsemB762Z7ozYBeSgDkllptx0fEmjI9hCN+cSyedKX7INzxhC\n/e640wrNoqAp68j/MJTC/m39sj1THXsDnphGHGKRJwEjNXKWP0mrN+D+EJrb\nB0dQpy014CZAKZ1MywMQHcxpDb8Hbo4jwIk3tWiU3r/I0XXVWMoWIbdF6F5A\nvSLIS4HxALJRhrtkodvvqxt3q/O97M3LNNrywofiFMVRvBfk3nTvMU1sdaLd\ntbDTXMA6jBu71Nj6BugCVJR75KACoApB265weNsAbhdui46hetarbhOxXdil\n9OZBcSPbrpx3S0H1jkpI9ygu7hzvi0kTwfVD+vux/ODx+E6wpGw7+YQ2V8+y\nvVut9cHo84LB47CK+eWiUqZ0quQ2DYwPBPN7wa7AAxVtEaf9G0CXAvyk/mt8\nUNBagOpx/WHCLfA17Yz3p7hIuzGCbji4/c/mzdpjn8LouLExkEoPWnOUaQVA\nmavzVror9OHust1GjDKM6gPVWLGzr/bfp5b252Y7Tua36vCG1WdTdsLT1RDB\nLfAY6ZWjkIJlP8D/VK9uTWG9elPvYlF+T58uuxF89M3hybKnHpUUaP+irXJ4\niqiDlMmT52p188o8s0U94tg7bHTNRymaePjBILgq9Cl/yHLZijfEr8ObZseR\njeAe\r\n=F47T\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDAZ/gv65L3QwTuCEmk3zyS4Lak6CZHOFgjAlDSstgRyAIhAKdvgN5zNxwlaPysHpH+9rwHsGlkDLUnGthBh/5jiEP0"}]},"_npmUser":{"name":"chasesmith","email":"chasesmith@berkeley.edu"},"directories":{},"maintainers":[{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.1.1_1640265966107_0.42090181136174776"},"_hasShrinkwrap":false},"0.1.2":{"name":"@proximaone/stream-client-js","version":"0.1.2","description":"## Installation","main":"dist/index.js","scripts":{"prepack":"yarn build","build":"yarn clean && yarn compile && yarn copy-content-files","clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo","copy-content-files":"copyfiles -u 1 src/**/*.proto dist/ && copyfiles -u 1 src/**/*.js dist/","compile":"tsc --build","push":"buf push ./src/proto","lint":"yarn run eslint","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"author":{"name":"proxima.one"},"license":"MIT","devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.4.0","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.1.2","dist":{"shasum":"39a713dee427aaf1a9a90053de92da2dcffacb10","integrity":"sha512-1080KC8tS/FzvN03lBdlNfCi84Yob4PwuqeRjXssqC1tVNyMZkVYYsZnkhi4o0IoEqB8xml0c8fpJ1FM68XiFQ==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.1.2.tgz","fileCount":37,"unpackedSize":1766621,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhxIE+CRA9TVsSAnZWagAAtg8P/1S6IqRNi/pxpxlhNDur\nSTsaFhCMXmToQ5NxSOOCzJFk0tVIPNDKk6zUJOPPsdqjFnpZkb/LyPPFSwhU\nCVVuWN4bG6S7biDhsw4qh061B3EL1bfxtXQArWbhZqjyoiTkd3ajyLAN4UDS\ns7/YEJBgb3miuHUqjPfDaXQpQVFVzJZ/TaNr+etbzXd1NwAt+GXE411zj74n\nrJC+Mlobdf0fB20xMOmt59r8bAXmwzY6REfPqhEo7mjJh7qC6rQpNwuU1C9G\nR1wDnx/mRenMhM1+pczdgZTbZ3vHQH0Vi2lIKQUkqbQfoxkFAX5har5Sm6pr\nPkrzYVoREEoOneotPFDxk/OmudBy+Qm8ewxtVp8w7IT92KX9qqIhJjVkDvph\n8E0uITGKW3AzeWWlQShdBw6JDBVTTt8wo+IDJF1ecmZ5dF9EN7LuTT9IaFLi\nyWyBaWIdB/fEe1rphCDC7HPdo8RBbUC8zSFgkYnAKFROUEMD7GgNPryMrhpg\nFDwAmEAYM5WWNBwWFVsCKGhANn0AcHxq/VnnI7TAxgJyZwVvoaG+FkJUJgsk\ndCVW0XlWfn3+arvX8zxTa4UIc6iO8PvkSmo4wEaG99gtiY3bhnTwtd/ELXdu\n10ovq8Z3/7UYBFb9zWYxudP4hWcuGat8q+U74vWzJ4auOfTgbNS9utCd3w+l\n61fl\r\n=Zl/F\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCoUjHPU4dF4HJPjXtOk6VW2VCYYw1w65ZSeaVGmSOIZAIhAMEm4PQokXhdS+EsRi19Ys2W57OpvHVCH70F8fLRSb+9"}]},"_npmUser":{"name":"chasesmith","email":"chasesmith@berkeley.edu"},"directories":{},"maintainers":[{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.1.2_1640268094810_0.43618760595691675"},"_hasShrinkwrap":false},"0.2.0":{"name":"@proximaone/stream-client-js","version":"0.2.0","description":"## Installation","main":"dist/index.js","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.proto dist/ && copyfiles -u 1 src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"author":{"name":"proxima.one"},"license":"MIT","devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","prettier":"^2.5.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.2.0","dist":{"shasum":"052722a54d3784817aca4c5ffefc6fe3fad2fc60","integrity":"sha512-OaluYEfain7/3Bun6DQ/C9JE3Au1ry9TJzQGCbIZ4xUYQ45ZfbwzoSj3xe8uuEQxM3TWp87AW8P9Vc7a8ApyAw==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.2.0.tgz","fileCount":36,"unpackedSize":104049,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5YRLCRA9TVsSAnZWagAAcJYQAJKNqNd4LN+Cm2yzbedG\nYlWuKTfN4jqWp++9aFgKoZhMELp8sjPWlD0YA6DsvNe18Y2SvpQiyRfBJpfU\nkjAM0TPMgFJHLshKxS1xOe0HZC/zO7uuUcxqpfcnGUgEMZxHYe+sJ7ZhjGZx\no+IAcfDqiln+24u+wdUPZzPYB5AwmsgxwsYV79/k7cOs1yVwJ2pwsJ/jOsRC\n4/DVuPHwbd2yvWTP7Kshy8Xxcg30/Dpeh8h7SBeSdMttYyvquipa8JYcrYxU\nM6FU6WXswiBJ0jmq3liU7SpPcZgJC4NsWvPPH2wmc1BPg+Trc8bTdiiaZICu\nsUp9Q0kU5HvJKCoyqoq3IW+QbYITsMHC772TjaX7kEdpX082k5mAPOFd6lDA\nveYZ71N82lufZDt1FCWXAoCV2RRBJMm6tUd7cDtS2cSYE5UKGCgvgw15fdcC\ncERTt7q1yQ/IHS1gb+5PUtWnKNwih5apBTnos/RmgACyw+a0DXBoDqgR0UJS\ngcl6ZiF8wOEbiIHbAb8VZd92AqtbUmq+uXhVtnQ8i7nPT0goa6t3RZoAWtLE\nsAuwsxkIy2dAlEJxeigRJvX4YyhebOQo2fiZF+6IkWyQHsh8pd7NX66UVLLy\nOpA6J/JfXoezO+APd0NsjdrKvoi0TBVVwFyfos88TOE4QW7DIURU0ixTT1Xg\nLvlI\r\n=ssSW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHSKQpiUqo53q+LUyCU37rI0wh6b0rpvtHBV3WrdJPaGAiBkbpQG7OMXIkcUrD24GtgaM7D3PZO98YwMahzshfjgSw=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.2.0_1642431563527_0.7313111770847893"},"_hasShrinkwrap":false},"0.2.1":{"name":"@proximaone/stream-client-js","version":"0.2.1","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.proto dist/ && copyfiles -u 1 src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.2.1","dist":{"shasum":"1e8c0da9f506f60c871f77f623e6fd08fe04cbf7","integrity":"sha512-3ro9WcwHZnhO7qvFDtk+FvfvYGRTfAOL5Lz9IW8hbzkYdR0f7ihyJ/23x197DRDM1udweZW7fz4/xrxqtdM7uA==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.2.1.tgz","fileCount":27,"unpackedSize":127394,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5YcqCRA9TVsSAnZWagAARZwP/3JhLhl4lGhLdiyF4Wtz\nIQMvj/VM9/y8Gha2sZD+nlqsk7zKgRznT8mLh5fSPIew+1/0/xpXoY8+duUa\nJFzFDMKlH2i7IVU55gAyf66xvJ5HEdUkAproIqM5It6uzBSijJG0eDiE3lzX\nhiWKAzyYBdrj6lD+5BP7idpwupErs3zHxiAoBKVZ7IkFC3+7C3TUD4BjczYR\n8gGg31NiX3Jp7jWxbm1Jnku+5LYu7XJaxuFOVVwsqVL/M5GTwraYkVmL+qka\nnWQSsmiJVcpCMD60VxK6JWFTajePgbVChWnQ87oDJMzOzDLh1Rypy2848b3x\nFC4YI0l1XmcGN+1MPJM5Q1b0b+ZjmEmgHShYAnCUq+jeZryVBFdjTNMRoC1x\n6rO3Sa4/br6m0YSV7OWApMD/pgvmIzWVdaOJH6ZlsvWa2hrJD9tiZdmBIL6c\nTjOVdDeQB6mjTT7KC6hCf1KLP4wrJa2Jw2vQsHq1V3WfBZS0M0B+M+ZkUoYl\nOd7EII7w/u9730H8J9kGNufkpZsYk8kqRKOS3dIupUORFZmLPsTlixDUtjZO\nGXPyV5nyaNZkhDyhs8SwwtlXBo72IQySr102adGfVBfcb4poBCHVu0g5LIOQ\nMxxDbcdoNAW3mYUO6Oc25wrK2F31XnRVG0gV+1PF+/T8iDUNt/FW/o6BFqCs\nQiLz\r\n=L6tz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFl4myEXX5xvvrSYcWp5514Ag3mNFPwRykB64cgnvPoPAiARLgsz8k+NFI/QuRzC9XIgdjEaEzpcdCb6oiNMQGZ1/w=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.2.1_1642432298506_0.6005869521649159"},"_hasShrinkwrap":false},"0.2.2":{"name":"@proximaone/stream-client-js","version":"0.2.2","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.2.2","dist":{"shasum":"5b059b034cfba62875a05ed3dcb6b695b88fee72","integrity":"sha512-At9BHNuV+upfGFKhcwdoLGvHEFkZ7wAtGq34o6HWnc+8qhy2NMDyR90yzJ1R06wwfK38nvB9LfVh+h7kFqHt4Q==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.2.2.tgz","fileCount":29,"unpackedSize":86049,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5Yk/CRA9TVsSAnZWagAAdy4P/3gTR0nXjMlraMYcNIlH\ntVvsXsw1PXs5vevADmTsjAsHnYYbpjc7Q/Jv0w3feOzujJuYuEbxgspDb86l\nAV/sj6LdoNgUmUjTY2aJgwT49HjjHBUkWl3HY98Px5XN9zyEV3spFH0WHEZW\nvkpu2IH3pgjBkYxVF57DFqnW4hOQbC/lMCp729srIDMEqplXz1B6qG1yEfO+\nKXdTrnXOIPBKeWdpmI0oOsKQffJJUFFChHo5OOhJBgvURUFVB0LfsxSTXcFz\nbNHUy8lwu1YclixNsV85sjVLdOGH6A65eIlmCFZjj3Ak05ZGpmf9O6HEqGzv\nBjRYFE+TOIilfYcD2izc4M27yiMP8Ree8+vNkPXSWFaC0G3jWkDpDhHUvbvK\n9LAcDY3SoL9FBi8Rc8kVDZ+OByFI0EL5Eir3GMpuehN9uHyxIiY3l1GtAdBI\nM4K56aihnfuMMfcbKD8qVWaVyMymgHRrZyMhZcYhr27IuPWT+mPeuSUNHbqc\nK+IJQrc2KAyNW8AaSaUzRDZjHnxZoYTKYq205eodsAq9Jwm5fA0TYKkb14AP\nhBdT/qEKNh0psJOltpT1Ud2PmU7oSWXGLYaqcv0M4C8R/tziBHOGaGs5KKWX\nPLoVkQtVy01oSSaX0ZvtAzlZes4Kk+vnP/Bqm/BTr/wj03e/O6iBk264wwqR\nIMyl\r\n=8Sm0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGnbOdUQgNXb3MaRh6MQzDt/phWq4jMRgL1q/BPzrD7kAiBryAKF2XUDEf0p0edyh+FlnQfwQUn0g7cu/LMPeOiriA=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.2.2_1642432831305_0.7120642559021217"},"_hasShrinkwrap":false},"0.3.0":{"name":"@proximaone/stream-client-js","version":"0.3.0","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","debug":"^4.3.2","dotenv":"^10.0.0","google-protobuf":"^3.19.0","grpc":"^1.24.11","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.3.0","dist":{"shasum":"bcc692c1796912404a86aca5d8b381dd295aa524","integrity":"sha512-o0pkFutSG4XY+6N5elTf5vZ1KEm5wX0G1wZU983z2kuKSvhK8krRm5qug2HujTWXZ6v2laSwk2F7sFh8XaOOIg==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.3.0.tgz","fileCount":29,"unpackedSize":86390,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh7984CRA9TVsSAnZWagAAyTQP/3vg5XB32elQKTXxWaML\nTbFoLsJ3FsAo7WznYbr/kNe59GxZrgJk0QPJre0zLTENbyxiJYJ2QvRGpInG\nrYm9dGAViXyNQU0wyiVW/G6OAniaH3BmO3fnC1xA0Hk4AnHcXC0Xz3FdcPkV\ndO5NrU2W/NEVl+PrSpUpzHdwuX4cqhnj2uCuM8Hri2sZHvIyAT0pe1TDmxur\nucLyOraFqTEKB1EJRxOmJbtpveouAElx6kcWQzTl7+zOarfrJsQlbFDrHONv\n8lYk+pc1W5r8IQxaA3rnpPl9bzixUVZ15neEkNkqoGEYdAnnz6Aei9zr+Gn9\nzpf2/vj38MlwGG99DLqP0qKUErLVSK/Ox8uMqH4kQachJ30CzUO4uL+j9Ts8\n8qc0C/dknzOyMci84UgdF8OL6TSfUNEYqMdctjInHfw3egKn3oTwr4gPHW+I\nlaBU7MXG+X0QzFGYvE8KFizs8xqCJEVa5K7vLRWsHZ+pzM+P2le18cxPSrgf\ngrOd5EV4JQzwKJa0MI1Yr24XKiNtoLgPnubtGJc+OafOuVXFSHTgeuZTnmxI\nGPdhJtdqtaou/3h4KloyyqixJFR6K7IFSY1AGGGhUo1rZt3RUGztDx26PbJS\nQ433SG1OPpr1NHFhkYGCyB50WYdMH6AaewYiM4f6PVx8U79H3V7uP6tHsOXQ\nSqY5\r\n=Ehqg\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC8kbqZAX3cR/+10N6gyICqd2WgQQ8ZVkfO2elOZaC9AAiAkz0dowLvN4lIvmyW5tu8vana2/A7sSvaUYK//vg82vw=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.3.0_1643110200339_0.402064809692378"},"_hasShrinkwrap":false},"0.3.1":{"name":"@proximaone/stream-client-js","version":"0.3.1","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","google-protobuf":"^3.19.0","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.3.1","dist":{"shasum":"53a05023df363b7f36d9b45340157249fa1b5480","integrity":"sha512-iMTPBbjmE9DegkqUcG1V8TGBgqDT34tl491X5v7OYgs4oza+1jZwfq/lH+EGFg1BWPgHrYD5+QJgYsnmYHkYww==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.3.1.tgz","fileCount":29,"unpackedSize":86317,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh++yyCRA9TVsSAnZWagAA91oP/3WoHVvryWHuu/rYG405\nX4fjYm3tAYSS362i62b6yJWxn3bhbCuO69qODFGnZecpWmJVknO1uJ+XZ4SN\nzJ6f5HoebEPSePyNxZTVvF0J3N6vGephQhtnWv6sobKaaDNsTS6oKTJf89ld\neDE29ec/8ffwMh6JApFdrx0YHYoy7p1Meux/p8rk4o59HlziGOtlU7i/efe4\nXSdCRaJnigu6bxfhpEV+3tZya8aaznAXlcdui+XnVYx6eiqAuLkkSuOJEoRe\nwD2OteLBV3FWo6KTSsuAIwHIwGMrbXKsz9QaOLM6pWfA+FBuKXlO+wkvG9bD\nXmZRW844tcm3H7SNT4RNNVhjrqwZSZ76p0Q7P8AMUcP1woSU6EOHdJsehVbJ\nQldrPxA+wJQNja1ZhxJConoeBsTlglDdoAbAVofCLUwfeZPkfYYKmk6sQ16M\ngdGyDeP3RioYHd4ZORZO21YAN8P0oX5MdeoCbeRghOUsIQmBB2gdDuJJ9n7V\n2ArDAfGgth2LWs/tP4gDk17No6nwEXMQf2vtXWmBuTMQHZFce2AvgwLMx+m/\noMyFblnN54fjjHDn3T/pFlFKItU9567k+lE8NBabThy2YQEcuymuJhOrn5/Z\nYTbKU/L9GTMHp9bf/qX4hUUwhJWbWR+/wRFufE4y+Njn0Pe6HHULscdk1dVP\nIiIR\r\n=ib35\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC4PMenI0s97jYclVdYgdQOls3AvdDFGhyKQ9gdSfTJlQIgZJtWW3X0MvBwwOM6nv92O65vJ2MWS7gzBcJWm5nTN2M="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.3.1_1643900081977_0.45257533754938284"},"_hasShrinkwrap":false},"0.4.0":{"name":"@proximaone/stream-client-js","version":"0.4.0","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","google-protobuf":"^3.19.0","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.4.0","dist":{"shasum":"a588d8f9ef14b613226371163b8ef99741aff62a","integrity":"sha512-TSQeTOUu8PS9en3K5pJj5lYh4lmnls0IbMosRJ/4cebP/giNEVWfFSLTu4RWeen5fPR5YqWPqk/YD+1ZYrmpKQ==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.4.0.tgz","fileCount":29,"unpackedSize":86517,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiEo84ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrKPA/8Dpc1Xp5hTNaEFH1+/o1BQNsSfOgtSo5RnsLkHJp+aCmmhUPh\r\nn32gvoOvBPQa53GpBFftLwL2543GaH/pHmWYLsDs05n2H2mTPNhejNt8EvPf\r\nKIszMCiZbAC/XlV/Moe+9vYxlBUyshox+Si1NLcMZKoPWxgG/cvvtM+I0SPM\r\nkXNSsd9rTrFKv2nYAbFFyACRAeqQbT1In14i93cIxJ4E/UKs4UF1tDJyJQk3\r\n3yxmL6qzJAqkFZ1eU+7f06ZPwvaTN7bMlyVWVFB6NjsSEOmxb0iL9ViKE3Hr\r\nTgFiuDPjU5jZ67ntzlQh60rkHYDLB40dJ8S+BZUcSgw/2toUD3NS20c3fq8U\r\n+oFFsw/5TmIy2LeZZGRU7L3EDYPNHbRJu6OQwr9f3ABCclMruIjOjKXw+fph\r\nHg8nNyDmo5wrdqoVEXQwOTr1FXLhMAteuXvdLKz9F+/2tQv8WxUQMWX2BIjS\r\nDQTlokkLMJsVzvPpD+ZXN5fAct2NKmnhuEPOOLv1Sd5+jTRqkSGW2dlW1Aef\r\nhgYWf2b99kLtJ1fmBZEno3LrJMI6HTm3X0C3M3/cHwXctupNN2qgL7eMn8Ck\r\nYYB3bXSHFSn0syVS+Xh9S5pVe80URYOaF+CMeR++7HWHtfpZvrDNnyZAOgAO\r\nvLAU2cSL1nFp/xRma2OqPXLpTnMZd1FZCzA=\r\n=ggtW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID1dFLNHul80BFAIHI4hYtF93QrNTbzX7GtA4WeT3lgRAiA9EWffEmXdnRG5K/H1qDC2A+EbuA3ye/Q5PNltlaA/iQ=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.4.0_1645383480216_0.5236344135125588"},"_hasShrinkwrap":false},"0.5.0":{"name":"@proximaone/stream-client-js","version":"0.5.0","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","dev":"ts-node ./src/dev.ts","prepublishOnly":"yarn build","push":"buf push ./src/proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","jest":"^27.3.1","js-yaml":"^4.1.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.4.2","google-protobuf":"^3.19.0","rxjs":"^7.1.0"},"_id":"@proximaone/stream-client-js@0.5.0","dist":{"shasum":"0a638831f18999701eb60271b31716d48564d515","integrity":"sha512-VHDowCOFjoHUfBUr0RA/zEypMN6o3ajG9yK0tHenR/ar4FgPRr0nGYZ1T9SHNQiEzfMmazlREN3mHTvZacvVYg==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.5.0.tgz","fileCount":37,"unpackedSize":92966,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiQZa4ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpQyw/+KzIiwPv+beiSkTsHA4qB8WyeJFNRZKX5eNNs9HkCmYGqkezD\r\nzvJcCAvHERK1M65VXOnM11aZaKqhg+SVjRKzeJQ7JyNUms20Afwknr1QogVy\r\nkNRPkpEZVWbDwNPNwYKYVOkLA5XEm/h1fCiwUCXh2tFf/21RGDMLpwRMf9vr\r\nMGdRayESbLFh3QfF2gH04njV4cWdGLNpbIzhskpCNPJN1gTsDaJkWxiNoIMu\r\ntzo7jVTpZ8+PU5V8G3rVstqhaiwZAsUbKmuXibNMO3riYnQdc5Qg5Tzvbe8P\r\nWayMLBhdvkIItWqAIZgllmlRJXlTfThScATw+eMpcA01IiAFCCoDQ8I1N0BG\r\nR45yzCKPaTOpRdz9pSrTlVRP5SXwFVADRAd1tiTj6SD2m+Km2NaDTAezn00r\r\nORZH5P8REDbblBrtMq9CUdv7dZT7wJQYqoQgNCZ3wmh2chPJhUwd5dkh/8MJ\r\nEYfb6uZOMJDVsx6+tvdFPqn5KCHqELPU/Gp0MCMz7kaq8+j/OL10q0N+ikwm\r\n/NqpWqCzL8NnGW6cyhyS9Z+pK1FMi/NFNByfSD8NypCfcKN6GptfBgX5Vfih\r\nkZWWh4EuJMfdrqhnMNbb/uat+nHFvTT9YIyt0XVJdhb5JY2vmYmnTqX57vh5\r\nXnYVLwl4T/w5ppJg27OlnN8KNx8jBzDAnrk=\r\n=RbhR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIH968VcgKOuHBagpns+kYXMNIdP1K/U4uhZfh/PMYmXfAiEA43cSlkPma3z74FFyHzcCyyJg44IKtbH7y/Vk0uuDZp4="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.5.0_1648465592033_0.21003876953532874"},"_hasShrinkwrap":false},"0.6.2":{"name":"@proximaone/stream-client-js","version":"0.6.2","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" \"!src/gen/**\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","dev":"ts-node ./src/dev.ts","prepublishOnly":"yarn build","push":"buf push ./proto","gen":"buf push ./proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"yarn publish"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","google-protobuf":"^3.20.0","rxjs":"^7.5.5"},"gitHead":"fe5e4560425eceb5c13842821b4f8d4a6b2a13f9","_id":"@proximaone/stream-client-js@0.6.2","_nodeVersion":"16.14.0","_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (darwin)","dist":{"integrity":"sha512-hstAN8+3ftYFp3u/xYmLEmwpYX16nVR2ZgQRV6TxwfsbUPV2pFK6UQxEz6rkCmRaO+cA/P6WCbZVZSoI3atAnQ==","shasum":"94ab0e75ddc2ebc05d87f510e1f9abda77b1f43b","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.6.2.tgz","fileCount":38,"unpackedSize":89379,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGwezFutsiUZydEq4PCbt6mdSwo/L+lFu2BtCu5nSWQTAiEAvb3bIr5mRvTZnDCQAXaCbdvCeVoVNp+7FzMwLwF35Sc="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiSKTfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo6XA//cxkJ5EG9FNn17ASSeeA2Mcj3cxklc8KW2+fhFmuwHZm1khtl\r\nSl2hHq3oWFLhzgAX8EObng/g/bWz5B0Ag8mEnBopvk6vbENN1grZ+loZHHZ5\r\nJhQaswTntBZteObkTI5Pf3JwP9y/CUfNX/W3RqOwyeX9kG4GVx7E3W2eLwEz\r\nTTSl5HF3W+KkSdN0kYxHiaD/eFfSxfGJmSx39SQy3BmFQSBdMtxC+ktiRu3V\r\noc1YAOkoA/DwyTPEHNopTusbvbulD2gy6dSsoUosuV1/GnRfvyJgKuIBNbkQ\r\nINQfeFnd0GBnjO7uxa1tsfKM6fpWhvwKSf1kL1sMTLc8qmNY0OBmAyH9G2e4\r\nIsQ9Tc7a6RPMj+4SYx7ugDa3LFQPvEdZvU1GKBg73HcGkBENvSEyg912bnQf\r\nNzo2SUZQV5iR9gptlhunn8fG/r22hWrLYrgl4BoT1bpsqQdXxw5KiH9F8XSh\r\ndmaX0BTHIvyPN9To6F6EGlUPr4iomjHFZMZuHprngaYup57gh74ZaZVfJO/Q\r\n/07ecjPW9MxW+ewBt5zlDvOSo/dJszG+fWsbEuSz1uHqV1DZ/4zWGTRKMXM8\r\n0Zcnzkhv/pdAj/6FSheatX2ZZs03nTt7pHmSBzwv2DgbT9g1V9WbB0uZYyVI\r\nfWcAglmoETCcnYusPLdIxR/yOD9XsHyaZqY=\r\n=msoG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.6.2_1648927966865_0.36723858219532346"},"_hasShrinkwrap":false},"0.7.0":{"name":"@proximaone/stream-client-js","version":"0.7.0","description":"Client to Proxima StreamDB","main":"dist/index.js","types":"dist/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf dist && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,test}/**/*.ts\" \"!src/gen/**\" --double-quote --trailing-comma es5","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js dist/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","dev":"ts-node ./src/dev.ts","prepublishOnly":"yarn build","push":"buf push ./proto","gen":"buf push ./proto","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \"test/.*\\.e2e\\.ts$\" --coverage --forceExit --runInBand","pub":"lerna publish --no-verify-access"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","google-protobuf":"^3.20.0","rxjs":"^7.5.5"},"gitHead":"0e4d90c31b9bce3a1495854dba3a62cacfe558ed","_id":"@proximaone/stream-client-js@0.7.0","_nodeVersion":"16.14.0","_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (darwin)","dist":{"integrity":"sha512-AA4mTq/InSG+o4Y2x2iNTNP6kEhh0z/xEW9h04hAZZtheKU1n2YprmAbJlQ0exlvniS7MtmfA0bLDrLVC2mKeA==","shasum":"40dd755145c292638af2334041c667e52758e4a0","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.7.0.tgz","fileCount":34,"unpackedSize":87469,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC4MhruNCnJUGmi9fHz8r1jAtOTd5AMWX3SMbSn44RYSgIga+o7r8LDUKVB8oA1CXJlS670oHmv1gy44B44Fr8HsKw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiSZIbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr8NhAAiaB77Xd+IDcy70pepMuV3S3KD+05m8t009B77VSIlCmNBnZS\r\ngiotwSbwLuTKA9hs29WnaRAb+6jNQXErVbTSC0XzD/tvadZlKTi0BZm8ACEY\r\n/g3MmGrjMMX/IcC7ba9ETekLVB41qRUaE+Nm8Elnlv5Zt0THJ8GmzFHoFv5n\r\niDhp7bGBAa/4hqwwgcqNEnVcXRVBV2gRvl6SNM54ZBXlQ+3RGiFUpHur/IUB\r\nXBiFp/6bUI/kyNWxDx3T8t85VfM/zripJWJ0g+i4LPSBKJJIOzpvRqNKAEBU\r\n7XmWYANYPOmjsISH05zGDTAcsoD5J34ANX7Ygli5kBelBY+ogcNuZflc8HlA\r\nfsWJXsDSQZJ2K6fplNt59SykJz07BTmLxlUQHC2Yq4riTBsskJFc4QjPmMQa\r\nqfU8fBuj11tz0gKj6B9NYb09hNaIeCd1/XaWB7wS59Yg/vh0V1d4frEtwc+C\r\nFVC/isJT1/0MSwDHfG7xvXbEC3vv7NVVa915mUwhRIh5IqW2kPiDGcwCHeKg\r\nyiHxtlepBjvMvN+6vc23jUE7HpddpPDcxNfhZH1c1URga4vX5q0KiaXrLQe4\r\n4ZVZvKcA/KGtJEOzJ0T1Bp7jCULd/Hk3A/KpJjdpgFHaqN9xXnqRuCdc4IF3\r\n+MhZk+T7MnoFBxCJbmJ7MvTErf3xJjxmebs=\r\n=tYlr\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.7.0_1648988699188_0.8338546335439889"},"_hasShrinkwrap":false},"0.4.1-preview.1.25":{"name":"@proximaone/stream-client-js","version":"0.4.1-preview.1.25","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","node-cache":"^5.1.2","rxjs":"^7.5.5"},"gitHead":"50973682d3b353623a652049d782a8d36976b38b","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/streamdb-client-js package \n```sh\nyarn add @proximaone/streamdb-client-js\n```\n\nInstall the dependencies and devDependencies.\n\n```sh\nyarn install\n```\n\n## Client Usage \n\nClient for StreamDB uses generated gRPC stubs to provide fast access to data. \n\n```typescript \n    const client = new StreamClient({});\n    const name = \"eth-main-blockheader0.new-runtime\"\n    const stream =  await client.getStream(name)\n    const height = stream.stats.start.height\n    const offset = await client.findOffset(name, {height: Number(height)})\n    console.log(`Consuming stream ${name} from offset ${offset}`)\n    const pausable = await client.streamEvents(name, offset) \n    pausable.observable.pipe(map(event => {\n            const e =  {\n              offset: event.offset,\n              payload: decodeJson(event.payload),\n              undo: event.undo,\n              timestamp: event.timestamp,\n            };\n            console.log(e)\n            return e\n    }))\n}\n\n  main().catch(err => console.error(err));\n```\n","readmeFilename":"README.md","_id":"@proximaone/stream-client-js@0.4.1-preview.1.25","_nodeVersion":"16.14.0","_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (darwin)","dist":{"integrity":"sha512-KM6be1+M0iFunKR47DYh7Cs2PUmUTsc9FTi+ahXwAg2Vivw9Y/6KVjYcxGFomVfcEMEPIMCeSdIxu4raVSBkUw==","shasum":"46697f8009851c84126bd2bba4841ac8b2a750c7","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-0.4.1-preview.1.25.tgz","fileCount":90,"unpackedSize":244562,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCR5ky8HeGY2tI/f+ZqBULQ1ApgrWrDZ7P1O3Nq5ZhZxQIgO0W0J9NieimVAmMUnLwlgwedNmgVZfbfQgeN1eHsY6A="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaokuACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoOJxAAjOVUnm1FSTPvpCfBLkPQti/z367pfxWPku7Er6+Zf2DFxAyN\r\nOGPlcbkq8YkNqjS2jj4BypEaNO6Bkq29jUiKH22ewSCU8EGmlUE8tssDhN4t\r\ncGsb1HeuCim4XiIPHMi9y2EIOrMiud4cslqq9NDLYIz5GkHkIuLawN9atTMT\r\npGo31b6k2ondnylV65MhdWXoJIDX6rOPcA9sS+ydDnm/COiZy2rDfCFYx41h\r\nzYDhI8hjlv53UrUb4djZ8GbujjzRwnXVJTuy1jqVh/r9m9/U3F6oYAGnRB3e\r\nAZigP04IF9YjeGV4UwKJAE+I1z5czPLfoavExfFEkKPLOPBkUOapoqlJ4LZF\r\nBxTj75/4JLRQpzR7NNrB4p9lCn0t0wjgudDfQ70Xeo1M60CvLjDwKUw2EtK4\r\nbmXFYxmqWyz8uOz35T3+iDb0AdDySPz7Y0D4Uk5vjukIn3wXvAjs7BxKnk8u\r\nV7wJXmsNsIhdZ9rEjTGc24Hw07hGyE2LMN+wvHKaFylENtxcrSQbmksWb5zX\r\nUhOumK/r1nt/eyJttlC7cD10/++05DIQnMR+46uTb9TXn57+5/n/S8SzdBQL\r\nvDdqXmDWvxk6DueVB/eOa0GnPreE+IVVYJtDFya5cFUsZigCAQK8Vr5JXzX1\r\nVyOFeBJEfgt1sB2gGcIEDTKK/dk29cIRKOA=\r\n=dPz3\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_0.4.1-preview.1.25_1667926318378_0.9368109785468905"},"_hasShrinkwrap":false},"1.0.0":{"name":"@proximaone/stream-client-js","version":"1.0.0","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","node-cache":"^5.1.2","rxjs":"^7.5.5"},"gitHead":"50973682d3b353623a652049d782a8d36976b38b","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/streamdb-client-js package \n```sh\nyarn add @proximaone/streamdb-client-js\n```\n\nInstall the dependencies and devDependencies.\n\n```sh\nyarn install\n```\n\n## Client Usage \n\nClient for StreamDB uses generated gRPC stubs to provide fast access to data. \n\n```typescript \n    const client = new StreamClient({});\n    const name = \"eth-main-blockheader0.new-runtime\"\n    const stream =  await client.getStream(name)\n    const height = stream.stats.start.height\n    const offset = await client.findOffset(name, {height: Number(height)})\n    console.log(`Consuming stream ${name} from offset ${offset}`)\n    const pausable = await client.streamEvents(name, offset) \n    pausable.observable.pipe(map(event => {\n            const e =  {\n              offset: event.offset,\n              payload: decodeJson(event.payload),\n              undo: event.undo,\n              timestamp: event.timestamp,\n            };\n            console.log(e)\n            return e\n    }))\n}\n\n  main().catch(err => console.error(err));\n```\n","readmeFilename":"README.md","_id":"@proximaone/stream-client-js@1.0.0","_nodeVersion":"16.14.0","_npmVersion":"lerna/4.0.0/node@v16.14.0+x64 (darwin)","dist":{"integrity":"sha512-YFpdw4P8ed+SX9GK8axqUzuDYcpptUGl/okgK6SbG/rZj/MsOVqUoywehRzXIKVfxDT7o318uvTZQb6oe2uAiA==","shasum":"12e7c0dd99de53ed897b8701cd6520e8c60d6810","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.0.0.tgz","fileCount":90,"unpackedSize":244541,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDMVtefuO2O0m9ec/njAbIk37rVVEuXIWiga7+o+MoR2gIgT3ANOw7otePHvZciwkblWdjGN5dKIgLih3UdXZ9OguA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjaomBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo41g//XXZ1xMzY2+0QDL18P+k+rdunOYD3WqIjxYaQX2wIsxXPuxgT\r\n65XRUIg5cCNsKwadKOM9/Wacez/iO1iu7cUOCsSBDLeKSEHS1QsFnhnkcGjh\r\nVYl8rbhV9q/yVO+I88/+pGNcAasPg1rwWTzcolUE8GnZtvONkX6F9tkCtCcg\r\nDMrUBXtzdrDNG4TL2dfjyJtfI7Yfh+t6aiw3z0E4mO1Eq8d4fOytF/7zrzEP\r\nP2XDoiKXqBzjLjyE2wXkmU8Mapv/6agXFB0PCTtZ4rXhACsth09728Ecw+CA\r\nA0Sh1xKC2cuQMifxrTKsBzh9xwZji28p9V0mHoi9NoM7w/Xi+GU+ZX3+jYee\r\n3Hnbein++9M/5pL0ySj8BcoU50hOviI4l82ZYvR6fIg+Vj6+3EfFzcjNLQ/R\r\nhnjedZyOuYHENK9M4nEVHdjEDrPLfSpLxQcrqh7j3lrJehBGOiG4WNXv2iGP\r\nKfKwabjuA7I5a1EB4RW4SgeLrTMm59uRnFuAgSeW4B1H83Y4Z5bk++bjbvy3\r\nrCwOQV3oUs4SVu9qqs4J/1R19mxCvWEqhl86PfGNiuvw7xKnxQ39zfv6F2rJ\r\nRV3yCpEpbKeBd6iD3pb20ZjPXhGFLylyV2VC8cUxGLps6cQ0nD/3MlG5LUvv\r\nCMa+kPzJbyYZZX8Lus0rChm0NegwUDABzT8=\r\n=yY7t\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.0.0_1667926401472_0.8741091205443705"},"_hasShrinkwrap":false},"1.0.1":{"name":"@proximaone/stream-client-js","version":"1.0.1","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","node-cache":"^5.1.2","rxjs":"^7.5.5"},"_id":"@proximaone/stream-client-js@1.0.1","dist":{"shasum":"b2c37342ac97eee48455b1d6c071582c169e9b65","integrity":"sha512-0aP57MCNtsw3xkA64HwsfgNCzp+XghpuSu0M6tiqJIOfo5lVwp0k8oOaHxJj29Z2n/qIYkVQrUeHqwgm60jZOg==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.0.1.tgz","fileCount":3,"unpackedSize":3166,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAizRFQ9AgVnCfbR5TclsLmTtvJ+CW1CO7+4JTCT01p4AiEAxJpOVo8TIQz2rTDJy+RNhn4CCXlEbf9YiHkMcE32yRI="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjdW3+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpOnhAAi9psVMaOY3P4GhsaIPmxdZxFQlhQeAImX1fiT/rCZzsKI6WV\r\noqIzW0gHOW/VB1JEKCyWY+12YqFX5Yh2f0H30lBViZJlkaob16ttMHhIxTX0\r\ny1Q2xt+1tQ55USk1H1kQdP6ateGtcOK4CriG8r3NeIjevJP2kdW3FYMdUYy9\r\nSoEeeJ/U9/71kFE3vPx7Ml28zPCwZ/9X+aKUlSVWIsTpkhX9UQ/Ln8zUhoGs\r\nWC/iLKrGTaR8wxb7Bi5FsPNdTA0eJlaffdNKD/81QhPaeWo/vplLxVmtBOyW\r\nmb/zCrn9vCUu8B1jV0jTCQErPi0W/KJm2H3JSCx8sxSeaJx8Ki+l34tnhwFJ\r\noFqSEekbXwHaT1bL1sDYgeJHKq4MMmiP7g2SGXFbrNIXWyp+bfTDwJHTKQRZ\r\nLNnw/9c1FFMXAi3WDEPFWpQPJ474zglFsIYNvg3Pek977rFhY4E3BA+F9fLj\r\nP5IZFTzYgiw4SA/FNJ7H5b1ZClZagnVnu1KOKrNWp3IX4O7j6HGW/D9lG5vM\r\na+vXucu3SBoL0RXd+A8BYwyVaT8EVnzzHeWE6dvrxlUq6L86rUq5Yns1evJs\r\nFUohPFta//KI/P7sOMXySyT8WwL2iXweg9Qyz31g0USxGeDq4qsOaG/Q7Jts\r\n+l0tXLvBWn8f31ujyZxNfdy6syvUJFKYYuQ=\r\n=JT9z\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.0.1_1668640254429_0.8443110550686428"},"_hasShrinkwrap":false},"1.1.0":{"name":"@proximaone/stream-client-js","version":"1.1.0","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","node-cache":"^5.1.2","rxjs":"^7.5.5"},"_id":"@proximaone/stream-client-js@1.1.0","dist":{"shasum":"b44552572fd8adcbc07201505eb5e78fede03d77","integrity":"sha512-Ua6RHpPn1d54JHWzsYtkvKs6dB7jFJEoRJsinyBOrKrMU/scPGvgeoGmXWHwqh0Wr734C9S+vTaL6qLX7KnYSg==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.1.0.tgz","fileCount":102,"unpackedSize":244764,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHrd29oFmx+Bbzv0l9HtIgvkliE+W1DDmg+KarIs4YDHAiAJJbm5q9bTtDBR8I26qFwkoHjuzKIk7jYBk3GbIlOGtg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfS6lACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrBfQ//TeiDRJ6LjJXqE/AQSINJP4a5Sagm9uA6jY63HWjiuRTYsNiC\r\npUsEX5UayDIwX2vg3yagozeObqDa3WW896PpSsZF8CLocdn7yIEFxGoiCCya\r\nHCFToNDVu3y59Ksz24i0ee3cZh5B8FJJuFEUf10HsuViW6A5E/MoPTrPTJfx\r\n3aRXb4vIoUmjE9yHku7o6JHBInl/pCPcFzgdgTlp5tL5wPQh+/qFMeITsKih\r\njnxmCmLcbv8ZqE9lbVxl1RDaAmV7tk4q/QxFrwnbXJhgcHiXmXLQFwJCVc+s\r\nXW2/TLZQD2GA9P3s+Opx5DYSCqieY74zn1U6607Lbp1CPoxlh23mhuRVjju0\r\nYNsTKHyx6A7jA7Hn2vSZxnkAe8cvIawxpSkA/54DzcdvcVRSRKMJSvFcqGoJ\r\nNv6daKYPQRAz23sxRlXB7ZVC5GTfZV4RtMV898XcwHCSddma/5NtqNu3NBsK\r\nAyKTEoIvgKJRe2Rwld9aH6WRYWAGsz4L4+1QFg5pUzhin/O4g/gYx+s+goLm\r\noKVb3IyEWdEv/3sY6lc0OvCzpMMeWyebBSSLS3nKiHi1iCcE7hMw0wWWYsMd\r\nDDmM3h9WmX1os7FrpMRsAAUgtRH8KrayG7TaSD/c3Sr8IJbjSx5Jq+yT3D3c\r\n4xirruOaObraRAnOoQTS2eXG0c6+N8zEp2Q=\r\n=7T0V\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.1.0_1669148324975_0.5875073654196141"},"_hasShrinkwrap":false},"1.1.1":{"name":"@proximaone/stream-client-js","version":"1.1.1","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","node-cache":"^5.1.2","rxjs":"^7.5.5","lodash":"^4.17.21"},"_id":"@proximaone/stream-client-js@1.1.1","dist":{"shasum":"db51129a8ef7b821859f1f53adaa9f0c7082b7e8","integrity":"sha512-/p2SZxIhL5lqyQqIsLy2klvxGNVcdkb9S9NcxVwwnhtT/bz5jwz91OWtTsk+FaqwltwfQ8YRIp9YInX69zDqFw==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.1.1.tgz","fileCount":102,"unpackedSize":244790,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEP11FAV9g5/lvIpmtYfVUPq2gi5ZAsY/Bp2fWoNSbDPAiBu4KAq8YrLMdnQA6aqwaJYW3rB11JdjSc2l1Sf8Aj2CA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfmT0ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmopYw//aCAqqwowk0XSriAfGiXuaYiSEi+z5LBTp1bySoLq3cvSrdxd\r\ngn3NdgcW3hh7/ikoxFF+i+U8yeHo3cDswVKWpJrZO0LgRt17OWpSwrDVB4uM\r\nf2ZvBejc2sJ99lh5hJh/scqxrCQ5f1g4UimnniJNz3TqxZgmIUvFyw1/yADe\r\nDUmA8Lxn9yGWJRgH8JGeXY3gEQZilgLn2M7Fdjz6/sCWKupg11g8T1zOCWal\r\nRPXhH1HDFeVFRRv9i5mQAD0KGgL5+4tvvERZqnxgIQ4ubYCr22m3YsJvyDv2\r\nfXcliIwvqeKqukEbSGQ+CuLbHyx3h4l4pMg5U3z/cfuW5EQZeTOjvdxhTMU8\r\n+aEeU0RR/CuxymUIeyzTLALCxhlJ5Ha+hvaepdq9Orapws54XJaQhFxRZ3hl\r\nlSQABlX/gVCUUF/W0JMEIEVoSV51BrM8Oi4ySaw6GItD0jYY/9zftZ2cFVKM\r\ny5k3qpYAJd577L8qr8cFJcNeT23P1andTfIkLiW2joRqggEYgVQLVYU3U+NE\r\nJ1vh/ufDPEybD9/U1B0GVnt69OpdPaniJzpiJdbdUO9hqL+NS4aOa8cyflQp\r\n8RDmdw/m6j0pesFP8oGatGA89KoF8K4qFEL9zRfmMIecMWrV98KM5g0zPMxt\r\nfr8AmHQL786z9T7061cwUGbAnzw+qd9pY9A=\r\n=1Lpm\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.1.1_1669227763947_0.0474788982319958"},"_hasShrinkwrap":false},"1.1.2":{"name":"@proximaone/stream-client-js","version":"1.1.2","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"_id":"@proximaone/stream-client-js@1.1.2","dist":{"shasum":"ed51254b0d88de74c7f06b2da45b433dbd634f00","integrity":"sha512-S1pD7oGAcnZHBQeILiuWJDP0TMzRu+il6hhwperFJ1uRuKNGJ+UWWXEsVInKdsw2fu0+SVxIconi8fCGPlRJUQ==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.1.2.tgz","fileCount":102,"unpackedSize":244995,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDcagfLq3ViT4UfJu9dghppxZ5216vsX5vCbFXrr3X9OwIgLOiq104YNMujMv6AspRNmoAGUB+5IsMcL2zfimVs7uk="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfmU1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoUrw/+OTHMeMiF28509fjzEsDyF4S6Cv8McgffJ5VLq//dsIhLtzN9\r\nuaME5h4BglKVTLGvQXm/jXesFnFoIgsQOiIvUQ4lM8lZE4li52CQXEkRZv8k\r\nEvkgMUQCpr/pkccr7ckYmXDHj4KxBZeMZfCo04k2oAMCquZN14m1zXcujMi9\r\nhPdN//B7Fn2NVhBQsax5es5pRBKHUjT4cJlcYFz+Wt96i3gGG4DMQDDPKj2N\r\nzPkx5w9PeCOnMDbq7T6vT9kZ0fkWW1fhXP36XaFNiVrXdMl9SzBhlpscU2wK\r\nsP9NghuOZBWu3So9/9yn7lLSGtBljtBzLdYC1a03qUh0fIQ7tRMtn9FzoFin\r\nj0ug+1L2wA8AaxrRJS7tGA+k2cSm4RbCFrW4Pl01X6uck5Im2yz3ytF5qo85\r\nI7058HTAagwWx8RCTduOKICucEhNty/UZYndZr2lHiwkbeoO1CXHJKabq9qM\r\nvJMf8QZjVowbjcubqZwzlpmrw191YrFhfl3l09lcB+4kcoAkIZcnvn9eTJRq\r\nnXRnOenPzqfLfpvDU+7+2R9Ah5GRrbsFtiKrWmx48vx/f2Iq4wrXbuSabjmm\r\nY4TwOH3o74vAg6LMqgg0wR+knMuIlIo6mR96shq7cxdrse7n9YZdgzzGYA4D\r\nofFLY91z+xOK6Fd9sAFDhRY4heeChi1iEzI=\r\n=pO6c\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.1.2_1669227829636_0.8761689694764774"},"_hasShrinkwrap":false},"1.2.0":{"name":"@proximaone/stream-client-js","version":"1.2.0","description":"Client to Proxima StreamDB","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","samples:eth_block_parsing":"ts-node ./samples/ethereum_block_parsing.ts"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"_id":"@proximaone/stream-client-js@1.2.0","dist":{"shasum":"5c7b0a21ec2b2745716ef91e0f74c1e084a90d68","integrity":"sha512-YM8TpHx1VTJIN4TohmQpNrP0gOtyhB3p1ynS0l2AVbxekxWyFU/RZT8O11aUyTQNyCzTnAh9P/4kmhDM7W0dvA==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.0.tgz","fileCount":106,"unpackedSize":246497,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDcQItyrpugLd26TjKkYF9rRo+idUt8djWb98c2p2t2BAiEAt4axfood5m3BztbSrPiifAlurrr2LraWew6RVdvg6dA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkZurACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpr2RAAjWBZnO5ODhGlCV1+lH6sZmrL4zUW2Ny1TturUvEDPwMNOyCX\r\n9QGUD1YG/wkdX1qIfMay/1MGPuBmIjCIXr2jCb0e03YEgwftvZ/sl91kP+G/\r\nFoNkenzfXjfCsBum9ZXrP00+MaH9ESnCQgTvMmJ9z2xGlFv3pIP0ZUNBl7Di\r\nSsD6sZBgNbMiYMNrtG1B7nQupoVparTCNI5Rm/UzgC9sMazkEdO8SiaH5deh\r\nnYVTGympu8H/OZDyYIVUpGrfICA59+E3eK4P+5KO2EEmeE4rXwCaWRDAzxtC\r\nceEB/BbZZxC9J8SLf+/mI1L7D4093N5mwWLVATIAvirTQkeTwnCg3vvZnR69\r\n9HADo5eN1W2ymzy1O0OzuDOkMiOZrooefL7hc7UY0YZMoZ+O8oU8sIzpZ42K\r\nM0bofW/SVXGlrKKZD1KTKM9L0G3oyX7r2720GcI6lKIVNxkhYne7RkfU5F+2\r\nC1IOow8NVKgeZQuLtAhLAD0vIEmUXG5VISJSLyIC0Qepnbjahn0CxNpoDvKS\r\n3ORUSi3sQN9tRyyTbm2ZiavA/d9TQ0JZO/FgxmfdcTFRPZqU6A5jKTzFCx67\r\nqhNy7gPbRZ3Q4k/V9dOn8WNBJgfhN0iYA//jmhpgIkeXdwoEUmisfmxcL10S\r\nwii4z+W0HCbhX6xbkc2XSp0bD35t/qztWoQ=\r\n=uwUR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.0_1670486955674_0.46044543070561095"},"_hasShrinkwrap":false},"1.2.1":{"name":"@proximaone/stream-client-js","version":"1.2.1","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"https://github.com/proxima-one/stream-client-js"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"_id":"@proximaone/stream-client-js@1.2.1","dist":{"shasum":"7eff551e55e1002f7f45f772874a6c729f992e9d","integrity":"sha512-AQPPkrtWR/FEEyIf5naZPxQZXskDWK9v/Fu2tyOKXA3jVh2vXwYr0eeJ9l8MgYwu6hXBFfcZ9yfLJwSJfPgoQA==","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.1.tgz","fileCount":103,"unpackedSize":241810,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCsBW25v4lv8eqikfHcqNEH9LmvqJsKXYPCQurqtUV1dwIgDW6LBUZHBd92DJTbeorKus7J+RCUxUDdSD+9r//tYiA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjoVVGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpqGA/+LG0orIwz49GBoA4PF6PSbXqw1hEQtLpI8p8DrJ6vR/gXg/m0\r\n1JpoajmAOr1P7u9/6xjmHQLmVWlD49Fylpb8xiHBJzdEfib7YWWDoWxbutQm\r\n0jrP6zVWdQEgao1DJnTlXc11E2cfLz7VtfUbb9FQBRPIA1Sj/CbZIxS3vjmK\r\ny2Bjd+mfJSu3GX1GI/Avya81HSIA6rKdkpoHqBNcn55+BUWU3k1HTalGlSRL\r\nbOuZI7Qyz/uKDmoCSQkqUDQujIbCznWi4kXTexzt6RtVcIjUC1YKzJQIL5XQ\r\nvIquWPjh5CJ01b3h3zj2xn0jOuNtMUjQG+lV2Oky4nN+X0ppKjs9JoXrcCUm\r\nXfn/IffXEhnBBVrqtxR22HevnsGKRJzYI3BHWFO1COr4V/gWw2BqWrGRLcK2\r\n57CCr2sRKjebAO1uzoRLjO0bjK+pUu87OFg0mz60b6btgUml40RSPNgxz9c0\r\nkKQSNyFaazRZSShXusvJepJKR5q8QMsm/alqZ7u503tAzW7nDe2/ns8+hUG1\r\nqa6ddpshVNtYuTIbkfsjTsEqimANy/+Yodl3nqmQ/+un8qCem5AZaGbMWxok\r\nlRSP1SGhwP1ZQDDqWyIxElqwH9PmCNilAi8tKnAOQ6uZg/jzSVWW2H9xh6y2\r\nog0MMduv2RlaiePPCLkCHpmwjHWPOsP/7Io=\r\n=Z0o4\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.1_1671517510046_0.34049518529419043"},"_hasShrinkwrap":false},"1.2.2":{"name":"@proximaone/stream-client-js","version":"1.2.2","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"262703df209cde89405305a5af5b492ee0890240","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.2","_nodeVersion":"16.19.0","_npmVersion":"lerna/4.0.0/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-1pKcdxbylE4HFqnnxstDpkAtf1bVghoGwu/iErbizu46KSylXTwnuvRUfKChV/c95biIHLamaRKtgjHLAE7Mfg==","shasum":"45b7423d075289c62ae4f7082d142c673ed12fdf","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.2.tgz","fileCount":90,"unpackedSize":238005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC9WWpKR2b6Dft/krFeVRN04pQT1fmfUprkxp1I11tQywIgCKqmV8g9PFzjU66K5xgUStlHjz95YsTj0YMa9mALObw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwxADACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq7RA//Ug0CZSiFsDFFp7gC8Vwvc5o9FSPBU4PUnNHsK2/x9iq+wdd/\r\n9uetuKSZ/TND6w2KNq+iyfKHnHq7tXc8Jqfe57jnDBVjh2Taq1eL8Oq4ropA\r\nq2YiIBGFLTmwtYucHxKMrkPBCiUiAL2iJRLOgBDkswml5BTNhh+z38v4TWNE\r\nHGEqOsK3PVIyCkv6hvJQgpo05YeKQNGLOAfkPterVCtT+1OXVd0GOEm+trV7\r\n5wUi5akxs1rutcH7CFvLid/jlQ9EhK771j3SDpf2y1ZDzH+e9d6snP2xWDzF\r\nNfji2CrdfWh8wdSEhIItr8PCcfVDG+4yc9NLhQTyDfsVTW9Q9Gdn7JCjWESr\r\n3D1+JOAv1uSUsicMgkICT7ZbpFWn0YScJDPtWo3+NB2XhqfrKcT5V+mvDW6v\r\nXDv6T32x/LY46Xh0nqydVhrDpK+AkxEHg4X82jcpWtMpLuARt9xw1a1Rn1IE\r\nd2smH8Cu4Fuyhyv0QfJ2tWO7j82YOKDAGjVztZvPVROrJNTyURaioevnPyJM\r\npIw6hdmlZHgFZCDtBV2/xECSCfDF19kIsCOtBBbGMLTPBHaAJwiNXqcX5G3m\r\ntGBT35ijjgXniOyQsXpZEh8eB2fyR1ztq6zIRZDMl+rhVbs2grxCOrzQOJk+\r\no/06Mk1/vCH2hwlnZk4Gi+Ok/v3sz7y/cf0=\r\n=Hdn9\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.2_1673728003418_0.5994779029254034"},"_hasShrinkwrap":false},"1.2.3-preview.23.0":{"name":"@proximaone/stream-client-js","version":"1.2.3-preview.23.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"ce2ff7a707fcd69a48454ea49e6b266261ec1511","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.3-preview.23.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/4.0.0/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-rHJLTxZMsyVXAoW5W9Bp6swVA13z0f3wWL3mTLSBXleAm8I6f7sIfwqeQg8Nw5L5+3S76EeSrhTwWKcgAuX3ow==","shasum":"50f678c57c323836d34abac67f380675dd68fc5c","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.3-preview.23.0.tgz","fileCount":90,"unpackedSize":238026,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC7E+w+rEO1r3BOypeFWBaDZ8KrEG0mXe+VEj/x5Sid2AiAeF/J7wNjWuY7zWjjKYKDWIVyyiq0Wb4R5q68YVJqpdw=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyR5VACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpIMQ/+NPjLHCxyPmDlsbTjimrw71NS9SYbNPVq3YeSBy/Zbvd/2SPD\r\nMMRcfxlUs0M2glioTNOGORGnmsyBjp17iR3PupibXOcY5WJosttePt/v1iQF\r\n/RNdcxhV1lgvy4TAq+jIhhKQT2k4nFn6jKfmSAXJOgHOf1n34yyzeXUGWRGe\r\nxOFVy6IEPuqSHr4kSrg9fp6zzjPzcNBNbOjcDx109GuHa0g/1+MWuFemDfDX\r\n2RM5WnrpJVy52rvzKexF3Esk1PfV+Veo1sEpPyYCDxfiV+Am6UF5fLbc0+Em\r\ni861StYLCWOiyul8jMaXgQtgweSTXI4baWp8pOGcQtROuF37IHOI7SdmQAMc\r\nX05jdynTy+9/aPgCtaLxTtBUgjyM4BOnhDwtxbejkspRzM09pJ59PFZU9xBP\r\nnlarIDgqvBAIA0+DKQleSD1FgSjhzAwZLDXqmvFobqXSO7UflioWD+1iqKSk\r\nb8CwcjD7Z/w37VCAwJ/+AireHoVyHDTZtn8jWYexZS94Ti1V5c+NSJR3Jdg1\r\noezoMPQxaoEmi+RsJDaEXe01VWB25WmrNzrbbMfBX3DiCqzOCZzlwlhoUq1C\r\nCebd8HOr9JgHacBk09o8QgU5ATswpEtPTza20mz3ox9t8S8iQu71yFWl2rFf\r\nSEFEUDPAKt+UEEz3LY64Bb0rgO9mCmHAxdg=\r\n=/hnG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.3-preview.23.0_1674124884869_0.4434030116802137"},"_hasShrinkwrap":false},"1.2.3-preview.24.0":{"name":"@proximaone/stream-client-js","version":"1.2.3-preview.24.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"0129906afd163f32e6db270d4482c44babea6d39","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.3-preview.24.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/4.0.0/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-o6mazPa/UI+txp9DE1/253FZuySMMQdIgaa+eCIM8OVRsRBM0sVJf6eVgfEyiEGR43ql5NsYPRxHzEJ/f0WoyA==","shasum":"573e8e4eba1605f0f345a42be7751204d31448f2","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.3-preview.24.0.tgz","fileCount":90,"unpackedSize":238026,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWKSPzdRMzBnFD+bkFBQ0cR++CokpIBMiteAjVZRUFPgIhAK2r49UXna8qrFcuIzYpE3lZGsrzACDiEJ52fSPXzPi0"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyqkxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrBGQ//XICVUu82SJvTRF+s/bZEvm3RJjltmjkoet/TWge7z1NSnbhx\r\nlF+swfFgGt8g2+v5IcLEfRmrhE8USX2ST204nBOwQBwsqYXb9DgfOqRIXZDw\r\nni8RNa1jmdzLq2RqTOO0vAJgmJdALpCDUCXKY7O5mW3G68/5Cbj28suzhyZ2\r\nX0mx53V2hgnJb76Q6d0RF4qXe7vktRL6r6SyT99s5QkAFAESgtSIqcys1V2L\r\np7LmuTzGzmvGEAZCoYsjXTP7z2WereA0WS4HY0z9j5L/9sOSiW4rf1PB32JR\r\nFZzbaZz9Ymwrv01NBaHvW/8/knLfnBIaojvvA+oLEToxam1qLDqk9vr8lXAc\r\nfPF3ilh+B+asTAUjQ/4bv3NpR5ZF7MX/SV9hczfJfS5mJeiU/eJyCAcycg30\r\nfSRTX5cQDyc5qg74zq5wR/DKIQjC11Oxxvk/UhQt5tqpQiVVsj9pAebLUTSi\r\nEvSn/g6f9KARGQUhyGAJu26+DNyg0v7EzXzR2pncB10zfUDD1NJ7roMQf+dJ\r\nkOvDTzelRg2/y7Q0LHLHBPmudWgWYB/26ZNAnCLCKaepYRzZL0g3Kyt7iGBu\r\nntnkFB8rsnAdtsTc50Ycf1ZyBbmXlczI+dB7hCvWQckCzxxTv1q7SbNskE/6\r\nNe+po9W+12RiYQZEjjorfu+MVat2weuUnb0=\r\n=8E4H\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.3-preview.24.0_1674225969226_0.12226459444875881"},"_hasShrinkwrap":false},"1.2.3":{"name":"@proximaone/stream-client-js","version":"1.2.3","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"420c99ceabad9ad06bd7f4c1044e265e133cf808","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.3","_nodeVersion":"16.19.0","_npmVersion":"lerna/4.0.0/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-Ew9ElfojfHknkSy1tuyY86NwrVKgqoBR1vjDIdG5nYFQzlI4YAmIojH0amHgzNplKEtW7On1DvXn6R2Xp+wUfQ==","shasum":"bfd3ebdd65e2d2ae77e08f9fb1e15e9df5f230d5","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.3.tgz","fileCount":90,"unpackedSize":238005,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDsUXIQVnfy+wfZcxc057S684VCoZrKIZsuvyiIAGVEQQIgfRAis6dZ9kJLHw215YZOayPYbsCxG9Fc0Z0cfeVfVDo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjyqlJACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr9zg//eeymEK8OoSRrU2ePGBDrUTA6uBsPOdVKC8mOjQhRxAgHjL+9\r\nipZVPMw220+83tonz+OWDK/hFK2hOpZ/9oyFWLnHFHfhrjviNPf1ZsbJFXT/\r\n/KFfi03OLvE/umP87Td6Uy0eJ5ZVmQJwZKx9YdkbnplcHVoRtTYy2ol7CneI\r\nnSSn+WcxYErCplzfCnLuWJt9Ome9I4z/orUHk+IRe0NSQH1ApSLVRxCHAxRy\r\n2y2ZnUwuQ1ylRhi6KmXp98R41rRkotrYB7WLkmZMydSmkeZzyEthyufqjkTZ\r\nndu7xoPfnyKJxwTIYC79beD7UkZWNMVEdrWkwKsCkFahVR2QwfFEfhawWNeB\r\nvGhf1ZgY3ZWG0Rqm/o0aaLXbqFRI3BYzIqjZx0wpMg/CIZDKza4TSC+bCwuT\r\nXrkP7XRQVEcjItDrMv5nt0TmxDLiJEz7W6tEO6gJFy7gcC6p7xy6eQkFzhr+\r\nR8AmBgimqwSgMwCiMGuyHFZWS58jmFKcNfwLQYG0AQRW0E1NSJu5ryHy+OxL\r\nOxsyQpG1Fvlkk5j4wNkbudtEVZ1TKaWluFU2nDRhbT8REVdbM0Vj8dK+nU73\r\nA4hmWpkVl6iqLLqsOybpd0NOrfeXsJDJXNTsWRtwMptsywMU0+K1T7b9mmfM\r\nxsHGjyr46cBfIZFNNyf8T43nXoeei/oXHPg=\r\n=x1cY\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.3_1674225993299_0.8406140936497284"},"_hasShrinkwrap":false},"1.2.4-preview.26.0":{"name":"@proximaone/stream-client-js","version":"1.2.4-preview.26.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"c40b9ab768e7d8a0517b8527e541cbe9f726af80","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.4-preview.26.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/6.5.1/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-HklO+1mWvVjaPm1hM0aEwkiIFOQoVAYjnUojiyQGyUxwNnSxdY6mLCwihivO9aZE95cp2i9f47OZ84+jTia6rQ==","shasum":"97acbd54e1d37fdbb057a44a6ed071a83a64686f","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.4-preview.26.0.tgz","fileCount":90,"unpackedSize":237986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEQq2+UxsBu0sHvetRM12XyaeukouqW/7inm4CZ6mv/wAiEAgGg6W2SaogJ1jLDzhJvt34JmRgJI0KDn8rYgEORITEY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9dzeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr3Gg//a4K3vljeM+0izbK3f5+DSscjYavwj3kcd/gRNwXjDkZetpHo\r\ntcnsTblXPTG4nfC599IwnyUTYKBQUeriKvMW8k4ThDbkF3KXIuHEWeMHfFJd\r\nbAZ88xDtgMPOUXRKzOV/u42LPPwo3mBzm0ilgWJUZUax46d8Dd+hfluesMZN\r\n/FnxqhoTmt6TOzEaxsNa3ea4IPgX/tDn2uT0OnzHw117ZLW/4CHsmr8NK2Z2\r\nrliR4Q0PZQDG0wo+g2FKOwRINja7trkGCairdHLtAEfGSCY5PK3FTOYM/Dl3\r\nKiJr8hl+8BJhdVZrrq/NdbwNgw0fvEnos7bfg81+rFv/KwKLP1cduixkm2V1\r\nu+ULAwM4MJWdpTAen8tI+PTR4DT8RsPq/mOi/5ZnNMIelMnERPi462fdzspM\r\nAy4xXCq9xQtA8joY7JfDQLyZc54SjtSTj50pcYpx+V5Am70DVKs+Hu7kQ+jt\r\npNjdcaNxPc01gfGR5zEO1u/dIavxrfkWShdN3euuZUUdHYazk5EK5kGn9Il8\r\ntDVNIhE7P9CFXE21/YJhSbyLayQWlS7Ps1XuDQIDom99VxjTjKAh4638K52c\r\njr/m5Jfx54Q/Qrfoc7F8tq71zLo1K/1vWqA7FOle2b5wcy/77kPSahvSY+vq\r\ngmBRF7jmBFMi2f8emL/30rLc5sagx4/danI=\r\n=n3tz\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.4-preview.26.0_1677057246381_0.9545476636726191"},"_hasShrinkwrap":false},"1.2.4":{"name":"@proximaone/stream-client-js","version":"1.2.4","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"92237df1a13e505727ebaa693ae48eb95fd906c2","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.4","_nodeVersion":"16.19.0","_npmVersion":"lerna/6.5.1/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-7J2EY3rUYbaAWfHlc1iN3ypdD6eg5W0n4SJ1Yr+A7HkgCbVl/QmFGY9sZ74UkRzwUZ2lTK/+m4pUJUBfQSvw+Q==","shasum":"87911348a2b7fe2bf94d1c1743b5c09b8c952c3c","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.4.tgz","fileCount":90,"unpackedSize":237965,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIECq2z/0BUcvFdRD+dSl8szFMtKpadpVSwYsQ3I4uyMHAiEAga5lsWpZVbE8mrw/KG8dV3Rx+LllbS2hUA/RLEnKK/U="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9hCZACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqobg//W8yk/yecUiIG7gR0XCQHd1nEwrr06l619Si//tZwCdzpZAvS\r\nOFZkm+L9YSM7PWsg+zJYFHlU1T1Fuj5xZloGe7vYYR94WeH2xGRHSocjkV4k\r\nw7dQyBToB8mpVMYqsdaAKdj/TjgtxLddWAIY/ikM7UmNYBAMX3yTjGrNLttA\r\nsLOlfIvwZK/npwGrvWVBJoeihnuiturgsUrOSMfVtvBYz1SAMapBOSrNOVWG\r\n4GLV6TiOQxL5n2ANNcTd16QcTix+spmCYZ+WxdMIYw5wgZk4P3VOvX6DqxXe\r\nERNz0jOGnVvSYZqzSR/xHIXOgezB2OHUEED+IoOT/RKqXvn3LQRYzMokNkvW\r\nyYAM8Y56doHhYJLhkF3UitrKisVvCrvm348I7EYIEw5+3xWFhKclhrZqsy6q\r\nqNsyQKKrBS99mdJtnhJrc3Xzq+C7Ho/oiesKFnVQByhN34uiGO7PRJxntPHN\r\nVHg1NJldRPdg0EGp4OT6OiMB70QFmFaTOn5AvOZ3MFK6R7MAPDI7WBmZHH1s\r\nU0uIsHxyD4/G/pHOoe4CD4a1SQcNkYG7bzfsH33ceL2c4CSaWjLHcZxzVxd0\r\nTCSUGqRRm9Zszpt2bvQVK5Ude6aBZDKC87Z8PakGj+KyAc9dVkEzCgR0HTrm\r\nUnSZ6H+e1EVMOCngIP3kN6pwUjFfjPjAI4I=\r\n=3Mwu\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.4_1677070489342_0.037769293370907286"},"_hasShrinkwrap":false},"1.2.5-preview.29.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.29.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"1dfc426b4a2e21d1580d38e9074b0987445c513e","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.29.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-rFukV8SaXlgfH7boKpCrGe4X9IAzbnXD7OQ2vwEftS6BsDHlPn0weofYUbJW7xJdjPasfJSkYRSbbCoVaEhZrw==","shasum":"ef4de5d16d164398032d1a72f679282ec55ada74","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.29.0.tgz","fileCount":98,"unpackedSize":245678,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEdcDrrnVNAjm3zuZJ2UFZCpB3ZB3Qa7u2JniEdHHN8hAiEAmGP5lZmm/9XIfdbGlVH1EnL/qFbgA9x7fZ8aLjiG4yw="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9h8zACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpkpxAAo4SHpyNqAKiWI7YHpjweal0HGIM7chS4/1HZViatTCcvWs20\r\nzbt/n4FHK4f4hxPmGiga2cvQjyNwS79Yfi4fcMInsX0ELcY+Fgzx1HEetvup\r\nAzMQYCMH3O07E6oef9VURBWRP4Y8uCZjyBp0Hz6kHgbkAhsmotwMSvT+DsMS\r\nK+y+nI6G42ref7+yU82dYTTWiOy2JvTcjvfsWV95Odup9KXctV/rFnlyfZnt\r\nhW8ryuB6ZEVrgLFjBCbxMyjXVP8uuZe8ZIwueBZNE0bkTAtYLON0+4inMu29\r\n+63P68o7esXYoNX/+19CLnOnAt0plkLZKjFf+biDl5Yfl4TU29u3RwxucF/n\r\nmKLtjSw4cVtz3/uUWjKWya33WtuhdXrVEHwPIJ83TtJuFbF7RqO2Ty62zQf7\r\nKzOfyLFSOkPObkRpsisWV6LAlawIfhVA1sPZ+vW/XP8HpYxDOe3cRkwWEG2/\r\naLcpNXvc3qbfXI/cl76gQ5pfeB+qVTM1sBwN137w2OoT3Gxx6vv8FOLJSoC9\r\nPWcOXBVHoSDz7CuFPdj23krD8EJP3djm6qoexm05WwMSZ+RFasTrZftlUyD1\r\nVu9TyAr42zH88MVfKi17yWi3a4k9DWNdVjT2twSeZUxIslRl3BVygy2KffbN\r\nuCjPaC+ylDma+ADrbdBq3NHC/PT9mswjalA=\r\n=AoPH\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.29.0_1677074227547_0.8696665367401819"},"_hasShrinkwrap":false},"1.2.5-preview.30.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.30.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"d4ca1dcce5a40872e655b8e6a4a07b89c282008a","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.30.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/6.5.1/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-FE4WmKNNt1SdzPTPN/uiGgO8LKwIbyA+4SzlKKpCClYQQGHGcXQW8DpYbYpOvQsif92syuNNRV2KeBS8guuHSA==","shasum":"103a36abf9178ca39316c9100ed017996fda82e7","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.30.0.tgz","fileCount":98,"unpackedSize":245700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQComaTxCSMQxGkEebfvaiGqJ/TfBauSaZbn+CtgXvCFFwIgQFLemfrcmLJ98fZLwV68F04z2/hPeR0ZQVo8wroC7xA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9h9eACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpoSA/+M+8fYtUNalNg80L5hLtzN8t90VlcneMnea9a/2p6oS2O2lJp\r\nu9Kq3z+C/KlSA0i65WINCQf9wR5qzy5VZPnHYbWkStK2C4n2OScvsgiygPb7\r\nX+Hv3q8PBox30jbRaohsdjYQOzOlnkZ63myHzXe+PAQgG//360J/NQSfQWuI\r\nzbLH13DPnSXtx4MnuQsNtJ0av05EKgUj+T+BZWZw1W1YtD9iLjcs0x5cr8Hk\r\nmudAYE07yu34BYpgX68AQUlxxPzdBbwiqI4uqPprFbJMjbi6w6jwcai5Dzyg\r\ngr7igYOzLg4aWgJeWh5YYxGAsCL4qsak8NE7iDYnQYkTTh+qz/wwYLbe3Odf\r\nZNS9i56PyOhZeoAu9btntWMkZHKpsQ+tbi0Yfpe/n4nChJC8mO41PCPqWHdp\r\nU7crgqWnvu2O0jWxQP10nSNmRGc6oKzVuhHkJ+Z65vcUGxvmedpBqNmips/6\r\nkgpfNHGtnQa2TnIGebshY2LE2ObUEiJWtFqqBl7Sx8lyNvlJwlSe0RfoJv/Y\r\njwLQvIYIby3ZpmxbH1PVks1PmBZw9kcVQykGs54nOa+i0s2ovQHIbMppmvPu\r\nDev5GcSSWLxJrlF4zvqS3xLIb/JVISvhQMUdnBRi/YhVEvtcQx5HEJuYfwn/\r\n35D53VUe7+czpJ6t41kuGOCjCsvDWuCCzM4=\r\n=TMXU\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.30.0_1677074270129_0.11724980548167885"},"_hasShrinkwrap":false},"1.2.5-preview.31.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.31.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"42d7f20f259d425640c596ff661f44a3b952f640","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.31.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-guoV+DCOsxPNr4azEWNzIrkbXPFl7/0pPIqOfW7Pcfr+Sg0+7zcpSWVyyqnImWN01g7Mex8HxUMML9ODarywOA==","shasum":"65f21ff9ed23b4b99bb8e41ce41a60a760b84b50","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.31.0.tgz","fileCount":98,"unpackedSize":245700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIF+CxEynIyRuQ0TUEAuuJVQ+leQc4XDaakL5rs/NaAV9AiBdNCHT8EJF6Km/GNzfjA3ePUW78SHrGaD4gN/MFEP86w=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9iA9ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo+mA//SkFxPEVk3XNFQySr/crVDnAy2pJaOv8oxvozMHlLaJXkaBpH\r\nBSBjawItHFQVmgPP1KJWPRP1foMCvmq3NvRlBNfcim5oJliNhND4udQyAlYt\r\nxuf9PpGTNV8VKjAp9etw50L+3ypE2kwuc1lx5dLa7fPgxcXsIka8fkPIZKGL\r\n1n1+fNYe1IyoaiEwCx1whF54HyHnJDJ5YE/Mq/6vFuRUsTPXLkQARju55txM\r\nJXPUKV+peeB2gez/F1wv1m/K8Wwf6xxKbiYWQqganVaUfTJp36G1pQQUBHqw\r\n07kExaEAiDiVCC84ACsjuAD7Ik7cxXX+tctmgUoHdda4AF5IHc8U6HMMDuR3\r\n39mgvvSPLMXNpTrwvYgnrF3k4TuhhLjE09PfFTRLXDDqfWFMPUIh83esArhX\r\n0IEhc8p5PmCrKlY3u/hRdYdIJ884dboQZ6sbbkRsX2eyF8r7gKS+rJZ0b1L1\r\nVzG54mbe2/RSMlGXsbF6n3dcIDC6gpBMBZnGIZNjHV+7jqJz6/zd7zosKgyQ\r\nK6Gx/gN3iviLkJngCIAvKtk8vF3im1wcBO5+mySXgxEaO9IKEEQhindnnM+m\r\ntl0Tk8f/IR2AfU5+RmK6ajNY1jYe0C6s0Dl4ItxqtPMJkNzHSV7mBxwo0vhm\r\nUcPAr16b5X9QenTMRjlAHLUKIdpubtIaPM8=\r\n=OnFf\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.31.0_1677074493614_0.01755792270404455"},"_hasShrinkwrap":false},"1.2.5-preview.32.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.32.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"48b787cf35fb7fcc8549861a4c51c636f545c85a","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.32.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/6.5.1/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-rg6SGjHPg5f4zMYUgf0Rli2EuRbXypkLkCt7gZ4d/qHpB7dDA31x860bI2EOUHGL+GD3RL8ErO7TLuXQSSPRzw==","shasum":"b67cd410e661e8f4e2093da4567d8fe14c9662f6","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.32.0.tgz","fileCount":98,"unpackedSize":245700,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDNe0Hesp/a0c2Eyz7j3bEvEliZ+iFRUpDJSqr4dAnL6gIhALumrWu+IoBYGYtd66WNEycSosRVTmc3SfD0uiNn37DX"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9iDyACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqAaA/8DJadCaYUcU5RKRqTdN6LG7KqL0f+R6vK8rZEHPJk6eLZVhBt\r\nDRpsZ9xAseaK6/euSWrZWBcAd6R3cDOLewYGZxisS8MViVN1OYvNmkKJKASJ\r\nkTiPCRaxUvjA69wwS5tAmwYYlG0TZI6tsw/XgrilJCZPzHQIaCcw3zPPE8zB\r\nK/1RXW4JKeyYwHYa4rNHy1D3OuQuEI/k86CsjTYcB9c2tVbROAyyQLh+h1m/\r\nhKITVAkh8knN9qG7HTPj1XoKbNgH9Lji85b/7MvgYGeJizMuqxntLXH02sIc\r\nL9s6Ih7mZV8z4ob+h7K6aLffY8FBuY9o5Z5YwS2TkK4zYoo2O9dA3IoXZ9V7\r\nGMG2xX9VM7vCT/kDHYbxNft/SUA7rxt7bUWYspz/d0yTu33TTKaCnnUfykyZ\r\nZW/ndRV4mATsZtooREb34+E9ozm5oeCNkrT4XMsXEs1S0X0CGjlG8rabPKll\r\nvy022oUN7S26mHfa3h472CXvP4j1LHuLdTOdB5F+HUBC4quu3fiHe4CUlNtz\r\nxmd2At3pWQ3N6P5cam8RVGzd/R5DBjyLivC62MgeUyDzot1+895qwboiCsgJ\r\nxmgmJr9HgQNa4aMAEDiDT8+0O41yQg1oYclAyKO3uAy7AkeORNetwTouEDiS\r\noofWA1Glt8BGHtogdwt3apMnp2WiFyfW+ZE=\r\n=oDDV\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.32.0_1677074673878_0.4949379852304452"},"_hasShrinkwrap":false},"1.2.5-preview.33.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.33.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"2e4984923eb74fb98fa91db7e77b4059a5cdad41","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.33.0","_nodeVersion":"16.19.0","_npmVersion":"lerna/6.5.1/node@v16.19.0+x64 (linux)","dist":{"integrity":"sha512-XCFxTjmfITKppgdZvclixGK9A+due3EafKUjUAWAnrpzAetGYH9dud8QS9eTLJ/ajOf4h4OcYPigwhzYtS7CRA==","shasum":"dbf34f02f6df03f6c06e4d16c3cf5794951b1fbf","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.33.0.tgz","fileCount":98,"unpackedSize":245807,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCgXW4/9Nautn/nDCfqVQ9pJ5bJMLFwSAuN8l7jATzgiAIgIwp2Ty6DVtpphyPSsz1haeY3XIjQ9ums/Q8SaXd8ToE="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9iImACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqdlw/+JdfEh6PcDAeUOOrF50J5wzLQ1Yl0QUxDnzaSXz3jtS3EP9yE\r\n4g01azFCsVPd+x/mkHo20PtxBlx6PwrwEYe87/sXvuzi+c5aP+vDnmFnKj7b\r\njuXoBm4MYtEmqsuKjw5/gpR8t2ekDJNGG/aizkXCRkKGqTXM6pljfl3wME7S\r\ndg26w4GaCeM0brFtxgCst8RagL/l4Znj8g15GhSgKmOa1fDAhHKw34JZnwrK\r\n3VGYGcvPhHftoZ3sjEYKst5OZRDlR/ZsKnbth9d/AnnTjBSJAiLjk5wTwxOp\r\n+oEA6MvKhpcRlMFWBL0F1G89CoBLxuZzLF4fAgHDNHoiW6VxfVOJRdunHg+O\r\nq/ACXOiBu22VBuf00FUbejmsZg1pJJLRWCD1ZmpZlqSjiaBZ5gYzIFBqYh11\r\nOsIHdDhP2cwuSDoRp9/ZKtgd/iT07rapzEUMMXU1Z5KSE2cM8/CeZSW4ggaw\r\nX/7P3y4J6XUudX87Um8pGghMLm0AD+yNUkkUEL0QtbzsqRR6us7YiZLA0VLR\r\n0TnDYXZcJULpOpBykEdm1ERWtiEoTcZq09fWdPz5UwQ8Mc2/pUrUGJEFp4Ed\r\nY/t0at+OsD9+y6SRvO3q88WPj06PK1t1cZbR4VfrmUVzYzSe2C7NXHNLLHtn\r\ncGZIc2lmKV9aDOT649YQN26N7Zv6u4YEAZs=\r\n=WjR1\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.33.0_1677074982280_0.21533544025513995"},"_hasShrinkwrap":false},"1.2.5-preview.34.0":{"name":"@proximaone/stream-client-js","version":"1.2.5-preview.34.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"1d7a6bb8a51dfeb346b9b92aec5e016c5b03411a","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5-preview.34.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-9vthGtRMcvyQDTnvIHkaZsPpEuJTexwTPkGb47t/v0z/X3r/gUtUuKok0N2QTMcddVKTFlY4egkNNQ5JILDoBg==","shasum":"3ec2e1ea5da1b9d35da536363ed27598e3553d4a","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5-preview.34.0.tgz","fileCount":90,"unpackedSize":237986,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICWRPUuufRHTB7AYeyyHcwl52nuuE9m6vFldKKjoHS1cAiEA84qLJNMePDEsAG8jHxfy3rJlVsQpKcC8dngJtUNiNPU="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9zrVACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqs0A/9H8Dfy+ePkvkYQaqLAbde+O/v04Bo31u6UIlcytkw7gEgy8q1\r\nDft7mxzHZ/8de6VWTuS2NcLVL7XSzAf1y4+vYONmk8mIV1sidE8D+dmyYzuZ\r\nIdZGF5S51ak+Gi+o91xnxXDgX/6y10ybvIYvMkzvnlkw5Ty683+MjprBcQXb\r\nH7B+XEkWIuf7m8T3tW8Ot5mgVD92SgWBoNzbkvUUDirnSpIBXtmsVjvw3DCk\r\n+dNm5o1Vws6hgZoAMtEcJMiqcD4y10kzYkv/+8zyj77Bn4JzWDcVVn7Hfuxh\r\nr6uVcjJvSb27W75htJw8TFOs9BG3XxGIkgRft1c0Ka1yk0opByqw+a7tkoP6\r\n6HDdtodNV/aPaparfZbWK0pPDR2S0Z475VZ4Cu7hkyngemMJDPDD75qujG7G\r\nzUhlBeeJ1npY9AQ3xX6mwScIKecbz5rKHHsP4NE34KliPImOc+D3XEg7bZ7B\r\nUHaDTVaGJEaRIPoWwWSWskmSiBI49DrScvVUR0xdV371l7VrTpueiyfwZ4Th\r\ncIunfp3Hz7eE4NBHb/J9BkdWPOlt3lVq/2Rc0ij7rM3v8Vv9ELbhlQzdIV3O\r\nGnkCf83ibhZSgQ/rrD+SmEYO8C4+rgmGqwsJz8KAdagHmdM9rfzM/mZmtIIJ\r\nFWLLsFreyJX0D77N0Eqm4nyC27jJTB01fRA=\r\n=ddhM\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5-preview.34.0_1677146837108_0.2683223425370267"},"_hasShrinkwrap":false},"1.2.5":{"name":"@proximaone/stream-client-js","version":"1.2.5","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"04bd0ae1643726d617acd7a47f595e7a92ebee57","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.5","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-er7TyjkuNt8jRZDhhFW5HEfsNfii6OqBOnwBcHiDCwtFCEaU4jUympJW7bjMstf/+yPUV4ConmOvHlsaqcR7gw==","shasum":"d46280715773c3509b1a30f239ce8f7143e35359","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.5.tgz","fileCount":90,"unpackedSize":237965,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAHrUzfpcOpXOf+30JQ8oGIdpYn286sncLHrjF7NPx6oAiBcvD7kAqLd9ZZZoNow1Pd8edCRGb4e0H/tMFqQXH22TQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj9zupACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqgEg//cut9XdSu4kbTOhGg9gsAQ6NLROGjBet1hOMgvP/n4B+aUIlW\r\n4t/8J4iD34yFHpOj9tqBs+4jmMYHhC5q/VmNVxkgkk04DMmjeyc1vAAhO1Vx\r\nXVahOdf3ZcwP6djW2+RXde1BCS6tDQ+O5de/DWfvVbevx2T825E4x6QBJ05n\r\nMlhAaz2Zb2UxVxKtf3PmDBBB5rrHwA/t1Es/Zc973XiuyTONXrNU0QZNtN2/\r\nkYA7ahEoOomf6sGOISP/A+mtYtNe4StTj6UzGHuZGxyNY073gQ6wdkj8ccT9\r\nj7CR0VEz1DT85WH7QhiXu5gLbADcRgn+Ul3Q/V1qhNBZ2D0WvDMi55InBucw\r\n2rVgJJ3+RA2NcktY+6MuBHVSg+V1BEIJKPfHyN+H7w/BhfTMaF1942Tk8BwL\r\nse7kUxt6WBlAprmyaDGiHCzOU77RuEzS6vdUZUHVxeJ9IsefOZz1b8qe+Wfj\r\numtmoHNWnvQOKskEx1ySQo15ybExOL9Zp8RdIAKdH8IZ9jbTtOSCdzC/fZYF\r\nISnCHiBsanZLYClgogToawpBiEkRNQOZUMZPzE6rceB1PxTdjcBD9btxU4WN\r\nqahDpBOnOlFnUBWyx6UtvEyXre/vmsU6t71eE1Hw6Tt0pq2yhMe0u4hsA1GD\r\nkOOoamXBfdvEZJc/cD1hM1kPNLeq2/7vDQo=\r\n=XdHR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.5_1677147049493_0.5467729522102558"},"_hasShrinkwrap":false},"1.2.6":{"name":"@proximaone/stream-client-js","version":"1.2.6","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"709b410e12f90152cc568fab029646191b87662f","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.6","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-36K5OA+b6Ie/5kGc8zF4FzSyiI6x3LwmiirBdoBXU9LJfaeRHc8aAzj7rY0Jzmi2pnCBMEzpvjxDPaPFT0maKw==","shasum":"50cd50b5f615e06c102e108e14e508954502b34a","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.6.tgz","fileCount":90,"unpackedSize":237965,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD1FJNqly43wTO27jG/leWxxYHVhqdUIjbaaODrr6pZygIhAKzw0vt4ZkevoBtsv9TwmwWckZODpwsAEcuJLduU0d02"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj+M59ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqYVQ/+Opa+V3PsXFpaDSXL1hBTibfsKKGGkTXm8jXRyDHdddccgZtd\r\nyF4atb1wGx60LuiJDvYs3Owwd5KlIghrwDq6tM8PYzr9Xm5+Di8FbnNOY3em\r\niTGsun0piVKM3logd0rF7l09unMKMeqaT9ZJ0ugOLsJeGL8Wd8ljEKJKYQE9\r\nPji0PYwMCj4wnwFmizWE195IwNoPMnC1Gp+uAG+DIqiO9E/cv/QHQfpS2Q85\r\nRNOQtA7kF6lJZDkWOFad3eINnSwqd/UP1nconFTOB82CX29BbOPe0kI+ZhMo\r\nUXeoY5KiVVHwn8RFLAHJmqbFphDZsT//mndtVuNJSk3JG8iijdGwveoPqFLO\r\n7Puiy4CAyXz4bJdWeJURgXPU4+2QCDq9rtvBHDXqLI8/MA+Sx5UQsQGNgeid\r\n9WXIJjGrpXz6iUjeMNqzLP7yexQbQsgxWxtMSnYHH3mDkj5lb6Ke3dtpaeB/\r\n3ixUPTfuLk8rU0DmZibw7EGgiue3YpOx+egwXOtrFgzchmQmB/muCVvxKEva\r\nF9EDN4ZeEuH4zpuXQfS5p1YDbbAbRWjluDaSS4O5HzFDnFVXh2GyWM3f4Meo\r\nfTRVyOu91HlVE2fcyPuTTt4wtPk4n0SzT5TCASb+EblEzsAghl5YexwQsqWp\r\nqLCVgO84/pigNTI6VP/9T1H6o4wuWyIxhpM=\r\n=MFWs\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.6_1677250173543_0.29632798316137343"},"_hasShrinkwrap":false},"1.2.7-preview.37.0":{"name":"@proximaone/stream-client-js","version":"1.2.7-preview.37.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"625f92dc1783d35447cb25fa0a709bd1b80a7b92","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.7-preview.37.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-E25zky72xdPNPYiS0AUaeKjLEgIGjw56QGUhpJUsVrfUn9pOtKXBuUadTMgiGZRbCvxK0yliNqUpjcuQr/s4Wg==","shasum":"a173045e2b818270af55f500cecc87cfcfb0ecd1","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.7-preview.37.0.tgz","fileCount":98,"unpackedSize":245614,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDsan4s5uPIXry6gZ3CYB5zxz4d0v3alg+aS4wiKwS1YAIgLvUy5hHIALih/oORt+Afu7BX2dP8kCAfVmx3pSXeac0="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkAJJNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmps0w/9FupLd9NQJVm3F3Pp3IcPrA6rprICESRMA1oCfjVkT969VaOc\r\nAX3HbRraqikZ6gHkCh7N1Uk98hYsqKF151BYYrV2Rns1advkSUF6Ehy0UhKw\r\nU32sS3eVLlo2B0i5g2vByiB9QS1l0FK3R3DZVloeI/3rAk/VAhqMfCKseaXn\r\nBh0+G6zmFNu3aqvk492hsEOY7ilVq4qAmwv64bJ3f5FSs8aDo0paZugZtnRa\r\nZSatEsYt2RYw3MheMwAB7aSxiVZ4c5ERVsSMbQYoWxL7mnlz9dE4IK6cAMC7\r\nU7OPeQc3yhMOyweAgMj/8OBb65h873Bxf70K+nhQHo5kNIYXrfh76p5nU5j1\r\nI96wnXNnRosJwViP+z75K4Bz2O/obw5dSp/th+/yheSvoMm/pIe9zSRT3CER\r\no0aQJng9wH8VHCu56r3PgGZWm54RL5r+Dhv05PjmEqXbTvlVTs58LLhbrFof\r\nUGC9VwsL1K0Z92cfgbiJOjgPkWiYsG1vBWi33j5tcvmUh4h2Uh4A4h0JzK4y\r\nMNPtnfYLZ06pJCuXATuOqsAeog4X+W0JfLQ5RET3YV2LtS0u4tMvodV9xXUH\r\nt9co7lDvKejuj3PW4k+yOcQ2fviiyao0neIesIBy9VCjyEJsv38z4/7kRKRi\r\nqZ9mH2d7CdEzbbCRQ7/VTiefUl4KrupClmE=\r\n=dPyb\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.7-preview.37.0_1677759053593_0.3370193792836429"},"_hasShrinkwrap":false},"1.2.7-preview.38.0":{"name":"@proximaone/stream-client-js","version":"1.2.7-preview.38.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5","websocket-ts":"^1.1.1"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@types/node":"16.18.14","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"20c2d3eb6fe41f1216c35c8b520a4f415991a28d","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.7-preview.38.0","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-hhw3kJvRCzN2sWVsCLs5nIqB8xJWG1DPL7VHiAT8uI9NgAxcZw+8thGLoW2FJ7mD2yIrYvx/nAiNJ6PyQiT15Q==","shasum":"76637021f087c8c5ec98f3898ff93c29eff7e860","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.7-preview.38.0.tgz","fileCount":102,"unpackedSize":248349,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIA9klpZebzOntREAegZXaVIRFN3RebdyIuKaGrrubc57AiAKOuofijTD2SGTgjCZdD49RHnHS55hFrd4PQCBWXRCRg=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkBiWYACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpXCxAAjpJFlnlGcX9RCJm3md6tA1liYIF0qaFCyj+WLB6oNuQyZPcb\r\nH/3pdHU9IixSxvPGnYwrNxZPtt6+7LB0E6pvEKHFwGIsBRM6LEewFjdoAj4J\r\nkSrz3Hh+O16Mjq7YC5T7NXZm4KhOK5nhLO6MLLy3pjigckcyjnGKgCZUoc22\r\nrbIcxguXHn34PXOLuIj5afRYw/voWGqfc+5nAUNIAd6XO9vktxK2z20cgBxT\r\ng460OoEcujG3QtRT4eyOJ/b6kE9OsXMWamYrYEUER+Qp8cnu3jGfUIhV6roU\r\nkfcoOkAnVdICeZZAR/jBJEc7ny+kMVIXaHj9m1rf2D14mpKfDdPSroCbPjvd\r\nVnXZrskmdckg5xPX/9wWqJn2W2nwj1kemt5arPmyCWkQvpqzc7mshUqfiY9P\r\nZZVdPNXmjMtelpa15DT2aReBIW0Bnts0GSpX5vA5t/fx7l1TsG7NqjZM1Bjq\r\nAlBnDYePoCh8g+5mSTt+ZY/MbL0FEa06N7iHVydyIa/IgX+bqFYI12qRW3fs\r\nf8i8CI4XECipW8z/haHpZkZksTFEVOcAnB81Zu8QFFtuwKTcTJxrcX+JYHyJ\r\n4qCMxpWhtE2jfBwIIX734uv52Vh/r/H1OQTFVDIbRVtF0T+ouZdU3GePs2Ff\r\n8TP64ShuXH+6vC919Ns8X0nqlh/xmoPjbwM=\r\n=nTTo\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.7-preview.38.0_1678124440751_0.059979324776378684"},"_hasShrinkwrap":false},"1.2.7":{"name":"@proximaone/stream-client-js","version":"1.2.7","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"1b2ea60810498b088eca782e44252b483bc074f5","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.7","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-QXrz1S8Vmyl6C7pyGhiudEDXQus92oSmFzCcGSaGzW7cglhTNP7HWdvudTW3N9r2sClcou1bjliDUW2KDceFFw==","shasum":"f1a36c1315ff8d148ad784244cda5161b88bb57c","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.7.tgz","fileCount":90,"unpackedSize":278749,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHEWvV6oM9m3ANOl/ISqrsD5FR5dVmhqyur1JAIvKyJmAiEA1LF1HzBiyaqVh4hx1NbN3XFY0JsujvLN3lTNJW8J5ME="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkEy29ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmriTA/8CyGMDWsCCJcp4eFQ2yndptCf7x3NsIlob8upFIzNslzPCLUX\r\nhB3Ly9BAGuU1Lf62fuzPi4UkFZKTcyDe6+rzKmP2Fk/vQ/T+7doGzrsYy4Rc\r\nD7wb6mlK/RXBj8K4iRVz1oL+WcGPNKoPU3t2bjlVu3q2JpGses5qttvMyke3\r\n4kdcMCfwC4iO6fbDYz0eVR3SuApYT8lBnOxBm2nTSSCOyqhGjgczwwb03f5p\r\npTjIchFfHQsfImdqhcp9kjfcp05Ca7JLWavmQUe6S6x8v40cIyOtWWIdpAEp\r\nNevfDX/DvnnF3MudtOUyaPb4JC8DZVfIcOi82YYysTSwJvZyDXjv7jLmq+ap\r\nOKhD9rAJf0JWYxDeiYp5PssEVElpwy9Ow2hgiv3F4T+Jc340PJG7tRjscKIi\r\nHjh8i9VX6hzBUrihBE1xOecfRYQwCUBBnTwApuSvdwUZpk+NcUscZPgX9LwZ\r\nlANSSbvHCyMlEWuWu7rmoGDjfb7K5eVoQK1MzIrvoxNZA3KODokeEhjnhfYe\r\nKeIF9f4hDHnP6Ce7CRClpQobd9/VI7eqT6DICf/u1PFt/uUsXe5PPRYZjRsg\r\n0uFbZvXlnWZY7Q7D1gvsQzg3tbr1kzIXvQZOg/wq9mv9VCd0KyE1LSZRxGOW\r\nLRQx/abs4eEcvuCh6jcI8oAjeMW1YLykg8o=\r\n=e6Ql\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.7_1678978493451_0.6096226298943404"},"_hasShrinkwrap":false},"1.2.8":{"name":"@proximaone/stream-client-js","version":"1.2.8","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"48d5f3be37351f6a9822c6fdf7f768d80536cf06","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.8","_nodeVersion":"16.19.1","_npmVersion":"lerna/6.5.1/node@v16.19.1+x64 (linux)","dist":{"integrity":"sha512-BNMRqub/TCXWyvbfur9InDSFjDDl5X1jjb0FX9oKgY+4Z5meXvfRVQiN27PFxpO2Uhq7aZS6L7Dx/YHva5id0A==","shasum":"7996ce8e4566f67f971cbc74196eaca670586b51","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.8.tgz","fileCount":98,"unpackedSize":497119,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAQPAQa4scH9UNQfmyGy7bRJRxCQpnea9QXhjEv7vl1TAiEAjBK/G2vTZICnL18Z2itVZ/LbdRiUkPiWMxH4GG4umLo="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkFClSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmrnfw//YtuJ93t/ji3fwHxbjlXb7IG/uen5AGboiMyuMSgv5aLa9IaD\r\nz7voeKkgntM+Pzi9nM1IV//1SZIdWfG3PatS7HYO3rAeQ6QbkqezcTZU9ba7\r\nx9RJNOQDXOid+B5SDPxx5DC34sqU5+WcWfVtqsAi69jID14FrDwDunyd1QvB\r\n6gr/+JdSPMiaHcZSIZA1fqmAhi6GNcD/AiFCJAyLM7QBn3f1Jn2EPecOmHFE\r\nnjQHuw9smnWP2UsmGpuYrjVHMe1BGAwDJpAfpFBrgCAlqFIAD3BSiFQQ9vrN\r\nisFBU5w45tMm6fz9fsq19D/VvrRH9eEPbRh/7lsxG1h4fALlE/3nMLFk5z1a\r\nf3sxzMCWiPRuIuxmxMsGLK3ikiir0fh9DaRmdttvWZ+j+2gApuX046bBTikm\r\n/wS4RLKVq0QiP521Gw2NVQcaEDSFk8Z58Yc+22YfuPo8wQ24ZJCvErfDQSBL\r\nSliWUUlRFiS/H0b2GaVTgtt/j/APGpxIBo4tFbgZ0XvjYXUwdue3ee3oDNNL\r\ng3xg/ywgt+IuKvPy/Z4w0fzuNeVOFdAKMlK3TiweitZvEY5CBxWVwQbfzKjq\r\nP/zuuv3RAG3Q2E+acSa7L83JbxNww4JeeNXMCZ6uFftn2RBx7JL2e0YyiWBr\r\nYH4sUVZcSACx5eFeqRtIfv8sMm6lkGZud94=\r\n=JsM8\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.8_1679042898655_0.06874295901571892"},"_hasShrinkwrap":false},"1.2.9-preview.41.0":{"name":"@proximaone/stream-client-js","version":"1.2.9-preview.41.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"2d936edc9f53a18724d59414cae1543c1d14413c","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.9-preview.41.0","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.1/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-1mD88dvWQRumiTpeqU3XCKaQpM9mve0lz8ImamtsNxgO1KhJufBeaFzoG/r8P6sFSH90/Sc/J1XxG55FWt4w1A==","shasum":"37255628d0e6f1c26e2943ff224af7d21b142b93","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.9-preview.41.0.tgz","fileCount":98,"unpackedSize":497196,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHV/LEoBk1/Bmqp4Xs5Pf56u5kH5xX0iYG0yKKTy7H49AiEAtM8mn+L9ULHPfg+Ub+CI6invobXbaNcbnq73AWtI32Q="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNoyTACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrlvQ/+OIszhAkYrdPfZc/6Q8y6Mz11FImEEh14auU7hyArtUI99cK1\r\nGynHx9rPvbsCQCiNjTdz7Zl1biuWJMbv9piDhiRt8XL+OHK5tUg9ImZg3QbD\r\nwOzBgf7QsHnDNIjd4QTzieyKw/60q7aUTTyGsEZ6PBtMpl1NCfSi1YQfri39\r\nCqOGwZm2ktzxctGbnf5Se9QV2xXSWdSUeMvZGdvXeEqZ8StlAk7H5Cg1BI1s\r\nIbKdCAJbgbAIQ2UaInwBqcUpejKkyHgSZclJtBlZmytHns8ujVSofdW5BXZA\r\nwgWomnmX+px/RkKdMCv0J2dot6NyROo8mqqAaALoUFI5agQP868pbFtpnV34\r\nTgXlPi3OmYlCIyd8+uWjJ6+tB1HbNFPqF7rIJO3WHAxTuFx/5tuKWsUeviSh\r\nuzH6PuG2QLQQFUadxlFgwtpa2WTDOkMYzrQv1AAuwtiZ3fP0kwV0z08ljHUE\r\nj20oqaFgNxV0NSJ447IAuNvIfAeLbLwoEArCIXsB8GB8waXNtugwAMsVHyNK\r\nyEl0nC02E0Tj6ff4za0H8nmKdKvNPIP09O2KRGRsqbJVkTOL2xVdtA4IJ7pi\r\naueNEk1hCelamG7bBhQmtL1xbOZEsaeKiJhMZ+adhiMPlXBuaXSAZ5uhmrW9\r\nh/JXMcEUCc9Zw3yXiUk5YWYRPwVSf73/UzY=\r\n=85ec\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.9-preview.41.0_1681296531074_0.8044929567341019"},"_hasShrinkwrap":false},"1.2.9-preview.42.0":{"name":"@proximaone/stream-client-js","version":"1.2.9-preview.42.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"30266bfa735f983b9812ee764bcf21f9ae7a78ed","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.9-preview.42.0","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.1/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-eOc+onLcgd05Hf9VRmPgDEXx4JXE7T4TWuAry5gGOGC1XMG5p49zUBexKATccGu/FnGnypdxEgVtMK0gbkq50A==","shasum":"75afd9b4c60aeca0d17ff1ac6f080f8b37856290","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.9-preview.42.0.tgz","fileCount":98,"unpackedSize":497140,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIG5snxbWGUqaB5PpBSj4gaQZPvQnzrNeHrZN29Z63POPAiAoLLeeM0dUKgWZ3MW2CqTM9fCe0c/egKtsfzP6pzqehA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkNqbeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoiNA/8DekuvDytW7GTZ/YbdVn38AxMOpbzuAh76/Gaw+9G9M/XIVaW\r\n10/Nt43GOYFt/gD4IuYDosMYnmC6pm0xfAW6PiYn07PVUL/7+OHwU4zTuj2N\r\nlUDDQ1idaw51iku7xooTawWlN52N0FumS4iu+yHzx6r4Ib+SiUmoe7p52jTp\r\nq0FoMuVHwXJYEzarp6h+Ypt3vHjJ42bRCUTlfbHlXdwjB1oCKG0qSi1zdlX8\r\n7d5+rwalgdeAs4wxE0US0+dWOJMLQMDy/Bppe5SeZJkes1wnW/njLnAitdGF\r\nFQp2GRcu3R/SMmjEa1eUYCe9uOkeA8SbvPjHlfYEEdbdoqA6PGnlaTC3V0Z3\r\nTpNdAF40ykqs7rRfODWG8BP8NIwhOIauaZ9B4mjXf4vb2HXz6txEIODQzQbj\r\nd3TnT3n341doaPXVCIqawWBy56BxCPxQgrGLmW7Wm6SiARSjA5Z1K3HtccJ9\r\nISfn5UkI7Uai9BESiJ0MIP9snLpYSM1lSiHgEDa9o9yhT+/Jg7T+xRJqMv7S\r\nJ4iYIQ9ltsgYbYPyvy21mEP0s2naMk1RoNcehUA5rcHbVtTtlWOiaTkgcKIU\r\nY0ztLQOxopdGy6cyrNmsz29hJqz9q411LEwm5Og4MykFWa2CV13CsbxJ54CB\r\nkn7T8NovA/ViH1XRwQtWjozalJBJ7eXn/Fo=\r\n=yjLF\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.9-preview.42.0_1681303262064_0.370387928813698"},"_hasShrinkwrap":false},"1.2.9":{"name":"@proximaone/stream-client-js","version":"1.2.9","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"96f4b901ac12cb5878ab76555b1122fdd400c836","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.9","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.1/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-H94ePl9s7G5CfSa+Fv5hw30+/Ta+vk/GlSc3st9t6A4wVpla2O/KdUe5TZTf9ereLjZ6sAxeAwdBqA7WPaguiA==","shasum":"20a7b7e56700064f69955885f3711e28a2de21bd","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.9.tgz","fileCount":98,"unpackedSize":497119,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID1lYi/IXOiyUqGQBcRczEQQmc85nv0vL9aw/L+XO7rYAiBdvoY1BwX26rKR4heEJRbiMFOf4HU1wK853QahoCMm7A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkN7kSACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmplzw/9E55zzsIExC4bUiKrhTYSNUQruAHV7l5WXDZw+YOagRS2LzVf\r\nLbUnHcX0rLRvvaPhAHVTRz6Q/vjsl+cfhhNQd8bMIiLTzpe7j1ZOSqcObenT\r\nOHtwvORAhOMCOfjNxdZutO5AJ0RdgpTJUybCSWkBiHqOwHQzk+YcBL38etyd\r\neKPjdUFlpdxyk8bCfKIvt3WTH/4MZuZN2UDJK+rC6VfS/vxmsvAJq5f+EUdx\r\n16OfPRh9ZgFZ+EhYIuOAbRHaQMXYbsZA8sGMdEF29i0ix/0jiHh89g9rijXc\r\n2/wK5B8+/tkMNLidqGq6uImYbv+HE5OWXh+eFzoG4HkqGVLlvtnVngvDG5GV\r\nTmPvWHWrgpSLDzDQ3GIw5u5pu5yY91HvCbYMQO7GRTM+XgNGL9SoZHA9EAF0\r\naONzv8sDct2xh3uNyFVQrF7eP0MdQCnEjhmhNesRf/ZLAgsTYfAE9fCRLBFB\r\nx2X8oC/1mVCniIOdCMu3aVuyBnb+8PFdPQse3cZQAYMg3LwDZ0IW8vuRpPWh\r\nvqHDSB7fprdFJ0kRzr+nkHu+4hDPIHAi/NfkhLP2ZzYdRWyTJ+RRYaTT7glh\r\nkx7VMyGwlQ7O9yqGRufWJMMM4BbyGejwPHKYpP4i7p3o70lyg6COxYndhR6Y\r\nSaN5mhdAFZgewoY7ceeePryYLWADLyLFWOg=\r\n=kSMG\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.9_1681373457867_0.3179281261497138"},"_hasShrinkwrap":false},"1.2.10":{"name":"@proximaone/stream-client-js","version":"1.2.10","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"9603b73d067402880eea36225dbe79cbce508ae0","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.10","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.1/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-1R+gNaWULOIFpsitiLsrQYF0zZfkys72ToznZY06R/ukyu0VKCaRKwTuf9Ts/OHBOnkrnuOHgGbOH3sdWoT2Vw==","shasum":"27558aef278d9ad1c6e2fa01b285989469b19e35","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.10.tgz","fileCount":98,"unpackedSize":497367,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCj5hFRLRiW0ZP28TElB05h7uk4RIvYDGtmcxnE3ov7BQIhAPB1SvuB/7c4uuCjJZlC3qUCnmKpekaX5ajd9OGha7zb"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkT73/ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoT0Q//QNJeHXJW95R+8vnkOEyHIIh9f6NoRDWxp7R9DVa7cthJ3TWs\r\nfAG4RWDsdKWH9ljqrL34M06ZCzsQWZ6g+hMPwPD/XcWWtzjZix1UOKkXP80+\r\nZ14FqlHlM5RLxS2CZUS2ne9ly25PrA1q7qN9lfyF99kGQGzCoRzMJCzO5ANv\r\ndQRus0gdB0tFFfy1qWmWmtEmo0NQKuJ2n99v8ujwacjhqt/0Tp4/KZHz8oRn\r\n40wIdiwF5yUh2EN3kvJjS8cwSI8BHhs6XrF83o9xsZq/pFqm9a2QiVmn/cd1\r\nU7ohHFlOvY3YnQL0JGwIlCk9fOG9bgRp3YvhPxd92JxT4p5n+Sy0hoqmEeSa\r\n8ZzJeW5YSL75i+Jovqw5s4sEv3sf0tpjiSoCuzNWaG5OBtQ6fKgzR5/1BToe\r\nWhAKFX7r+txQsPu8sUqF83+XWuplCNklbPnZ3Uk3Ptu3+4oknPAycUMBZap/\r\nNr49j0XnfUEi3O8fEyjHbQ3ElAx1JuQMKgKj2Na1Oa+iiph/7/5Pa+LTZij8\r\n5wgUoIAiT8/bg4FbdUAux/PE65t9TrfKfSS3NQ2ulfsNCTw9bPJodBQ8eOV4\r\nOUndCx0ocCXH33JLsMHswzZYU75px9nevSnCuE6Ghh+IPOxW/Us7Ss4Wuxw9\r\n3h1J1mYasGwq3wt/Qvnu4VF8E73lqZ0Gg7c=\r\n=SHqR\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.10_1682947582986_0.2555993190727981"},"_hasShrinkwrap":false},"1.2.11":{"name":"@proximaone/stream-client-js","version":"1.2.11","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"d767a14c3facace5eb45e9f4ba614c6dffacb043","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.2.11","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.2/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-3hxwDElqHw8n+WdDK4y7/WcnWu/cd588xbv6PTOG1nSK/UVclbq/Dni7GuJBqyQZXziKxGDepNdi02Lr4+A4rA==","shasum":"ad14c9cc79bef85866f0b2878711cc675d1a96ea","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.2.11.tgz","fileCount":98,"unpackedSize":497367,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGelIxFS5SnxdnspzaG+tAVbl5nyDwSXz0cdCM13ySuzAiBGe/lb7FwZICBDQn95sNHZEJtuyZ+ZfnTTnqU6q8FLew=="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.2.11_1684237522829_0.3530111857429994"},"_hasShrinkwrap":false},"1.3.0":{"name":"@proximaone/stream-client-js","version":"1.3.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"290cfc3a316c68ff48f14ccb782c0c532c55f8a1","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.3.0","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.2/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-Fk4GpJ7Xtt0zu9qFlM5og1hPuQdqrhRx4K14KTceJQFSuBSC9gSHGyRSyUyJTJULEHvgGre40A2WI/HVTis9Kg==","shasum":"b7ae4d5f88535711487e333b3952a46b1160f6aa","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.3.0.tgz","fileCount":98,"unpackedSize":497568,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCSr5L4O0tvZl2OmvSrAbSB5CBKy8679InB4nvhXf2eUQIhAPoq0N7MvN3GPguCFA8ojoLyW2K34a4G1i5iq8qDdUy3"}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.3.0_1686041606662_0.44214568295339585"},"_hasShrinkwrap":false},"1.3.1-preview.50.0":{"name":"@proximaone/stream-client-js","version":"1.3.1-preview.50.0","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"995849727388be426b84eac199d806bb3a9c7123","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.3.1-preview.50.0","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.2/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-MEdjjORFCARBIARlWLLJTO2e02VhPiZoltAJqgw6AxoRtXitAUYDTi6+b3iDsdltxybbi3ZCjjUvJgYNTiDAiA==","shasum":"1ed5c2fa88a95535170cbc23e847dffe7b828d5e","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.3.1-preview.50.0.tgz","fileCount":98,"unpackedSize":498771,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCLo/TTdaMjmYymbMvAsdBFiK1KcrY7wnMoy8tcxOeCIwIgOHHInny1uFvuNPACX1XV9qo4JCH39XoDbC56Zg8dVPQ="}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.3.1-preview.50.0_1686816807970_0.4777658583106734"},"_hasShrinkwrap":false},"1.3.1":{"name":"@proximaone/stream-client-js","version":"1.3.1","description":"Proxima Streams client library","main":"build/index.js","types":"build/index.d.ts","publishConfig":{"access":"public"},"author":{"name":"proxima.one"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"scripts":{"prepack":"yarn build","clean":"rimraf -rf build && rimraf tsconfig.tsbuildinfo && rimraf coverage","format":"prettier --write \"{src,__tests__}/**/*.ts\"","lint":"eslint . --ext .ts","copy-content-files":"copyfiles -u 1 src/**/*.d.ts src/**/*.proto src/**/*.js build/","compile":"tsc --build","prebuild":"yarn clean && yarn format && yarn lint && echo Using TypeScript && tsc --version","build":"yarn compile && yarn copy-content-files","codegen":"buf generate","dev":"ts-node ./src/dev.ts","test":"yarn test:samples && jest \".*\\.(spec|test)\\.ts$\" --coverage","test:e2e":"jest \".*\\.(e2e)\\.ts$\" --coverage","pub":"lerna publish --no-verify-access","test:samples":"tsc --project tsconfig.samples.json"},"dependencies":{"@grpc/grpc-js":"^1.6.1","axios":"^1.1.3","google-protobuf":"^3.20.0","lodash":"^4.17.21","node-cache":"^5.1.2","rxjs":"^7.5.5"},"devDependencies":{"@types/dotenv":"^8.2.0","@types/fs-extra":"^9.0.11","@types/google-protobuf":"^3.15.5","@types/jest":"^27.0.2","@types/js-yaml":"^4.0.1","@types/lodash":"^4.14.168","@typescript-eslint/eslint-plugin":"^5.8.1","@typescript-eslint/parser":"^5.8.1","copyfiles":"^2.4.1","eslint":"7.24.0","fs-extra":"^9.1.0","grpc-tools":"^1.11.2","grpc_tools_node_protoc_ts":"^5.3.2","jest":"^27.3.1","js-yaml":"^4.1.0","lerna":"^4.0.0","loadash":"^1.0.0","prettier":"^2.5.1","rimraf":"^3.0.2","ts-jest":"^27.0.7","ts-node":"^10.3.1","tsconfig-paths":"^3.9.0","typescript":"^4.4.4"},"gitHead":"0aee8f7381c9e6b44a29da079ff79e4cd6daf9f9","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","_id":"@proximaone/stream-client-js@1.3.1","_nodeVersion":"16.20.0","_npmVersion":"lerna/6.6.2/node@v16.20.0+x64 (linux)","dist":{"integrity":"sha512-CxhnwXbZY4HZ+zpgE2z2G6fEwA45Y202+0B/zBvGrVS3dMmNds3Hh/iy1INLK0hA4IISJC+ZnhCYOZcwVu0jrw==","shasum":"eb4ca31adc53be3d5a4f1e272f16f50477e1b994","tarball":"https://registry.npmjs.org/@proximaone/stream-client-js/-/stream-client-js-1.3.1.tgz","fileCount":98,"unpackedSize":499345,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC0tGYC5EnSF1yHMV9KvjgpZKU/+jTnabv7yHV8jvXJCAIhAKe2GNFj5b/XEYjoQ7s/IdobxVSjUZ1or3dzMAmAKXrg"}]},"_npmUser":{"name":"ivan.proxima","email":"ivan@proxima.one"},"directories":{},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/stream-client-js_1.3.1_1686823494899_0.5465964201587179"},"_hasShrinkwrap":false}},"time":{"created":"2021-12-23T13:26:06.023Z","0.1.1":"2021-12-23T13:26:06.248Z","modified":"2023-06-15T10:04:55.285Z","0.1.2":"2021-12-23T14:01:34.969Z","0.2.0":"2022-01-17T14:59:23.654Z","0.2.1":"2022-01-17T15:11:38.644Z","0.2.2":"2022-01-17T15:20:31.500Z","0.3.0":"2022-01-25T11:30:00.544Z","0.3.1":"2022-02-03T14:54:42.106Z","0.4.0":"2022-02-20T18:58:00.345Z","0.5.0":"2022-03-28T11:06:32.168Z","0.6.2":"2022-04-02T19:32:47.067Z","0.7.0":"2022-04-03T12:24:59.306Z","0.4.1-preview.1.25":"2022-11-08T16:51:58.547Z","1.0.0":"2022-11-08T16:53:21.699Z","1.0.1":"2022-11-16T23:10:54.585Z","1.1.0":"2022-11-22T20:18:45.188Z","1.1.1":"2022-11-23T18:22:44.144Z","1.1.2":"2022-11-23T18:23:49.793Z","1.2.0":"2022-12-08T08:09:15.902Z","1.2.1":"2022-12-20T06:25:10.207Z","1.2.2":"2023-01-14T20:26:43.623Z","1.2.3-preview.23.0":"2023-01-19T10:41:25.031Z","1.2.3-preview.24.0":"2023-01-20T14:46:09.439Z","1.2.3":"2023-01-20T14:46:33.471Z","1.2.4-preview.26.0":"2023-02-22T09:14:06.585Z","1.2.4":"2023-02-22T12:54:49.558Z","1.2.5-preview.29.0":"2023-02-22T13:57:07.693Z","1.2.5-preview.30.0":"2023-02-22T13:57:50.309Z","1.2.5-preview.31.0":"2023-02-22T14:01:33.782Z","1.2.5-preview.32.0":"2023-02-22T14:04:34.123Z","1.2.5-preview.33.0":"2023-02-22T14:09:42.509Z","1.2.5-preview.34.0":"2023-02-23T10:07:17.290Z","1.2.5":"2023-02-23T10:10:49.682Z","1.2.6":"2023-02-24T14:49:33.699Z","1.2.7-preview.37.0":"2023-03-02T12:10:53.775Z","1.2.7-preview.38.0":"2023-03-06T17:40:40.925Z","1.2.7":"2023-03-16T14:54:53.615Z","1.2.8":"2023-03-17T08:48:18.824Z","1.2.9-preview.41.0":"2023-04-12T10:48:51.261Z","1.2.9-preview.42.0":"2023-04-12T12:41:02.398Z","1.2.9":"2023-04-13T08:10:58.108Z","1.2.10":"2023-05-01T13:26:23.167Z","1.2.11":"2023-05-16T11:45:23.041Z","1.3.0":"2023-06-06T08:53:26.963Z","1.3.1-preview.50.0":"2023-06-15T08:13:28.188Z","1.3.1":"2023-06-15T10:04:55.155Z"},"maintainers":[{"name":"ivan.proxima","email":"ivan@proxima.one"},{"name":"chasesmith","email":"chasesmith@berkeley.edu"}],"description":"Proxima Streams client library","author":{"name":"proxima.one"},"license":"MIT","readme":"# StreamDB Client JS\n\n## Installation\n\nStreamDB Client requires [Node.js](https://nodejs.org/) v12+ to run.\n\nInstall @proximaone/stream-client-js package.\n```sh\nyarn add @proximaone/stream-client-js\n```\n\nInstall the dependencies and devDependencies.\n```sh\nyarn install\n```\n\n## Relevant Links \nTo get a simple look at streams without using the client you can check out these quick links:\n- Stream Registry: [https://streams.proxima.one]\n- Streams API Documentation: [https://streams.api.proxima.one]\n\n## Client Usage\n\n### Reading the stream from the beginning\n\nThe most simple scenario is just consuming all the events from the stream.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst name = \"proxima.eth-main.blocks.1_0\";\nconst pauseable = await client.streamEvents(name, Offset.zero);\npauseable.observable.forEach(event => {\n    console.log({\n        offset: event.offset,\n        payload: decodeJson(event.payload),\n        undo: event.undo,\n        timestamp: event.timestamp,\n    });\n});\n```\n[Full code](samples/basic.ts)\n\n### Reading the stream starting from given position\n\nSometimes you may want to skip first events of the stream and start reading from a certain point. How do you get the offset to pass to the `streamEvents` call?\n\nOne option would be to find it through the UI (TODO: add link).\nHowever it may be more convenient to do it directly from the code. For this you have to use `StreamRegistryClient` which provides access to information about the streams themselves. You can find the offset by events's height or timestamp (see [Concepts](#concepts)).\n\n```typescript\nconst registryClient = new StreamRegistryClient();\nconst offsetByHeight = await registryClient.findOffset(name, 1000000);\nassert(offsetByHeight);\nconst offsetByTime = await registryClient.findOffset(name, undefined, 1667131199000);\nassert(offsetByTime);\nconst pauseable = await client.streamEvents(name, offsetByHeight);\n```\n\n### Finding all existing streams\n\nAnother useful function of `StreamRegistryClient` is fetching a list of all streams. You can get the first event of each stream like this.\n\n```typescript\nconst client = new ProximaStreamClient();\nconst registryClient = new StreamRegistryClient();\nfor (const stream of await registryClient.getStreams()) {\n    const encoding = stream.metadata.labels[\"encoding\"];\n    if (encoding != \"json\") {\n        console.log(`Stream ${stream.name} has unknown encoding: ${encoding}`);\n        return;\n    }\n    const events = await client.fetchEvents(stream.name, Offset.zero, 1, \"next\");\n    const event = events.pop()!;\n    console.log(`Stream: ${stream.name} (${stream.metadata.description})`);\n    console.log(decodeJson(event.payload));\n}\n```\n[Full code](samples/streamsPreview.ts)\n\n### Handling backpressure\n\nIf you are processing events slower than read them they are accumulating in memory possibly causing too high memory consumption. In order to automatically pause reading new events during consumption you can use a `BufferedStreamReader` helper.\n\n```typescript\nconst bufferSize = 10000;\nconst chunkSize = 1000;\nconst streamReader = BufferedStreamReader.fromStream(pauseable, bufferSize);\nwhile (true) {\n    const chunk = await streamReader.read(chunkSize);\n    if (chunk === undefined) {\n        console.log(\"Completed\");\n        break;\n    }\n    assert(chunk.length <= chunkSize);\n    console.log(`Processing batch from ${chunk[0].offset} to ${chunk[chunk.length - 1].offset}...`);\n    await sleep(500);\n}\n```\n[Full code](samples/bufferedReading.ts)\n\n## Concepts\n\nIn order to fully understand the client design you should first learn some facts about the event streams themselves.\n\n![Fork illustration](resources/handling-reorgs.png)\n\n### Handling reorgs\nFirst, the streams are immutable (append-only). That means that after the event was produced to the stream it can never be removed from it even if no one has consumed it yet. But the sources of most our streams' events are blockchains which are not immutable. After publishing events coming from some blocks \"X\" and \"Y\" those blocks could be \"forked\" rewriting history with blocks \"B\", \"C\" and \"D\" instead. As we can't remove published events from the stream, we publish \"undo\" events (\"-Y\" and \"-X\" on the illustration) which logically cancel the effect of previous events. Each \"undo\" event corresponds to the last uncancelled event in the stream, has the same payload and has `undo` property set to `true`.\n\n### Offset\n**Offset** is some unique pointer to the place in event history. Offset actually points not to the event but to the state between the events. Every stream has initial offset `Offset.zero`.\n\n### Height\nWe call a **height** of an offset a number of events directly preceding it, without considering forks. Hence every regular event increases height by one and every undo event decreases it by one.\n\n### Timestamp\nEach event has a **timestamp** which is the time when the event actually happened. For example, when the block was mined in a blockchain. It may differ from a time when that event got produced to the stream. Timestamp of an offset is the timestamp of the event preceding it.\n\nAside from epoch time in milliseconds a timestamp may contain additional `parts` which help to strictly order the events with equal time. For example, `parts` list may contain index of transaction inside a block and index of emitted log inside a transaction.\n\n### Reading direction\nWhen you try to read stream events starting from a given offset most client methods will require specifying a direction of reading which can be either `next` or `last`. It controls the direction of consumption.\n- The `next` mode starts reading events that happened after the given offset, in the order they were produced. Note that because the offset points between the events the first produced event in this mode may have timestamp greater than the timestamp of the given offset.\n- The `last` mode starts reading events backwards from the given offset. Note that because the offset points between the events the first produced event in this mode will have a timestamp equal to the timestamp of the given offset.\n\n## Internals\n\nInstead of having a single backend service the client actually communicates to multiple services:\n- **Stream registry** which stores streams metadata and endpoints of StreamDBs for a given stream.\n- **StreamDB** instances which store stream events.\n\nFor accessing them there are two client classes:\n- `StreamRegistryClient` which only accesses stream registry and can fetch metadata.\n- `ProximaStreamClient` which makes requests to both stream registry and StreamDBs. It fetches a list of StreamDB endpoints from the registry and uses it to automatically connect to the correct instances and switch between them when necessary.\n\n![Client connections](resources/streams-client.png)\n","readmeFilename":"README.md","repository":{"type":"git","url":"git+https://github.com/proxima-one/stream-client-js.git"},"homepage":"https://github.com/proxima-one/stream-client-js#readme","bugs":{"url":"https://github.com/proxima-one/stream-client-js/issues"}}