Releases: faceteer/facet
Releases · faceteer/facet
v6.0.0
Stable promotion of 6.0.0-alpha.0. No behavioral changes to library code; see the 6.0.0-alpha.0 entry for the full set of v6 changes.
Infrastructure
- Regenerated typedoc output for v6 and added a
docsnpm script. - Bumped
actions/checkoutandactions/setup-nodefrom v4 to v6 in CI.
v6.0.0-alpha.0
First publish of the v6 line. Breaking changes from v5 touch module format, the DynamoDB client wiring, the cursor format, and the public API surface — migrating existing v5 consumers is not a drop-in upgrade.
Changed (breaking)
- Package is now ESM (
"type": "module") with a singleexportsentry. CJS consumers on Node ≥ 22.12 can stillrequire()viarequire(esm); older Node cannot. - Minimum Node bumped to
>=22.12.0(the first LTS whererequire(esm)is unflagged). - DynamoDB client must be passed in explicitly on
connection.dynamoDb. The library no longer constructs a client internally; consumers own credential chains, endpoint overrides, and retry config.@aws-sdk/client-dynamodbis also a peer dep now, not a direct dep. - Cursor format replaced (CBOR → custom binary tuples, base64url-encoded). Cursors minted by v5 will not decode in v6. Pagination state stored from v5 callers is not forward-compatible.
- Cursors now use URL-safe base64url, not standard base64 (#48).
- Public API fenced: subpath imports are no longer resolvable. Only the root barrel (
import { Facet } from '@faceteer/facet') is supported (#55). - Reserved attribute names (
PK,SK,facet,ttl,GSI*PK/GSI*SK) are now rejected at both the type level (viaWithoutReservedAttributes) and at runtime in the constructor. v5 silently clobbered colliding model fields (#54). - Query sort-key arguments are now typed against the active sort key — base-table queries used to accept only GSI SK shapes (#41).
ShardConfiguration.keysis restricted to primitive-typed fields at the type level; non-primitive fields are no longer silently hashed as[object Object](#44).
Added
PutOptions.concurrency/DeleteOptions.concurrency/GetOptions.concurrency— cap outer fan-out on batch put/delete/get. Defaults to 8, tuned to sit just above new-on-demand starting capacity. Fixes unbounded fan-out that triggered throttling storms on large batches (#47).- Projected reads via
selectonFacet.get(single + batch) and everyPartitionQueryoperator. Returns aPick<T, K | PK | SK>and validates through a newpickValidatorfactory. PK/SK fields are always re-projected, even if omitted fromselect. Facet.addIndex(..., { alias })— register a human-readable alias (facet.PagePostStatus.query(...)) alongside the rawGSInaccessor. Type-level collision check prevents alias/index-name overlap.- Tests for projected reads across
PartitionQuerymethods (equals/beginsWith/between/etc.). - Root
index.tsbarrel widened to cover the full public surface and typedoc-validated. - Extensive hover docs on
Facet, including guidance on composite sort-key patterns.
Fixed
- Batch put/delete no longer silently misreport unprocessed items as successful. The final-failure loop now iterates the post-retry
UnprocessedItems, not the pre-retry snapshot (#31, #35). - Delete batch retry now checks the correct
WriteRequestshape, so failure reporting actually fires (#34). Facet.out()strips syntheticttleven when the facet has no registered indexes, and the delete-ttl step no longer runs N times per read (#33, #49).- TTL attributes are now written as the DynamoDB
Ntype with epoch-seconds value, not the rawS-typed ISO string. Date-typed TTL fields were silently broken (#32). deleteSingleItemno longer sends emptyExpressionAttributeNames/ExpressionAttributeValuesmaps, which DynamoDB rejects withValidationException. Conditional deletes without value placeholders now succeed (#38).SK.shardconfiguration is no longer silently dropped byFacet.sk()(#37).buildKey()now honours an explicitshard: 0; v5 treated it as unspecified (#36).addIndexrejects silent overwrite of an already-registered GSI slot or alias (#53).- The
WithoutReservedAttributes<T>constraint no longer structurally rejects every concreteT: it maps overkeyof Tso only colliding fields becomenever. - Test helpers now branch on SDK v3
error.nameinstead of v2error.code; the reset path was never firing (#40). - Removed duplicate
this.#PK = PKassignment in theFacetconstructor (#39). tsconfig.test.jsonno longer inherits theexcludepattern that dropped test files from the default type-check graph.
Removed
crc-32npm dependency — shard hashing now usesnode:zlib.crc32(available from Node 20 onward).- Dead-code exports from
lib/keys.ts:IndexPrivatePropertyMap,isIndex,IndexKeyConfiguration,IndexKeyOptions(#42).
Infrastructure
- Migrated test runner from Jest → Vitest; CI runs against Node 20, 22, and 24 with DynamoDB Local as a service container.
- Upgraded to TypeScript 6 with strict flat ESLint v10 + Prettier 3 configuration.
- Split library and test tsconfigs so published builds no longer contain test files.
- Widened
@aws-sdk/client-dynamodbpeer dep range to^3.0.0. - Shared VS Code workspace setting makes IDE auto-imports insert the required
.jsextension for NodeNext module resolution.