{"_id":"@dashevo/blake3","_rev":"4-9c6b6efbd1c5af8f3d1740be74a4399f","name":"@dashevo/blake3","dist-tags":{"latest":"2.1.5"},"versions":{"2.1.5":{"name":"@dashevo/blake3","version":"2.1.5","keywords":["blake3","node-addon","hash","webassembly","wasm"],"author":{"name":"Connor Peet","email":"connor@peet.io"},"license":"MIT","_id":"@dashevo/blake3@2.1.5","maintainers":[{"name":"shumkov","email":"ivan@shumkov.ru"},{"name":"alex-werner","email":"alex@werner.fr"},{"name":"nmarley","email":"nathan.marley@gmail.com"},{"name":"cofresi","email":"cofresi@dash.org"},{"name":"antouhou","email":"antouhou@gmail.com"},{"name":"evodeploy","email":"evodeploy@blackcarrot.be"},{"name":"jawid-h","email":"djavidoff@gmail.com"}],"homepage":"https://github.com/connor4312/blake3#readme","bugs":{"url":"https://github.com/connor4312/blake3/issues"},"dist":{"shasum":"e81bd7096d91edfd0549e1fd8b33e21060b41e16","tarball":"https://registry.npmjs.org/@dashevo/blake3/-/blake3-2.1.5.tgz","fileCount":195,"integrity":"sha512-Rws+fmKuxrEbVPGIH3TdncFyKot8aVWJdBs09eabQQ+05W6x6+vsNt2omoS83TBLaVMW0iAtsrEz5EF12+6/5A==","signatures":[{"sig":"MEQCIAnCFQYD0jWf97wF+Pp5jH83GROfWQszNmdll3QJ0jSCAiA4J+VjjTtgMHrsI6CTI/L0Xt3s8kYtQSIf5Thiy2TaQg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":1543767,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhzscWCRA9TVsSAnZWagAAERwP+wetakK5AIZ3szudrIbV\n9HrFY8YbH2Lts2FkOeaUcazDpTAryyXzmILLNaTG/Q5DLvHVAjtWv1SXMc4x\nNTL2CWNtw8vcsaknCDr85EajEEDn16/8quZc+Xzt9ZKGOlHtIWLm0tDdFjDp\nxto0yXZZIHM8yO0ATDlrXYkGutc1dDslRhCSYjROpksEm0H3NHnlwBvK3Geh\nD/BiMl6IzvxcSzQ/20dLbt5DGQDezHtRBM4/EpAeeWi9ntkVtwv/N4pQtbCa\n/76tspLFKB1Md6JpcTBC6ebdtUELLnSxrcgBXDK8Ojtw9fVaUrJKu83daXdu\ndXG31XjCeQuGFosFJ6Vdj/ZKmjnQ+ee6s+sN4F6U9UpiilB3SARyzqCotF7y\ngEHmWR0M58S8Fzhz8J74M5O8cbPNig1LoSYiDngHW8pHglinyMGKYfW2gBwF\nA/XGeg5HU2kqmM8t5Mbb99pkB/Rw3zO3qwXM8FBQcKD/Iundh8Eu+G/GXi6N\nkNMS9AayriHjPwPr5BebHJloMuxqye6uKwkXU7ostnUSO4mhnDpqfYTA4Fhz\nHnvWj7MvDB8ddoBg4tOgKba29Ss5sRH+YAPNTCyGs1EKsqisWMhP5UfBtFyM\n0EqAP+MWlOTYLBpkBo6dUSiMNnOnShRaZIL63uc+zsm5lnZF6e7Kd/0g9bo+\nrwPq\r\n=Xhs6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"./dist/index","types":"./dist/index.d.ts","module":"./esm/index","browser":"./esm/browser/index","gitHead":"63ace7d9fdfcba45e40bfbe40db9721eb746c76b","scripts":{"fmt":"make fmt","test":"mocha --require source-map-support/register --recursive \"dist/**/*.test.js\" --timeout 5000","watch":"tsc --watch","compile":"tsc && tsc -p tsconfig.esm.json && node dist/build/add-js-extensions","prepack":"make clean && make prepare-binaries-nogit && make patch-loader"},"_npmUser":{"name":"jawid-h","email":"djavidoff@gmail.com"},"prettier":{"printWidth":100,"singleQuote":true,"trailingComma":"all"},"repository":{"url":"git+https://github.com/connor4312/blake3.git","type":"git"},"_npmVersion":"7.24.0","description":"BLAKE3 hashing for JavaScript: native Node bindings (where available) and WebAssembly","directories":{},"_nodeVersion":"16.10.0","_hasShrinkwrap":false,"devDependencies":{"chai":"^4.2.0","mocha":"^7.0.0","rimraf":"^3.0.0","js-yaml":"^3.13.1","webpack":"^4.41.5","neon-cli":"^0.3.3","prettier":"^1.19.1","puppeteer":"^2.0.0","node-fetch":"^2.6.0","remark-cli":"^7.0.1","remark-toc":"^6.0.0","typescript":"^3.8.0-beta","@types/chai":"^4.2.7","@types/node":"^13.1.6","@types/mocha":"^5.2.7","serve-handler":"^6.1.2","@types/js-yaml":"^3.12.1","@types/webpack":"^4.41.2","stream-buffers":"^3.0.2","@types/puppeteer":"^2.0.0","@types/node-fetch":"^2.5.4","source-map-support":"^0.5.16","@types/serve-handler":"^6.1.0","@types/stream-buffers":"^3.0.3"},"_npmOperationalInternal":{"tmp":"tmp/blake3_2.1.5_1635959988402_0.9092221741215094","host":"s3://npm-registry-packages"}}},"time":{"created":"2021-11-03T17:19:48.278Z","modified":"2026-01-20T16:36:13.658Z","2.1.5":"2021-11-03T17:19:48.671Z"},"bugs":{"url":"https://github.com/connor4312/blake3/issues"},"author":{"name":"Connor Peet","email":"connor@peet.io"},"license":"MIT","homepage":"https://github.com/connor4312/blake3#readme","keywords":["blake3","node-addon","hash","webassembly","wasm"],"repository":{"url":"git+https://github.com/connor4312/blake3.git","type":"git"},"description":"BLAKE3 hashing for JavaScript: native Node bindings (where available) and WebAssembly","maintainers":[{"email":"ivan@shumkov.ru","name":"shumkov"},{"email":"obusco@gmail.com","name":"alex-werner"},{"email":"nathan.marley@gmail.com","name":"nmarley"},{"email":"cofresi@dash.org","name":"cofresi"},{"email":"evodeploy@blackcarrot.be","name":"evodeploy"},{"email":"djavidoff@gmail.com","name":"jawid-h"}],"readme":"# BLAKE3\n\n[BLAKE3](https://github.com/BLAKE3-team/BLAKE3) running in JavaScript (node.js and browsers) via native bindings, where available, or WebAssembly.\n\n    npm install blake3\n\nAdditionally, there's a flavor of the package which is identical except that it will not download native Node.js bindings and use only WebAssembly:\n\n    npm install blake3-wasm\n\n## Table of Contents\n\n- [Quickstart](#quickstart)\n- [API](#api)\n  - [Node.js](#nodejs)\n    - [`hash(data: BinaryLike, options?: { length: number }): Buffer`](#hashdata-binarylike-options--length-number--buffer)\n    - [`keyedHash(key: Buffer, data: BinaryLike, options?: { length: number }): Buffer`](#keyedhashkey-buffer-data-binarylike-options--length-number--buffer)\n    - [`deriveKey(context: string, material: BinaryLike, options?: { length: number }): Buffer`](#derivekeycontext-string-material-binarylike-options--length-number--buffer)\n    - [Hasher](#hasher)\n      - [`createHash(): Hasher`](#createhash-hasher)\n      - [`createKeyed(key: Buffer): Hasher`](#createkeyedkey-buffer-hasher)\n      - [`createDeriveKey(context: string): Hasher`](#createderivekeycontext-string-hasher)\n      - [`hasher.update(data: BinaryLike): this`](#hasherupdatedata-binarylike-this)\n      - [`hasher.digest(encoding?: string, options?: { length: number, dispose: boolean })): Buffer | string`](#hasherdigestencoding-string-options--length-number-dispose-boolean--buffer--string)\n      - [`hasher.reader(options?: { dispose: boolean }): HashReader`](#hasherreaderoptions--dispose-boolean--hashreader)\n      - [`hasher.dispose()`](#hasherdispose)\n    - [HashReader](#hashreader)\n      - [`reader.position: bigint`](#readerposition-bigint)\n      - [`reader.readInto(target: Buffer): void`](#readerreadintotarget-buffer-void)\n      - [`reader.read(bytes: number): Buffer`](#readerreadbytes-number-buffer)\n      - [`reader.toString([encoding]): string`](#readertostringencoding-string)\n      - [`reader.toBuffer(): Buffer`](#readertobuffer-buffer)\n      - [`reader.dispose()`](#readerdispose)\n    - [`using(disposable: IDisposable, fn: disposable => T): T`](#usingdisposable-idisposable-fn-disposable--t-t)\n  - [Browser](#browser)\n    - [`hash(data: BinaryLike, options?: { length: number }): Hash`](#hashdata-binarylike-options--length-number--hash)\n    - [`keyedHash(key: Buffer, data: BinaryLike, options?: { length: number }): Hash`](#keyedhashkey-buffer-data-binarylike-options--length-number--hash)\n    - [`deriveKey(context: string, material: BinaryLike, options?: { length: number }): Hash`](#derivekeycontext-string-material-binarylike-options--length-number--hash)\n    - [`Hash`](#hash)\n      - [`hash.equals(other: Uint8Array)`](#hashequalsother-uint8array)\n      - [`hash.toString(encoding: 'hex' | 'base64' | 'utf8'): string`](#hashtostringencoding-hex--base64--utf8-string)\n    - [Hasher](#hasher-1)\n      - [`createHash(): Hasher`](#createhash-hasher-1)\n      - [`createKeyed(key: Buffer): Hasher`](#createkeyedkey-buffer-hasher-1)\n      - [`createDeriveKey(context: string): Hasher`](#createderivekeycontext-string-hasher-1)\n      - [`hasher.update(data: BinaryLike): this`](#hasherupdatedata-binarylike-this-1)\n      - [`hasher.digest(encoding?: 'hex' | 'base64' | 'utf8', options?: { length: number, dispose: boolean })): Hash | string`](#hasherdigestencoding-hex--base64--utf8-options--length-number-dispose-boolean--hash--string)\n      - [`hasher.reader(options?: { dispose: boolean }): HashReader`](#hasherreaderoptions--dispose-boolean--hashreader-1)\n      - [`hasher.dispose()`](#hasherdispose-1)\n    - [HashReader](#hashreader-1)\n      - [`reader.position: bigint`](#readerposition-bigint-1)\n      - [`reader.readInto(target: Uint8Array): void`](#readerreadintotarget-uint8array-void)\n      - [`reader.read(bytes: number): Hash`](#readerreadbytes-number-hash)\n      - [`reader.toString(encoding?: string): string`](#readertostringencoding-string-string)\n      - [`reader.toArray(): Uint8Array`](#readertoarray-uint8array)\n      - [`reader.dispose()`](#readerdispose-1)\n    - [`using(disposable: IDisposable, fn: disposable => T): T`](#usingdisposable-idisposable-fn-disposable--t-t-1)\n- [Speed](#speed)\n- [Contributing](#contributing)\n  - [Publishing](#publishing)\n\n## Quickstart\n\nIf you're on Node, import the module via\n\n```js\nconst blake3 = require('blake3');\n\nblake3.hash('foo'); // => Buffer\n```\n\nIf you're in the browser, import `blake3/browser`. This includes a WebAssembly binary, so you probably want to import it asynchronously, like so:\n\n```js\nimport('blake3/browser').then(blake3 => {\n  blake3.hash('foo'); // => Uint8Array\n});\n```\n\nThe API is very similar in Node.js and browsers, but Node supports and returns Buffers and a wider range of input and output encoding.\n\nMore complete example:\n\n```js\nconst { hash, createHash } = require('blake3');\n\nhash('some string'); // => hash a string to a uint8array\n\n// Update incrementally (Node and Browsers):\nconst hash = createHash();\nstream.on('data', d => hash.update(d));\nstream.on('error', err => {\n  // hashes use unmanaged memory in WebAssembly, always free them if you don't digest()!\n  hash.dispose();\n  throw err;\n});\nstream.on('end', () => finishedHash(hash.digest()));\n\n// Or, in Node, it's also a transform stream:\ncreateReadStream('file.txt')\n  .pipe(createHash())\n  .on('data', hash => console.log(hash.toString('hex')));\n```\n\n## API\n\n### Node.js\n\nThe Node API can be imported via `require('blake3')`.\n\n#### `hash(data: BinaryLike, options?: { length: number }): Buffer`\n\nReturns a hash for the given data. The data can be a string, buffer, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a Buffer.\n\n#### `keyedHash(key: Buffer, data: BinaryLike, options?: { length: number }): Buffer`\n\nReturns keyed a hash for the given data. The key must be exactly 32 bytes. The data can be a string, buffer, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a Buffer.\n\nFor more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.keyed_hash.html).\n\n#### `deriveKey(context: string, material: BinaryLike, options?: { length: number }): Buffer`\n\nThe key derivation function. The data can be a string, buffer, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a Buffer.\n\nFor more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.derive_key.html).\n\n#### Hasher\n\nThe hasher is a type that lets you incrementally build a hash. It's compatible with Node's crypto hash instance. For instance, it implements a transform stream, so you could do something like:\n\n```js\ncreateReadStream('file.txt')\n  .pipe(createHash())\n  .on('data', hash => console.log(hash.toString('hex')));\n```\n\n##### `createHash(): Hasher`\n\nCreates a new hasher instance using the standard hash function.\n\n##### `createKeyed(key: Buffer): Hasher`\n\nCreates a new hasher instance for a keyed hash. For more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.keyed_hash.html).\n\n##### `createDeriveKey(context: string): Hasher`\n\nCreates a new hasher instance for the key derivation function. For more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.derive_key.html).\n\n##### `hasher.update(data: BinaryLike): this`\n\nAdds data to a hash. The data can be a string, buffer, typedarray, array buffer, or array. This will throw if called after `digest()` or `dispose()`.\n\n##### `hasher.digest(encoding?: string, options?: { length: number, dispose: boolean })): Buffer | string`\n\nReturns the hash of the data. If an `encoding` is given, a string will be returned. Otherwise, a Buffer is returned. Optionally, you can specify the requested byte length of the hash.\n\nIf `dispose: false` is given in the options, the hash will not automatically be disposed of, allowing you to continue updating it after obtaining the current reader.\n\n##### `hasher.reader(options?: { dispose: boolean }): HashReader`\n\nReturns a [HashReader](#HashReader) for the current hash.\n\nIf `dispose: false` is given in the options, the hash will not automatically be disposed of, allowing you to continue updating it after obtaining the current reader.\n\n##### `hasher.dispose()`\n\nDisposes of unmanaged resources. You should _always_ call this if you don't call `digest()` to free umanaged (WebAssembly-based) memory.\n\n#### HashReader\n\nThe hash reader can be returned from hashing functions. Up to 2<sup>64</sup>-1 bytes of data can be read from BLAKE3 hashes; this structure lets you read those. Note that, like `hash`, this is an object which needs to be manually disposed of.\n\n##### `reader.position: bigint`\n\nA property which gets or sets the position of the reader in the output stream. A `RangeError` is thrown if setting this to a value less than 0 or greater than 2<sup>64</sup>-1. Note that this is a bigint, not a standard number.\n\n```js\nreader.position += 32n; // advance the reader 32 bytes\n```\n\n##### `reader.readInto(target: Buffer): void`\n\nReads bytes into the target array, filling it up and advancing the reader's position. A `RangeError` is thrown if reading this data puts the reader past 2<sup>64</sup>-1 bytes.\n\n##### `reader.read(bytes: number): Buffer`\n\nReads and returns the given number of bytes from the reader, and advances the position. A `RangeError` is thrown if reading this data puts the reader past 2<sup>64</sup>-1 bytes.\n\n##### `reader.toString([encoding]): string`\n\nConverts first 32 bytes of the hash to a string with the given encoding. Defaults to hex encoding.\n\n##### `reader.toBuffer(): Buffer`\n\nConverts first 32 bytes of the hash to a Buffer.\n\n##### `reader.dispose()`\n\nDisposes of unmanaged resources. You should _always_ call this to free umanaged (WebAssembly-based) memory, or you application will leak memory.\n\n#### `using(disposable: IDisposable, fn: disposable => T): T`\n\nA helper method that takes a disposable, and automatically calls the dispose method when the function returns, or the promise returned from the function is settled.\n\n```js\n// read and auto-dispose the first 64 bytes\nconst first64Bytes = using(hash.reader(), reader => reader.toBuffer(64));\n\n// you can also return promises/use async methods:\nusing(hash.reader(), async reader => {\n  do {\n    await send(reader.read(64));\n  } while (needsMoreData());\n});\n```\n\n### Browser\n\nThe browser API can be imported via `import('blake3/browser')`, which works well with Webpack.\n\nIf you aren't using a bundler or using a more \"pure\" bundler like Parcel, you can import `blake3/browser-async` which exports a function to asynchronously load the WebAssembly code and resolves to the package contents.\n\n```js\nimport load from 'blake3/browser-async';\n\nload().then(blake3 => {\n  console.log(blake3.hash('hello world'));\n});\n```\n\n#### `hash(data: BinaryLike, options?: { length: number }): Hash`\n\nReturns a hash for the given data. The data can be a string, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a [Hash](#Hash) instance.\n\n#### `keyedHash(key: Buffer, data: BinaryLike, options?: { length: number }): Hash`\n\nReturns keyed a hash for the given data. The key must be exactly 32 bytes. The data can be a string, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a [Hash](#Hash) instance.\n\nFor more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.keyed_hash.html).\n\n#### `deriveKey(context: string, material: BinaryLike, options?: { length: number }): Hash`\n\nThe key derivation function. The data can be a string, typedarray, array buffer, or array. By default, it generates the first 32 bytes of the hash for the data, but this is configurable. It returns a [Hash](#Hash) instance.\n\nFor more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.derive_key.html).\n\n#### `Hash`\n\nA Hash is the type returned from hash functions and the hasher in the browser. It's a `Uint8Array` with a few additional helper methods.\n\n##### `hash.equals(other: Uint8Array)`\n\nReturns whether this hash equals the other hash, via a constant-time equality check.\n\n##### `hash.toString(encoding: 'hex' | 'base64' | 'utf8'): string`\n\n#### Hasher\n\nThe hasher is a type that lets you incrementally build a hash. For instance, you can hash a `fetch`ed page like:\n\n```js\nconst res = await fetch('https://example.com');\nconst body = await res.body;\n\nconst hasher = blake3.createHash();\nconst reader = body.getReader();\n\nwhile (true) {\n  const { done, value } = await reader.read();\n  if (done) {\n    break;\n  }\n\n  hasher.update(value);\n}\n\nconsole.log('Hash of', res.url, 'is', hasher.digest('hex'));\n```\n\nConverts the hash to a string with the given encoding.\n\n##### `createHash(): Hasher`\n\nCreates a new hasher instance using the standard hash function.\n\n##### `createKeyed(key: Buffer): Hasher`\n\nCreates a new hasher instance for a keyed hash. For more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.keyed_hash.html).\n\n##### `createDeriveKey(context: string): Hasher`\n\nCreates a new hasher instance for the key derivation function. For more information, see [the blake3 docs](https://docs.rs/blake3/0.1.3/blake3/fn.derive_key.html).\n\n##### `hasher.update(data: BinaryLike): this`\n\nAdds data to a hash. The data can be a string, buffer, typedarray, array buffer, or array. This will throw if called after `digest()` or `dispose()`.\n\n##### `hasher.digest(encoding?: 'hex' | 'base64' | 'utf8', options?: { length: number, dispose: boolean })): Hash | string`\n\nReturns the hash of the data. If an `encoding` is given, a string will be returned. Otherwise, a [Hash](#hash) is returned. Optionally, you can specify the requested byte length of the hash.\n\nIf `dispose: false` is given in the options, the hash will not automatically be disposed of, allowing you to continue updating it after obtaining the current reader.\n\n##### `hasher.reader(options?: { dispose: boolean }): HashReader`\n\nReturns a [HashReader](#HashReader) for the current hash.\n\nIf `dispose: false` is given in the options, the hash will not automatically be disposed of, allowing you to continue updating it after obtaining the current reader.\n\n##### `hasher.dispose()`\n\nDisposes of unmanaged resources. You should _always_ call this if you don't call `digest()` to free umanaged (WebAssembly-based) memory.\n\n#### HashReader\n\nThe hash reader can be returned from hashing functions. Up to 2<sup>64</sup>-1 bytes of data can be read from BLAKE3 hashes; this structure lets you read those. Note that, like `hash`, this is an object which needs to be manually disposed of.\n\n##### `reader.position: bigint`\n\nA property which gets or sets the position of the reader in the output stream. A `RangeError` is thrown if setting this to a value less than 0 or greater than 2<sup>64</sup>-1. Note that this is a bigint, not a standard number.\n\n```js\nreader.position += 32n; // advance the reader 32 bytes\n```\n\n##### `reader.readInto(target: Uint8Array): void`\n\nReads bytes into the target array, filling it up and advancing the reader's position. A `RangeError` is thrown if reading this data puts the reader past 2<sup>64</sup>-1 bytes.\n\n##### `reader.read(bytes: number): Hash`\n\nReads and returns the given number of bytes from the reader, and advances the position. A `RangeError` is thrown if reading this data puts the reader past 2<sup>64</sup>-1 bytes.\n\n##### `reader.toString(encoding?: string): string`\n\nConverts first 32 bytes of the hash to a string with the given encoding. Defaults to hex encoding.\n\n##### `reader.toArray(): Uint8Array`\n\nConverts first 32 bytes of the hash to an array.\n\n##### `reader.dispose()`\n\nDisposes of unmanaged resources. You should _always_ call this to free umanaged (WebAssembly-based) memory, or you application will leak memory.\n\n#### `using(disposable: IDisposable, fn: disposable => T): T`\n\nA helper method that takes a disposable, and automatically calls the dispose method when the function returns, or the promise returned from the function is settled.\n\n```js\n// read and auto-dispose the first 64 bytes\nconst first64Bytes = using(hash.reader(), reader => reader.toArray(64));\n\n// you can also return promises/use async methods:\nusing(hash.reader(), async reader => {\n  do {\n    await send(reader.read(64));\n  } while (needsMoreData());\n});\n```\n\n## Speed\n\n> Native Node.js bindings are a work in progress.\n\nYou can run benchmarks by installing `npm install -g @c4312/matcha`, then running `matcha benchmark.js`. These are the results running on Node 12 on my MacBook. Blake3 is significantly faster than Node's built-in hashing.\n\n        276,000 ops/sec > 64B#md5 (4,240x)\n        263,000 ops/sec > 64B#sha1 (4,040x)\n        271,000 ops/sec > 64B#sha256 (4,160x)\n      1,040,000 ops/sec > 64B#blake3 wasm (15,900x)\n        625,000 ops/sec > 64B#blake3 native (9,590x)\n\n          9,900 ops/sec > 64KB#md5 (152x)\n         13,900 ops/sec > 64KB#sha1 (214x)\n          6,470 ops/sec > 64KB#sha256 (99.2x)\n          6,410 ops/sec > 64KB#blake3 wasm (98.4x)\n         48,900 ops/sec > 64KB#blake3 native (750x)\n\n            106 ops/sec > 6MB#md5 (1.63x)\n            150 ops/sec > 6MB#sha1 (2.3x)\n           69.2 ops/sec > 6MB#sha256 (1.06x)\n           65.2 ops/sec > 6MB#blake3 wasm (1x)\n            502 ops/sec > 6MB#blake3 native (7.7x)\n\n## Contributing\n\nThis build is a little esoteric due to the mixing of languages. We use a `Makefile` to coodinate things.\n\nTo get set up, you'll want to open the repository in VS Code. Make sure you have [Remote Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) installed, and then accept the \"Reopen in Container\" prompt when opening the folder. This will get the environment set up with everything you need. Then, run `make prepare` to install local dependencies.\n\nFinally, `make` will create a build for you; you can run `make MODE=release` for a production release, and certainly should if you want to [benchmark it](#speed).\n\n- Rust code is compiled from `src/lib.rs` to `pkg/browser` and `pkg/node`\n- TypeScript code is compiled from `ts/*.ts` into `dist`\n\n### Publishing\n\nIn case I get hit by a bus or get other contributors, these are the steps for publishing:\n\n1.  Get all your code ready to go in master, pushed up to Github.\n2.  Run `make prepare-binaries`. This will update the branch `generate-binary`, which kicks off a build via Github actions to create `.node` binaries for every relevant Node.js version.\n3.  When the build completes, it'll generate a zip file of artifacts. Download those.\n4.  Back on master, run `npm version <type>` to update the version in git. `git push --tags`.\n5.  On Github, upload the contents of the artifacts folder to the release for the newly tagged version.\n6.  Run `npm publish`.\n","readmeFilename":"readme.md"}