{"_id":"@aptre/it-ws","_rev":"3-5e5b8debd36796d53f00bb76c9eaddee","name":"@aptre/it-ws","dist-tags":{"latest":"1.1.2"},"versions":{"1.0.0":{"name":"@aptre/it-ws","version":"1.0.0","keywords":["async","iterable","iterator","websocket","ws"],"author":{"name":"Alan Shaw"},"license":"Apache-2.0 OR MIT","_id":"@aptre/it-ws@1.0.0","maintainers":[{"name":"paralin","email":"christian@paral.in"}],"homepage":"https://github.com/alanshaw/it-ws#readme","bugs":{"url":"https://github.com/alanshaw/it-ws/issues"},"dist":{"shasum":"dfcdbb654cc66fd8c8695ed8aa62aa9cc40db11c","tarball":"https://registry.npmjs.org/@aptre/it-ws/-/it-ws-1.0.0.tgz","fileCount":59,"integrity":"sha512-QAqbfb2btw7FDTlCWimBDtUSu835S0+6FqG9lx6MfDbwKz6NXUAZTrMscIMgM7wF5ZpHmehvXqZl2KdANL6zSg==","signatures":[{"sig":"MEQCIHddUhkaeIqo7fdScY1bjo+BoHYvrtaGnOyVShuhvKP6AiBEtDnaFazEMyHVMUTVJm5WYIvZmEtI5fXVPw0fjf6WUg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":80449},"type":"module","types":"./dist/src/index.d.ts","browser":{"ws":false,"http":false,"https":false,"./dist/src/server.js":false,"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js"},"engines":{"npm":">=7.0.0","node":">=16.0.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./sink":{"types":"./dist/src/sink.d.ts","import":"./dist/src/sink.js"},"./client":{"types":"./dist/src/client.d.ts","import":"./dist/src/client.js"},"./duplex":{"types":"./dist/src/duplex.d.ts","import":"./dist/src/duplex.js"},"./server":{"types":"./dist/src/server.d.ts","import":"./dist/src/server.js","browser":"./dist/src/server.browser.js"},"./source":{"types":"./dist/src/source.d.ts","import":"./dist/src/source.js"},"./web-socket":{"types":"./dist/src/web-socket.d.ts","import":"./dist/src/web-socket.js","browser":"./dist/src/web-socket.browser.js"}},"gitHead":"a3e769760d3843f625883f83af9fdc16a6f0d79d","release":{"plugins":[["@semantic-release/commit-analyzer",{"preset":"conventionalcommits","releaseRules":[{"release":"major","breaking":true},{"revert":true,"release":"patch"},{"type":"feat","release":"minor"},{"type":"fix","release":"patch"},{"type":"docs","release":"patch"},{"type":"test","release":"patch"},{"type":"deps","release":"patch"},{"scope":"no-release","release":false}]}],["@semantic-release/release-notes-generator",{"preset":"conventionalcommits","presetConfig":{"types":[{"type":"feat","section":"Features"},{"type":"fix","section":"Bug Fixes"},{"type":"chore","section":"Trivial Changes"},{"type":"docs","section":"Documentation"},{"type":"deps","section":"Dependencies"},{"type":"test","section":"Tests"}]}}],"@semantic-release/changelog","@semantic-release/npm","@semantic-release/github","@semantic-release/git"],"branches":["master"]},"scripts":{"docs":"aegir docs","lint":"aegir lint","test":"aegir test","build":"aegir build","clean":"aegir clean","release":"aegir release","dep-check":"aegir dep-check","test:node":"aegir test -t node --cov","test:chrome":"aegir test -t browser --cov","test:firefox":"aegir test -t browser -- --browser firefox","test:electron-main":"aegir test -t electron-main","test:chrome-webworker":"aegir test -t webworker","test:firefox-webworker":"aegir test -t webworker -- --browser firefox"},"_npmUser":{"name":"paralin","email":"christian@paral.in"},"repository":{"url":"git+https://github.com/alanshaw/it-ws.git","type":"git"},"_npmVersion":"10.2.4","description":"Simple async iterables for websocket client connections","directories":{},"_nodeVersion":"21.4.0","dependencies":{"ws":"^8.4.0","@types/ws":"^8.2.2","uint8arrays":"^5.0.0","event-iterator":"^2.0.0","it-stream-types":"^2.0.1"},"eslintConfig":{"extends":"ipfs","parserOptions":{"sourceType":"module"}},"react-native":{"ws":false,"http":false,"https":false,"./dist/src/server.js":false,"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js"},"typesVersions":{"*":{"*":["*","dist/*","dist/src/*","dist/src/*/index"],"src/*":["*","dist/*","dist/src/*","dist/src/*/index"]}},"_hasShrinkwrap":false,"devDependencies":{"aegir":"^40.0.0","delay":"^6.0.0","wsurl":"^1.0.0","it-all":"^3.0.1","it-map":"^3.0.2","it-pipe":"^3.0.1","p-defer":"^4.0.0","it-drain":"^3.0.1","it-ndjson":"^1.0.0","it-foreach":"^2.0.2","it-goodbye":"^4.0.0","wherearewe":"^2.0.1"},"_npmOperationalInternal":{"tmp":"tmp/it-ws_1.0.0_1703024797694_0.7923795158678293","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"@aptre/it-ws","version":"1.0.1","keywords":["async","iterable","iterator","websocket","ws"],"author":{"name":"Alan Shaw"},"license":"Apache-2.0 OR MIT","_id":"@aptre/it-ws@1.0.1","homepage":"https://github.com/alanshaw/it-ws#readme","bugs":{"url":"https://github.com/alanshaw/it-ws/issues"},"dist":{"shasum":"fd3e45d517849b7a76a37f19d5c25f5dbc3ba991","tarball":"https://registry.npmjs.org/@aptre/it-ws/-/it-ws-1.0.1.tgz","fileCount":60,"integrity":"sha512-8gbaW9utMyVtAi317JX+CYm4uM2XUy+a4y62pok++sSkvlHjG4tjPYOkzVxeTer10BjgTHLek2K/1naWgYicgQ==","signatures":[{"sig":"MEUCIQC9M5WrnB1osm/+pWu8KkYHYLBNCUFygT0zzD1UQJy4sAIgbcC9q2MSxcb/jNQ/DskxFRcNZEDC2AiFVP3jXErsL6s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":82708},"type":"module","types":"./dist/src/index.d.ts","browser":{"ws":false,"http":false,"https":false,"./dist/src/server.js":false,"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js"},"engines":{"npm":">=7.0.0","node":">=16.0.0"},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./sink":{"types":"./dist/src/sink.d.ts","import":"./dist/src/sink.js"},"./client":{"types":"./dist/src/client.d.ts","import":"./dist/src/client.js"},"./duplex":{"types":"./dist/src/duplex.d.ts","import":"./dist/src/duplex.js"},"./server":{"types":"./dist/src/server.d.ts","import":"./dist/src/server.js","browser":"./dist/src/server.browser.js"},"./source":{"types":"./dist/src/source.d.ts","import":"./dist/src/source.js"},"./web-socket":{"types":"./dist/src/web-socket.d.ts","import":"./dist/src/web-socket.js","browser":"./dist/src/web-socket.browser.js"}},"gitHead":"49a1121d33be71452a50bb3eba482d5b2edf4286","release":{"plugins":[["@semantic-release/commit-analyzer",{"preset":"conventionalcommits","releaseRules":[{"release":"major","breaking":true},{"revert":true,"release":"patch"},{"type":"feat","release":"minor"},{"type":"fix","release":"patch"},{"type":"docs","release":"patch"},{"type":"test","release":"patch"},{"type":"deps","release":"patch"},{"scope":"no-release","release":false}]}],["@semantic-release/release-notes-generator",{"preset":"conventionalcommits","presetConfig":{"types":[{"type":"feat","section":"Features"},{"type":"fix","section":"Bug Fixes"},{"type":"chore","section":"Trivial Changes"},{"type":"docs","section":"Documentation"},{"type":"deps","section":"Dependencies"},{"type":"test","section":"Tests"}]}}],"@semantic-release/changelog","@semantic-release/npm","@semantic-release/github","@semantic-release/git"],"branches":["master"]},"scripts":{"docs":"aegir docs","lint":"aegir lint","test":"aegir test","build":"aegir build","clean":"aegir clean","release":"aegir release","dep-check":"aegir dep-check","test:node":"aegir test -t node --cov","test:chrome":"aegir test -t browser --cov","test:firefox":"aegir test -t browser -- --browser firefox","test:electron-main":"aegir test -t electron-main","test:chrome-webworker":"aegir test -t webworker","test:firefox-webworker":"aegir test -t webworker -- --browser firefox"},"_npmUser":{"name":"paralin","email":"christian@paral.in"},"repository":{"url":"git+https://github.com/alanshaw/it-ws.git","type":"git"},"_npmVersion":"10.8.1","description":"Simple async iterables for websocket client connections","directories":{},"_nodeVersion":"22.3.0","dependencies":{"ws":"^8.17.1","@types/ws":"^8.2.2","uint8arrays":"^5.1.0","event-iterator":"^2.0.0","it-stream-types":"^2.0.1"},"eslintConfig":{"extends":"ipfs","parserOptions":{"sourceType":"module"}},"react-native":{"ws":false,"http":false,"https":false,"./dist/src/server.js":false,"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js"},"typesVersions":{"*":{"*":["*","dist/*","dist/src/*","dist/src/*/index"],"src/*":["*","dist/*","dist/src/*","dist/src/*/index"]}},"_hasShrinkwrap":false,"devDependencies":{"aegir":"^44.0.0","delay":"^6.0.0","wsurl":"^1.0.0","it-all":"^3.0.6","it-map":"^3.1.1","it-pipe":"^3.0.1","p-defer":"^4.0.1","it-drain":"^3.0.7","it-ndjson":"^1.0.7","it-foreach":"^2.1.1","it-goodbye":"^4.0.6","wherearewe":"^2.0.1"},"_npmOperationalInternal":{"tmp":"tmp/it-ws_1.0.1_1719354804505_0.3340793376187541","host":"s3://npm-registry-packages"}},"1.1.2":{"name":"@aptre/it-ws","version":"1.1.2","description":"Simple async iterables for websocket client connections","author":{"name":"Alan Shaw"},"license":"Apache-2.0 OR MIT","homepage":"https://github.com/alanshaw/it-ws#readme","repository":{"type":"git","url":"git+https://github.com/alanshaw/it-ws.git"},"bugs":{"url":"https://github.com/alanshaw/it-ws/issues"},"publishConfig":{"access":"public"},"keywords":["async","iterable","iterator","websocket","ws"],"engines":{"node":">=16.0.0","npm":">=7.0.0"},"type":"module","types":"./dist/src/index.d.ts","typesVersions":{"*":{"*":["*","dist/*","dist/src/*","dist/src/*/index"],"src/*":["*","dist/*","dist/src/*","dist/src/*/index"]}},"exports":{".":{"types":"./dist/src/index.d.ts","import":"./dist/src/index.js"},"./client":{"types":"./dist/src/client.d.ts","import":"./dist/src/client.js"},"./duplex":{"types":"./dist/src/duplex.d.ts","import":"./dist/src/duplex.js"},"./server":{"types":"./dist/src/server.d.ts","browser":"./dist/src/server.browser.js","import":"./dist/src/server.js"},"./sink":{"types":"./dist/src/sink.d.ts","import":"./dist/src/sink.js"},"./source":{"types":"./dist/src/source.d.ts","import":"./dist/src/source.js"},"./web-socket":{"types":"./dist/src/web-socket.d.ts","import":"./dist/src/web-socket.js","browser":"./dist/src/web-socket.browser.js"}},"eslintConfig":{"extends":"ipfs","parserOptions":{"sourceType":"module"}},"release":{"branches":["master"],"plugins":[["@semantic-release/commit-analyzer",{"preset":"conventionalcommits","releaseRules":[{"breaking":true,"release":"major"},{"revert":true,"release":"patch"},{"type":"feat","release":"minor"},{"type":"fix","release":"patch"},{"type":"docs","release":"patch"},{"type":"test","release":"patch"},{"type":"deps","release":"patch"},{"scope":"no-release","release":false}]}],["@semantic-release/release-notes-generator",{"preset":"conventionalcommits","presetConfig":{"types":[{"type":"feat","section":"Features"},{"type":"fix","section":"Bug Fixes"},{"type":"chore","section":"Trivial Changes"},{"type":"docs","section":"Documentation"},{"type":"deps","section":"Dependencies"},{"type":"test","section":"Tests"}]}}],"@semantic-release/changelog","@semantic-release/npm","@semantic-release/github","@semantic-release/git"]},"scripts":{"clean":"aegir clean","lint":"aegir lint","dep-check":"aegir dep-check","build":"aegir build","test":"aegir test","test:chrome":"aegir test -t browser --cov","test:chrome-webworker":"aegir test -t webworker","test:firefox":"aegir test -t browser -- --browser firefox","test:firefox-webworker":"aegir test -t webworker -- --browser firefox","test:node":"aegir test -t node --cov","test:electron-main":"aegir test -t electron-main","docs":"aegir docs","release":"npm run release:version && npm run release:commit","release:minor":"npm run release:version:minor && npm run release:commit","release:version":"npm version patch -m \"release: v%s\" --no-git-tag-version","release:version:minor":"npm version minor -m \"release: v%s\" --no-git-tag-version","release:commit":"git reset && git add package.json && git commit -s -m \"release: v$npm_package_version\" && git tag v$npm_package_version","release:publish":"git push && git push --tags && npm run build && npm publish"},"dependencies":{"@types/ws":"^8.2.2","event-iterator":"^2.0.0","it-stream-types":"^2.0.1","ws":"^8.17.1"},"devDependencies":{"aegir":"^44.0.1","delay":"^6.0.0","it-all":"^3.0.6","it-drain":"^3.0.7","it-foreach":"^2.1.1","it-goodbye":"^4.0.6","it-map":"^3.1.1","it-ndjson":"^1.0.7","it-pipe":"^3.0.1","p-defer":"^4.0.1","uint8arrays":"^5.1.0","wherearewe":"^2.0.1","wsurl":"^1.0.0"},"browser":{"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js","./dist/src/server.js":false,"ws":false,"http":false,"https":false},"react-native":{"./dist/src/web-socket.js":"./dist/src/web-socket.browser.js","./dist/src/server.js":false,"ws":false,"http":false,"https":false},"_id":"@aptre/it-ws@1.1.2","gitHead":"ad480c280a5b1a0982bfcc88c41fb0d251122042","_nodeVersion":"24.3.0","_npmVersion":"10.8.1","dist":{"integrity":"sha512-llC/rTR1YXs3sNven2QRyHp3PoUwxpe0/iohiFNIfUTjbThlv1vGuq6GZysOGwCqEgbYRJGMhu4A4pTjwqztJQ==","shasum":"c158e7ee534e2ecd7e3b0f23c8ac7bb39a2e12bb","tarball":"https://registry.npmjs.org/@aptre/it-ws/-/it-ws-1.1.2.tgz","fileCount":60,"unpackedSize":66224,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCjCI4oAXASmuwAF22MAnkQ/KzZ1+9NwXO1ScdZiOtwCwIhAPXPwubTw7/J5QBWblqSg8vAvglWJpmG7rfxUPjcXjno"}]},"_npmUser":{"name":"paralin","email":"christian@paral.in","actor":{"name":"paralin","email":"christian@paral.in","type":"user"}},"directories":{},"maintainers":[{"name":"paralin","email":"christian@paral.in"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/it-ws_1.1.2_1751772440156_0.2631533165918636"},"_hasShrinkwrap":false}},"time":{"created":"2023-12-19T22:26:37.589Z","modified":"2025-07-06T03:27:20.560Z","1.0.0":"2023-12-19T22:26:37.897Z","1.0.1":"2024-06-25T22:33:24.699Z","1.1.2":"2025-07-06T03:27:20.380Z"},"bugs":{"url":"https://github.com/alanshaw/it-ws/issues"},"author":{"name":"Alan Shaw"},"license":"Apache-2.0 OR MIT","homepage":"https://github.com/alanshaw/it-ws#readme","keywords":["async","iterable","iterator","websocket","ws"],"repository":{"type":"git","url":"git+https://github.com/alanshaw/it-ws.git"},"description":"Simple async iterables for websocket client connections","maintainers":[{"name":"paralin","email":"christian@paral.in"}],"readme":"# it-ws <!-- omit in toc -->\n\n> Simple async iterables for websocket client connections\n\n## Notice: Fork\n\n**This is a maintenance fork of it-ws. It minimizes dependencies when compared to the upstream package.**\n\nThis package is published at `@aptre/it-ws`.\n\n## Table of contents <!-- omit in toc -->\n\n- [Install](#install)\n  - [Browser `<script>` tag](#browser-script-tag)\n- [Usage](#usage)\n  - [Example - client](#example---client)\n  - [Example - server](#example---server)\n- [API](#api)\n  - [`import { connect } from 'it-ws/client'`](#import--connect--from-it-wsclient)\n  - [`import { createServer } from 'it-ws/server'`](#import--createserver--from-it-wsserver)\n    - [Example](#example)\n- [use with an http server](#use-with-an-http-server)\n  - [core, websocket wrapping functions](#core-websocket-wrapping-functions)\n  - [`import duplex from 'it-ws/duplex'`](#import-duplex-from-it-wsduplex)\n  - [`import sink from 'it-ws/sink'`](#import-sink-from-it-wssink)\n  - [`import source from 'it-ws/source'`](#import-source-from-it-wssource)\n- [License](#license)\n- [Contribution](#contribution)\n\n## Install\n\n```console\n$ npm i @aptre/it-ws\n```\n\n## Usage\n\n### Example - client\n\n```js\nimport { connect } from '@aptre/it-ws/client'\nimport { pipe } from 'it-pipe'\n\nconst stream = connect(WS_URL)\n\nawait stream.connected() // Wait for websocket to be connected (optional)\n\npipe(source, stream, sink)\n```\n\n### Example - server\n\n```js\nimport { createServer } from '@aptre/it-ws/server'\nimport { pipe } from 'it-pipe'\n\nconst server = createServer(stream => {\n  //pipe the stream somewhere.\n  //eg, echo server\n  pipe(stream, stream)\n})\n\nawait server.listen(PORT)\n```\n\n## API\n\n### `import { connect } from '@aptre/it-ws/client'`\n\n`connect(url, { binary: boolean })`\n\nCreate a websocket client connection. Set `binary: true` to get a stream of arrayBuffers (on the browser). Defaults to true on node, but to strings on the browser. This may cause a problems if your application assumes binary.\n\nFor adding options to the WebSocket instance, as [websockets/ws/blob/master/doc/ws.md#new-websocketaddress-protocols-options](https://github.com/websockets/ws/blob/master/doc/ws.md#new-websocketaddress-protocols-options), you can provide an object with the `websocket` property into the connect options.\n\n```js\nconst stream = connect(url)\n// stream is duplex and is both a `source` and `sink`.\n// See this for more information:\n// https://gist.github.com/alanshaw/591dc7dd54e4f99338a347ef568d6ee9#duplex-it\n```\n\n### `import { createServer } from '@aptre/it-ws/server'`\n\nCreate async iterable websocket servers.\n\n`createServer(options?, onConnection)`\n\n`options` takes the same server options as [ws module](https://github.com/websockets/ws/blob/master/doc/ws.md#new-wsserveroptions-callback)\n\n`onConnection(stream)` is called every time a connection is received.\n\n#### Example\n\nOne duplex service you may want to use this with is [muxrpc](https://github.com/dominictarr/muxrpc)\n\n```js\nimport { createServer } from '@aptre/it-ws/server'\nimport { connect } from '@aptre/it-ws/client'\nimport { pipe } from 'it-pipe'\n\ncreateServer({\n  onConnection: (stream) => {\n    // pipe duplex style to your service\n    pipe(stream, service.createStream(), stream)\n  }\n})\n.listen(9999)\n\nconst stream = client.createStream()\n\nawait pipe(\n  stream,\n  connect('ws://localhost:9999'),\n  stream\n)\n```\n\nif the connection fails, the stream will throw\n\n```js\ntry {\n  await pipe(\n    stream,\n    connect('ws://localhost:9999'),\n    stream\n  )\n} catch (err) {\n  // handle err\n}\n```\n\nTo run the server over TLS:\n\n```js\ncreateServer({\n  key: fs.readFileSync('test/fixtures/keys/agent2-key.pem'),\n  cert: fs.readFileSync('test/fixtures/keys/agent2-cert.pem')\n  // other options\n})\n.listen(9999)\n```\n\nTo add client-authentication to the server, you can set `verifyClient`.\n[Documentation here](https://github.com/websockets/ws/blob/master/doc/ws.md#optionsverifyclient).\n\n```js\nfunction verifyClient (info) {\n  return info.secure == true\n}\ncreateServer({\n  verifyClient: verifyClient\n  // other options\n})\n```\n\n## use with an http server\n\nif you have an http server that you also need to serve stuff\nover, and want to use a single port, use the `server` option.\n\n```js\nimport http from 'http'\n\nconst server = http.createServer(function(req, res){...}).listen(....)\n\ncreateServer({\n  server: server\n  // other options\n})\n```\n\n### core, websocket wrapping functions\n\nthese modules are used internally, to wrap a websocket.\nyou probably won't need to touch these,\nbut they are documented anyway.\n\n### `import duplex from '@aptre/it-ws/duplex'`\n\nturn a websocket into a duplex stream.\nIf provided, `opts` is passed to `sink(socket, opts)`.\n\nWebSockets do not support half open mode.\n[see allowHalfOpen option in net module](http://nodejs.org/api/net.html#net_net_createserver_options_connectionlistener)\n\nIf you have a protocol that assumes halfOpen connections, but are using\na networking protocol like websockets that does not support it, I suggest\nusing [it-goodbye](https://github.com/alanshaw/it-goodbye) with your\nprotocol.\n\nThe duplex stream will also contain a copy of the properties from\nthe http request that became the websocket. they are `method`, `url`,\n`headers` and `upgrade`.\n\nalso exposed at: `import { duplex } from '@aptre/it-ws'`\n\n### `import sink from '@aptre/it-ws/sink'`\n\nCreate a `Sink` that will write data to the `socket`.\n`opts` may be `{closeOnEnd: true, onClose: onClose}`.\n`onClose` will be called when the sink ends. If `closeOnEnd=false`\nthe stream will not close, it will just stop emitting data.\n(by default `closeOnEnd` is true)\n\nIf `opts` is a function, then `onClose = opts; opts.closeOnEnd = true`.\n\n```js\nimport sink from '@aptre/it-ws/sink'\nimport { pipe } from 'it-pipe'\nimport each from 'it-foreach'\nimport delay from 'delay'\n\n// connect to the echo endpoint for test/server.js\nvar socket = new WebSocket('wss://echo.websocket.org')\n\n// write values to the socket\npipe(\n  async function * () {\n    while (true) {\n      yield 'hello @ ' + Date.now()\n    }\n  }(),\n  // throttle so it doesn't go nuts\n  (source) => each(source, () => delay(100))\n  sink(socket)\n);\n\nsocket.addEventListener('message', function(evt) {\n  console.log('received: ' + evt.data);\n});\n```\n\nalso exposed at `import { sink } from '@aptre/it-ws'`\n\n### `import source from '@aptre/it-ws/source'`\n\nCreate a `Source` that will read data from the `socket`.\n\n```js\nimport { pipe } from 'it-pipe'\nimport source from '@aptre/it-ws/source'\n\npipe(\n  // connect to the test/server.js endpoint\n  source(new WebSocket('ws://localhost:3000/read')),\n  async (source) => {\n    for await (const buf of source) {\n      console.info(buf)\n    }\n  }\n);\n\n```\n\nalso exposed at `import { source } from '@aptre/it-ws'`\n\n## License\n\nLicensed under either of\n\n- Apache 2.0, ([LICENSE-APACHE](LICENSE-APACHE) / <http://www.apache.org/licenses/LICENSE-2.0>)\n- MIT ([LICENSE-MIT](LICENSE-MIT) / <http://opensource.org/licenses/MIT>)\n\n## Contribution\n\nUnless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.\n","readmeFilename":"README.md"}