-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: iso-web supports signals and crypto
- Loading branch information
1 parent
d9e2cf7
commit 0a0da99
Showing
13 changed files
with
320 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
name: iso-web | ||
env: | ||
CI: true | ||
FORCE_COLOR: 1 | ||
on: | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- 'packages/iso-web/**' | ||
- '.github/workflows/iso-web.yml' | ||
- 'pnpm-lock.yaml' | ||
pull_request: | ||
paths: | ||
- 'packages/iso-web/**' | ||
- '.github/workflows/iso-web.yml' | ||
- 'pnpm-lock.yaml' | ||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- uses: pnpm/action-setup@v2.4.0 | ||
with: | ||
version: 8 | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: 18 | ||
cache: 'pnpm' | ||
- run: pnpm install | ||
- run: pnpm run build | ||
- run: pnpm -r --filter iso-web run lint | ||
- run: pnpm -r --filter iso-web run test | ||
- run: pnpm -r --filter iso-web exec depcheck |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
{ | ||
"name": "iso-web", | ||
"version": "0.0.1", | ||
"description": "Isomorphic Web APIs", | ||
"author": "Hugo Dias <hugomrdias@gmail.com> (hugodias.me)", | ||
"license": "MIT", | ||
"repository": { | ||
"url": "hugomrdias/iso-repo", | ||
"directory": "packages/iso-web" | ||
}, | ||
"homepage": "https://github.com/hugomrdias/iso-repo/tree/master/packages/iso-web", | ||
"bugs": { | ||
"url": "https://github.com/hugomrdias/iso-repo/issues" | ||
}, | ||
"keywords": [ | ||
"web apis", | ||
"crypto", | ||
"webcrypto", | ||
"abortcontroller", | ||
"abortsignal" | ||
], | ||
"type": "module", | ||
"main": "src/index.js", | ||
"types": "dist/src/index.d.ts", | ||
"browser": { | ||
"crypto": false, | ||
"./src/crypto.js": "./src/crypto-browser.js" | ||
}, | ||
"exports": { | ||
".": { | ||
"types": "./dist/src/index.d.ts", | ||
"default": "./src/index.js" | ||
}, | ||
"./crypto": { | ||
"types": "./dist/src/crypto.d.ts", | ||
"node": "./src/crypto.js", | ||
"react-native": "./src/crypto-browser.js", | ||
"default": "./src/crypto-browser.js" | ||
}, | ||
"./signals": { | ||
"types": "./dist/src/signals.d.ts", | ||
"default": "./src/signals.js" | ||
} | ||
}, | ||
"typesVersions": { | ||
"*": { | ||
"crypto": [ | ||
"dist/src/crypto" | ||
], | ||
"signals": [ | ||
"dist/src/signals" | ||
] | ||
} | ||
}, | ||
"files": [ | ||
"src", | ||
"dist/src/*.d.ts", | ||
"dist/src/*.d.ts.map" | ||
], | ||
"scripts": { | ||
"lint": "tsc --build && eslint '**/*.{js,ts}' && prettier --check '**/*.{js,ts,yml,json}' --ignore-path ../../.gitignore", | ||
"test": "tsc --build && pnpm run test:node && pnpm run test:browser", | ||
"test:node": "playwright-test 'test/**/!(*.browser).test.js' --mode node", | ||
"test:browser": "playwright-test 'test/**/!(*.node).test.js'" | ||
}, | ||
"devDependencies": { | ||
"@types/assert": "^1.5.6", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "^20.4.3", | ||
"assert": "^2.0.0", | ||
"delay": "^6.0.0", | ||
"hd-scripts": "^7.0.0", | ||
"mocha": "^10.2.0", | ||
"playwright-test": "^12.2.0", | ||
"typescript": "5.1.6" | ||
}, | ||
"publishConfig": { | ||
"provenance": true | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
"../../node_modules/hd-scripts/eslint/index.js" | ||
], | ||
"parserOptions": { | ||
"project": "./tsconfig.json" | ||
}, | ||
"env": { | ||
"mocha": true | ||
}, | ||
"ignorePatterns": [ | ||
"dist" | ||
] | ||
}, | ||
"depcheck": { | ||
"specials": [ | ||
"bin" | ||
], | ||
"ignores": [ | ||
"@types/*", | ||
"hd-scripts", | ||
"assert" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# iso-web [![NPM Version](https://img.shields.io/npm/v/iso-web.svg)](https://www.npmjs.com/package/iso-web) [![License](https://img.shields.io/npm/l/iso-web.svg)](https://github.com/hugomrdias/iso-repo/blob/main/license) [![iso-web](https://github.com/hugomrdias/iso-repo/actions/workflows/iso-web.yml/badge.svg)](https://github.com/hugomrdias/iso-repo/actions/workflows/iso-web.yml) | ||
|
||
> Isomorphic web apis. | ||
## Install | ||
|
||
```bash | ||
pnpm install iso-web | ||
``` | ||
|
||
## License | ||
|
||
MIT © [Hugo Dias](http://hugodias.me) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export const webcrypto = globalThis.crypto | ||
|
||
/** | ||
* Secure PRNG - Random bytes from webcrypto | ||
* | ||
* @param {number} length | ||
*/ | ||
export function randomBytes(length = 32) { | ||
if (globalThis.crypto) { | ||
return globalThis.crypto.getRandomValues(new Uint8Array(length)) | ||
} else { | ||
throw new Error("The environment doesn't have randomBytes function") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* Isomorphic web crypto and random bytes exports | ||
* | ||
* @module | ||
*/ | ||
import crypto from 'crypto' | ||
|
||
export const webcrypto = /** @type {Crypto} */ (crypto.webcrypto) | ||
|
||
/** | ||
* Secure PRNG - Random bytes from webcrypto | ||
* | ||
* @param {number} length | ||
*/ | ||
export function randomBytes(length = 32) { | ||
if (crypto.webcrypto) { | ||
return crypto.webcrypto.getRandomValues(new Uint8Array(length)) | ||
} else { | ||
throw new Error("The environment doesn't have randomBytes function") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export * as Crypto from './crypto.js' | ||
export * as Signals from './signals.js' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
/** | ||
* Isomorphic signals | ||
* | ||
* @module | ||
*/ | ||
|
||
/** | ||
* Combines an array of AbortSignals into a single signal that is aborted when any signal is | ||
* | ||
* @param {Iterable<AbortSignal>} signals | ||
* @returns {AbortSignal} | ||
*/ | ||
export function anySignal(signals) { | ||
const controller = new AbortController() | ||
|
||
for (const signal of signals) { | ||
if ('aborted' in signal && 'reason' in signal) { | ||
if (signal.aborted) { | ||
controller.abort(signal.reason) | ||
return signal | ||
} | ||
|
||
signal.addEventListener('abort', () => controller.abort(signal.reason), { | ||
signal: controller.signal, | ||
once: true, | ||
}) | ||
} | ||
} | ||
|
||
return controller.signal | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { assert, test } from 'playwright-test/taps' | ||
import { anySignal } from '../src/signals.js' | ||
import delay from 'delay' | ||
|
||
test('should abort from any signal', async (t) => { | ||
const controllers = Array.from({ length: 5 }).map(() => new AbortController()) | ||
const signals = controllers.map((c) => c.signal) | ||
const signal = anySignal(signals) | ||
|
||
assert.equal(signal.aborted, false) | ||
|
||
controllers[0].abort() | ||
|
||
assert.equal(signal.aborted, true) | ||
assert.equal(signals[0].aborted, true) | ||
assert.equal(signals[1].aborted, false) | ||
assert.equal(signals[2].aborted, false) | ||
}) | ||
|
||
test('should ignore non signal', async (t) => { | ||
const controllers = Array.from({ length: 5 }).map(() => new AbortController()) | ||
const signals = controllers.map((c) => c.signal) | ||
// @ts-ignore | ||
const signal = anySignal([...signals, { reason: 'test' }]) | ||
|
||
assert.equal(signal.aborted, false) | ||
|
||
controllers[0].abort() | ||
|
||
assert.equal(signal.aborted, true) | ||
}) | ||
|
||
test('should abort only once', async (t) => { | ||
const controllers = Array.from({ length: 5 }).map(() => new AbortController()) | ||
const signals = controllers.map((c) => c.signal) | ||
const signal = anySignal(signals) | ||
|
||
let count = 0 | ||
signal.addEventListener('abort', () => { | ||
count++ | ||
}) | ||
|
||
for (const controller of controllers) { | ||
controller.abort() | ||
} | ||
|
||
for (const controller of controllers) { | ||
controller.abort() | ||
} | ||
|
||
await delay(100) | ||
|
||
assert.equal(count, 1) | ||
|
||
assert.equal(signal.aborted, true) | ||
}) | ||
|
||
test('should abort with an AbortSignal.timeout', async (t) => { | ||
const controllers = Array.from({ length: 5 }).map(() => new AbortController()) | ||
const signals = controllers.map((c) => c.signal) | ||
const signal = anySignal([...signals, AbortSignal.timeout(100)]) | ||
|
||
await delay(101) | ||
|
||
assert.equal(signal.reason.name, 'TimeoutError') | ||
assert.equal(signal.aborted, true) | ||
}) | ||
|
||
test('should abort if any signal already aborted', (t) => { | ||
const controllers = Array.from({ length: 5 }).map(() => new AbortController()) | ||
const signals = controllers.map((c) => c.signal) | ||
const signal = anySignal([...signals, AbortSignal.abort('test')]) | ||
|
||
assert.equal(signal.aborted, true) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"extends": "../../tsconfig.json", | ||
"compilerOptions": { | ||
"outDir": "dist", | ||
"lib": ["ESNext", "DOM"], | ||
"emitDeclarationOnly": true | ||
}, | ||
"include": ["src", "scripts", "test", "package.json"], | ||
"exclude": ["node_modules", "dist", "out"], | ||
"typedocOptions": { | ||
"entryPoints": ["src/signals.js", "src/crypto.js"], | ||
"includeVersion": true, | ||
"excludeExternals": true, | ||
"internalModule": "<internal>" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters