|
|
|
@@ -18,8 +18,11 @@ const OUT = 'docs/persistence-catalog.md'
|
|
|
|
|
* doc-typecheck, since their imported types are not standalone-compilable). */
|
|
|
|
|
const FENCE = 'ts persistence-catalog'
|
|
|
|
|
|
|
|
|
|
/** The package whose module id plugin merges augment (`declare module '…'`). */
|
|
|
|
|
const SESSION_MODULE = '@deepseek-ai/dsh-session'
|
|
|
|
|
/** The package that owns the durable event vocabulary. */
|
|
|
|
|
const SESSION_PACKAGE = '@deepseek-ai/dsh-session'
|
|
|
|
|
|
|
|
|
|
/** The type-only module that plugin declaration merges augment. */
|
|
|
|
|
const SESSION_TYPES_MODULE = '@deepseek-ai/dsh-session/types'
|
|
|
|
|
|
|
|
|
|
/** Event-envelope declarations rendered before the per-event vocabulary. */
|
|
|
|
|
const EVENT_ENVELOPE_TYPE_NAMES = [
|
|
|
|
@@ -115,7 +118,7 @@ function declarationText(text: string, sf: ts.SourceFile, node: ts.Node): string
|
|
|
|
|
/**
|
|
|
|
|
* Every `interface SessionEventMap` declaration in a source file: the owning
|
|
|
|
|
* top-level declaration (in `@deepseek-ai/dsh-session`) and any declaration
|
|
|
|
|
* merge inside a `declare module '@deepseek-ai/dsh-session'` block. Both forms
|
|
|
|
|
* merge inside a `declare module '@deepseek-ai/dsh-session/types'` block. Both forms
|
|
|
|
|
* declare members of the SAME merged interface, so both are catalogued
|
|
|
|
|
* uniformly. `topLevel` distinguishes the owning form so the caller can verify
|
|
|
|
|
* it actually lives in the owning package — an unrelated local interface that
|
|
|
|
@@ -125,7 +128,7 @@ function sessionEventMapDecls(sf: ts.SourceFile): { decl: ts.InterfaceDeclaratio
|
|
|
|
|
const decls: { decl: ts.InterfaceDeclaration; topLevel: boolean }[] = []
|
|
|
|
|
for (const stmt of sf.statements) {
|
|
|
|
|
if (ts.isInterfaceDeclaration(stmt) && stmt.name.text === 'SessionEventMap') decls.push({ decl: stmt, topLevel: true })
|
|
|
|
|
if (ts.isModuleDeclaration(stmt) && ts.isStringLiteral(stmt.name) && stmt.name.text === SESSION_MODULE
|
|
|
|
|
if (ts.isModuleDeclaration(stmt) && ts.isStringLiteral(stmt.name) && stmt.name.text === SESSION_TYPES_MODULE
|
|
|
|
|
&& stmt.body && ts.isModuleBlock(stmt.body)) {
|
|
|
|
|
for (const inner of stmt.body.statements) {
|
|
|
|
|
if (ts.isInterfaceDeclaration(inner) && inner.name.text === 'SessionEventMap') decls.push({ decl: inner, topLevel: false })
|
|
|
|
@@ -174,8 +177,8 @@ export function collectLogEvents(scanRoot: string = root): LogEventEntry[] {
|
|
|
|
|
// the owning package. Same-named interfaces elsewhere are different
|
|
|
|
|
// types and must not enter the on-disk catalog.
|
|
|
|
|
const pkg = packageNameFor(rel, scanRoot)
|
|
|
|
|
if (pkg !== SESSION_MODULE) {
|
|
|
|
|
violations.push(`top-level interface SessionEventMap (${declSrc}) is outside ${SESSION_MODULE} (package ${pkg ?? 'unknown'}). Rename the interface, or contribute events via declare module '${SESSION_MODULE}'.`)
|
|
|
|
|
if (pkg !== SESSION_PACKAGE) {
|
|
|
|
|
violations.push(`top-level interface SessionEventMap (${declSrc}) is outside ${SESSION_PACKAGE} (package ${pkg ?? 'unknown'}). Rename the interface, or contribute events via declare module '${SESSION_TYPES_MODULE}'.`)
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
const exported = decl.modifiers?.some(m => m.kind === ts.SyntaxKind.ExportKeyword) ?? false
|
|
|
|
@@ -243,7 +246,7 @@ export function collectEventEnvelopeTypes(scanRoot: string = root): EventEnvelop
|
|
|
|
|
const abs = resolve(scanRoot, rel)
|
|
|
|
|
const text = readFileSync(abs, 'utf8')
|
|
|
|
|
if (!EVENT_ENVELOPE_TYPE_NAMES.some(name => text.includes(name))) continue
|
|
|
|
|
if (packageNameFor(rel, scanRoot) !== SESSION_MODULE) continue
|
|
|
|
|
if (packageNameFor(rel, scanRoot) !== SESSION_PACKAGE) continue
|
|
|
|
|
const sf = ts.createSourceFile(abs, text, ts.ScriptTarget.Latest, true)
|
|
|
|
|
for (const stmt of sf.statements) {
|
|
|
|
|
if (!ts.isTypeAliasDeclaration(stmt) || !wanted.has(stmt.name.text)) continue
|
|
|
|
@@ -352,7 +355,7 @@ export function render(events: AnnotatedLogEventEntry[], envelopeTypes: EventEnv
|
|
|
|
|
'',
|
|
|
|
|
'# Session Persistence Event Catalog',
|
|
|
|
|
'',
|
|
|
|
|
'Every event type that can appear in a session\'s durable event log: the complete persisted `SessionEvent` envelope and each member of the merge-extensible `SessionEventMap` — the owning vocabulary in `@deepseek-ai/dsh-session` plus every plugin declaration merge in this repo — with source JSDoc, full payload declaration, surface badge, and declaration site. It complements [session.md](subsystems/session.md) (surface ordering and the `deriveMessages()` projection), [persistence.md](subsystems/persistence.md) (how the log is made durable), and the generated region of [session.md](subsystems/session.md#cordis-surface) (the live bus wiring — a log event is NOT a cordis event; it reaches listeners via the single `session/event` emit).',
|
|
|
|
|
'Every event type that can appear in a session\'s durable event log: the complete persisted `SessionEvent` envelope and each member of the merge-extensible `SessionEventMap` — the owning vocabulary in `@deepseek-ai/dsh-session` plus every plugin declaration merge into `@deepseek-ai/dsh-session/types` in this repo — with source JSDoc, full payload declaration, surface badge, and declaration site. It complements [session.md](subsystems/session.md) (surface ordering and the `deriveMessages()` projection), [persistence.md](subsystems/persistence.md) (how the log is made durable), and the generated region of [session.md](subsystems/session.md#cordis-surface) (the live bus wiring — a log event is NOT a cordis event; it reaches listeners via the single `session/event` emit).',
|
|
|
|
|
'',
|
|
|
|
|
'This file is GENERATED from source (`scripts/gen-persistence-catalog.ts`) and verified fresh by `pnpm run verify-persistence-catalog` (part of `doc-sync`) — do not edit it by hand. Declaration blocks retain the source declaration and nested property JSDoc, removing only the indentation imposed by a containing interface/module, and use a `ts persistence-catalog` fence (skipped by doc-typecheck because declarations reference types from their owning modules). Type names in a payload link to the page that documents them. See [the persistence-log-catalog Agent Note](../.agents/notes/archived/process/2026-07-04-persistence-log-catalog.md).',
|
|
|
|
|
'',
|
|
|
|
|