Skip to content

feat(typespec-ts): generate structured JSONL and SSE streaming by default - #1

Closed
l0lawrence wants to merge 1 commit into
mainfrom
l0lawrence-vigilant-system
Closed

l0lawrence wants to merge 1 commit into
mainfrom
l0lawrence-vigilant-system

Conversation

@l0lawrence

Copy link
Copy Markdown
Owner

Summary

Adds structured JSONL + SSE streaming code generation to the @azure-tools/typespec-ts modular emitter. A response whose TCGC metadata indicates a structured stream now generates a Promise<AsyncIterable<T>> of deserialized items/events instead of returning the raw binary Uint8Array body. This mirrors microsoft/typespec#11594 (Python emitter) and the sibling @typespec/http-client-js work.

This is the default behavior — there is no opt-in option.

What's generated

  • JSONL (JsonlStream<T>) → Promise<AsyncIterable<T>> that lazily decodes JSON Lines.
  • SSE (SSEStream<T>) → Promise<AsyncIterable<...>> that dispatches each Server-Sent Event by its event: name (via @azure/core-sse), deserializes the payload, and stops at the terminal event. Full heterogeneous multi-event dispatch and @terminalEvent handling are supported (both named terminals, keyed on the terminal flag, and unnamed data: [DONE] sentinel terminals).

Operations connect eagerly (HTTP status/errors surface at call time) and decode the body lazily.

Implementation

  • New static helper static/static-helpers/streamingHelpers.ts (getStreamResponse, readJsonlStream, readSseStream, SseEventDescriptor), registered in static-helpers-metadata.ts and loaded only when the package actually has a structured-stream operation (packageHasStructuredStreaming, a side-effect-free metadata check).
  • operation-helpers.ts: getStructuredStreamInfo resolves stream metadata (gated purely on response.streamMetadata / sseMetadata); branches in the operation and deserialize builders emit the AsyncIterable shape.
  • @azure/core-sse added to AzureCoreDependencies and injected into the generated package's dependencies only when an SSE op is present.

Tests

Three new unit-modular scenarios: JSONL, SSE named (heterogeneous + terminal [DONE]), and SSE unnamed (homogeneous message events). Terminal handling was verified against the real http-specs SSE spec wire frames plus a runtime smoke of the helper.

Validation

  • pnpm build (tsc) — pass
  • pnpm lint (oxlint --deny-warnings) — pass
  • unit-modular — 662 passed
  • test-next — 254 passed
  • SSE runtime smoke against exact spec frames — pass

Only the 3 new streaming scenarios are semantically changed baselines; no non-streaming snapshots change.

…ault

JSONL/SSE stream responses now return Promise<AsyncIterable<T>> of
deserialized items/events instead of the raw binary Uint8Array body.
JsonlStream<T> lazily decodes JSON Lines; SSEStream<T> dispatches each
Server-Sent Event by its event: name (via @azure/core-sse), deserializes
the payload, and stops at the terminal event. Heterogeneous multi-event
dispatch and terminal-event handling are supported.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: de6a6ea9-d1f8-4a50-831f-d64d9f7cfa0d
@l0lawrence

Copy link
Copy Markdown
Owner Author

Superseded by the upstream draft PR against Azure/typespec-azure main (Azure#5196). Closing this fork-targeted duplicate; branch and commit remain intact.

@l0lawrence l0lawrence closed this Aug 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant