Răsfoiți Sursa

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

Yichen Jiang 2 săptămâni în urmă
părinte
comite
f2e4078d8c

+ 2 - 2
docs/subsystems/session-projection.i18n.yaml

@@ -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

+ 15 - 3
docs/subsystems/session-projection.md

@@ -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,

+ 15 - 3
docs/subsystems/session-projection.zh.md

@@ -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,