├── .changeset ├── README.md └── config.json ├── .github ├── actions │ └── install-dependencies │ │ └── action.yml ├── dependabot.yml └── workflows │ ├── canary.yml │ ├── on-pull-request.yml │ ├── on-push-to-main.yml │ └── verify.yml ├── .gitignore ├── .vscode ├── extensions.json └── settings.json ├── CHANGELOG.md ├── LICENSE ├── README.md ├── biome.json ├── bun.lockb ├── package.json ├── scripts ├── prepublishOnly.ts └── tsconfig.json ├── src ├── CHANGELOG.md ├── LICENSE ├── README.md ├── index.ts ├── native.ts ├── package.json └── utils.ts ├── test ├── bun │ ├── index.ts │ └── package.json ├── deno │ ├── index.ts │ └── package.json ├── next │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── playwright.config.ts │ ├── src │ │ └── app │ │ │ ├── client.tsx │ │ │ ├── layout.tsx │ │ │ └── page.tsx │ ├── tests │ │ └── default.spec.ts │ └── tsconfig.json ├── node │ ├── index.js │ ├── index.mjs │ └── package.json ├── sveltekit │ ├── .gitignore │ ├── package.json │ ├── playwright.config.ts │ ├── src │ │ ├── app.d.ts │ │ ├── app.html │ │ └── routes │ │ │ ├── +page.svelte │ │ │ ├── +page.ts │ │ │ ├── edge │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ │ ├── node16 │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ │ └── node18 │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ ├── static │ │ └── favicon.png │ ├── svelte.config.js │ ├── tests │ │ └── default.spec.ts │ ├── tsconfig.json │ └── vite.config.ts ├── tsc │ ├── .gitignore │ ├── index.ts │ ├── package.json │ └── tsconfig.json └── vite │ ├── index.html │ ├── package.json │ ├── playwright.config.ts │ ├── src │ └── main.ts │ ├── tests │ └── default.spec.ts │ └── tsconfig.json ├── tsconfig.base.json ├── tsconfig.build.json └── tsconfig.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@1.6.3/schema.json", 3 | "changelog": ["@changesets/changelog-github", { "repo": "wevm/isows" }], 4 | "commit": false, 5 | "access": "public", 6 | "baseBranch": "main", 7 | "updateInternalDependencies": "patch", 8 | "___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH": { 9 | "onlyUpdatePeerDependentsWhenOutOfRange": true 10 | }, 11 | "ignore": ["test-*"] 12 | } 13 | -------------------------------------------------------------------------------- /.github/actions/install-dependencies/action.yml: -------------------------------------------------------------------------------- 1 | name: "Install dependencies" 2 | description: "Prepare repository and all dependencies" 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Set up Bun 8 | uses: oven-sh/setup-bun@v1 9 | 10 | - name: Install dependencies 11 | shell: bash 12 | run: bun install -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: 'github-actions' 4 | directory: '/' 5 | schedule: 6 | interval: 'monthly' 7 | -------------------------------------------------------------------------------- /.github/workflows/canary.yml: -------------------------------------------------------------------------------- 1 | name: Release (Canary) 2 | on: 3 | push: 4 | branches: [main] 5 | workflow_dispatch: 6 | 7 | jobs: 8 | canary: 9 | name: Release canary 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 5 12 | 13 | steps: 14 | - name: Clone repository 15 | uses: actions/checkout@v4 16 | 17 | - name: Install dependencies 18 | uses: ./.github/actions/install-dependencies 19 | 20 | - name: Setup .npmrc file 21 | uses: actions/setup-node@v4 22 | with: 23 | registry-url: 'https://registry.npmjs.org' 24 | 25 | - name: Set version 26 | run: | 27 | jq --arg prop "workspaces" 'del(.[$prop])' package.json > package.tmp.json && rm package.json && cp package.tmp.json package.json && rm package.tmp.json 28 | cd src 29 | npm --no-git-tag-version version 0.0.0 30 | npm --no-git-tag-version version $(npm pkg get version | sed 's/"//g')-$(git branch --show-current | tr -cs '[:alnum:]-' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//').$(date +'%Y%m%dT%H%M%S') 31 | 32 | - name: Build 33 | run: bun run build 34 | 35 | - name: Publish to npm 36 | run: cd src && npm publish --tag $(git branch --show-current | tr -cs '[:alnum:]-' '-' | tr '[:upper:]' '[:lower:]' | sed 's/-$//') 37 | env: 38 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} 39 | -------------------------------------------------------------------------------- /.github/workflows/on-pull-request.yml: -------------------------------------------------------------------------------- 1 | name: Pull request 2 | on: 3 | pull_request: 4 | types: [opened, reopened, synchronize, ready_for_review] 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | verify: 12 | name: Verify 13 | uses: ./.github/workflows/verify.yml 14 | secrets: inherit 15 | 16 | size: 17 | name: Size 18 | runs-on: ubuntu-latest 19 | timeout-minutes: 5 20 | 21 | steps: 22 | - name: Clone repository 23 | uses: actions/checkout@v4 24 | 25 | - name: Install dependencies 26 | uses: ./.github/actions/install-dependencies 27 | 28 | - name: Report build size 29 | uses: preactjs/compressed-size-action@v2 30 | with: 31 | repo-token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/on-push-to-main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | on: 3 | push: 4 | branches: [main] 5 | 6 | concurrency: 7 | group: ${{ github.workflow }}-${{ github.ref }} 8 | cancel-in-progress: true 9 | 10 | jobs: 11 | verify: 12 | name: Verify 13 | uses: ./.github/workflows/verify.yml 14 | secrets: inherit 15 | 16 | changesets: 17 | name: Changesets 18 | needs: verify 19 | runs-on: ubuntu-latest 20 | timeout-minutes: 5 21 | 22 | steps: 23 | - name: Clone repository 24 | uses: actions/checkout@v4 25 | with: 26 | # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits 27 | fetch-depth: 0 28 | 29 | - name: Install dependencies 30 | uses: ./.github/actions/install-dependencies 31 | 32 | - name: Create version pull request or publish to npm 33 | uses: changesets/action@v1 34 | with: 35 | title: 'chore: version packages' 36 | commit: 'chore: version packages' 37 | publish: bun run changeset:release 38 | version: bun run changeset:version 39 | env: 40 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 41 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }} -------------------------------------------------------------------------------- /.github/workflows/verify.yml: -------------------------------------------------------------------------------- 1 | name: Verify 2 | on: 3 | workflow_call: 4 | 5 | jobs: 6 | lint: 7 | name: Lint 8 | runs-on: ubuntu-latest 9 | timeout-minutes: 5 10 | 11 | steps: 12 | - name: Clone repository 13 | uses: actions/checkout@v4 14 | 15 | - name: Install dependencies 16 | uses: ./.github/actions/install-dependencies 17 | 18 | - name: Lint code 19 | run: bun run format && bun run lint 20 | 21 | - uses: stefanzweifel/git-auto-commit-action@v5 22 | env: 23 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 24 | with: 25 | commit_message: 'chore: format' 26 | commit_user_name: 'github-actions[bot]' 27 | commit_user_email: 'github-actions[bot]@users.noreply.github.com' 28 | 29 | types: 30 | name: Types 31 | runs-on: ubuntu-latest 32 | 33 | steps: 34 | - name: Clone repository 35 | uses: actions/checkout@v4 36 | 37 | - name: Install dependencies 38 | uses: ./.github/actions/install-dependencies 39 | 40 | - name: Check types 41 | run: bun run typecheck 42 | 43 | test: 44 | name: Test 45 | runs-on: ubuntu-latest 46 | strategy: 47 | matrix: 48 | type: ['bun', 'deno', 'node-16', 'node-18', 'node-20', 'node-latest', 'next', 'sveltekit', 'tsc'] 49 | include: 50 | - type: bun 51 | runtime: bun 52 | - type: deno 53 | runtime: deno 54 | - type: node-16 55 | node-version: 16 56 | runtime: node 57 | - type: node-18 58 | node-version: 18 59 | runtime: node 60 | - type: node-20 61 | node-version: 20 62 | runtime: node 63 | - type: node-latest 64 | node-version: latest 65 | runtime: node 66 | - type: next 67 | runtime: next 68 | - type: sveltekit 69 | node-version: 18 70 | runtime: sveltekit 71 | - type: tsc 72 | node-version: 20 73 | runtime: tsc 74 | 75 | steps: 76 | - name: Clone repository 77 | uses: actions/checkout@v4 78 | 79 | - name: Set up Bun 80 | if: ${{ matrix.runtime == 'bun' }} 81 | uses: oven-sh/setup-bun@v2 82 | 83 | - name: Set up Node 84 | if: ${{ matrix.node-version }} 85 | uses: actions/setup-node@v4 86 | with: 87 | node-version: ${{ matrix.node-version }} 88 | 89 | - name: Set up Deno 90 | if: ${{ matrix.runtime == 'deno' }} 91 | uses: denoland/setup-deno@v1 92 | 93 | - name: Install dependencies 94 | uses: ./.github/actions/install-dependencies 95 | 96 | - name: Install Playwright Browsers 97 | if: ${{ matrix.runtime == 'next' || matrix.runtime == 'sveltekit' || matrix.runtime == 'vite' }} 98 | run: npx playwright@1.52.0 install --with-deps 99 | 100 | - name: Build 101 | run: bun run build 102 | 103 | - name: Run tests 104 | run: bun run test:${{ matrix.runtime }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.local 2 | .DS_Store 3 | .eslintcache 4 | .next 5 | bench 6 | cache 7 | coverage 8 | node_modules 9 | tsconfig*.tsbuildinfo 10 | src/_cjs 11 | src/_esm 12 | src/_types 13 | 14 | # local env files 15 | .env 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | .envrc 21 | 22 | /test-results/ 23 | /playwright-report/ 24 | /playwright/.cache/ 25 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["orta.vscode-twoslash-queries", "biomejs.biome"] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "biomejs.biome", 3 | "editor.formatOnSave": true, 4 | "typescript.tsdk": "node_modules/typescript/lib", 5 | "typescript.enablePromptUseWorkspaceTsdk": true, 6 | "editor.codeActionsOnSave": { 7 | "source.organizeImports.biome": "explicit" 8 | }, 9 | "[json]": { 10 | "editor.defaultFormatter": "biomejs.biome" 11 | }, 12 | "[javascript]": { 13 | "editor.defaultFormatter": "biomejs.biome" 14 | }, 15 | "[javascriptreact]": { 16 | "editor.defaultFormatter": "biomejs.biome" 17 | }, 18 | "[typescript]": { 19 | "editor.defaultFormatter": "biomejs.biome" 20 | }, 21 | "[typescriptreact]": { 22 | "editor.defaultFormatter": "biomejs.biome" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ./src/CHANGELOG.md -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | ./src/LICENSE -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ./src/README.md -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "files": { 3 | "ignore": [ 4 | "_cjs", 5 | "_esm", 6 | "_types", 7 | ".next", 8 | ".vercel", 9 | ".svelte-kit", 10 | "bun.lockb", 11 | "tsconfig.json", 12 | "tsconfig.*.json", 13 | "tsconfig.node.json" 14 | ] 15 | }, 16 | "formatter": { 17 | "enabled": true, 18 | "indentStyle": "space", 19 | "indentWidth": 2 20 | }, 21 | "linter": { 22 | "enabled": true, 23 | "rules": { 24 | "recommended": true, 25 | "performance": { 26 | "noDelete": "off" 27 | }, 28 | "style": { 29 | "noNonNullAssertion": "off" 30 | }, 31 | "suspicious": { 32 | "noAssignInExpressions": "off" 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wevm/isows/871b9251a89b422002c65d070bce8be12fb3d6d4/bun.lockb -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "workspaces": ["test/*", "src"], 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "build": "bun run clean && bun run build:cjs && bun run build:esm && bun run build:types", 7 | "build:cjs": "tsc --project ./tsconfig.build.json --module commonjs --moduleResolution node --outDir ./src/_cjs --removeComments --verbatimModuleSyntax false && printf '{\"type\":\"commonjs\"}' > ./src/_cjs/package.json", 8 | "build:esm": "tsc --project ./tsconfig.build.json --module es2015 --moduleResolution node --outDir ./src/_esm && printf '{\"type\": \"module\",\"sideEffects\":false}' > ./src/_esm/package.json", 9 | "build:types": "tsc --project ./tsconfig.build.json --module esnext --moduleResolution node --declarationDir ./src/_types --emitDeclarationOnly --declaration --declarationMap", 10 | "changeset": "changeset", 11 | "changeset:release": "bun run build && bun run prepublishOnly && changeset publish", 12 | "changeset:version": "changeset version && bun install --lockfile-only", 13 | "clean": "rimraf src/_esm src/_cjs src/_types", 14 | "format": "biome format . --write", 15 | "lint": "biome check . --apply", 16 | "preinstall": "npx only-allow bun", 17 | "prepare": "npx simple-git-hooks", 18 | "prepublishOnly": "npx bun scripts/prepublishOnly.ts", 19 | "size": "size-limit", 20 | "test": "bun run test:node && bun run test:bun && bun run test:deno && bun run test:vite && bun run test:sveltekit && bun run test:next && bun run test:tsc", 21 | "test:bun": "cd test/bun && bun run test", 22 | "test:deno": "cd test/deno && bun run test", 23 | "test:next": "cd test/next && bun run test", 24 | "test:node": "cd test/node && bun run test", 25 | "test:tsc": "cd test/tsc && bun run test", 26 | "test:sveltekit": "cd test/sveltekit && bun run test", 27 | "test:vite": "cd test/vite && bun run test", 28 | "typecheck": "tsc --noEmit" 29 | }, 30 | "devDependencies": { 31 | "@biomejs/biome": "^1.2.2", 32 | "@changesets/changelog-github": "^0.4.8", 33 | "@changesets/cli": "^2.26.1", 34 | "@types/node": "^20.3.1", 35 | "@types/ws": "^8.5.6", 36 | "bun": "^1.0.4", 37 | "bun-types": "^1.0.4", 38 | "rimraf": "^5.0.1", 39 | "simple-git-hooks": "^2.8.1", 40 | "typescript": "^5.2.2", 41 | "ws": "^8.14.2" 42 | }, 43 | "simple-git-hooks": { 44 | "pre-commit": "bun run format && bun run lint" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /scripts/prepublishOnly.ts: -------------------------------------------------------------------------------- 1 | import { join } from "node:path"; 2 | 3 | const packageJsonPath = join(import.meta.dir, "../src/package.json"); 4 | const packageJson = await Bun.file(packageJsonPath).json(); 5 | 6 | // NOTE: We explicitly don't want to publish the type field. 7 | // We create a separate package.json for `dist/cjs` and `dist/esm` that has the type field. 8 | delete packageJson.type; 9 | 10 | Bun.write(packageJsonPath, JSON.stringify(packageJson, null, 2)); 11 | -------------------------------------------------------------------------------- /scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "module": "nodenext", 5 | "types": ["bun-types"] 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # isows 2 | 3 | ## 1.0.7 4 | 5 | ### Patch Changes 6 | 7 | - [#21](https://github.com/wevm/isows/pull/21) [`8d6f65858afc0cb131d40c6f415542347b0c909c`](https://github.com/wevm/isows/commit/8d6f65858afc0cb131d40c6f415542347b0c909c) Thanks [@lucasloisp](https://github.com/lucasloisp)! - Fixed `react-native` export in `package.json#exports`. 8 | 9 | ## 1.0.6 10 | 11 | ### Patch Changes 12 | 13 | - [#15](https://github.com/wevm/isows/pull/15) [`a8d943b5c2a47ada792d9070379aacabb8d01ceb`](https://github.com/wevm/isows/commit/a8d943b5c2a47ada792d9070379aacabb8d01ceb) Thanks [@lkwr](https://github.com/lkwr)! - Renamed conditional export `worked` to `workerd` in `package.json#exports`. 14 | 15 | ## 1.0.5 16 | 17 | ### Patch Changes 18 | 19 | - [`fc36fcbbea8a91411263dbd053e44623eac385b5`](https://github.com/wevm/isows/commit/fc36fcbbea8a91411263dbd053e44623eac385b5) Thanks [@jxom](https://github.com/jxom)! - Added `worked` export to `package.json#exports`. 20 | 21 | ## 1.0.4 22 | 23 | ### Patch Changes 24 | 25 | - [#9](https://github.com/wevm/isows/pull/9) [`1d0e496db949a59ec6d3e635522f42b69daa52b7`](https://github.com/wevm/isows/commit/1d0e496db949a59ec6d3e635522f42b69daa52b7) Thanks [@iketw](https://github.com/iketw)! - Added `react-native` export to `package.json#exports`. 26 | 27 | ## 1.0.3 28 | 29 | ### Patch Changes 30 | 31 | - [`8d37b99`](https://github.com/wagmi-dev/isows/commit/8d37b99ad08c286c20a50864d98c8119d7dae0db) Thanks [@jxom](https://github.com/jxom)! - Fixed CommonJS builds. 32 | 33 | ## 1.0.2 34 | 35 | ### Patch Changes 36 | 37 | - [`c0c0e87`](https://github.com/wagmi-dev/isows/commit/c0c0e8724407a989da70bfff29cf444ccbf31b84) Thanks [@jxom](https://github.com/jxom)! - Removed `"module"` from `package.json`. 38 | 39 | - [`59ccdf9`](https://github.com/wagmi-dev/isows/commit/59ccdf9a45900a5854b010f58bf4a6f11169c23f) Thanks [@jxom](https://github.com/jxom)! - Added `"deno"` conditional export. 40 | 41 | ## 1.0.0 42 | 43 | ### Major Changes 44 | 45 | - [`bd4f010`](https://github.com/wagmi-dev/isows/commit/bd4f010d8267a0c48ecc9c09d3a5e8ff8aa1b05d) Thanks [@jxom](https://github.com/jxom)! - Initial release. 46 | -------------------------------------------------------------------------------- /src/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-present weth, LLC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/README.md: -------------------------------------------------------------------------------- 1 | # isows 2 | 3 | Isomorphic WebSocket implementation for Node.js, Bun, Deno, and modern browsers. 4 | 5 | ## Install 6 | 7 | ```bash 8 | npm i isows 9 | ``` 10 | 11 | ```bash 12 | pnpm i isows 13 | ``` 14 | 15 | ```bash 16 | bun i isows 17 | ``` 18 | 19 | ## Usage 20 | 21 | ```ts 22 | import { WebSocket } from 'isows' 23 | 24 | const ws = new WebSocket('ws://localhost:8080') 25 | ``` 26 | 27 | ## Authors 28 | 29 | - [@jxom](https://github.com/jxom) (jxom.eth, [Twitter](https://twitter.com/_jxom)) 30 | 31 | ## License 32 | 33 | [MIT](/LICENSE) License 34 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import * as WebSocket_ from "ws"; 2 | import { getNativeWebSocket } from "./utils.js"; 3 | 4 | export const WebSocket = (() => { 5 | try { 6 | return getNativeWebSocket(); 7 | } catch { 8 | if (WebSocket_.WebSocket) return WebSocket_.WebSocket; 9 | return WebSocket_; 10 | } 11 | })(); 12 | -------------------------------------------------------------------------------- /src/native.ts: -------------------------------------------------------------------------------- 1 | import { getNativeWebSocket } from "./utils.js"; 2 | 3 | export const WebSocket = getNativeWebSocket(); 4 | 5 | type MessageEvent_ = MessageEvent; 6 | export type { MessageEvent_ as MessageEvent }; 7 | -------------------------------------------------------------------------------- /src/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "isows", 3 | "description": "Isomorphic WebSocket", 4 | "version": "1.0.7", 5 | "type": "module", 6 | "browser": "./_esm/native.js", 7 | "main": "./_cjs/index.js", 8 | "module": "./_esm/index.js", 9 | "types": "./_types/native.d.ts", 10 | "typings": "./_types/native.d.ts", 11 | "sideEffects": false, 12 | "files": [ 13 | "*", 14 | "!**/*.tsbuildinfo", 15 | "!**/*.test.ts", 16 | "!**/*.test.ts.snap", 17 | "!**/*.test-d.ts", 18 | "!**/*.bench.ts", 19 | "!tsconfig.build.json" 20 | ], 21 | "exports": { 22 | ".": { 23 | "types": "./_types/native.d.ts", 24 | "bun": "./_esm/native.js", 25 | "browser": "./_esm/native.js", 26 | "deno": "./_esm/native.js", 27 | "workerd": "./_esm/native.js", 28 | "react-native": "./_esm/native.js", 29 | "import": "./_esm/index.js", 30 | "default": "./_cjs/index.js" 31 | }, 32 | "./package.json": "./package.json" 33 | }, 34 | "peerDependencies": { 35 | "ws": "*" 36 | }, 37 | "license": "MIT", 38 | "repository": "wevm/isows", 39 | "authors": ["jxom.eth"], 40 | "funding": [ 41 | { 42 | "type": "github", 43 | "url": "https://github.com/sponsors/wevm" 44 | } 45 | ], 46 | "keywords": ["isomorphic", "websocket", "ws", "node", "browser"] 47 | } 48 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | export function getNativeWebSocket() { 2 | if (typeof WebSocket !== "undefined") return WebSocket; 3 | if (typeof global.WebSocket !== "undefined") return global.WebSocket; 4 | if (typeof window.WebSocket !== "undefined") return window.WebSocket; 5 | if (typeof self.WebSocket !== "undefined") return self.WebSocket; 6 | throw new Error("`WebSocket` is not supported in this environment"); 7 | } 8 | -------------------------------------------------------------------------------- /test/bun/index.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => process.exit(0); 7 | -------------------------------------------------------------------------------- /test/bun/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-bun", 3 | "private": true, 4 | "scripts": { 5 | "test": "bun index.ts" 6 | }, 7 | "dependencies": { 8 | "isows": "file:../../src/" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/deno/index.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "../../src/_esm/native.js"; 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => Deno.exit(0); 7 | -------------------------------------------------------------------------------- /test/deno/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-deno", 3 | "private": true, 4 | "scripts": { 5 | "test": "deno run --allow-net --allow-env index.ts" 6 | }, 7 | "dependencies": { 8 | "isows": "file:../../src/" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/next/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /test/next/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = {}; 3 | 4 | module.exports = { 5 | webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => { 6 | config.externals.push({ 7 | "utf-8-validate": "commonjs utf-8-validate", 8 | bufferutil: "commonjs bufferutil", 9 | }); 10 | return config; 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /test/next/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-next", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint", 10 | "test": "playwright test" 11 | }, 12 | "dependencies": { 13 | "react": "^18", 14 | "react-dom": "^18", 15 | "next": "13.5.4", 16 | "isows": "file:../../src/" 17 | }, 18 | "devDependencies": { 19 | "@playwright/test": "1.52.0", 20 | "@types/node": "^20", 21 | "@types/react": "^18", 22 | "@types/react-dom": "^18", 23 | "typescript": "^5.2.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/next/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from "@playwright/test"; 2 | 3 | /** 4 | * Read environment variables from file. 5 | * https://github.com/motdotla/dotenv 6 | */ 7 | // require('dotenv').config(); 8 | 9 | /** 10 | * See https://playwright.dev/docs/test-configuration. 11 | */ 12 | export default defineConfig({ 13 | testDir: "./tests", 14 | retries: 3, 15 | projects: [ 16 | { 17 | name: "chromium", 18 | use: { ...devices["Desktop Chrome"] }, 19 | }, 20 | 21 | { 22 | name: "firefox", 23 | use: { ...devices["Desktop Firefox"] }, 24 | }, 25 | 26 | { 27 | name: "webkit", 28 | use: { ...devices["Desktop Safari"] }, 29 | }, 30 | ], 31 | webServer: { 32 | command: "bun run dev", 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /test/next/src/app/client.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { useEffect, useState } from "react"; 4 | 5 | export function Client() { 6 | const [success, setSuccess] = useState(); 7 | useEffect(() => { 8 | const ws = new WebSocket( 9 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 10 | ); 11 | ws.onopen = () => setSuccess(true); 12 | }, []); 13 | return
client: {success ? "success" : ""}
; 14 | } 15 | -------------------------------------------------------------------------------- /test/next/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | export const metadata = { 2 | title: "Next.js", 3 | description: "Generated by Next.js", 4 | }; 5 | 6 | export default function RootLayout({ 7 | children, 8 | }: { 9 | children: React.ReactNode; 10 | }) { 11 | return ( 12 | 13 | {children} 14 | 15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /test/next/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | import { Client } from "./client"; 3 | 4 | export default async function Home() { 5 | await new Promise((res) => { 6 | const ws = new WebSocket( 7 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 8 | ); 9 | ws.onopen = () => res(); 10 | }); 11 | return ( 12 | <> 13 |
server: success
14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /test/next/tests/default.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from "@playwright/test"; 2 | 3 | test("default", async ({ page }) => { 4 | await page.goto("http://localhost:3000/"); 5 | await expect(page.getByText("server: success")).toBeVisible(); 6 | await expect(page.getByText("client: success")).toBeVisible(); 7 | }); 8 | -------------------------------------------------------------------------------- /test/next/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /test/node/index.js: -------------------------------------------------------------------------------- 1 | const { WebSocket } = require("isows"); 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => process.exit(0); 7 | -------------------------------------------------------------------------------- /test/node/index.mjs: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => process.exit(0); 7 | -------------------------------------------------------------------------------- /test/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-node", 3 | "private": true, 4 | "scripts": { 5 | "test": "node index.js && node index.mjs" 6 | }, 7 | "dependencies": { 8 | "isows": "file:../../src/" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/sveltekit/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /build 4 | /.svelte-kit 5 | /package 6 | .env 7 | .env.* 8 | !.env.example 9 | vite.config.js.timestamp-* 10 | vite.config.ts.timestamp-* 11 | 12 | .vercel 13 | -------------------------------------------------------------------------------- /test/sveltekit/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-sveltekit", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "dev": "vite dev", 7 | "build": "vite build", 8 | "preview": "vite preview", 9 | "test": "playwright test" 10 | }, 11 | "dependencies": { 12 | "isows": "file:../../src/" 13 | }, 14 | "devDependencies": { 15 | "@playwright/test": "1.52.0", 16 | "@sveltejs/adapter-vercel": "^3.0.3", 17 | "@sveltejs/kit": "^1.20.4", 18 | "isows": "^1.0.7", 19 | "svelte": "^4.0.5", 20 | "svelte-check": "^3.4.3", 21 | "tslib": "^2.4.1", 22 | "typescript": "^5.2.2", 23 | "vite": "^4.4.2" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /test/sveltekit/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from "@playwright/test"; 2 | 3 | /** 4 | * Read environment variables from file. 5 | * https://github.com/motdotla/dotenv 6 | */ 7 | // require('dotenv').config(); 8 | 9 | /** 10 | * See https://playwright.dev/docs/test-configuration. 11 | */ 12 | export default defineConfig({ 13 | testDir: "./tests", 14 | retries: 3, 15 | projects: [ 16 | { 17 | name: "chromium", 18 | use: { ...devices["Desktop Chrome"] }, 19 | }, 20 | 21 | { 22 | name: "firefox", 23 | use: { ...devices["Desktop Firefox"] }, 24 | }, 25 | 26 | { 27 | name: "webkit", 28 | use: { ...devices["Desktop Safari"] }, 29 | }, 30 | ], 31 | webServer: { 32 | command: "bun run build && bun run preview", 33 | port: 4173, 34 | }, 35 | }); 36 | -------------------------------------------------------------------------------- /test/sveltekit/src/app.d.ts: -------------------------------------------------------------------------------- 1 | // See https://kit.svelte.dev/docs/types#app 2 | // for information about these interfaces 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | // interface Locals {} 7 | // interface PageData {} 8 | // interface Platform {} 9 | } 10 | } 11 | 12 | export type {}; 13 | -------------------------------------------------------------------------------- /test/sveltekit/src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /test/sveltekit/src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 14 | 15 |
server: success
16 |

17 | {#await promise} 18 | Loading... 19 | {:then blockNumber} 20 | client: success 21 | {:catch error} 22 | Error: {error.message}. 23 | {/await} 24 |

-------------------------------------------------------------------------------- /test/sveltekit/src/routes/+page.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | export async function load() { 4 | await new Promise((res) => { 5 | const ws = new WebSocket( 6 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 7 | ); 8 | ws.onopen = () => res(); 9 | }); 10 | 11 | return { 12 | success: true, 13 | }; 14 | } 15 | -------------------------------------------------------------------------------- /test/sveltekit/src/routes/edge/+page.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
server: success {data.success}
-------------------------------------------------------------------------------- /test/sveltekit/src/routes/edge/+page.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | export const config = { 4 | runtime: "edge", 5 | }; 6 | 7 | export async function load() { 8 | await new Promise((res) => { 9 | const ws = new WebSocket( 10 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 11 | ); 12 | ws.onopen = () => res(); 13 | }); 14 | 15 | return { 16 | success: true, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /test/sveltekit/src/routes/node16/+page.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
server: success {data.success}
-------------------------------------------------------------------------------- /test/sveltekit/src/routes/node16/+page.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | export const config = { 4 | runtime: "nodejs16.x", 5 | }; 6 | 7 | export async function load() { 8 | await new Promise((res) => { 9 | const ws = new WebSocket( 10 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 11 | ); 12 | ws.onopen = () => res(); 13 | }); 14 | 15 | return { 16 | success: true, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /test/sveltekit/src/routes/node18/+page.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 |
server: success {data.success}
-------------------------------------------------------------------------------- /test/sveltekit/src/routes/node18/+page.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | export const config = { 4 | runtime: "nodejs18.x", 5 | }; 6 | 7 | export async function load() { 8 | await new Promise((res) => { 9 | const ws = new WebSocket( 10 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 11 | ); 12 | ws.onopen = () => res(); 13 | }); 14 | 15 | return { 16 | success: true, 17 | }; 18 | } 19 | -------------------------------------------------------------------------------- /test/sveltekit/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wevm/isows/871b9251a89b422002c65d070bce8be12fb3d6d4/test/sveltekit/static/favicon.png -------------------------------------------------------------------------------- /test/sveltekit/svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from "@sveltejs/adapter-vercel"; 2 | import { vitePreprocess } from "@sveltejs/kit/vite"; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://kit.svelte.dev/docs/integrations#preprocessors 7 | // for more information about preprocessors 8 | preprocess: vitePreprocess(), 9 | 10 | kit: { 11 | // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. 12 | // If your environment is not supported or you settled on a specific environment, switch out the adapter. 13 | // See https://kit.svelte.dev/docs/adapters for more information about adapters. 14 | adapter: adapter(), 15 | }, 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /test/sveltekit/tests/default.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from "@playwright/test"; 2 | 3 | test("default", async ({ page }) => { 4 | await page.goto("http://localhost:4173/"); 5 | await expect(page.getByText("server: success")).toBeVisible(); 6 | await expect(page.getByText("client: success")).toBeVisible(); 7 | }); 8 | -------------------------------------------------------------------------------- /test/sveltekit/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true 12 | } 13 | // Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias 14 | // 15 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 16 | // from the referenced tsconfig.json - TypeScript does not merge them in 17 | } 18 | -------------------------------------------------------------------------------- /test/sveltekit/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from "@sveltejs/kit/vite"; 2 | import { defineConfig } from "vite"; 3 | 4 | export default defineConfig({ 5 | plugins: [sveltekit()], 6 | }); 7 | -------------------------------------------------------------------------------- /test/tsc/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules -------------------------------------------------------------------------------- /test/tsc/index.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => process.exit(0); 7 | -------------------------------------------------------------------------------- /test/tsc/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-tsc", 3 | "private": true, 4 | "type": "module", 5 | "scripts": { 6 | "test": "tsc --module commonjs --verbatimModuleSyntax false && tsc --module es2015 && tsc --module es2020 && tsc --module esnext && tsc --module node16 --moduleResolution nodenext && tsc --module nodenext --moduleResolution nodenext" 7 | }, 8 | "dependencies": { 9 | "isows": "file:../../src/", 10 | "typescript": "^5.2.2" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /test/tsc/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "include": ["index.ts"], 3 | "compilerOptions": { 4 | /* Visit https://aka.ms/tsconfig to read more about this file */ 5 | 6 | /* Projects */ 7 | // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ 8 | // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ 9 | // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ 10 | // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ 11 | // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ 12 | // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ 13 | 14 | /* Language and Environment */ 15 | "target": "ESNext" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, 16 | // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ 17 | // "jsx": "preserve", /* Specify what JSX code is generated. */ 18 | // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ 19 | // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ 20 | // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ 21 | // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ 22 | // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ 23 | // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ 24 | // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ 25 | // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ 26 | // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ 27 | 28 | /* Modules */ 29 | "module": "ESNext" /* Specify what module code is generated. */, 30 | // "rootDir": "./", /* Specify the root folder within your source files. */ 31 | "moduleResolution": "Node" /* Specify how TypeScript looks up a file from a given module specifier. */, 32 | // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ 33 | // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ 34 | // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ 35 | // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ 36 | // "types": [], /* Specify type package names to be included without being referenced in a source file. */ 37 | // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ 38 | // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ 39 | // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ 40 | // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ 41 | // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ 42 | // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ 43 | // "resolveJsonModule": true, /* Enable importing .json files. */ 44 | // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ 45 | // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ 46 | 47 | /* JavaScript Support */ 48 | // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ 49 | // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ 50 | // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ 51 | 52 | /* Emit */ 53 | // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ 54 | // "declarationMap": true, /* Create sourcemaps for d.ts files. */ 55 | // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ 56 | // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ 57 | // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ 58 | // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ 59 | "outDir": "./dist" /* Specify an output folder for all emitted files. */, 60 | // "removeComments": true, /* Disable emitting comments. */ 61 | // "noEmit": true, /* Disable emitting files from a compilation. */ 62 | // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ 63 | // "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types. */ 64 | // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ 65 | // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ 66 | // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ 67 | // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ 68 | // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ 69 | // "newLine": "crlf", /* Set the newline character for emitting files. */ 70 | // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ 71 | // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ 72 | // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ 73 | // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ 74 | // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ 75 | // "preserveValueImports": true, /* Preserve unused imported values in the JavaScript output that would otherwise be removed. */ 76 | 77 | /* Interop Constraints */ 78 | "isolatedModules": true /* Ensure that each file can be safely transpiled without relying on other imports. */, 79 | "verbatimModuleSyntax": true /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */, 80 | "allowSyntheticDefaultImports": true /* Allow 'import x from y' when a module doesn't have a default export. */, 81 | "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, 82 | "preserveSymlinks": true /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */, 83 | "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, 84 | 85 | /* Type Checking */ 86 | "strict": true /* Enable all strict type-checking options. */, 87 | "noImplicitAny": true /* Enable error reporting for expressions and declarations with an implied 'any' type. */, 88 | "strictNullChecks": true /* When type checking, take into account 'null' and 'undefined'. */, 89 | "strictFunctionTypes": true /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */, 90 | "strictBindCallApply": true /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */, 91 | "strictPropertyInitialization": true /* Check for class properties that are declared but not set in the constructor. */, 92 | "noImplicitThis": true /* Enable error reporting when 'this' is given the type 'any'. */, 93 | // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ 94 | // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ 95 | // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ 96 | // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ 97 | // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ 98 | // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ 99 | // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ 100 | // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ 101 | // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ 102 | // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ 103 | // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ 104 | // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ 105 | 106 | /* Completeness */ 107 | // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ 108 | "skipLibCheck": true /* Skip type checking all .d.ts files. */ 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /test/vite/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Vite + TS 8 | 9 | 10 |
11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test/vite/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test-vite", 3 | "private": true, 4 | "version": "0.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite --port 5173", 8 | "test": "playwright test" 9 | }, 10 | "dependencies": { 11 | "isows": "file:../../src/" 12 | }, 13 | "devDependencies": { 14 | "@playwright/test": "1.52.0", 15 | "@types/node": "^20.8.3", 16 | "typescript": "^5.2.2", 17 | "vite": "^4.4.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /test/vite/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from "@playwright/test"; 2 | 3 | /** 4 | * Read environment variables from file. 5 | * https://github.com/motdotla/dotenv 6 | */ 7 | // require('dotenv').config(); 8 | 9 | /** 10 | * See https://playwright.dev/docs/test-configuration. 11 | */ 12 | export default defineConfig({ 13 | testDir: "./tests", 14 | retries: 3, 15 | projects: [ 16 | { 17 | name: "chromium", 18 | use: { ...devices["Desktop Chrome"] }, 19 | }, 20 | 21 | { 22 | name: "firefox", 23 | use: { ...devices["Desktop Firefox"] }, 24 | }, 25 | 26 | { 27 | name: "webkit", 28 | use: { ...devices["Desktop Safari"] }, 29 | }, 30 | ], 31 | webServer: { 32 | command: "bun run dev", 33 | }, 34 | }); 35 | -------------------------------------------------------------------------------- /test/vite/src/main.ts: -------------------------------------------------------------------------------- 1 | import { WebSocket } from "isows"; 2 | 3 | const ws = new WebSocket( 4 | "wss://ws-ap1.pusher.com:443/app/78a7f9604f977d235435", 5 | ); 6 | ws.onopen = () => (document.getElementById("app")!.innerText = "success"); 7 | -------------------------------------------------------------------------------- /test/vite/tests/default.spec.ts: -------------------------------------------------------------------------------- 1 | import { expect, test } from "@playwright/test"; 2 | 3 | test("default", async ({ page }) => { 4 | await page.goto("http://localhost:5173/"); 5 | await expect(page.getByText("success")).toBeVisible(); 6 | }); 7 | -------------------------------------------------------------------------------- /test/vite/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "useDefineForClassFields": true, 5 | "module": "ESNext", 6 | "lib": ["ES2020", "DOM", "DOM.Iterable"], 7 | "skipLibCheck": true, 8 | 9 | /* Bundler mode */ 10 | "moduleResolution": "bundler", 11 | "allowImportingTsExtensions": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "noEmit": true, 15 | 16 | /* Linting */ 17 | "strict": true, 18 | "noUnusedLocals": true, 19 | "noUnusedParameters": true, 20 | "noFallthroughCasesInSwitch": true 21 | }, 22 | "include": ["src"] 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.base.json: -------------------------------------------------------------------------------- 1 | { 2 | // This tsconfig file contains the shared config for the build (tsconfig.build.json) and type checking (tsconfig.json) config. 3 | "include": [], 4 | "compilerOptions": { 5 | // Incremental builds 6 | // NOTE: Enabling incremental builds speeds up `tsc`. Keep in mind though that it does not reliably bust the cache when the `tsconfig.json` file changes. 7 | "incremental": true, 8 | 9 | // Type checking 10 | "strict": true, 11 | "useDefineForClassFields": true, // Not enabled by default in `strict` mode unless we bump `target` to ES2022. 12 | "noFallthroughCasesInSwitch": true, // Not enabled by default in `strict` mode. 13 | "noImplicitReturns": true, // Not enabled by default in `strict` mode. 14 | "useUnknownInCatchVariables": true, // TODO: This would normally be enabled in `strict` mode but would require some adjustments to the codebase. 15 | "noImplicitOverride": true, // Not enabled by default in `strict` mode. 16 | "noUnusedLocals": true, // Not enabled by default in `strict` mode. 17 | "noUnusedParameters": true, // Not enabled by default in `strict` mode. 18 | 19 | // JavaScript support 20 | "allowJs": false, 21 | "checkJs": false, 22 | 23 | // Interop constraints 24 | "esModuleInterop": false, 25 | "allowSyntheticDefaultImports": false, 26 | "forceConsistentCasingInFileNames": true, 27 | "verbatimModuleSyntax": true, 28 | "importHelpers": true, // This is only used for build validation. Since we do not have `tslib` installed, this will fail if we accidentally make use of anything that'd require injection of helpers. 29 | 30 | // Language and environment 31 | "moduleResolution": "NodeNext", 32 | "module": "NodeNext", 33 | "target": "ES2021", // Setting this to `ES2021` enables native support for `Node v16+`: https://github.com/microsoft/TypeScript/wiki/Node-Target-Mapping. 34 | "lib": ["ES2022", "DOM"], 35 | 36 | // Skip type checking for node modules 37 | "skipLibCheck": true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /tsconfig.build.json: -------------------------------------------------------------------------------- 1 | { 2 | // This file is used to compile the for cjs and esm (see package.json build scripts). It should exclude all test files. 3 | "extends": "./tsconfig.base.json", 4 | "include": ["src"], 5 | "exclude": [ 6 | "src/**/*.test.ts", 7 | "src/**/*.test-d.ts" 8 | ], 9 | "compilerOptions": { 10 | "sourceMap": true, 11 | "rootDir": "./src" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | // This configuration is used for local development and type checking. 3 | "extends": "./tsconfig.base.json", 4 | "include": ["src"], 5 | "references": [{ "path": "./scripts/tsconfig.json" }] 6 | } 7 | --------------------------------------------------------------------------------