docs(session-projection): carry viewKey through the subsystem type fences

This commit is contained in:
Yichen Jiang 2026-08-31 14:46:29 +08:00 • committed by imccyu
parent 9836fdbbd7
commit f2e4078d8c
3 changed files with 32 additions and 8 deletions

View file

@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write docs/subsystems/session-projection.md
session-projection.md: b241c7dbceab23850e9a3755076ee23f83d1ecda
session-projection.zh.md: 53cb8c251f54ee0343eccab57533d9a0d91f993a
session-projection.md: 5943281952def6e86f819e73c7822dc7f6ed4ed6
session-projection.zh.md: 99009a0472ed40f418527848e91523d0ff0e2303

View file

@ -52,6 +52,18 @@ interface ProjectionDefinition<
* @returns the whole current value for this unit's key.
*/
view(state: NoInfer<S>): SessionProjectionMap[K]
/**
* Change-detection token for the served view: after a changed `apply`,
* the feed compares this token across the previous and next states with
* `Object.is` and stays quiet when identical, so `view` runs only for an
* actual push. Must be a cheap pure read (a state field, not a
* computation). Omitted, the raw `view` output itself is the token —
* correct for identity-stable views, but then `view` runs per changed
* state, and views building fresh objects per call push on every change.
* @param state - a state on either side of the comparison.
* @returns the token deciding whether the served view changed.
*/
viewKey?(state: NoInfer<S>): unknown
} : never
/**
* Persisted-cache invalidation version: bump whenever the serialized state fields or the
@ -86,9 +98,9 @@ interface ProjectionSnapshot {
* Change-feed listener: one unit's served value changed for one session.
* `value` is the schema-validated `view` output; `seq` is the unit's
* watermark at emission (the seq of the event that caused the change). A
* changed state whose raw `view` output is `Object.is`-identical to the
* unit's previous projection does not fire, so a unit can buffer working
* fields in state behind an identity-stable projection.
* changed state whose `viewKey` token (default: the raw `view` output) is
* `Object.is`-identical to the previous state's does not fire, so a unit can
* buffer working fields in state behind an identity-stable projection.
*/
type ProjectionChangeListener = (
session: Session,

View file

@ -52,6 +52,18 @@ interface ProjectionDefinition<
* @returns the whole current value for this unit's key.
*/
view(state: NoInfer<S>): SessionProjectionMap[K]
/**
* Change-detection token for the served view: after a changed `apply`,
* the feed compares this token across the previous and next states with
* `Object.is` and stays quiet when identical, so `view` runs only for an
* actual push. Must be a cheap pure read (a state field, not a
* computation). Omitted, the raw `view` output itself is the token —
* correct for identity-stable views, but then `view` runs per changed
* state, and views building fresh objects per call push on every change.
* @param state - a state on either side of the comparison.
* @returns the token deciding whether the served view changed.
*/
viewKey?(state: NoInfer<S>): unknown
} : never
/**
* Persisted-cache invalidation version: bump whenever the serialized state fields or the
@ -86,9 +98,9 @@ interface ProjectionSnapshot {
* Change-feed listener: one unit's served value changed for one session.
* `value` is the schema-validated `view` output; `seq` is the unit's
* watermark at emission (the seq of the event that caused the change). A
* changed state whose raw `view` output is `Object.is`-identical to the
* unit's previous projection does not fire, so a unit can buffer working
* fields in state behind an identity-stable projection.
* changed state whose `viewKey` token (default: the raw `view` output) is
* `Object.is`-identical to the previous state's does not fire, so a unit can
* buffer working fields in state behind an identity-stable projection.
*/
type ProjectionChangeListener = (
session: Session,