Skip to content

feat(realtime): add realtime command and handler scaffolding#555

Draft
ImriKochWix wants to merge 11 commits into
mainfrom
feat/realtime-handler
Draft

feat(realtime): add realtime command and handler scaffolding#555
ImriKochWix wants to merge 11 commits into
mainfrom
feat/realtime-handler

Conversation

@ImriKochWix

@ImriKochWix ImriKochWix commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Note

Description

Adds first-class support for realtime handlers to the Base44 CLI. Introduces a new realtime resource (scaffold, config discovery, deploy) plus a base44 realtime command group (new, deploy), wires realtime handlers into the unified base44 deploy flow, and extends TypeScript type generation to emit strongly-typed message catalogs (RealtimeHandlerRegistry, RealtimeHandlerNameRegistry) from each handler's schema.jsonc.

Related Issue

None

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Other (please describe):

Changes Made

  • New realtime-handler core resource (src/core/resources/realtime-handler/): schema.ts (Zod schemas for config, message catalog, and deploy response), config.ts (discovers entry.ts handlers in named subfolders, reads optional schema.jsonc, guards against duplicate/misplaced handlers), api.ts (PUT to /realtime-handlers/{name}), deploy.ts (sequential deploy with per-handler status reporting), and resource.ts (unified Resource binding).
  • New base44 realtime command group (src/cli/commands/realtime/): new <HandlerName> scaffolds a RealtimeHandler class extending @base44/sdk, and deploy [names...] deploys selected or all handlers with progress output and non-zero exit on failure.
  • Project config integration: added realtimeDir (default \"realtime\") to the project config schema, realtimeHandlers to ProjectData, and read/deploy wiring in config.ts, deploy.ts, and the top-level deploy command summary.
  • Type generation: compiles each handler's message catalog (types / toClient / toServer) in a single pass into named interfaces and discriminated unions, injecting the type discriminant per message and rewriting #/types/X refs; emits RealtimeHandlerRegistry and RealtimeHandlerNameRegistry. Also detects the SDK package name (@base44/sdk vs @base44-preview/sdk) and adds export {}; so the generated types.d.ts augments rather than replaces the SDK module.
  • Tests & fixtures: added tests/core/types-realtime.spec.ts, updated tests/cli/types_generate.spec.ts, and added a ChatRoom realtime fixture (entry.ts + schema.jsonc).

Testing

  • I have tested these changes locally
  • I have added/updated tests as needed
  • All tests pass (`npm test`)

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (if applicable)
  • My changes generate no new warnings
  • I have updated `docs/` (AGENTS.md) if I made architectural changes

Additional Notes

The realtime resource mirrors the existing function resource conventions (multi-file payloads, sequential deploy, Resource<T> interface) for consistency. Handler message schemas use a toClient/toServer naming convention (renamed from an earlier inbound/outbound within this PR). Consider adding a docs/ topic guide and updating AGENTS.md to document the new resource before release.


🤖 Generated by Claude | 2026-07-05 21:30 UTC | 77b65cb

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/cli@0.1.1-pr.555.77b65cb

Prefer not to change any import paths? Install using npm alias so your code still imports base44:

npm i "base44@npm:@base44-preview/cli@0.1.1-pr.555.77b65cb"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "base44": "npm:@base44-preview/cli@0.1.1-pr.555.77b65cb"
  }
}

Preview published to npm registry — try new features instantly!

ImriKochWix and others added 10 commits June 30, 2026 13:54
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
new.ts used project.root but readAllRealtimeHandlers uses dirname(configPath),
causing handlers to be created at realtime/ instead of base44/realtime/.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
'base44' is the CLI package name and has no exported types.
@base44/sdk now exports RealtimeHandler and Conn for type-checking,
and the bundler rewrites the import to the CF shim at deploy time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- base44 types generate now includes realtime handlers in types.d.ts
- RealtimeHandlerNameRegistry: auto-registers handler names (no manual declare needed)
- RealtimeHandlerRegistry: compiled from schema.jsonc inbound/outbound JSON schemas
- Add schema.jsonc support to realtime-handler resource reader
- Update test fixture with ChatRoom schema and assertions

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Detect @base44/sdk vs @base44-preview/sdk from project's package.json
  so declare module targets the correct package name
- Add export {} to generated types.d.ts to ensure module context,
  preventing ambient module from shadowing the SDK package types

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove unused RealtimeHandlerConfig type alias
- Replace [^]* regex with [\s\S]* (Biome noEmptyCharacterClassInRegex)
- Auto-format long lines per Biome formatter rules

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The dedicated endpoint calls ensure_cfw_backend and uses force_per_function
so the bundler runs applyRealtimeCompat instead of the per-app path.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
schema.jsonc is now a catalog of named messages (inbound/outbound maps of
message-name -> full JSON Schema, like entities) plus optional shared `types`.
compileRealtimeHandler emits one named interface per message (direction- and
handler-prefixed to avoid collisions) + shared types, and composes the
inbound/outbound unions in the registry.

Removes the /\{([\s\S]*)\}/ body-scrape, which produced invalid TS whenever
json-schema-to-typescript emitted more than one declaration (unions with
$defs). Because every message is a single flat object, that multi-declaration
case can no longer arise.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…lient/toServer

The old names were written from the client's perspective, so handler code
read backwards (InMsg = Reg["outbound"]) and every reader had to do the
double-negative. toClient/toServer read correctly from both sides:
Reg["toServer"] is what the handler receives, Reg["toClient"] is what it
sends. Generated interface prefixes follow (GameRoomToClientInit).

Breaking for schema.jsonc files and the generated registry shape; done now
while there are zero external users.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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