Upgrade @arki/contracts 0.2.0 to 0.3.0

For @arki/[email protected] · source docs/upgrades/0.2.0-to-0.3.0.md

Most apps skip this: ids keep their shape. Act only if you create many default-format ids in a hot path (a cuid2 now costs about 100 µs).

What changed

  • defineId(...) default ids (and createIdBody, so @arki/db's createId / createPrefixedId too) are cuid2 ids, generated with @paralleldrive/cuid2: 24 characters, a letter first, then letters and digits, a SHA3 of time, a counter, a host fingerprint and random salt. The shape is unchanged (today's ids already passed isCuid), so stored ids and schemas keep working. Every random bit still comes from Web Crypto, resolved per generation: an unusable provider answers RandomSourceUnavailable, a provider that breaks the protocol answers UnexpectedDefect. Rejection sampling is gone with the old construction. A cuid2 costs about 100 µs on Bun and Node, so it is for entity identities; format: 'uuid' (used by @arki/http's requestId) is unchanged and stays under a microsecond.

Public API changes

No public API changes. defineId, createIdBody and the IdGenerationFailure results keep their signatures. @paralleldrive/cuid2 is a new runtime dependency.

Steps

  1. Only for hot paths: an id made per request or per item in a large loop should use format: 'uuid', as @arki/http's requestId does.

    Before:

    export const traceId = defineId('trc_');

    After:

    export const traceId = defineId('trc_', { kind: 'telemetry.trace', format: 'uuid' });

    The options form needs a kind: one literal domain name for this identity. A uuid id has a different body shape, so do this only for ids that are not stored yet, or accept both shapes when you read old rows.

Verify

bun -e "import { defineId } from '@arki/contracts'; console.log(defineId('sty_').create())"

It prints sty_ followed by 24 characters: a lowercase letter, then lowercase letters and digits.

All docs for @arki/[email protected]