Skip to main content

SchemaDoc & Generated JSDoc

In LIVON, the schema is the living documentation of the system.

Rule

Every schema should include a doc object with concise summary and example.

If no doc object is provided, LIVON generates a minimal default JSDoc example so generated client surfaces remain documented.

Schema with doc metadata

import {object, string} from '@livon/schema';

const Message = object({
name: 'Message',
shape: {
text: string(),
},
doc: {
summary: 'Message payload',
example: {text: 'Hello'},
},
});

Parameters in this example

object({...}):

  • name (string): schema identifier used in generated output.
  • shape (Record<string, Schema>): schema field map.
  • doc (SchemaDoc): documentation metadata for generated client JSDoc.

doc:

  • summary (string): short purpose text.
  • example (unknown): concrete payload example for generated docs.

Generated client output (actual format)

/**
* Operation: sendMessage.
* Constraints: publish=["onMessage"], request="MessageInput", response="Message".
* Output type: Message.
* Input type: MessageInput.
* @param input - MessageInput request payload.
* See {@link MessageInput}.
* @returns Message operation result.
* See {@link Message}.
* Publishes events: onMessage.
* @example
* await client.sendMessage({ text: "Hello" })
* @example
* sendMessage({ text: "Hello" }: MessageInput): Message
*/
sendMessage(input: MessageInput): Promise<Message>;

How to read generated operation JSDoc

Generated operation docs include runtime schema metadata so IDE hovers explain both type shape and delivery behavior.

Example:

/**
* Operation: sendMessage.
* Constraints: publish=["onMessage"], ack={"required":true,"mode":"received","timeoutMs":5000,"retries":3}, request="MessageInput", response="Message".
* Output type: Message.
* Input type: MessageInput.
* @param input - MessageInput request payload.
* See {@link MessageInput}.
* @returns Message operation result.
* See {@link Message}.
* Publishes events: onMessage.
*/

Meaning:

  • Operation: sendMessage: operation name in the schema.
  • Constraints: normalized runtime metadata from schema AST.
  • publish=["onMessage"]: this operation emits the onMessage topic.
  • request="MessageInput": schema-level request schema name.
  • response="Message": schema-level response schema name.
  • Output type: Message: generated TypeScript return payload type used by client code.
  • Input type: MessageInput: generated TypeScript input type required by client code.
  • @param / @returns / See {@link ...}: hover-friendly links and call schema details for IDE usage.

Subscription hover format

Generated subscription hover docs use the same deterministic structure:

/**
* Subscription callback for "onMessage".
* Constraints: input="MessageInput", payload="Message", output="Message".
* Request input: MessageInput.
* Output type: Message.
* @param payload - Message payload emitted for "onMessage".
* @param ctx - ClientHandlerContext runtime metadata and room context.
* See {@link Message} and {@link ClientHandlerContext}.
* @example
* api({ onMessage: (payload) => payload.text });
*/
onMessage?(payload: Message, ctx: ClientHandlerContext): void;

and(...) schema composition in generated types

When schemas are composed with and(...), generated client types are emitted as TypeScript intersections.

Example:

type MessageWithId = MessageInput & WithId;

If and({ left, right, name }) is used, the explicit name becomes the generated type surface name.

ack constraints

ack defines delivery confirmation behavior for publish flow:

  • required: true: publish requires acknowledgement.
  • mode: "received": acknowledgement is emitted on receive.
  • timeoutMs: 5000: acknowledgement timeout window.
  • retries: 3: retry attempts before failure is surfaced.

In generated JSDoc, this appears inside Constraints so delivery behavior is visible directly at the call site (api.sendMessage(...)).

Generator and docs sync rule

Generated JSDoc is produced by the client generator (@livon/client), so generator output and docs must stay synchronized.

Required when changing generator behavior:

  • update generator implementation in packages/client/src/generate.ts or templates in packages/client/templates/*
  • if TypeScript interface/signature surface should change globally, update packages/client/src/typeScriptSurfaceTemplate.ts
  • update this page when generated JSDoc structure or terminology changes
  • update package docs in @livon/client when usage/hover behavior changes
  • keep packages/client/src/generate.spec.ts aligned with current generated output expectations

Prompt rule source for this package:

IDE impact

  • Hover tooltips show summary and example from the schema source.
  • Schema docs stay near the schema that defines execution boundaries.
  • Frontend and backend teams read the same canonical description.

Why this matters

Generated JSDoc from schema metadata reduces documentation drift and keeps structural alignment visible in daily development workflows.