Initial Commit
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
# availability
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Provides a runtime check for the presence of the Web Crypto API (`crypto.subtle`). The check is a prerequisite for every operation in `@suaveplan/crypto-browser`: all engine methods and primitives call `assertWebCryptoAvailable()` before attempting any `crypto.subtle` call, so callers receive a structured, typed `BrowserCryptoError` rather than an opaque `TypeError: Cannot read properties of undefined (reading 'subtle')`.
|
||||
|
||||
The two exported helpers form a small contract: `isWebCryptoAvailable` is a pure predicate useful for conditional branching or feature-flag evaluation, while `assertWebCryptoAvailable` is the guard variant used internally throughout the package.
|
||||
|
||||
## Features
|
||||
|
||||
- `isWebCryptoAvailable(): boolean` — returns `true` when both `globalThis.crypto` and `globalThis.crypto.subtle` are defined; otherwise `false`
|
||||
- `assertWebCryptoAvailable(): void` — throws `BrowserCryptoError` with code `BROWSER_CRYPTO.NOT_AVAILABLE` if the check fails
|
||||
- Zero side effects — purely reads globals, never modifies them
|
||||
- Works across Node 20+, Bun, Deno, and modern browsers without polyfills
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { isWebCryptoAvailable } from "@suaveplan/crypto-browser/availability/availability";
|
||||
|
||||
if (!isWebCryptoAvailable()) {
|
||||
console.warn("WebCrypto not available — using fallback cipher");
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { assertWebCryptoAvailable } from "@suaveplan/crypto-browser/availability/availability";
|
||||
import { BrowserCryptoError } from "@suaveplan/crypto-browser/errors";
|
||||
|
||||
async function encryptUserData(key: Uint8Array, data: Uint8Array): Promise<Uint8Array> {
|
||||
// Guard before any crypto.subtle calls
|
||||
assertWebCryptoAvailable();
|
||||
|
||||
// ... proceed with crypto.subtle.encrypt
|
||||
return new Uint8Array();
|
||||
}
|
||||
|
||||
// Caller can catch the specific structured error
|
||||
try {
|
||||
await encryptUserData(key, data);
|
||||
} catch (err) {
|
||||
if (err instanceof BrowserCryptoError && err.code === "BROWSER_CRYPTO.NOT_AVAILABLE") {
|
||||
// Fall back to a server-side encryption endpoint
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `isWebCryptoAvailable(): boolean`
|
||||
|
||||
Returns `true` when `typeof crypto !== 'undefined' && typeof crypto.subtle !== 'undefined'`.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| _(none)_ | — | — |
|
||||
|
||||
**Returns:** `boolean` — `true` if `crypto.subtle` is accessible.
|
||||
|
||||
**Throws:** never.
|
||||
|
||||
---
|
||||
|
||||
### `assertWebCryptoAvailable(): void`
|
||||
|
||||
Calls `isWebCryptoAvailable()` and throws if the result is `false`.
|
||||
|
||||
| Parameter | Type | Description |
|
||||
|-----------|------|-------------|
|
||||
| _(none)_ | — | — |
|
||||
|
||||
**Returns:** `void`
|
||||
|
||||
**Throws:** `BrowserCryptoError` — code `BROWSER_CRYPTO.NOT_AVAILABLE` when `crypto.subtle` is absent.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The check deliberately uses `typeof crypto !== 'undefined'` (rather than a `try/catch` or optional chaining on a possibly-unset global) to avoid triggering a `ReferenceError` in environments where `crypto` is not declared at all. Optional chaining `globalThis?.crypto?.subtle` is not used because `globalThis` itself might be unavailable in some older embedded runtimes.
|
||||
|
||||
Both exports are side-effect-free and tree-shakeable: `"sideEffects": false` is set on the package, so bundlers that import only `isWebCryptoAvailable` will not include `BrowserCryptoError` in the output unless it is actually used.
|
||||
Reference in New Issue
Block a user