Skip to content

feat(captures): add named API sources, CDL routes, and capturer grains#3323

Draft
Copilot wants to merge 6 commits into
mainfrom
copilot/add-capture-declaration-language
Draft

feat(captures): add named API sources, CDL routes, and capturer grains#3323
Copilot wants to merge 6 commits into
mainfrom
copilot/add-capture-declaration-language

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 25, 2026

Summary

This extends capture authoring and CDL to support named API sources with optional routes, renames the declarative capture interface to ICapturer, and adds initial backend capturer supervision grains. Documentation has been updated to match the current APIs and language behavior.

Added

  • New declarative capture entry interface: ICapturer.
  • API route support for capture sources in both client authoring and CDL (route on API sources).
  • Initial backend capture supervision primitives in Core: capturer manager, trigger, and capturer grains.
  • Expanded capture documentation covering named API usage and optional API routes.

Changed

  • Declarative client API now references APIs by name instead of inline URLs (FromApi(api, ...)), with optional route configuration.
  • Model-bound API capture attribute now uses API name semantics and supports optional route configuration.
  • CDL API source properties now use api (required for API sources) and optional route instead of inline url.
  • Declarative samples and language/spec docs updated to reflect current syntax and behavior.
  • ICaptureFor is now compatibility-only via inheritance from ICapturer.

Fixed

  • Corrected named-argument ordering in WebhookSourceBuilder to satisfy analyzer rule RCS1205 and unblock client build.

Removed

  • None.

Security

  • None.

Deprecated

  • ICaptureFor is superseded by ICapturer and retained for compatibility.

Implements a complete CDL parser, compiler, and language service for
Change Data Capture following the same conventions as the existing PDL.

Includes:
- Capture concepts (CaptureId, CaptureDefinition, SourceDefinition, etc.)
- CDL tokenizer with capture-specific keywords
- Full AST node hierarchy (CaptureDocument, SourceBlock, MapBlock, AppendBlock, etc.)
- Parser stack (CaptureParser, directive parsers, WhenClauseParser, etc.)
- Compiler turning AST into CaptureDefinition
- ILanguageService + LanguageService
- 25 BDD specs covering all major features

Agent-Logs-Url: https://github.com/Cratis/Chronicle/sessions/ceeb3daa-8771-49a3-980f-176a970a81df

Co-authored-by: einari <134365+einari@users.noreply.github.com>
Copilot AI changed the title [WIP] Introduce Capture Declaration Language for Change Data Capture feat(cdl): Capture Declaration Language (CDL) — Change Data Capture DSL May 25, 2026
Copilot finished work on behalf of einari May 25, 2026 12:15
Copilot AI requested a review from einari May 25, 2026 12:15
@einari
Copy link
Copy Markdown
Contributor

einari commented May 25, 2026

@copilot Great. And as we have for Projections in the workbench, we need a similar editor with full Monaco a language service implemented.

Implements the Monaco-editor language service for CDL and a Captures
feature page in the workbench, following the same conventions as the
existing ProjectionEditor.

- Components/CaptureEditor/language.ts — Monarch tokenizer for CDL keywords
- Components/CaptureEditor/CaptureDefinitionLanguageValidator.ts — inline validation
- Components/CaptureEditor/CaptureDefinitionLanguageCompletionProvider.ts — context-sensitive completions
- Components/CaptureEditor/CaptureDefinitionLanguageHoverProvider.ts — hover documentation
- Components/CaptureEditor/CaptureHelpPanel.tsx — slide-in CDL reference panel
- Components/CaptureEditor/CaptureEditor.tsx — Monaco wrapper component
- Components/CaptureEditor/index.ts — language registration
- Features/EventStore/General/Captures/Captures.tsx — captures feature page
- EventStore.tsx — route + menu item for Captures
- translation.json — new strings for capture editor and captures feature

Agent-Logs-Url: https://github.com/Cratis/Chronicle/sessions/1d098b9d-80e5-4fbb-8a74-750b2b3c4cc3

Co-authored-by: einari <134365+einari@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 25, 2026

@copilot Great. And as we have for Projections in the workbench, we need a similar editor with full Monaco a language service implemented.

Done in commit 7acc52c. Added the full Monaco language service for CDL and a Captures feature page, following the same conventions as the ProjectionEditor:

Components/CaptureEditor/

  • language.ts — Monarch tokenizer with all CDL keywords highlighted, template-literal support, and $.path, $previous.path, $context.*, $env.* expressions
  • CaptureDefinitionLanguageValidator.ts — inline validation (first line must be capture Name, checks for source/key, each append block needs a when)
  • CaptureDefinitionLanguageCompletionProvider.ts — context-sensitive completions (source types, keyword suggestions, $., $previous., $context.occurred, etc.)
  • CaptureDefinitionLanguageHoverProvider.ts — hover docs for every CDL keyword and built-in expression
  • CaptureHelpPanel.tsx — slide-in reference panel with all CDL sections
  • CaptureEditor.tsx — Monaco wrapper with ? help button and changed-line gutter decorations

Features/EventStore/General/Captures/Captures.tsx — two-pane page: capture list on the left, editor on the right, with New / Save toolbar actions.

EventStore.tsx — route (captures) and menu item wired in.

Copilot finished work on behalf of einari May 25, 2026 13:44
@einari
Copy link
Copy Markdown
Contributor

einari commented May 25, 2026

@copilot Great. Lets do a few more things:

  • Create 2 client APIs for this; declarative and model-bound - take inspiration from what we've done for Projections
  • Create full documentation for this, including a language specification - like we've done for the Projection. Document both client approaches, and the language and an actual language specification as well.

Agent-Logs-Url: https://github.com/Cratis/Chronicle/sessions/213dbec4-5e25-47f6-a3c2-f8bb9d18cf7e

Co-authored-by: einari <134365+einari@users.noreply.github.com>
Copilot AI changed the title feat(cdl): Capture Declaration Language (CDL) — Change Data Capture DSL feat(captures): add client APIs and full CDL documentation May 27, 2026
Copilot finished work on behalf of einari May 27, 2026 12:52
Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Cratis Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: c9f6338 Previous: 9c41e1c Ratio
Cratis.Chronicle.Benchmarks.AppendManyBenchmark.AppendManyEvents(EventCount: 100) 137919161.41666666 ns (± 7181163.209171882) 68128824.7 ns (± 7671149.609764319) 2.02

This comment was automatically generated by workflow using github-action-benchmark.

CC: @einari

@einari
Copy link
Copy Markdown
Contributor

einari commented May 29, 2026

@copilot The API definition should not be done inline - but instead reference an API by name - the API should be defined in a similar way to how we do WebHooks, but we should be able to define the trigger; polling every N minutes - like done here, that is fine. But the API itself is typically something we configure independently.However, on the CDL we should also be able to define a route. So while the API is defined as a source, that can be the root for many different APIs and we then use routes on top. But if not a route is specified, we'll just use the URL straight up.

This means we need a way to handle this.

On the backend in Core. We need a Capturer manager that sets up the triggers. The manager should be a grain and the triggers should also be a grain, and the actual Capturer should also be a grain. That way we can easily scale things out. See them as supervisors over supervisors.

In the client, the interface ICaptureFor should be renamed to ICapturer.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 29, 2026

@copilot The API definition should not be done inline - but instead reference an API by name - the API should be defined in a similar way to how we do WebHooks, but we should be able to define the tri...

Implemented in 80c737a.

  • Capture client API now references API definitions by name (FromApi(api, ...)) and supports optional route configuration (OnRoute(route)), with model-bound parity via [ApiCapture(api, Route = ...)].
  • CDL source API configuration now supports api + optional route (and no inline url), including parser/compiler/spec updates and documentation.
  • Added Core Orleans supervision primitives for captures: ICapturerManager/CapturerManager, ICaptureTrigger/CaptureTrigger, and ICapturerGrain/Capturer.
  • Introduced ICapturer and updated docs/usages accordingly (ICaptureFor now inherits ICapturer for compatibility).

Copilot AI changed the title feat(captures): add client APIs and full CDL documentation feat(captures): add named API sources, CDL routes, and capturer grains May 29, 2026
Copilot finished work on behalf of einari May 29, 2026 16:55
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.

Capture Declaration Language (CDL) — Change Data Capture DSL

2 participants