|
@@ -488,7 +488,7 @@ export class SessionProjectionRegistry extends Service {
|
|
|
* @param baseSeq - the seq `events` starts at (its first event's seq when non-empty).
|
|
* @param baseSeq - the seq `events` starts at (its first event's seq when non-empty).
|
|
|
* @param header - immutable metadata for the Session being restored.
|
|
* @param header - immutable metadata for the Session being restored.
|
|
|
* @param inheritedEventCount - exact fork-inherited prefix length supplied to unit initialization.
|
|
* @param inheritedEventCount - exact fork-inherited prefix length supplied to unit initialization.
|
|
|
- * @param keys - optional client-visible outputs; an empty list restores every state without computing or validating views.
|
|
|
|
|
|
|
+ * @param projectionMode - `none` restores every state without computing or validating client views; defaults to `all`.
|
|
|
* @returns the snapshot cut at the supplied log end (`asOfSeq` is the last
|
|
* @returns the snapshot cut at the supplied log end (`asOfSeq` is the last
|
|
|
* supplied event's seq, `baseSeq - 1` for an empty tail) plus the
|
|
* supplied event's seq, `baseSeq - 1` for an empty tail) plus the
|
|
|
* refreshed checkpoint rows at that cut, ready for a durable write-back.
|
|
* refreshed checkpoint rows at that cut, ready for a durable write-back.
|
|
@@ -499,14 +499,13 @@ export class SessionProjectionRegistry extends Service {
|
|
|
baseSeq: SessionLogOffset,
|
|
baseSeq: SessionLogOffset,
|
|
|
header: SessionHeader,
|
|
header: SessionHeader,
|
|
|
inheritedEventCount: SessionLogOffset,
|
|
inheritedEventCount: SessionLogOffset,
|
|
|
- keys?: readonly Extract<keyof SessionProjectionMap, string>[],
|
|
|
|
|
|
|
+ projectionMode: 'all' | 'none' = 'all',
|
|
|
):
|
|
):
|
|
|
{ snapshot: ProjectionSnapshot; checkpoint: ProjectionCheckpoint } {
|
|
{ snapshot: ProjectionSnapshot; checkpoint: ProjectionCheckpoint } {
|
|
|
const endSeq: SessionSeqCursor = events.at(-1)?.seq ?? cursorBefore(baseSeq)
|
|
const endSeq: SessionSeqCursor = events.at(-1)?.seq ?? cursorBefore(baseSeq)
|
|
|
const beforeBase = cursorBefore(baseSeq)
|
|
const beforeBase = cursorBefore(baseSeq)
|
|
|
const values: Record<string, unknown> = {}
|
|
const values: Record<string, unknown> = {}
|
|
|
const refreshed: ProjectionCheckpoint = {}
|
|
const refreshed: ProjectionCheckpoint = {}
|
|
|
- const selected = keys === undefined ? undefined : new Set<string>(keys)
|
|
|
|
|
for (const registration of this.registrations.values()) {
|
|
for (const registration of this.registrations.values()) {
|
|
|
const def = registration.def
|
|
const def = registration.def
|
|
|
const row = checkpoint[def.key]
|
|
const row = checkpoint[def.key]
|
|
@@ -533,7 +532,7 @@ export class SessionProjectionRegistry extends Service {
|
|
|
}
|
|
}
|
|
|
state = def.apply(state, event)
|
|
state = def.apply(state, event)
|
|
|
}
|
|
}
|
|
|
- if (def.wire !== undefined && (selected === undefined || selected.has(def.key))) {
|
|
|
|
|
|
|
+ if (projectionMode === 'all' && def.wire !== undefined) {
|
|
|
values[def.key] = def.wire.viewSchema.parse(def.wire.view(state))
|
|
values[def.key] = def.wire.viewSchema.parse(def.wire.view(state))
|
|
|
}
|
|
}
|
|
|
refreshed[def.key] = { ver: def.stateVersion, seq: endSeq, val: state }
|
|
refreshed[def.key] = { ver: def.stateVersion, seq: endSeq, val: state }
|
|
@@ -552,15 +551,15 @@ export class SessionProjectionRegistry extends Service {
|
|
|
* @param checkpoint - persisted rows for this Session lifecycle.
|
|
* @param checkpoint - persisted rows for this Session lifecycle.
|
|
|
* @param events - exact events at the observation cut.
|
|
* @param events - exact events at the observation cut.
|
|
|
* @param baseSeq - first supplied event sequence.
|
|
* @param baseSeq - first supplied event sequence.
|
|
|
- * @param keys - optional client-visible outputs; an empty list installs every state without computing or validating views.
|
|
|
|
|
- * @returns selected projection values at the supplied cut, defaulting to all views.
|
|
|
|
|
|
|
+ * @param projectionMode - `none` installs every state without computing or validating client views; defaults to `all`.
|
|
|
|
|
+ * @returns the supplied cut with all client views, or empty values in `none` mode.
|
|
|
*/
|
|
*/
|
|
|
hydrate(
|
|
hydrate(
|
|
|
session: Session,
|
|
session: Session,
|
|
|
checkpoint: ProjectionCheckpoint,
|
|
checkpoint: ProjectionCheckpoint,
|
|
|
events: readonly SessionEvent[],
|
|
events: readonly SessionEvent[],
|
|
|
baseSeq: SessionLogOffset,
|
|
baseSeq: SessionLogOffset,
|
|
|
- keys?: readonly Extract<keyof SessionProjectionMap, string>[],
|
|
|
|
|
|
|
+ projectionMode: 'all' | 'none' = 'all',
|
|
|
): ProjectionSnapshot {
|
|
): ProjectionSnapshot {
|
|
|
const endSeq: SessionSeqCursor = events.at(-1)?.seq ?? cursorBefore(baseSeq)
|
|
const endSeq: SessionSeqCursor = events.at(-1)?.seq ?? cursorBefore(baseSeq)
|
|
|
let complete = true
|
|
let complete = true
|
|
@@ -573,12 +572,12 @@ export class SessionProjectionRegistry extends Service {
|
|
|
}
|
|
}
|
|
|
if (complete) {
|
|
if (complete) {
|
|
|
const values: Record<string, unknown> = {}
|
|
const values: Record<string, unknown> = {}
|
|
|
- const selected = keys === undefined ? undefined : new Set<string>(keys)
|
|
|
|
|
- for (const registration of this.registrations.values()) {
|
|
|
|
|
- if (registration.def.wire === undefined) continue
|
|
|
|
|
- if (selected !== undefined && !selected.has(registration.def.key)) continue
|
|
|
|
|
- const current = registration.cells.get(session) as UnitCell
|
|
|
|
|
- values[registration.def.key] = this.viewCell(registration, current)
|
|
|
|
|
|
|
+ if (projectionMode === 'all') {
|
|
|
|
|
+ for (const registration of this.registrations.values()) {
|
|
|
|
|
+ if (registration.def.wire === undefined) continue
|
|
|
|
|
+ const current = registration.cells.get(session) as UnitCell
|
|
|
|
|
+ values[registration.def.key] = this.viewCell(registration, current)
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
return { asOfSeq: endSeq, values }
|
|
return { asOfSeq: endSeq, values }
|
|
|
}
|
|
}
|
|
@@ -588,7 +587,7 @@ export class SessionProjectionRegistry extends Service {
|
|
|
baseSeq,
|
|
baseSeq,
|
|
|
session.header,
|
|
session.header,
|
|
|
session.inheritedEventCount,
|
|
session.inheritedEventCount,
|
|
|
- keys,
|
|
|
|
|
|
|
+ projectionMode,
|
|
|
)
|
|
)
|
|
|
for (const registration of this.registrations.values()) {
|
|
for (const registration of this.registrations.values()) {
|
|
|
const row = restored.checkpoint[registration.def.key]
|
|
const row = restored.checkpoint[registration.def.key]
|