Docs: DocumentPayload stops direct reads and assignment, not runtime narrowing or a cast
The cultcache-ts README, the DocumentPayload comment (comment only) and the cultmesh-browser README say plainly what the opaque type guarantees and what it does not; documentPayloadBytes is the escape for bytes. All commits build. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
a6478a9cab
commit
b25d86a873
3 changed files with 16 additions and 1 deletions
|
|
@ -39,6 +39,14 @@ realtime frame. At run time it is the same `Uint8Array`, so nothing on the wire
|
|||
time it is opaque: it is assignable to and from neither `Uint8Array` nor `ArrayLike<number>`, so no
|
||||
MessagePack decoder accepts it.
|
||||
|
||||
What the type guarantees is that a payload cannot be read or assigned directly: a decoder call, an
|
||||
assignment to `Uint8Array` and `new Uint8Array(payload)` fail to compile. It does not stop what the
|
||||
runtime value allows. Because the value is a `Uint8Array`, a check such as `payload instanceof
|
||||
Uint8Array` narrows it back to bytes, and a cast does the same; a read made that way sees the raw
|
||||
bytes, which for a codec or formatter document are not the document. Read through
|
||||
`decodeDocumentPayload`, and when you need the bytes themselves (hashing, signing, a store write)
|
||||
take them with `documentPayloadBytes`.
|
||||
|
||||
- `decodeDocumentPayload(definition, payload)` reads a payload through the definition's formatter,
|
||||
codec or plain map and then its schema. The definition is required.
|
||||
- `encodeDocumentPayload(definition, value)` is the writer: the schema first, then the formatter,
|
||||
|
|
|
|||
|
|
@ -102,6 +102,11 @@ const plainDocumentFormatter: CultCacheDocumentFormatter<unknown> = {
|
|||
* `documentPayloadBytes` where they leave (a store write, a frame encode, hashing or signing).
|
||||
*
|
||||
* The key is a plain string, not a unique symbol, so two installed copies of this package stay compatible.
|
||||
*
|
||||
* What the type guarantees: a payload cannot be read or assigned directly (a decoder call, `const b: Uint8Array = p`,
|
||||
* `new Uint8Array(p)` fail to compile). What it does not: the runtime value is a `Uint8Array`, so runtime narrowing
|
||||
* (`p instanceof Uint8Array`) or a cast gets the raw bytes back, and a codec or formatter document read that way is not
|
||||
* the document. The escape for bytes is `documentPayloadBytes`; the reader is `decodeDocumentPayload`.
|
||||
*/
|
||||
export interface DocumentPayload {
|
||||
readonly "cultcache.documentPayload": true;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,9 @@ A record's `payload` is a `DocumentPayload`, an opaque type over the same bytes,
|
|||
`decodeCultNetPayload(record, definition)` is how it is read: through the CultCache document
|
||||
definition that says whether the bytes are a plain map, a codec's slot record or a
|
||||
formatter's, then through the definition's schema. A plain MessagePack decode of a payload
|
||||
does not compile, and `decodeCultNetPayload` takes no definition-less form. The definition
|
||||
does not compile, and `decodeCultNetPayload` takes no definition-less form. The type stops direct reads
|
||||
and assignment; it does not stop runtime narrowing (`payload instanceof Uint8Array`) or a cast, which
|
||||
would read the raw bytes. For the bytes themselves use `documentPayloadBytes`. The definition
|
||||
comes from `@gamecult/cultcache-ts` (this package imports only its `./document` entry, which
|
||||
holds no Node built-ins).
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue