CipherStashDocs
ReferenceStack SDKAPI reference

wasm-inline

wasm-inline is a module in @cipherstash/stack. TypeScript API reference with its signature, parameters, and usage.

@cipherstash/stack


wasm-inline

Classes

AccessKeyStrategy

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:106

An auth strategy that uses a static access key for service-to-service or CI/CD authentication, scoped to a single workspace identified by a CRN. The region is derived from the CRN, so there's no separate region argument and no chance of the strategy operating against a region the caller didn't expect.

Every issued token's workspace JWT claim is verified against the CRN's workspace ID. A mismatch fails the getToken() call with an AuthError whose code is "WORKSPACE_MISMATCH" — the strategy never silently lets a multi-workspace access key operate on the wrong workspace.

Methods

create()
static create(
   workspaceCrn, 
   accessKey, 
   options?): Result<AccessKeyStrategy, AuthFailure>;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:122

Create a new AccessKeyStrategy for the given workspace CRN and access key.

The CRN format is crn:<region>:<workspace-id> (e.g. "crn:ap-southeast-2.aws:ZVATKW3VHMFG27DY"). Region is parsed from the CRN and used for service discovery; the workspace ID is used to verify every issued token belongs to the right workspace.

Pass options.store to back the strategy with a persistent cache — see TokenStore and the `@cipherstash/auth/cookies` helper.

Parameters
workspaceCrn

string

accessKey

string

options?

AccessKeyStrategyOptions

Returns

Result<AccessKeyStrategy, AuthFailure>

getToken()
getToken(): Promise&lt;GetTokenResult&gt;;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:128

Retrieve a valid access token, refreshing or re-authenticating as needed.

Returns

Promise<GetTokenResult>

free()
free(): void;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:130

Release the underlying wasm resources.

Returns

void


OidcFederationStrategy

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:160

An auth strategy that federates a third-party OIDC JWT (Clerk, Supabase, …) into a CipherStash CTS service token via /api/authorise.

Methods

create()
static create(
   workspaceCrn, 
   getJwt, 
   options?): Result&lt;OidcFederationStrategy, AuthFailure&gt;;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:174

Create an OidcFederationStrategy for the given workspace CRN.

The CRN format is crn:&lt;region&gt;:&lt;workspace-id&gt; (e.g. "crn:ap-southeast-2.aws:ZVATKW3VHMFG27DY"). Region is parsed from the CRN and used for service discovery; the workspace ID is used to verify every federated token belongs to the right workspace.

getJwt must return the current third-party OIDC JWT (it is re-invoked on every re-federation). Pass options.store to back the strategy with a persistent cache — see TokenStore.

Parameters
workspaceCrn

string

getJwt

OidcProvider

options?

OidcFederationStrategyOptions

Returns

Result<OidcFederationStrategy, AuthFailure>

getToken()
getToken(): Promise&lt;GetTokenResult&gt;;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:180

Retrieve a valid CTS service token, federating or re-federating as needed.

Returns

Promise<GetTokenResult>

free()
free(): void;

Defined in: ../../../node_modules/.bun/@[email protected]/node_modules/@cipherstash/auth/wasm-inline.d.ts:182

Release the underlying wasm resources.

Returns

void


WasmEncryptionClient

Defined in: wasm-inline.ts:731

WASM encryption client. Returned by Encryption.

