Files
suaveplan/packages/security-stack/crypto/crypto-browser/src/availability/availability.md
2026-05-27 23:47:53 +01:00

3.4 KiB

availability

(no submodules)

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

import { isWebCryptoAvailable } from "@suaveplan/crypto-browser/availability/availability";

if (!isWebCryptoAvailable()) {
  console.warn("WebCrypto not available — using fallback cipher");
}

Usage: Advanced Example

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.