npm.io
0.16.0 • Published 3 months ago

@prisma-next/mongo-codec

Licence
Apache-2.0
Version
0.16.0
Deps
3
Size
35 kB
Vulns
0
Weekly
0
Stars
412
DeprecatedThis package is deprecated

@prisma-next/mongo-codec

Codec interface and registry for MongoDB value serialization.

Responsibilities

  • Codec interface: MongoCodec<Id, TTraits, TWire, TInput> — declares how a JS value translates to and from the BSON-shaped wire format the Mongo driver exchanges, plus the JSON-safe form stored in contract artifacts. Same four generics as the framework Codec base; the codec instance carries only id plus the four conversion methods. Trait annotations (equality, order, boolean, numeric, textual, vector) for operator gating live on the unified CodecDescriptor (see ADR 208).
  • Codec factory: mongoCodec() — creates frozen codec instances from a config object. Both encode and decode are required so TInput and TWire are always covered by an explicit author function — the factory installs no identity fallback. encode and decode may be authored as sync or async functions and are lifted to Promise-returning query-time methods automatically. Build-time methods (encodeJson, decodeJson) are synchronous and default to identity when omitted.
  • Codec registry: MongoCodecRegistry and newMongoCodecRegistry() — a map-based container that stores and retrieves codecs by ID, with duplicate-ID protection
  • Type-level helper: MongoCodecInput<T> for extracting the JS application type from a codec type. Trait metadata lives on the unified CodecDescriptor (see ADR 208).

Examples

// Sync authoring:
const intCodec = mongoCodec({
  typeId: 'mongo/int@1',
  encode: (v: number) => v,
  decode: (w: number) => w,
  encodeJson: (v: number) => v,
  decodeJson: (j: number) => j,
});

// Async authoring (e.g. KMS-backed encryption): same factory, same shape.
const secretCodec = mongoCodec({
  typeId: 'mongo/secret@1',
  encode: async (v: string) => encrypt(v, await getKey()),
  decode: async (w: string) => decrypt(w, await getKey()),
  encodeJson: (v: string) => v,
  decodeJson: (j: string) => j,
});
Codec call context (ctx)

Codecs receive a second ctx options argument; you may ignore it. The Mongo runtime allocates one CodecCallContext per mongoRuntime.execute(plan, { signal }) call and threads the same reference to every codec dispatch site as a non-optional argument — when no signal is supplied the runtime still threads an empty {}, never undefined. Mongo uses the framework CodecCallContext directly (signal-only); column metadata is SQL-family-specific and isn't part of Mongo's per-call shape today. The internal MongoCodec interface declares the parameter as required (encode(value, ctx: CodecCallContext) / decode(wire, ctx: CodecCallContext)); single-arg author functions (value) => … continue to compile via TypeScript's bivariance for trailing parameters, so codec ergonomics are unchanged. The signal field on the ctx may be undefined when the caller didn't supply one.

// Forward ctx.signal to a network SDK so aborted queries stop the round-trip.
const kmsSecretCodec = mongoCodec({
  typeId: 'mongo/kms-secret@1',
  encode: async (v: string, ctx) =>
    kms.encrypt({ plaintext: v }, { signal: ctx?.signal }),
  decode: async (w: string, ctx) =>
    kms.decrypt({ ciphertext: w }, { signal: ctx?.signal }),
  encodeJson: (v: string) => v,
  decodeJson: (j: string) => j,
});

Note. Mongo's read path doesn't go through codec.decode (per ADR 204 cross-family scope notes), so the decode signature above accepts ctx for parity with the codec interface but the runtime doesn't currently invoke decode on the Mongo read side. Encode-side ctx.signal is observed at every recursion level of resolveValue so a mid-encode abort surfaces as RUNTIME.ABORTED { phase: 'encode' }.

Codec bodies that ignore ctx.signal complete in the background (cooperative cancellation); aborts still surface to the caller as RUNTIME.ABORTED.

See ADR 204 — Single-Path Async Codec Runtime for the codec runtime's async boundary contract, and ADR 207 — Codec call context: per-query AbortSignal and column metadata for the per-call context shape.

Dependencies

  • Depends on: nothing (leaf package)
  • Depended on by:
    • @prisma-next/adapter-mongo (registers concrete codec implementations)