Wraps an opaque wasmNewClient handle and exposes encrypt, decrypt, isEncrypted, encryptQuery / encryptQueryBulk for minting v3 query terms (#662, which made searchable encryption reachable on the edge), bulkEncrypt / bulkDecrypt for single-round-trip list reads and writes (#737), and the model helpers encryptModel / decryptModel / bulkEncryptModels / bulkDecryptModels (#742).

Every fallible method returns a Result

{ data } | { failure }, with failure.type drawn from EncryptionErrorTypes — the same contract the native entry honours, and the one AGENTS.md states outright: "Operations return { data } or { failure }. Preserve this shape and error type values in EncryptionErrorTypes."

This entry THREW until #741. That was drift, not a design decision: nothing about WASM prevents it (@byteslice/result is already bundled into dist/wasm-inline.js — see tsup.config.ts noExternal), and the divergence just meant edge code had to be written in a different shape from every other surface, with failures that were easy to miss. Aligned before 1.0 so it never had to be a breaking change afterwards.

isEncrypted is the one exception, and stays a plain boolean: it is a pure predicate with nothing to fail at, exactly as on the native entry.

The model helpers run the SAME traversal the native entry uses (@/encryption/helpers/model-traversal — shared, not ported, so the two entries cannot drift on which fields get encrypted), and each call is one ZeroKMS round trip regardless of how many fields or models it covers. What still differs from the native surface is deliberate and local: failures come back as this entry's { failure } Results (rather than a thenable operation with .audit()).

There is also no .withLockContext() here, and that one is a gap, not a design decision (#797). An earlier version of this comment said identity-bound encryption is "configured at client construction via config.authStrategy instead" (#663 context). That is wrong, and the conflation is worth naming because it is the one people arrive with: an auth strategy decides WHO THE CLIENT IS; a lock context decides WHO CAN RETRIEVE A VALUE'S DATA KEY (the claim from the encrypting caller's service token is bound to the key, and retrieval requires presenting the same claim). They are orthogonal, and only the first exists on this entry.

The consequences are silent, which is why they are stated here rather than left to a failed decrypt: values written from this entry carry no identity condition on key retrieval — any client with keyset access can decrypt them — even when the client is authenticated as an end user, and this entry cannot read anything the native entry wrote under a lock context, since key retrieval requires the same claim. skills/stash-auth is canonical for the model; skills/stash-edge documents this entry's gap.

The binding accepts a lock context on both paths — lockContext is an option field on the single calls and per-payload-item on the bulk ones — so closing this is plumbing rather than a new capability. It is not plumbed here yet, and shipping it would want a live round-trip test first: a wrong or missing claim surfaces as a failed decrypt, not a key error.

Construct via Encryption — the constructor is private to prevent callers from wrapping arbitrary objects in this type.

Properties

requiresTableForDecrypt
readonly requiresTableForDecrypt: true = true;

Defined in: wasm-inline.ts:748

This client's decryptModel / bulkDecryptModels REQUIRE the table — they resolve date fields from a per-table map and throw without it. The native clients derive the table from the payloads instead, so callers that hold a client structurally cannot tell the two apart.

Declared rather than sniffed so the capability is a stated fact, not a guess about arity or constructor name (#772 review, finding 10).

This does NOT imply the entry cannot serve a legacy EQL v2 read. It once did: encryptedDynamoDB used to omit the table on that path, reaching requireTable with undefined. It now forwards the registered v3 table on every read, v2 storage included — the reconstructor map is keyed by the current schema either way, and protect-ffi's decrypt accepts both wire generations regardless of the client's eqlVersion.

Methods

encrypt()
encrypt(plaintext, opts): Promise&lt;WasmResult&lt;EncryptedPayload&gt;>;

Defined in: wasm-inline.ts:806

Parameters
plaintext

WasmPlaintext

opts

WasmEncryptOptions

Returns

Promise<WasmResult<EncryptedPayload>>

decrypt()
decrypt(encrypted): Promise&lt;WasmResult&lt;WasmPlaintext&gt;>;

Defined in: wasm-inline.ts:837

Decrypt a single stored payload, resolving to the plaintext union unchanged.

A date / timestamp column comes back as the string it was stored as, not a Date — where decryptModel(row, table) reconstructs it via datePropertyPaths. Same boundary the native client draws, and for the same reason: reconstruction is a property of the MODEL path, which is handed a table to read cast_as from. Not because the identity is missing — every payload carries i: { t, c } — but because this method's declared plaintext union excludes Date, and returning one would make the type a lie (#779). Read through the model helpers, or new Date(value) yourself.

Parameters
encrypted

EncryptedPayload

Returns

Promise<WasmResult<WasmPlaintext>>

isEncrypted()
isEncrypted(value): boolean;

Defined in: wasm-inline.ts:850

Parameters
value

unknown

Returns

boolean

encryptQuery()
encryptQuery(plaintext, opts): Promise&lt;WasmResult&lt;
  | EncryptedQuery
  | null&gt;>;

Defined in: wasm-inline.ts:929

Encrypt a QUERY TERM (search needle) for a queryable v3 column — equality, free-text match, ORE range, or JSON containment/selector.

The returned term is ciphertext-free: it is matched against stored envelopes, never decrypted, so it is safe to log-scrub less aggressively than storage payloads (though it still derives from the plaintext). Interpolate it as a parameter and cast to the column's eql_v3.query_&lt;domain&gt; type to reach the indexed operators — the domain suffix mirrors the storage domain (eql_v3_text_eqeql_v3.query_text_eq; irregular: eql_v3_json_searcheql_v3.query_json).

Parameters
plaintext

WasmPlaintext

The search needle. null/undefined returns null without contacting ZeroKMS (nothing to search for), mirroring the native client.

opts

WasmEncryptQueryOptions

Table, column, and (optionally) which index to target — see WasmEncryptQueryOptions.queryType for the inference rules.

Returns

Promise<WasmResult< | EncryptedQuery | null>>

{ data } with the v3 query term (or null for null plaintext), or { failure } when the requested queryType isn't configured on the column, the column has no indexes at all, the value fails the same pre-flight validation the native client runs (NaN / Infinity / out-of-int64 bigint, or a numeric value against a freeTextSearch index), or encryption fails.

Examples
const term = await client.encryptQuery("[email protected]", {
  table: users, column: users.email, queryType: "equality",
})
if (term.failure) throw new Error(term.failure.message)
// postgres-js — bind the unwrapped term, not the Result:
sql`SELECT * FROM users
    WHERE email = ${term.data}::jsonb::eql_v3.query_text_eq`
const term = await client.encryptQuery("needle", {
  table: users, column: users.bio, queryType: "freeTextSearch",
})
if (term.failure) throw new Error(term.failure.message)
sql`SELECT * FROM users
    WHERE eql_v3.matches(bio, ${term.data}::jsonb::eql_v3.query_text_search)`
const term = await client.encryptQuery(42, {
  table: users, column: users.age, queryType: "orderAndRange",
})
if (term.failure) throw new Error(term.failure.message)
sql`SELECT * FROM users
    WHERE eql_v3.gte(age, ${term.data}::jsonb::eql_v3.query_integer_ord)`
// Object value → containment needle (a v3 envelope):
const contains = await client.encryptQuery({ role: "admin" }, {
  table: users, column: users.prefs, queryType: "searchableJson",
})
if (contains.failure) throw new Error(contains.failure.message)
sql`SELECT * FROM users
    WHERE prefs @> ${contains.data}::jsonb::eql_v3.query_json`

// String value → JSONPath selector. NOTE: v3 has no encrypted-selector
// envelope — this returns the BARE selector-hash string, bound as the
// text argument of -> / ->>:
const selector = await client.encryptQuery("$.role", {
  table: users, column: users.prefs, queryType: "searchableJson",
})
if (selector.failure) throw new Error(selector.failure.message)
sql`SELECT prefs -> ${selector.data} FROM users`
encryptQueryBulk()
encryptQueryBulk(terms): Promise&lt;WasmResult&lt;(
  | EncryptedQuery
  | null)[]&gt;>;

Defined in: wasm-inline.ts:971

Batch form of encryptQuery — one ZeroKMS round trip for many terms, which is the shape query builders want (encrypt every needle in a WHERE clause together).

Position-stable: the result array is index-aligned with terms, and a null/undefined value yields null at the same index (an all-null batch short-circuits without calling ZeroKMS). Terms may mix query types and columns freely.

Parameters
terms

readonly WasmQueryTerm[]

The needles to encrypt; see WasmQueryTerm.

Returns

Promise<WasmResult<( | EncryptedQuery | null)[]>>

{ data } with an index-aligned array of v3 query terms (null per null value), or { failure } — the first invalid term aborts the batch, as encryptQuery.

Example
const terms = await client.encryptQueryBulk([
  { value: "[email protected]", table: users, column: users.email,
    queryType: "equality" },
  { value: "needle", table: users, column: users.bio,
    queryType: "freeTextSearch" },
])
if (terms.failure) throw new Error(terms.failure.message)
const [emailEq, bioMatch] = terms.data
bulkEncrypt()
bulkEncrypt(items): Promise&lt;WasmResult&lt;(EncryptedPayload | null)[]&gt;>;

Defined in: wasm-inline.ts:1040

Encrypt many storage values in ONE ZeroKMS round trip.

Without this, an edge function writing N rows pays N round trips — the property AGENTS.md calls out ("prefer bulk operations to exercise ZeroKMS bulk speed") was unreachable from the WASM entry entirely (#737).

Position-stable: the result is index-aligned with items, and a null/undefined plaintext yields null at the same index without being sent to ZeroKMS (an all-null batch short-circuits entirely). Entries may mix tables and columns freely — see WasmBulkPlaintext.

How this differs from the native bulkEncrypt

The failure shape is the SAME — { data } | { failure }, per AGENTS.md — but the batch shape differs: the Node entry takes one column for the whole batch and wraps values in { id, plaintext } envelopes, where this takes per-item routing and plain values.

That divergence is about capability, not convention. Per-item routing is what makes the round-trip saving real (one call covers several columns across many rows), and the id bookkeeping buys nothing once positions are stable — the FFI's EncryptPayload has no id field, so the native one is dropped at the boundary anyway.

Parameters
items

readonly WasmBulkPlaintext[]

Values to encrypt, each with its own table and column.

Returns

Promise<WasmResult<(EncryptedPayload | null)[]>>

{ data } with an index-aligned array of storage payloads (null per null input), or { failure }. The batch is all-or-nothing: ZeroKMS rejects the call as a whole, so there is no per-item error to report (unlike bulkDecrypt, whose FFI primitive IS fallible).

Example
const rows = [{ email: "[email protected]", bio: "hi" }, { email: "[email protected]", bio: "yo" }]
const encrypted = await client.bulkEncrypt(
  rows.flatMap((r) => [
    { plaintext: r.email, table: users, column: users.email },
    { plaintext: r.bio,   table: users, column: users.bio },
  ]),
)
if (encrypted.failure) throw new Error(encrypted.failure.message)
// encrypted.data[0] = email of row 0, [1] = bio of row 0, …
bulkDecrypt()
bulkDecrypt(ciphertexts): Promise&lt;WasmResult&lt;WasmPlaintext[]&gt;>;

Defined in: wasm-inline.ts:1110

Decrypt many stored payloads in ONE ZeroKMS round trip.

This is the half that matters most on the edge: rendering a list of N encrypted rows cost N round trips before this existed, which is what made list endpoints impractical on Deno / Workers (#737).

Position-stable, same contract as bulkEncrypt: index-aligned with ciphertexts, null/undefined passes through as null without reaching ZeroKMS, and an all-null batch short-circuits.

Partial failure

The underlying primitive is decryptBulkFallible, which reports success or failure PER ITEM — one undecryptable row does not fail the call at the FFI level. Any failure still collapses the whole call into a single { failure }, but its message names EVERY failed index and reason rather than surfacing the first and discarding the rest. So a caller debugging one bad row in a page of 50 learns which row, and that the other 49 were fine.

(A per-item Result[] would preserve the partial success too, and is worth considering if callers ask for it — but it is a different return type from every other method here, so it is not the default.)

No date reconstruction

Same boundary as decrypt: date-like columns arrive as their stored strings, not Date values. Prefer bulkDecryptModels with the table when you want the column's declared plaintext type back (#779).

Parameters
ciphertexts

readonly (EncryptedPayload | null | undefined)[]

Stored payloads; null/undefined entries allowed.

Returns

Promise<WasmResult<WasmPlaintext[]>>

{ data } with an index-aligned array of plaintexts (null per null input), or { failure } naming each failing index and its reason.

Example
const rows = await sql`SELECT email FROM users LIMIT 50`
const emails = await client.bulkDecrypt(rows.map((r) => r.email))
if (emails.failure) throw new Error(emails.failure.message)
// one ZeroKMS call, not 50
encryptModel()
encryptModel&lt;Table, T&gt;(model, table): Promise&lt;WasmResult&lt;V3EncryptedModel&lt;Table, T&gt;>>;

Defined in: wasm-inline.ts:1188

Encrypt a model's schema-declared fields in ONE ZeroKMS round trip.

Walks model against table's columns — matched by JS property name, nested fields via a column's dotted path ('profile.ssn') — and encrypts exactly the declared fields. Everything else passes through untouched, and a null/undefined schema field is preserved as-is without reaching ZeroKMS. The traversal is the native entry's own, shared from @/encryption/helpers/model-traversal (#742): a column added to the schema is picked up by construction, instead of by remembering to extend a hand-written bulkEncrypt mapping — the failure mode of that mapping is a field that silently persists in PLAINTEXT.

Date plaintexts (date/timestamp domains) are sent as ISO-8601 strings — WasmPlaintext carries no Date across the WASM serde boundary — and decryptModel rebuilds them into Date values on the way out.

Type Parameters
Table

Table extends AnyV3Table

T

T extends Record<string, unknown>

Parameters
model

V3ModelInput<Table, T>

table

Table

Returns

Promise<WasmResult<V3EncryptedModel<Table, T>>>

Example
const row = await client.encryptModel(
  { id: 1, email: "[email protected]", verified: true },
  users,
)
if (row.failure) throw new Error(row.failure.message)
// row.data = { id: 1, email: &lt;EQL envelope&gt;, verified: true }
bulkEncryptModels()
bulkEncryptModels&lt;Table, T&gt;(models, table): Promise&lt;WasmResult&lt;V3EncryptedModel&lt;Table, T&gt;[]>>;

Defined in: wasm-inline.ts:1214

Encrypt many models in ONE ZeroKMS round trip — encryptModel's traversal applied per model, with every collected field across every model batched into a single FFI call. N models × M columns is still one crossing, the same economics as bulkEncrypt.

The result array is index-aligned with models. An empty input returns { data: [] } without contacting ZeroKMS.

Type Parameters
Table

Table extends AnyV3Table

T

T extends Record<string, unknown>

Parameters
models

V3ModelInput<Table, T>[]

table

Table

Returns

Promise<WasmResult<V3EncryptedModel<Table, T>[]>>

decryptModel()
decryptModel&lt;Table, T&gt;(model, table): Promise&lt;WasmResult&lt;V3ModelInput&lt;Table, T&gt;>>;

Defined in: wasm-inline.ts:1250

Decrypt every encrypted payload in a model, in ONE ZeroKMS round trip.

Schema-blind on the way in — any value that IS an EQL envelope is decrypted, wherever it nests; everything else (nulls included) passes through untouched, and the caller's model is never mutated. Schema-aware on the way out: table's date-like columns (date / timestamp domains, matched by JS property name) are rebuilt into Date values, so a value this client encrypted round-trips DateDate. table must be one the client was initialized with, else the call fails (as the native client).

Partial failure

Built on the same per-item-fallible primitive as bulkDecrypt: one undecryptable field does not mask the rest. Any failure collapses to a single { failure } whose message names EVERY failed field by its path in the model (e.g. profile.ssn), with its per-item code.

Type Parameters
Table

Table extends AnyV3Table

T

T extends Record<string, unknown>

Parameters
model

T

table

Table

Returns

Promise<WasmResult<V3ModelInput<Table, T>>>

bulkDecryptModels()
bulkDecryptModels&lt;Table, T&gt;(models, table): Promise&lt;WasmResult&lt;V3ModelInput&lt;Table, T&gt;[]>>;

Defined in: wasm-inline.ts:1272

Decrypt many models in ONE ZeroKMS round trip — decryptModel across a list, which is the shape a page of database rows arrives in. The result array is index-aligned with models; an empty input returns { data: [] } without contacting ZeroKMS. Failures are reported for every bad field across the whole batch, labelled [model &lt;i&gt;] &lt;field&gt;.

Type Parameters
Table

Table extends AnyV3Table

T

T extends Record<string, unknown>

Parameters
models

T[]

table

Table

Returns

Promise<WasmResult<V3ModelInput<Table, T>[]>>

Type Aliases

WasmPlaintext

type WasmPlaintext = 
  | string
  | number
  | bigint
  | boolean
  | null
  | Record&lt;string, unknown&gt;
  | WasmPlaintext[];

Defined in: wasm-inline.ts:191

The plaintext shape accepted by encrypt and returned by decrypt. Mirrors protect-ffi's JsPlaintext (recursive: arrays of any of these are valid), plus bigint for int8 columns. Re-defined here so the wasm-inline .d.ts doesn't pull in the Node-only protect-ffi types.

bigint is carried natively across the wasm boundary by protect-ffi 0.28's Rust encode_plaintext (which i64-bounds-checks on encrypt and builds a js_sys::BigInt on decrypt), so widening the type here is all the SDK needs to accept/return bigint on the wasm entry point.


WasmClientConfig

type WasmClientConfig = {
  clientId: string;
  clientKey: string;
  eqlVersion?: never;
} & 
  | {
  workspaceCrn: string;
  accessKey: string;
  authStrategy?: never;
  strategy?: never;
}
  | {
  workspaceCrn?: string;
  accessKey?: never;
  authStrategy: WasmAuthStrategy;
  strategy?: WasmAuthStrategy;
}
  | {
  workspaceCrn?: string;
  accessKey?: never;
  authStrategy?: never;
  strategy: WasmAuthStrategy;
};

Defined in: wasm-inline.ts:221

Config for Encryption on the WASM entry point.

The workspace CRN is the single source of truth for workspace identity and deployment region — matching the Node entry and protect-ffi 0.25+, which read CS_WORKSPACE_CRN and no longer consult a separate CS_REGION. The CRN is passed straight to the underlying AccessKeyStrategy, which derives the region from it, so there is no region field to keep in sync.

For service-to-service / CI use, pass accessKey plus the workspace clientId / clientKey and we construct an AccessKeyStrategy for you. To plug in a custom token store (cookies on Supabase Edge, KV on Cloudflare Workers, …) or to bind encryption to an end user, build the strategy yourself — AccessKeyStrategy or OidcFederationStrategy — and hand it to config.authStrategy instead. A pre-built strategy already carries the CRN, so workspaceCrn is optional on that path.

Mirrors the Node ClientConfig: authStrategy is the documented field, strategy is retained as a deprecated alias (see below).

Type Declaration

clientId
clientId: string;

Workspace client identifier — required by the WASM client.

clientKey
clientKey: string;

Workspace client key — required by the WASM client.

eqlVersion?
optional eqlVersion: never;

Removed: this entry always emits EQL v3. Declared as never rather than omitted because excess-property checking — the only thing that caught a leftover eqlVersion — fires on FRESH object literals alone. A shared config const, which is what a v2 → v3 migration actually holds, therefore type-checked clean and then hit the runtime guard in Encryption.

On the shared base so it applies across all three auth arms below; a copy per arm would drift. Mirrors ClientConfig.eqlVersion on the native entry, whose guard this one is a byte-for-byte mirror of — the type is defence in depth for the JS/JSON callers that bypass it, not a replacement.

As on the native entry, ?: never still admits eqlVersion: undefined without exactOptionalPropertyTypes (not enabled in this repo) and cannot be made to reject it, so the runtime tolerates that one value and rejects every real one.


WasmAuthStrategy

type WasmAuthStrategy = 
  | AccessKeyStrategy
  | OidcFederationStrategy;

Defined in: wasm-inline.ts:303

Any auth strategy accepted on the WASM path. Both expose getToken(): Promise&lt;Result&lt;TokenResult, AuthFailure&gt;> — as of @cipherstash/auth 0.41 the token is wrapped in a @byteslice/result envelope. @cipherstash/protect-ffi 0.28+ unwraps that envelope (reading .data.token, surfacing .failure) inside its WASM newClient; 0.27 read .token off the envelope and saw undefined, so keep the ffi floor at 0.28.


WasmEncryptionConfig

type WasmEncryptionConfig = {
  schemas: readonly [AnyV3Table, ...AnyV3Table[]];
  config: WasmClientConfig;
};

Defined in: wasm-inline.ts:305

Properties

schemas
schemas: readonly [AnyV3Table, ...AnyV3Table[]];

Defined in: wasm-inline.ts:320

One or more EQL v3 tables, authored with types / encryptedTable from this entry. The WASM entry is EQL v3 only.

readonly (not the mutable tuple this once was) for the same reason the native entry was widened in A-4: a mutable tuple rejects every shape that is not an array literal — a shared export const all: AnyV3Table[], a ReadonlyArray, anything spread. But non-emptiness stays HERE rather than moving entirely onto the Encryption overloads: a loose readonly AnyV3Table[] on the exported type laundered an empty set past both overloads, because NonEmptyV3&lt;readonly AnyV3Table[]&gt; resolves S['length'] to number, not 0. A config object built once and passed around — precisely what this type exists for — then reached the runtime throw with a clean typecheck. The overloads still accept widened arrays passed INLINE, which is the case A-4 was actually about.

config
config: WasmClientConfig;

Defined in: wasm-inline.ts:321


WasmEncryptOptions

type WasmEncryptOptions = {
  table: AnyV3Table;
  column: AnyEncryptedV3Column;
};

Defined in: wasm-inline.ts:335

Properties

table
table: AnyV3Table;

Defined in: wasm-inline.ts:336

column
column: AnyEncryptedV3Column;

Defined in: wasm-inline.ts:337


WasmEncryptQueryOptions

type WasmEncryptQueryOptions = {
  table: AnyV3Table;
  column: WasmQueryableV3Column;
  queryType?: QueryTypeName;
};

Defined in: wasm-inline.ts:352

Options for WasmEncryptionClient.encryptQuery.

The column must be a QUERYABLE v3 column (authored via the types.* factories re-exported from this entry) — storage-only columns like types.Text with no indexes have nothing to query.

Properties

table
table: AnyV3Table;

Defined in: wasm-inline.ts:354

The encryptedTable(...) the column belongs to.

column
column: WasmQueryableV3Column;

Defined in: wasm-inline.ts:356

The queryable v3 column the term targets, e.g. users.email.

queryType?
optional queryType: QueryTypeName;

Defined in: wasm-inline.ts:375

Which of the column's indexes the term targets:

  • 'equality' — exact match (unique index; = / IN)
  • 'freeTextSearch' — fuzzy token match (match index; one-sided — a match may be a false positive, a non-match never is)
  • 'orderAndRange' — comparisons and ranges (ore index; &lt; &gt; BETWEEN / ORDER BY)
  • 'searchableJson' — encrypted JSON (ste_vec index): a string value is treated as a JSONPath selector ('$.user.email'), any other value as a containment needle ({ role: 'admin' })

Omit to infer from the column's configured indexes (priority: unique > match > ore > ste_vec, matching the native client) — unambiguous for single-index columns like types.TextEq, but be explicit for multi-index domains like types.TextSearch (which carries all three scalar indexes).


WasmQueryTerm

type WasmQueryTerm = WasmEncryptQueryOptions & {
  value: WasmPlaintext;
};

Defined in: wasm-inline.ts:384

One term for WasmEncryptionClient.encryptQueryBulk — the WasmEncryptQueryOptions plus the plaintext needle. A null value yields null at the same position in the result (nothing to search for).

Type Declaration

value
value: WasmPlaintext;

WasmBulkPlaintext

type WasmBulkPlaintext = {
  plaintext:   | WasmPlaintext
     | undefined;
  table: AnyV3Table;
  column: AnyEncryptedV3Column;
};

Defined in: wasm-inline.ts:403

One storage value in a WasmEncryptionClient.bulkEncrypt batch.

Each entry carries its OWN table and column, rather than the batch taking a single WasmEncryptOptions the way WasmEncryptionClient.encrypt does. That mirrors WasmQueryTerm — and it is what makes the round-trip saving worth having: rendering a page of rows means encrypting several columns across many rows, and a single-column batch would still cost one ZeroKMS call per column. The FFI's EncryptPayload is per-item ({ plaintext, table, column }), so mixing is free at the boundary.

(The native entry's bulkEncrypt takes one column for the whole batch and wraps values in { id, plaintext } envelopes. This surface does neither — see WasmEncryptionClient.bulkEncrypt for why.)

Properties

plaintext
plaintext: 
  | WasmPlaintext
  | undefined;

Defined in: wasm-inline.ts:415

The value to encrypt. null/undefined yields null at this index without reaching ZeroKMS.

undefined is admitted explicitly — unlike WasmQueryTerm.value, which is WasmPlaintext alone. Both are guarded identically at runtime, but the shapes fed to them differ: a query needle is written by hand, whereas a bulk batch is mapped straight off database rows, where an absent column is undefined. Typing it out would force ?? null at every call site to satisfy a check the runtime does anyway.

table
table: AnyV3Table;

Defined in: wasm-inline.ts:416

column
column: AnyEncryptedV3Column;

Defined in: wasm-inline.ts:417


WasmResult

type WasmResult&lt;T&gt; = 
  | {
  data: T;
  failure?: never;
}
  | {
  data?: never;
  failure: EncryptionError;
};

Defined in: wasm-inline.ts:444

The { data } | { failure } envelope every fallible method here returns.

Structurally identical to @byteslice/result's Result&lt;T, EncryptionError&gt; — which is what withResult actually produces — but declared LOCALLY on purpose, for the same reason WasmPlaintext re-declares protect-ffi's JsPlaintext: @byteslice/result is bundled into dist/wasm-inline.js (tsup noExternal), so it is not a package an edge consumer can resolve. Re-exporting its type put import { Result } from '@byteslice/result' at the top of the emitted .d.ts, which a Deno consumer cannot resolve at all — the e2e import map maps only the three /wasm-inline subpaths.

Declaring it here keeps the published types self-contained.

Type Parameters

T

T

Functions

isEncrypted()

function isEncrypted(value): boolean;

Defined in: wasm-inline.ts:165

Re-exported convenience predicate — same as the raw protect-ffi one.

Parameters

value

unknown

Returns

boolean


Encryption()

Call Signature

function Encryption&lt;S&gt;(config): Promise&lt;WasmEncryptionClient&gt;;

Defined in: wasm-inline.ts:1460

Initialize a WASM-backed encryption client.

Mirrors the Node entry's import('./encryption').Encryption factory, but constructs the protect-ffi client via the WASM strategy API. Use from Deno / Edge / Workers / Bun.

Type Parameters
S

S extends readonly [AnyV3Table, AnyV3Table]

Parameters
config
schemas

S

config

WasmClientConfig

Returns

Promise<WasmEncryptionClient>

Call Signature

function Encryption&lt;S&gt;(config): Promise&lt;WasmEncryptionClient&gt;;

Defined in: wasm-inline.ts:1466

Initialize a WASM-backed encryption client.

Mirrors the Node entry's import('./encryption').Encryption factory, but constructs the protect-ffi client via the WASM strategy API. Use from Deno / Edge / Workers / Bun.

Type Parameters
S

S extends readonly AnyV3Table[]

Parameters
config
schemas

NonEmptyV3<S>

config

WasmClientConfig

Returns

Promise<WasmEncryptionClient>


toWasmFfiPlaintext()

function toWasmFfiPlaintext(value): unknown;

Defined in: wasm-inline.ts:1625

Normalise a value for the wasm serde boundary, applied at EVERY encrypt/query crossing (#742 review — previously only the model path did this).

A JS Date has no enumerable own properties, so wasm-bindgen carries it across as {} — silent corruption of every date/timestamp column. Serialise it to RFC 3339 (which protect-ffi's parse_naive_date accepts for both casts, yielding the same canonical value as the native Date-object path) and reject an invalid Date rather than emit "Invalid Date". WasmPlaintext excludes Date so TS callers are already stopped; this is the runtime guard for plain-JS callers, the same belt-and-braces rationale assertValidNumericValue uses on the numeric path. Everything else passes through unchanged.

Parameters

value

unknown

Returns

unknown

References

AnyEncryptedV3Column

Re-exports AnyEncryptedV3Column


EncryptedV3TableColumn

Re-exports EncryptedV3TableColumn


EqlTypeForColumn

Re-exports EqlTypeForColumn


JsonDocument

Re-exports JsonDocument


JsonValue

Re-exports JsonValue


PlaintextForColumn

Re-exports PlaintextForColumn


QueryCapabilities

Re-exports QueryCapabilities


QueryTypesForColumn

Re-exports QueryTypesForColumn


EncryptedBigintColumn

Re-exports EncryptedBigintColumn


EncryptedBigintEqColumn

Re-exports EncryptedBigintEqColumn


EncryptedBigintOrdColumn

Re-exports EncryptedBigintOrdColumn


EncryptedBigintOrdOreColumn

Re-exports EncryptedBigintOrdOreColumn


EncryptedBooleanColumn

Re-exports EncryptedBooleanColumn


EncryptedDateColumn

Re-exports EncryptedDateColumn


EncryptedDateEqColumn

Re-exports EncryptedDateEqColumn


EncryptedDateOrdColumn

Re-exports EncryptedDateOrdColumn


EncryptedDateOrdOreColumn

Re-exports EncryptedDateOrdOreColumn


EncryptedDoubleColumn

Re-exports EncryptedDoubleColumn


EncryptedDoubleEqColumn

Re-exports EncryptedDoubleEqColumn


EncryptedDoubleOrdColumn

Re-exports EncryptedDoubleOrdColumn


EncryptedDoubleOrdOreColumn

Re-exports EncryptedDoubleOrdOreColumn


EncryptedIntegerColumn

Re-exports EncryptedIntegerColumn


EncryptedIntegerEqColumn

Re-exports EncryptedIntegerEqColumn


EncryptedIntegerOrdColumn

Re-exports EncryptedIntegerOrdColumn


EncryptedIntegerOrdOreColumn

Re-exports EncryptedIntegerOrdOreColumn


EncryptedJsonColumn

Re-exports EncryptedJsonColumn


EncryptedNumericColumn

Re-exports EncryptedNumericColumn


EncryptedNumericEqColumn

Re-exports EncryptedNumericEqColumn


EncryptedNumericOrdColumn

Re-exports EncryptedNumericOrdColumn


EncryptedNumericOrdOreColumn

Re-exports EncryptedNumericOrdOreColumn


EncryptedRealColumn

Re-exports EncryptedRealColumn


EncryptedRealEqColumn

Re-exports EncryptedRealEqColumn


EncryptedRealOrdColumn

Re-exports EncryptedRealOrdColumn


EncryptedRealOrdOreColumn

Re-exports EncryptedRealOrdOreColumn


EncryptedSmallintColumn

Re-exports EncryptedSmallintColumn


EncryptedSmallintEqColumn

Re-exports EncryptedSmallintEqColumn


EncryptedSmallintOrdColumn

Re-exports EncryptedSmallintOrdColumn


EncryptedSmallintOrdOreColumn

Re-exports EncryptedSmallintOrdOreColumn


EncryptedTextColumn

Re-exports EncryptedTextColumn


EncryptedTextEqColumn

Re-exports EncryptedTextEqColumn


EncryptedTextMatchColumn

Re-exports EncryptedTextMatchColumn


EncryptedTextOrdColumn

Re-exports EncryptedTextOrdColumn


EncryptedTextOrdOreColumn

Re-exports EncryptedTextOrdOreColumn


EncryptedTextSearchColumn

Re-exports EncryptedTextSearchColumn


EncryptedTimestampColumn

Re-exports EncryptedTimestampColumn


EncryptedTimestampEqColumn

Re-exports EncryptedTimestampEqColumn


EncryptedTimestampOrdColumn

Re-exports EncryptedTimestampOrdColumn


EncryptedTimestampOrdOreColumn

Re-exports EncryptedTimestampOrdOreColumn


TEXT_SEARCH_EQL_TYPE

Re-exports TEXT_SEARCH_EQL_TYPE


AnyV3Table

Re-exports AnyV3Table


ColumnsOf

Re-exports ColumnsOf


InferEncrypted

Re-exports InferEncrypted


InferPlaintext

Re-exports InferPlaintext


QueryableColumnsOf

Re-exports QueryableColumnsOf


V3DecryptedModel

Re-exports V3DecryptedModel


V3EncryptedModel

Re-exports V3EncryptedModel


V3ModelInput

Re-exports V3ModelInput


buildEncryptConfig

Re-exports buildEncryptConfig


EncryptedTable

Re-exports EncryptedTable


encryptedTable

Re-exports encryptedTable


types

Re-exports types


EncryptionError

Re-exports EncryptionError


EncryptionErrorTypes

Re-exports EncryptionErrorTypes


Encrypted

Re-exports Encrypted

On this page

wasm-inlineClassesAccessKeyStrategyMethodscreate()ParametersworkspaceCrnaccessKeyoptions?ReturnsgetToken()Returnsfree()ReturnsOidcFederationStrategyMethodscreate()ParametersworkspaceCrngetJwtoptions?ReturnsgetToken()Returnsfree()ReturnsWasmEncryptionClientEvery fallible method returns a ResultPropertiesrequiresTableForDecryptMethodsencrypt()ParametersplaintextoptsReturnsdecrypt()ParametersencryptedReturnsisEncrypted()ParametersvalueReturnsencryptQuery()ParametersplaintextoptsReturnsExamplesencryptQueryBulk()ParameterstermsReturnsExamplebulkEncrypt()How this differs from the native bulkEncryptParametersitemsReturnsExamplebulkDecrypt()Partial failureNo date reconstructionParametersciphertextsReturnsExampleencryptModel()Type ParametersTableTParametersmodeltableReturnsExamplebulkEncryptModels()Type ParametersTableTParametersmodelstableReturnsdecryptModel()Partial failureType ParametersTableTParametersmodeltableReturnsbulkDecryptModels()Type ParametersTableTParametersmodelstableReturnsType AliasesWasmPlaintextWasmClientConfigType DeclarationclientIdclientKeyeqlVersion?WasmAuthStrategyWasmEncryptionConfigPropertiesschemasconfigWasmEncryptOptionsPropertiestablecolumnWasmEncryptQueryOptionsPropertiestablecolumnqueryType?WasmQueryTermType DeclarationvalueWasmBulkPlaintextPropertiesplaintexttablecolumnWasmResultType ParametersTFunctionsisEncrypted()ParametersvalueReturnsEncryption()Call SignatureType ParametersSParametersconfigschemasconfigReturnsCall SignatureType ParametersSParametersconfigschemasconfigReturnstoWasmFfiPlaintext()ParametersvalueReturnsReferencesAnyEncryptedV3ColumnEncryptedV3TableColumnEqlTypeForColumnJsonDocumentJsonValuePlaintextForColumnQueryCapabilitiesQueryTypesForColumnEncryptedBigintColumnEncryptedBigintEqColumnEncryptedBigintOrdColumnEncryptedBigintOrdOreColumnEncryptedBooleanColumnEncryptedDateColumnEncryptedDateEqColumnEncryptedDateOrdColumnEncryptedDateOrdOreColumnEncryptedDoubleColumnEncryptedDoubleEqColumnEncryptedDoubleOrdColumnEncryptedDoubleOrdOreColumnEncryptedIntegerColumnEncryptedIntegerEqColumnEncryptedIntegerOrdColumnEncryptedIntegerOrdOreColumnEncryptedJsonColumnEncryptedNumericColumnEncryptedNumericEqColumnEncryptedNumericOrdColumnEncryptedNumericOrdOreColumnEncryptedRealColumnEncryptedRealEqColumnEncryptedRealOrdColumnEncryptedRealOrdOreColumnEncryptedSmallintColumnEncryptedSmallintEqColumnEncryptedSmallintOrdColumnEncryptedSmallintOrdOreColumnEncryptedTextColumnEncryptedTextEqColumnEncryptedTextMatchColumnEncryptedTextOrdColumnEncryptedTextOrdOreColumnEncryptedTextSearchColumnEncryptedTimestampColumnEncryptedTimestampEqColumnEncryptedTimestampOrdColumnEncryptedTimestampOrdOreColumnTEXT_SEARCH_EQL_TYPEAnyV3TableColumnsOfInferEncryptedInferPlaintextQueryableColumnsOfV3DecryptedModelV3EncryptedModelV3ModelInputbuildEncryptConfigEncryptedTableencryptedTabletypesEncryptionErrorEncryptionErrorTypesEncrypted