Docs: cacheless single-file access names WriteDocument and DecodeDocument; CultElementIds is not public

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Meta Vens 2026-10-23 00:15:28 +02:00
commit bf01212f9a
2 changed files with 14 additions and 10 deletions

View file

@ -349,24 +349,28 @@ no serialization; a CultMath encoding, if added, uses this shape.
## Cacheless single-file access
A single-file store file can be read and written without a cache, through two public members of `SingleFileBackingStore` (for
example `SingleFileMessagePackBackingStore`): `ReadStoreSnapshot()` and `WriteRecord(record, catalogEntry, holdsIds, registry)`.
A single-file store file can be read and written without a cache, through public members of `SingleFileBackingStore` (for
example `SingleFileMessagePackBackingStore`): `ReadStoreSnapshot()`, `WriteRecord(record, catalogEntry, holdsIds, registry)`,
`WriteDocument<T>(key, document, storedAt, registry)` and `DecodeDocument<T>(key, payload, registry)`.
- `ReadStoreSnapshot()` reads the file once, under the store's gate, and returns the durable snapshot (records, schema catalog,
format stamp), or null when nothing is at the path. It throws `CultStoreUnreadableException` for a file the reader refuses.
- `WriteRecord` writes one record under the store's lock: the record replaces the one at its key, every other record and catalog
entry is copied forward as stored, and the file is replaced atomically.
entry is copied forward as stored, and the file is replaced atomically. It takes a payload the caller already encoded, so a
payload it cannot read leaves the header as the file has it (`holdsIds` null).
- `WriteDocument<T>` writes one typed document as a cache write does: it plans element ids, encodes the document with the
registry, and stores it through `WriteRecord`. A failed write gives the minted ids back.
- `DecodeDocument<T>` decodes a payload read from the store as a cache load does: it mints the ids a load mints and refuses what
a cache load refuses.
They share everything with a cache's store and nothing is re-implemented beside it: one reader (the stamp is judged before the
body, and a file the reader refuses is refused by a read and by a write alike), the store's lock, the atomic replace, and the
header rule (`holdsIds` true marks a v3 store; false leaves it as the rule decides; null, for a payload the caller cannot read,
keeps whatever the file already says). Ownership by declaration binds a cacheless write too: a record at the key under a schema id
the written catalog entry does not own or list as compatible is refused with `CultSchemaConflictException`, and the file is left as
it was. A typed writer plans element ids with `CultElementIds.Plan` before it serializes and passes `CultElementIds.Holds` as
`holdsIds`.
A store attached to a cache refuses `WriteRecord` with `InvalidOperationException`: write through the cache, whose staged writes
land through the same private write. CultMesh's single-file document helpers (`CultMesh.WriteSingleFileDocument`,
it was. Element-id planning (`CultElementIds`) is internal to the library: a caller never plans or marks ids, the store does. A store
attached to a cache refuses `WriteRecord` and `WriteDocument` (write through the cache, whose staged writes land through the
same private write) and `DecodeDocument` (read through the cache) with `InvalidOperationException`. CultMesh's single-file document helpers (`CultMesh.WriteSingleFileDocument`,
`ReadSingleFileDocument` and their payload forms) are built on these members and nothing else of the store.
## Runtime status

View file

@ -19,12 +19,12 @@ Releases as 3.0.0 (major).
- `GameCult.Mesh`: `AsSchemaAlias<TAlias>()` is removed from `CultMeshDocumentHandle` and `CultMeshCollectionHandle`. Read the handle by the schema you mean.
- The element types of owned lists in `GameCult.Mesh` (`CultMeshBodies`, `CultMeshCdn`, `CultMeshDiscoveryService` and `CultMeshEntityPrefabs`) and `GameCult.Networking` (`CultWitnessArtifactBundle`) gain a public string `Id` member with `[CultElementId]`, so their lists merge by identity. Code that matched those elements positionally by shape must set or read `Id`.
- `CultNetDocumentRegistry.Register` refuses a binding that claims a document type or a schema id another binding already holds, with `CultSchemaConflictException`; binding a type to the schema id it already holds still replaces that binding.
- `InternalsVisibleTo GameCult.Mesh` is removed from `GameCult.Caching`: CultMesh's single-file document helpers use the public `ReadStoreSnapshot`, `WriteRecord` and `CultElementIds` below.
- `InternalsVisibleTo GameCult.Mesh` is removed from `GameCult.Caching`: CultMesh's single-file document helpers use the public `ReadStoreSnapshot`, `WriteDocument`, `DecodeDocument` and `WriteRecord` below.
### Added
- `SingleFileBackingStore.ReadStoreSnapshot()` reads a store file once, under the store's lock, with the reader a cache's store opens with, and returns the durable snapshot or null when nothing is at the path. `SingleFileBackingStore.WriteRecord(record, catalogEntry, holdsIds, registry)` writes one record without a cache: every other record and catalog entry is copied as stored, the file is replaced atomically, and the header is decided as a flush decides it. It refuses on a store attached to a cache.
- `CultElementIds.Plan`, `CultElementIds.Holds` and `CultElementIds.IdPlan` are public: a cacheless typed writer plans element ids before it serializes and passes `Holds` as `holdsIds`.
- `SingleFileBackingStore.WriteDocument<T>(key, document, storedAt, registry)` writes one typed document without a cache, as a cache write does: it plans element ids, encodes the document and marks the store when it holds an id; a failed write gives the minted ids back. `SingleFileBackingStore.DecodeDocument<T>(key, payload, registry)` decodes a stored payload as a cache load does. Both refuse on a store attached to a cache. `CultElementIds` stays internal.
- A store written by 1.0.x with a record-reference list in a slot still opens (from 2.0.1).
## [2.0.1] - 2026-10-22