{"_id":"@daniel-nagy/transporter-browser","_rev":"3-adb0d516284581a7243a961b843dd50f","name":"@daniel-nagy/transporter-browser","dist-tags":{"latest":"1.0.0-beta.6"},"versions":{"1.0.0-beta.3":{"name":"@daniel-nagy/transporter-browser","version":"1.0.0-beta.3","keywords":["client","message","observable","postMessage","proxy","pubsub","rpc","server","socket","soa"],"author":{"name":"Daniel Nagy","email":"1622446+daniel-nagy@users.noreply.github.com"},"license":"Apache-2.0","_id":"@daniel-nagy/transporter-browser@1.0.0-beta.3","maintainers":[{"name":"daniel-nagy","email":"daniel_nagy@me.com"}],"homepage":"https://github.com/daniel-nagy/transporter#readme","bugs":{"url":"https://github.com/daniel-nagy/transporter/issues"},"dist":{"shasum":"aa934d6b80c6e5316b71b552aa90013465d79336","tarball":"https://registry.npmjs.org/@daniel-nagy/transporter-browser/-/transporter-browser-1.0.0-beta.3.tgz","fileCount":39,"integrity":"sha512-ocQTauLwtY8NnLfMBVdqaL0WzdamuxeipIfYXDRdRKLcxx0J8CMEwlv8itldbCl4KOiPP+mLchVVu1y/UaJO7A==","signatures":[{"sig":"MEQCICldqUVUnlpfUDG4CO8LMirTACZHhQIuHhc7H3mEAkoMAiA1gBy94MsYBWgmEMeabSdlPdJwRoHNhzy0IOjzEWDZDw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103943},"type":"module","exports":{"./*":"./build/*.js","./*.js":"./build/*.js","./BrowserSocket":"./build/BrowserSocket/index.js","./BrowserSocket/index.js":"./build/BrowserSocket/index.js"},"gitHead":"0b70ad18bc8d8d184f76e3c6d9d3113327a41258","scripts":{"test":"web-test-runner","build":"tsc --project tsconfig-build.json","clean":"rm -rf node_modules build","eslint":"eslint src","prebuild":"bun clean","prettier":"prettier --check --ignore-path .gitignore .","postbuild":"cp ../../LICENSE build","eslint-fix":"eslint src --fix","prettier-fix":"prettier --write --ignore-path .gitignore ."},"_npmUser":{"name":"daniel-nagy","email":"daniel_nagy@me.com"},"repository":{"url":"git+https://github.com/daniel-nagy/transporter.git","type":"git"},"_npmVersion":"9.8.0","description":"Typesafe distributed computing in the browser.","directories":{},"_nodeVersion":"20.5.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"sinon":"^17.0.1","eslint":"^8.51.0","prettier":"^3.0.3","typescript":"^5.3.3","@types/mocha":"^10.0.3","@types/sinon":"^17.0.1","@web/test-runner":"^0.18.0","@web/dev-server-esbuild":"^1.0.0","@typescript-eslint/parser":"^6.7.5","eslint-plugin-expect-type":"^0.2.3","@web/test-runner-playwright":"^0.11.0","@typescript-eslint/eslint-plugin":"^6.7.5","eslint-plugin-require-extensions":"^0.1.3"},"peerDependencies":{"@daniel-nagy/transporter":"1.0.0-beta.3"},"_npmOperationalInternal":{"tmp":"tmp/transporter-browser_1.0.0-beta.3_1703695410842_0.9201183034871396","host":"s3://npm-registry-packages"}},"1.0.0-beta.4":{"name":"@daniel-nagy/transporter-browser","version":"1.0.0-beta.4","keywords":["client","message","observable","postMessage","proxy","pubsub","rpc","server","socket","soa"],"author":{"name":"Daniel Nagy","email":"1622446+daniel-nagy@users.noreply.github.com"},"license":"Apache-2.0","_id":"@daniel-nagy/transporter-browser@1.0.0-beta.4","maintainers":[{"name":"daniel-nagy","email":"daniel_nagy@me.com"}],"homepage":"https://github.com/daniel-nagy/transporter#readme","bugs":{"url":"https://github.com/daniel-nagy/transporter/issues"},"dist":{"shasum":"ab53104f337da595bcf50349e21c40a9a16baf39","tarball":"https://registry.npmjs.org/@daniel-nagy/transporter-browser/-/transporter-browser-1.0.0-beta.4.tgz","fileCount":39,"integrity":"sha512-m/DEPaFY+QmDB6lURg7e6YNRK92VXxh9P+b1psy3MuV97DMJxleF2C2wV5XuP18ABXEmUvhJMEKfEmF8Ygn4tQ==","signatures":[{"sig":"MEUCID0xSOP5XtC5gPFjkZ6AGEsx7VZd8ZMDiPc/ybL4LSlyAiEA3R0dVYNs3dwPiGeUhP9QOrKymcnsZiEwkIKSD79Pu6s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":106332},"type":"module","exports":{"./*":"./build/*.js","./*.js":"./build/*.js","./BrowserSocket":"./build/BrowserSocket/index.js","./BrowserSocket/index.js":"./build/BrowserSocket/index.js"},"gitHead":"ed505206d2a89a2e2c09618b8fd0c3f6a52d0bb5","scripts":{"test":"web-test-runner","build":"tsc --project tsconfig-build.json","clean":"rm -rf node_modules build","eslint":"eslint src","prebuild":"bun clean","prettier":"prettier --check --ignore-path .gitignore .","postbuild":"cp ../../LICENSE build","eslint-fix":"eslint src --fix","prettier-fix":"prettier --write --ignore-path .gitignore ."},"_npmUser":{"name":"daniel-nagy","email":"daniel_nagy@me.com"},"repository":{"url":"git+https://github.com/daniel-nagy/transporter.git","type":"git"},"_npmVersion":"9.8.0","description":"Typesafe distributed computing in the browser.","directories":{},"_nodeVersion":"20.5.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"sinon":"^17.0.1","eslint":"^8.51.0","prettier":"^3.0.3","typescript":"^5.3.3","@types/mocha":"^10.0.3","@types/sinon":"^17.0.1","@web/test-runner":"^0.18.0","@web/dev-server-esbuild":"^1.0.0","@typescript-eslint/parser":"^6.7.5","eslint-plugin-expect-type":"^0.2.3","@web/test-runner-playwright":"^0.11.0","@typescript-eslint/eslint-plugin":"^6.7.5","eslint-plugin-require-extensions":"^0.1.3"},"peerDependencies":{"@daniel-nagy/transporter":"1.0.0-beta.4"},"_npmOperationalInternal":{"tmp":"tmp/transporter-browser_1.0.0-beta.4_1704065603671_0.775840906459903","host":"s3://npm-registry-packages"}},"1.0.0-beta.5":{"name":"@daniel-nagy/transporter-browser","version":"1.0.0-beta.5","keywords":["client","message","observable","postMessage","proxy","pubsub","rpc","server","socket","soa"],"author":{"name":"Daniel Nagy","email":"1622446+daniel-nagy@users.noreply.github.com"},"license":"Apache-2.0","_id":"@daniel-nagy/transporter-browser@1.0.0-beta.5","maintainers":[{"name":"daniel-nagy","email":"daniel_nagy@me.com"}],"homepage":"https://github.com/daniel-nagy/transporter#readme","bugs":{"url":"https://github.com/daniel-nagy/transporter/issues"},"dist":{"shasum":"e630fcdc7cf56cc47c19a1802b2806743f61e294","tarball":"https://registry.npmjs.org/@daniel-nagy/transporter-browser/-/transporter-browser-1.0.0-beta.5.tgz","fileCount":39,"integrity":"sha512-z77ek321cnghdQh7QNEyBPOOXqWwU4nHRt38pn3oBDSJTXtojWgyKr02/R+tQCvyyrzNDOHsfUHB9XEiO3hiBw==","signatures":[{"sig":"MEYCIQCs8OgtdP5cL2b+9Ps17Ox+50+HfGavkgRAkzB1v+JmbwIhAKONz2JPpoOObXrHXsy5wiwknQ6ccvzd8cUWKjvhZIDi","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":106310},"type":"module","exports":{"./*":"./build/*.js","./*.js":"./build/*.js","./BrowserSocket":"./build/BrowserSocket/index.js","./BrowserSocket/index.js":"./build/BrowserSocket/index.js"},"gitHead":"96551555a018926f4ac2e44104930fc569784e12","scripts":{"test":"web-test-runner","build":"tsc --project tsconfig-build.json","clean":"rm -rf node_modules build","eslint":"eslint src","prebuild":"bun clean","prettier":"prettier --check --ignore-path .gitignore .","postbuild":"cp ../../LICENSE build","eslint-fix":"eslint src --fix","prettier-fix":"prettier --write --ignore-path .gitignore ."},"_npmUser":{"name":"daniel-nagy","email":"daniel_nagy@me.com"},"repository":{"url":"git+https://github.com/daniel-nagy/transporter.git","type":"git"},"_npmVersion":"9.8.0","description":"Typesafe distributed computing in the browser.","directories":{},"_nodeVersion":"20.5.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"_hasShrinkwrap":false,"devDependencies":{"sinon":"^17.0.1","eslint":"^8.51.0","prettier":"^3.0.3","typescript":"^5.3.3","@types/mocha":"^10.0.3","@types/sinon":"^17.0.1","@web/test-runner":"^0.18.0","@web/dev-server-esbuild":"^1.0.0","@typescript-eslint/parser":"^6.7.5","eslint-plugin-expect-type":"^0.2.3","@web/test-runner-playwright":"^0.11.0","@typescript-eslint/eslint-plugin":"^6.7.5","eslint-plugin-require-extensions":"^0.1.3"},"peerDependencies":{"@daniel-nagy/transporter":"1.0.0-beta.5"},"_npmOperationalInternal":{"tmp":"tmp/transporter-browser_1.0.0-beta.5_1705347350157_0.3797003042714906","host":"s3://npm-registry-packages"}},"1.0.0-beta.6":{"name":"@daniel-nagy/transporter-browser","type":"module","version":"1.0.0-beta.6","description":"Typesafe distributed computing in the browser.","author":{"name":"Daniel Nagy","email":"1622446+daniel-nagy@users.noreply.github.com"},"repository":{"type":"git","url":"git+https://github.com/daniel-nagy/transporter.git"},"license":"Apache-2.0","keywords":["client","message","observable","postMessage","proxy","pubsub","rpc","server","socket","soa"],"exports":{"./*":"./build/*.js","./*.js":"./build/*.js","./BrowserSocket":"./build/BrowserSocket/index.js","./BrowserSocket/index.js":"./build/BrowserSocket/index.js"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org"},"scripts":{"prebuild":"bun clean","build":"tsc --project tsconfig-build.json","postbuild":"cp ../../LICENSE build","clean":"rm -rf node_modules build","eslint":"eslint src","eslint-fix":"eslint src --fix","prettier":"prettier --check --ignore-path .gitignore .","prettier-fix":"prettier --write --ignore-path .gitignore .","test":"web-test-runner"},"devDependencies":{"@types/mocha":"^10.0.3","@types/sinon":"^17.0.1","@typescript-eslint/eslint-plugin":"^6.7.5","@typescript-eslint/parser":"^6.7.5","@web/dev-server-esbuild":"^1.0.0","@web/test-runner":"^0.18.0","@web/test-runner-playwright":"^0.11.0","eslint":"^8.51.0","eslint-plugin-expect-type":"^0.2.3","eslint-plugin-require-extensions":"^0.1.3","prettier":"^3.0.3","sinon":"^17.0.1","typescript":"^5.3.3"},"peerDependencies":{"@daniel-nagy/transporter":"1.0.0-beta.5"},"_id":"@daniel-nagy/transporter-browser@1.0.0-beta.6","gitHead":"f13d713cd8339f2f4493607a811cd09a043eef00","bugs":{"url":"https://github.com/daniel-nagy/transporter/issues"},"homepage":"https://github.com/daniel-nagy/transporter#readme","_nodeVersion":"22.2.0","_npmVersion":"10.7.0","dist":{"integrity":"sha512-S7wH6NZWYxoN/UxZ7Tujpo/MUbv5sn7XIN3/VVQZFjajdLo0+OxE6SgZb56O8KVcrtIINIO35CWbHl1OMrN6RA==","shasum":"6997a66d76b713be07ed2bbe8edfa032defba12f","tarball":"https://registry.npmjs.org/@daniel-nagy/transporter-browser/-/transporter-browser-1.0.0-beta.6.tgz","fileCount":39,"unpackedSize":106310,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAK0DSx7W4TqNRbb4Mlfr9fsbsC0cEPM8D3F8LTmUCz/AiEA2DJVScrto6DpmdBfV/ler8d1U4EIloTEZAwZUfy+txo="}]},"_npmUser":{"name":"daniel-nagy","email":"daniel_nagy@me.com"},"directories":{},"maintainers":[{"name":"daniel-nagy","email":"daniel_nagy@me.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/transporter-browser_1.0.0-beta.6_1722548763682_0.05147169747177682"},"_hasShrinkwrap":false}},"time":{"created":"2023-12-27T16:43:30.763Z","modified":"2024-08-01T21:46:04.051Z","1.0.0-beta.3":"2023-12-27T16:43:31.017Z","1.0.0-beta.4":"2023-12-31T23:33:23.858Z","1.0.0-beta.5":"2024-01-15T19:35:50.333Z","1.0.0-beta.6":"2024-08-01T21:46:03.887Z"},"bugs":{"url":"https://github.com/daniel-nagy/transporter/issues"},"author":{"name":"Daniel Nagy","email":"1622446+daniel-nagy@users.noreply.github.com"},"license":"Apache-2.0","homepage":"https://github.com/daniel-nagy/transporter#readme","keywords":["client","message","observable","postMessage","proxy","pubsub","rpc","server","socket","soa"],"repository":{"type":"git","url":"git+https://github.com/daniel-nagy/transporter.git"},"description":"Typesafe distributed computing in the browser.","maintainers":[{"name":"daniel-nagy","email":"daniel_nagy@me.com"}],"readme":"# Browser\n\nThe browser package contains APIs designed to work in the browser.\n\n```\nnpm add @daniel-nagy/transporter @daniel-nagy/transporter-browser\n```\n\nTransporter is distributed as ES modules.\n\nTransporter may also be imported directly in the browser from a URL. For example,\n\n```html\n<script type=\"importmap\">\n  {\n    \"imports\": {\n      \"@daniel-nagy/transporter/\": \"https://unpkg.com/@daniel-nagy/transporter@1.0.0-beta.3/build/\",\n      \"@daniel-nagy/transporter-browser/\": \"https://unpkg.com/@daniel-nagy/transporter-browser@1.0.0-beta.3/build/\"\n    }\n  }\n</script>\n<script type=\"module\">\n  import * as BrowserServer from \"@daniel-nagy/transporter-browser/BrowserServer.js\";\n  import * as Session from \"@daniel-nagy/transporter/Session.js\";\n</script>\n```\n\n## API\n\nThe browser package contains the following modules.\n\n- [BroadcastSubject](#BroadcastSubject)\n- [BrowserClient](#BrowserClient)\n- [BrowserRequest](#BrowserRequest)\n- [BrowserResponse](#BrowserResponse)\n- [BrowserServer](#BrowserServer)\n- [BrowserSocket](#BrowserSocket)\n- [BrowserSocket.Message](#BrowserSocketMessage)\n- [BrowserSocket.State](#BrowserSocketState)\n- [BrowserSocketServer](#BrowserSocketServer)\n- [StructuredCloneable](#StructuredCloneable)\n\n### BroadcastSubject\n\n<sup>_Module_</sup>\n\nA `BroadcastSubject` can be used to synchronize state between same-origin browsing contexts or workers.\n\n###### Types\n\n- [BroadcastSubject](#BroadcastSubject_BroadcastSubject)\n\n###### Constructors\n\n- [fromChannel](#FromChannel)\n\n<h4 id=\"BroadcastSubject_BroadcastSubject\">BroadcastSubject</h4>\n\n<sup>_Type_</sup>\n\n```ts\nclass BroadcastSubject<T extends StructuredCloneable.t> extends Subject.t<T> {}\n```\n\nA `BroadcastSubject` is a `Subject` that broadcasts emitted values over a [`BroadcastChannel`](https://developer.mozilla.org/en-US/docs/Web/API/BroadcastChannel).\n\n#### FromChannel\n\n<sup>_Constructor_</sup>\n\n```ts\nfunction fromChannel<T extends StructuredCloneable.t>(\n  name: string\n): BroadcastSubject<T>;\n```\n\nCreates a `BroadcastSubject` from a broadcast channel name.\n\n##### Example\n\n```ts\nimport * as BroadcastSubject from \"@daniel-nagy/transporter-browser/BroadcastSubject\";\nconst darkMode = BroadcastSubject.fromChannel(\"darkMode\");\ndarkMode.subscribe(console.log);\n```\n\n### BrowserClient\n\n<sup>_Module_</sup>\n\nAn interface for making requests to a browsing context or worker.\n\n###### Types\n\n- [BrowserClient](#BrowserClient_BrowserClient)\n- [Options](#Options)\n\n###### Constants\n\n- [SW](#SW)\n\n###### Constructors\n\n- [from](#From)\n\n###### Methods\n\n- [fetch](#Fetch)\n\n<h4 id=\"BrowserClient_BrowserClient\">BrowserClient</h4>\n\n<sup>_Type_</sup>\n\n```ts\nclass BrowserClient {\n  /**\n   * The address of the server. An address is like a port number, except an\n   * address can be any string instead of a meaningless number.\n   */\n  public readonly serverAddress: string;\n  /**\n   * If the window and the origin do not match the connection will fail. The\n   * origin is only relevant when connecting to a window since the browser\n   * will require worker URLs to be same-origin.\n   */\n  public readonly origin: string;\n  /**\n   * The message target. A message target is like a server host.\n   */\n  public readonly target: Window | Worker | SharedWorker | SW;\n}\n```\n\nAn object that may be used to make fetch requests to a browsing context or worker.\n\n#### Options\n\n<sup>_Type_</sup>\n\n```ts\ntype Options = {\n  /**\n   * The address of the server. The default is the empty string.\n   */\n  address?: string;\n  /**\n   * When connecting to a `Window` you may specify the allowed origin. If the\n   * window and the origin do not match the connection will fail. The origin is\n   * passed directly to the `targetOrigin` parameter of `postMessage` when\n   * connecting to the window. The default is `\"*\"`, which allows any origin.\n   */\n  origin?: string;\n};\n```\n\nOptions when creating a `BrowserClient`.\n\n#### SW\n\n<sup>_Constant_</sup>\n\n```ts\nconst SW = Symbol.for(\"ServiceWorker\");\n```\n\nAn atom that symbolizes a `ServiceWorker`. When used as a target the client will make requests to the currently active `ServiceWorker`.\n\n##### Example\n\n```ts\nimport * as BrowserClient from \"@daniel-nagy/transporter-browser/BrowserClient\";\n\nawait navigator.serviceWorker.register(\"./sw.js\", {\n  type: \"module\"\n});\n\nconst client = BrowserClient.from(BrowserClient.SW);\n```\n\n#### From\n\n<sup>_Constructor_</sup>\n\n```ts\nfunction from(\n  target: Window | Worker | SharedWorker | SW,\n  options?: Options\n): BrowserClient;\n```\n\nCreates a new `BrowserClient`.\n\n##### Example\n\n```ts\nimport * as BrowserClient from \"@daniel-nagy/transporter-browser/BrowserClient\";\n\nconst worker = new Worker(\"/worker.js\", { type: \"module\" });\nconst client = BrowserClient.from(worker);\n```\n\n#### Fetch\n\n<sup>_Method_</sup>\n\n```ts\nfetch(body: StructuredCloneable.t): Promise<StructuredCloneable.t>;\n```\n\nMakes a request to a `BrowserServer`.\n\n##### Example\n\n```ts\nimport * as BrowserClient from \"@daniel-nagy/transporter-browser/BrowserClient\";\n\nconst worker = new Worker(\"/worker.js\", { type: \"module\" });\nconst client = BrowserClient.from(worker);\nconst response = await client.fetch(\"👋\");\n```\n\n### BrowserRequest\n\n<sup>_Module_</sup>\n\nA server receives a `Request` object when a client makes a request.\n\n###### Types\n\n- [Request](#Request)\n\n###### Functions\n\n- [isRequest](#IsRequest)\n\n#### Request\n\n<sup>_Type_</sup>\n\n```ts\ntype Request = {\n  address: string;\n  /**\n   * Contains the value sent by the client.\n   */\n  body: StructuredCloneable.t;\n  id: string;\n  /**\n   * The origin of the client making the request. The origin will be set\n   * securely on the server using `MessageEvent.origin`.\n   */\n  origin: string;\n  type: \"Request\";\n};\n```\n\nA `Request` is created when a client makes a fetch request.\n\n#### IsRequest\n\n<sup>_Function_</sup>\n\n```ts\nfunction isRequest(event: MessageEvent): event is MessageEvent<Request>;\n```\n\nReturns `true` if the message event contains a `Request` object.\n\n### BrowserResponse\n\n<sup>_Module_</sup>\n\nA server sends a `Response` to a client in response to a request.\n\n###### Types\n\n- [Response](#Response)\n\n###### Functions\n\n- [isResponse](#IsResponse)\n\n#### Response\n\n<sup>_Type_</sup>\n\n```ts\ntype Response = {\n  /**\n   * The payload of the response. This is the value the client will receive.\n   */\n  body: StructuredCloneable.t;\n  id: string;\n  type: \"Response;\n};\n```\n\nA `Response` is created from the value returned by the server's request handler.\n\n#### IsResponse\n\n<sup>_Function_</sup>\n\n```ts\nfunction isResponse(event: MessageEvent): event is MessageEvent<Response>;\n```\n\nReturns `true` if the message event contains a `Response` object.\n\n### BrowserServer\n\n<sup>_Module_</sup>\n\nA `BrowserServer` provides request/response semantics on top of `postMessage`. It also normalizes the interface for connecting to different types of processes in the browser.\n\n###### Types\n\n- [BrowserServer](#BrowserServer_BrowserServer)\n- [Options](#BrowserServer_Options)\n- [RequestHandler](#RequestHandler)\n- [State](#State)\n\n###### Constructors\n\n- [listen](#listen)\n\n###### Methods\n\n- [stop](#Stop)\n\n<h4 id=\"BrowserServer_BrowserServer\">BrowserServer</h4>\n\n<sup>_Type_</Sup>\n\n```ts\nclass BrowserServer {\n  public readonly address: string;\n  public readonly handle: RequestHandler;\n  public readonly state: State;\n  public readonly stateChange: Observable.t<State>;\n  public readonly stopped: Observable.t<State.Stopped>;\n}\n```\n\nA `BrowserServer` listens for incoming requests from clients.\n\n<h4 id=\"BrowserServer_Options\">Options</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype Options = {\n  /**\n   * The address of the server. The default is the empty string. All servers\n   * must have a globally unique address.\n   */\n  address?: string;\n  /**\n   * Called whenever a request is received from a client. The request handler\n   * may return anything that is structured cloneable.\n   *\n   * The request object will contain the origin of the client. The origin can be\n   * used to validate the client before fulfilling the request.\n   */\n  handle: RequestHandler;\n};\n```\n\nOptions when creating a `BrowserServer`.\n\n#### RequestHandler\n\n<sup>_Type_</sup>\n\n```ts\ntype RequestHandler = (\n  request: Readonly<Request.t>\n) => StructuredCloneable.t | Promise<StructuredCloneable.t>;\n```\n\nA `RequestHandler` receives a `Request` from a client and returns the body of the `Response` that will be sent back to the client.\n\n#### State\n\n<sup>_Type_</sup>\n\n```ts\nenum State {\n  Listening = \"Listening\",\n  Stopped = \"Stopped\"\n}\n```\n\nAn enumerable of the different server states.\n\n#### Listen\n\n<sup>_Constructor_</sup>\n\n```ts\nfunction listen(options: Options): BrowserServer;\n```\n\nCreates a new `BrowserServer` in the global scope. A `UniqueAddressError` will\nbe thrown if the address is already taken.\n\n#### Example\n\n```ts\nimport * as BrowserServer from \"@daniel-nagy/transporter/BrowserServer\";\n\nconst server = BrowserServer.listen({\n  handle(request) {\n    // Message received from client. Return any response.\n    return \"👋\";\n  }\n});\n```\n\n#### Stop\n\n<sup>_Method_</sup>\n\n```ts\nstop(): void;\n```\n\nStops the server. Once stopped the server will no longer receive requests.\n\n#### Example\n\n```ts\nimport * as BrowserServer from \"@daniel-nagy/transporter/BrowserServer\";\n\nconst server = BrowserServer.listen({\n  handle(request) {}\n});\n\nserver.stop();\n```\n\n### BrowserSocket\n\n<sup>_Module_</sup>\n\nProvides a socket API on top of `postMessage` that is similar to the WebSocket API. A `BrowserSocket` is connection-oriented, duplex, and unicast. Any data that is structured cloneable can be passed through a browser socket.\n\n###### Types\n\n- [BrowserSocket](#BrowserSocket_BrowserSocket)\n- [ConnectionError](#ConnectionError)\n- [ConnectTimeoutError](#ConnectTimeoutError)\n- [DisconnectTimeoutError](#DisconnectTimeoutError)\n- [HeartbeatTimeoutError](#HeartbeatTimeoutError)\n- [Options](#BrowserSocket_Options)\n- [WindowOptions](#WindowOptions)\n\n###### Constructors\n\n- [connect](#connect)\n\n###### Methods\n\n- [close](#Close)\n- [ping](#Ping)\n- [send](#Send)\n\n<h4 id=\"BrowserSocket_BrowserSocket\">BrowserSocket</h4>\n\n<sup>_Type_</sup>\n\n```ts\nclass BrowserSocket {\n  /**\n   * Emits when the socket's state changes to `Closed` and then completes.\n   */\n  public readonly closed: Observable.t<State.Closed>;\n  /**\n   * Emits when the socket's state changes to `Closing` and then completes.\n   */\n  public readonly closing: Observable.t<State.Closing>;\n  /**\n   * Emits if the socket's state changes to `Connected` and then completes. If\n   * the socket errors during connection it will complete without emitting.\n   */\n  public readonly connected: Observable.t<State.Connected>;\n  /**\n   * Emits when the socket receives data.\n   */\n  public readonly receive: Observable.t<StructuredCloneable.t>;\n  /**\n   * The current state of the socket.\n   */\n  public readonly state: State;\n  /**\n   * Emits when the socket's state changes. Completes when the socket state\n   * becomes `Closed`.\n   */\n  public readonly stateChange: Observable.t<State>;\n}\n```\n\nA `BrowserSocket` is used to create a connection between browsing contexts or a browsing context and a worker context.\n\n#### ConnectionError\n\n<sup>_Type_</sup>\n\n```ts\ntype ConnectionError =\n  | Observable.BufferOverflowError\n  | ConnectTimeoutError\n  | HeartbeatTimeoutError;\n```\n\nA variant type for the different reasons a socket may transition to a closing state with an error.\n\n#### ConnectTimeoutError\n\n<sup>_Type_</sup>\n\n```ts\nclass ConnectTimeoutError extends Error {}\n```\n\nUsed to indicate that the connection failed because the server did not complete the connection in the allotted time.\n\n#### DisconnectTimeoutError\n\n<sup>_Type_</sup>\n\n```ts\nclass DisconnectTimeoutError extends Error {}\n```\n\nUsed to indicate that an acknowledgement was not received when closing the connection in the allotted time.\n\n#### HeartbeatTimeoutError\n\n<sup>_Type_</sup>\n\n```ts\nclass HeartbeatTimeoutError extends Error {}\n```\n\nUsed to indicate that a response to a health-check was not received in the allotted time.\n\n<h4 id=\"BrowserSocket_Options\">Options</h4>\n\n<sup>_Type_</sup>\n\n```ts\ninterface Options {\n  /**\n   * The maximum number of messages to buffer before the socket is connected.\n   * The default is `Infinity`.\n   */\n  bufferLimit?: number;\n  /**\n   * What to do incase there is a buffer overflow. The default is to error.\n   */\n  bufferOverflowStrategy?: Observable.BufferOverflowStrategy;\n  /**\n   * The maximum amount of time to wait for a connection in milliseconds. The\n   * default is `2000` or 2 seconds.\n   */\n  connectTimeout?: number;\n  /**\n   * The maximum amount of time to wait for a disconnection in milliseconds. The\n   * default is `2000` or 2 seconds.\n   */\n  disconnectTimeout?: number;\n  /**\n   * The frequency at which to request heartbeats in milliseconds. The default\n   * is `1000` or 1 second.\n   */\n  heartbeatInterval?: number;\n  /**\n   * The maximum amount of time to wait for a heartbeat in milliseconds. The\n   * default is `2000` or 2 seconds.\n   */\n  heartbeatTimeout?: number;\n  /**\n   * The address of the socket server.\n   */\n  serverAddress?: string;\n}\n```\n\nOptions when creating a `BrowserSocket`.\n\n#### WindowOptions\n\n<sup>_Type_</sup>\n\n```ts\ninterface WindowOptions extends Options {\n  /**\n   * When connecting to a `Window` you may specify the allowed origin. If the\n   * window and the origin do not match the connection will fail. The origin is\n   * passed directly to the `targetOrigin` parameter of `postMessage` when\n   * connecting to the window. The default is `\"*\"`, which allows any origin.\n   */\n  origin?: string;\n}\n```\n\nAdditional options when connecting to a browsing context.\n\n#### Connect\n\n<sup>_Constructor_</sup>\n\n```ts\nfunction connect(\n  target: SharedWorker | Window | Worker,\n  options?: Options | WindowOptions\n): BrowserSocket;\n```\n\nCreates a new `BrowserSocket`. The socket will start in a `Connecting` state.\n\n##### Example\n\n```ts\nimport * as BrowserSocket from \"@daniel-nagy/transporter/BrowserSocket\";\nusing socket = BrowserSocket.connect(self.parent);\n```\n\n#### Close\n\n<sup>_Method_</sup>\n\n```ts\nclose(): void;\n```\n\nCloses the socket causing its state to transition to `Closing`.\n\n##### Example\n\n```ts\nimport * as BrowserSocket from \"@daniel-nagy/transporter/BrowserSocket\";\nconst socket = BrowserSocket.connect(self.parent);\nsocket.close();\n```\n\n#### Ping\n\n<sup>_Method_</sup>\n\n```ts\nping(timeout: number = 2000): Promise<void>;\n```\n\nSends a ping to a connected socket and waits for a pong to be sent back. Returns a promise that resolves when a pong is received or rejects if a pong is not received in the allotted time.\n\n##### Example\n\n```ts\nimport * as BrowserSocket from \"@daniel-nagy/transporter/BrowserSocket\";\nusing socket = BrowserSocket.connect(self.parent);\nawait socket.ping();\n```\n\n#### Send\n\n<sup>_Method_</sup>\n\n```ts\nsend(message: StructuredCloneable.t): void;\n```\n\nSends data through the socket. Data will automatically be buffered until the socket connects.\n\n##### Example\n\n```ts\nimport * as BrowserSocket from \"@daniel-nagy/transporter/BrowserSocket\";\nconst socket = BrowserSocket.connect(self.parent);\nsocket.send(\"👋\");\n```\n\n### BrowserSocket.Message\n\n<sup>_Module_</sup>\n\nInternal messages to facilitate the socket API. These messages are filtered from the data received from the socket.\n\n###### Types\n\n- [Connect](#Message_Connect)\n- [Connected](#Connected)\n- [Disconnect](#Disconnect)\n- [Disconnected](#Disconnected)\n- [Message](#Message)\n- [Ping](#Message_Ping)\n- [Pong](#Pong)\n- [Type](#Type)\n\n###### Functions\n\n- [isMessage](#IsMessage)\n- [isType](#IsType)\n- [typeOf](#typeOf)\n\n<h4 id=\"Message_Connect\">Connect</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype Connect = {\n  address: string;\n  type: Type.Connect;\n};\n```\n\nSent when a connection is initiated. This starts the \"handshake\".\n\n#### Connect\n\n<sup>_Type_</sup>\n\n```ts\ntype Connected = {\n  type: Type.Connected;\n};\n```\n\nA message indicating the connection is complete and was successful. This concludes the \"handshake\".\n\n#### Disconnect\n\n<sup>_Type_</sup>\n\n```ts\ntype Disconnect = {\n  type: Type.Disconnect;\n};\n```\n\nSent when a socket is closing so that the other endpoint may preform some cleanup logic or otherwise close the connection gracefully. This starts the \"closing handshake\".\n\n#### Disconnected\n\n<sup>_Type_</sup>\n\n```ts\ntype Disconnected = {\n  type: Type.Disconnected;\n};\n```\n\nA message that acknowledges the disconnection. If this message is received then the disconnect was graceful. This concludes the \"closing handshake\".\n\n#### Message\n\n<sup>_Type_</sup>\n\n```ts\nexport type Message =\n  | Connect\n  | Connected\n  | Disconnect\n  | Disconnected\n  | Ping\n  | Pong;\n```\n\nA variant type for the different types of messages.\n\n<h4 id=\"Message_Ping\">Ping</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype Ping = {\n  id: string;\n  type: Type.Ping;\n};\n```\n\nA ping message may be sent to solicit a response from the other endpoint.\n\n#### Pong\n\n<sup>_Type_</sup>\n\n```ts\ntype Pong = {\n  id: string;\n  type: Type.Pong;\n};\n```\n\nA pong message must always be sent in response to a ping message.\n\n#### Type\n\n<sup>_Type_</sup>\n\n```ts\nenum Type {\n  Connect = \"Connect\",\n  Connected = \"Connected\",\n  Disconnect = \"Disconnect\",\n  Disconnected = \"Disconnected\",\n  Ping = \"Ping\",\n  Pong = \"Pong\"\n}\n```\n\nAn enumerable of the different types of socket messages.\n\n#### IsMessage\n\n<sup>_Function_</sup>\n\n```ts\nfunction isMessage(message: StructuredCloneable.t): message is Message;\n```\n\nReturns `true` if the message is a socket message.\n\n#### IsType\n\n<sup>_Function_</sup>\n\n```ts\nfunction isType<T extends Type>(\n  message: StructuredCloneable.t,\n  type: T\n): message is {\n  [Type.Connect]: Connect;\n  [Type.Connected]: Connected;\n  [Type.Disconnect]: Disconnect;\n  [Type.Disconnected]: Disconnected;\n  [Type.Ping]: Ping;\n  [Type.Pong]: Pong;\n}[T];\n```\n\nReturns `true` if the message is of the specified type.\n\n#### TypeOf\n\n<sup>_Function_</sup>\n\n```ts\nfunction typeOf(message: StructuredCloneable.t): Type | null;\n```\n\nReturns the message `Type` if the message is a socket message. Returns `null` otherwise.\n\n### BrowserSocket.State\n\n<sup>_Module_</sup>\n\nA socket's state.\n\n###### Types\n\n- [Closed](#Closed)\n- [Closing](#Closing)\n- [Connected](#State_Connected)\n- [Connecting](#Connecting)\n- [State](#State_State)\n- [Type](#State_Type)\n\n#### Closed\n\n<sup>_Type_</sup>\n\n```ts\ntype Closed<E> = {\n  error?: E;\n  type: Type.Closed;\n};\n```\n\nThe socket is closed, possibly with an error.\n\n#### Closing\n\n<sup>_Type_</sup>\n\n```ts\ntype Closing<E> = {\n  error?: E;\n  type: Type.Closing;\n};\n```\n\nThe socket is closing, possibly with an error.\n\n<h4 id=\"State_Connected\">Connected</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype Connected = {\n  type: Type.Connected;\n};\n```\n\nThe socket is connected.\n\n#### Connecting\n\n<sup>_Type_</sup>\n\n```ts\ntype Connecting = {\n  type: Type.Connecting;\n};\n```\n\nThe socket is connecting.\n\n<h4 id=\"State_State\">State</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype State =\n  | Connecting\n  | Connected\n  | Closing<Error.ConnectionError>\n  | Closed<Error.DisconnectTimeoutError>;\n```\n\nA variant type for the different socket states.\n\n<h4 id=\"State_Type\">Type</h4>\n\n<sup>_Type_</sup>\n\n```ts\nenum Type {\n  Connecting = \"Connecting\",\n  Connected = \"Connected\",\n  Closing = \"Closing\",\n  Closed = \"Closed\"\n}\n```\n\nAn enumerable of the different socket states.\n\n### BrowserSocketServer\n\n<sup>_Module_</sup>\n\nA `BrowserSocketServer` listens for socket connect requests. When a request is received it will create a corresponding socket server side and complete the handshake.\n\n###### Types\n\n- [BrowserSocketServer](#BrowserSocketServer_BrowserSocketServer)\n- [Options](#BrowserSocketServer_Options)\n- [SocketOptions](#SocketOptions)\n- [State](#BrowserSocketServer_State)\n\n###### Constructors\n\n- [listen](#BrowserSocketServer_Listen)\n\n###### Methods\n\n- [stop](#BrowserSocketServer_Stop)\n\n<h4 id=\"BrowserSocketServer_BrowserSocketServer\">BrowserSocketServer</h4>\n\n<sup>_Type_</sup>\n\n```ts\nclass BrowserSocketServer {\n  public readonly address: string;\n  public readonly connect: Observable.t<BrowserSocket.t>;\n  public readonly state: State;\n  public readonly stateChange: Observable.t<State>;\n  public readonly stopped: Observable.t<State.Stopped>;\n}\n```\n\nCreates socket connections as requests come in.\n\n<h4 id=\"BrowserSocketServer_Options\">Options</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype Options = {\n  /**\n   * The address of the server. The default is an empty string.\n   */\n  address?: string;\n  /**\n   * Allows intercepting connection requests and denying the request if\n   * necessary.\n   */\n  connectFilter?(message: MessageEvent<Message.Connect>): boolean;\n  /**\n   * Forwarded to the socket that is created on connection.\n   */\n  socketOptions?: SocketOptions;\n};\n```\n\nOptions when creating a `BrowserSocketServer`.\n\n#### SocketOptions\n\n<sup>_Type_</sup>\n\n```ts\ntype SocketOptions = {\n  disconnectTimeout?: number;\n  heartbeatInterval?: number;\n  heartbeatTimeout?: number;\n};\n```\n\nOptions forwarded to the `BrowserSocket` when it is created.\n\n<h4 id=\"BrowserSocketServer_State\">State</h4>\n\n<sup>_Type_</sup>\n\n```ts\nenum State {\n  Listening = \"Listening\",\n  Stopped = \"Stopped\"\n}\n```\n\nAn enumerable of the different server states.\n\n<h4 id=\"BrowserSocketServer_Listen\">Listen</h4>\n\n<sup>_Constructor_</sup>\n\n```ts\nfunction listen(options?: Options): BrowserSocketServer;\n```\n\nCreates a new `BrowserSocketServer`. Throws a `UniqueAddressError` if the address is already taken.\n\n#### Example\n\n```ts\nimport * as BrowserSocketServer from \"@daniel-nagy/transporter/BrowserSocketServer\";\n\nconst server = BrowserSocketServer.listen();\nserver.connect.subscribe((socket) => socket.send(\"👋\"));\n```\n\n<h4 id=\"BrowserSocketServer_Stop\">Stop</h4>\n\n<sup>_Method_</sup>\n\n```ts\nfunction stop(): void;\n```\n\nStops the server. A disconnect message will be sent to all connected clients.\n\n#### Example\n\n```ts\nimport * as BrowserSocketServer from \"@daniel-nagy/transporter/BrowserSocketServer\";\n\nconst server = BrowserSocketServer.listen();\nserver.stop();\n```\n\n### StructuredCloneable\n\n<sup>_Module_</sup>\n\nA `StructuredCloneable` type can be passed between processes in the browser.\n\n###### Types\n\n- [StructuredCloneable](#StructuredCloneable_StructuredCloneable)\n- [TypedArray](#TypedArray)\n\n<h4 id=\"StructuredCloneable_StructuredCloneable\">StructuredCloneable</h4>\n\n<sup>_Type_</sup>\n\n```ts\ntype StructuredCloneable =\n  | void\n  | null\n  | undefined\n  | boolean\n  | number\n  | bigint\n  | string\n  | Date\n  | ArrayBuffer\n  | RegExp\n  | TypedArray\n  | Array<StructuredCloneable>\n  | Map<StructuredCloneable, StructuredCloneable>\n  | Set<StructuredCloneable>\n  | { [key: string]: StructuredCloneable };\n```\n\nA value that can be cloned using the [structured clone algorithm](https://developer.mozilla.org/en-US/docs/Web/API/structuredClone).\n\n#### TypedArray\n\n<sup>_Type_</sup>\n\n```ts\ntype TypedArray =\n  | BigInt64Array\n  | BigUint64Array\n  | Float32Array\n  | Float64Array\n  | Int8Array\n  | Int16Array\n  | Int32Array\n  | Uint8Array\n  | Uint8ClampedArray\n  | Uint16Array\n  | Uint32Array;\n```\n\nA `TypedArray` object describes an array-like view of an underlying binary data buffer.\n","readmeFilename":"README.md"}