Skip to content

feat(platform)!: Socket messages page, and getSession with the socket path from the session - #313

Draft
amitbardos wants to merge 11 commits into
amitb/platform-event-codegenfrom
amitb/platform-asyncapi-sync
Draft

amitbardos wants to merge 11 commits into
amitb/platform-event-codegenfrom
amitb/platform-asyncapi-sync

Conversation

@amitbardos

@amitbardos amitbardos commented Oct 10, 2026 •

Copy link
Copy Markdown
Contributor

Stacked on #312. Merge that first; GitHub then retargets this PR to main.

Two parts, in separate commits so they can be reviewed apart. The weekly AsyncAPI sync workflow moved to #318, which waits for the backend deploy. #317 is folded in here and closed.

1. Socket messages page and JSDoc links (4a0a781…c8db94c)

  • One event catalog. events-to-mdx.mjs renders only protocol/socket-messages: every message on the connection in both directions, the { room, data } envelope as fields, and the examples the document publishes. The builder events page is gone, since the callbacks' JSDoc already says how the client delivers each message. onEvent links to the protocol page, which the docs list beside the session endpoints (base44-dev/mintlify-docs#2479). protocol isn't in the category map, so copy-docs-local keeps it out of the Platform SDK nav.
  • asyncapi.json is synced with sync:asyncapi from the document base44-dev/apper#29607 serves, and gen:events regenerated the types. TaskProgressed.event_type is now the five task values, and current/total are integers.
  • The JSDoc links "Create socket session" to /api-reference/create-socket-session.

2. getSession and the socket path from the session (10d8bae, breaking, 0.2.0)

The browser passes one function instead of socketUrl and getSessionToken, and the socket path comes from the session instead of the hard-coded /ws/socket.io/.

const client = createPlatformClient();
const builder = client.builder.init({
  async getSession() {
    const response = await fetch('/api/builder-socket-session', { method: 'POST' });
    return response.json(); // the Create socket session body, unchanged
  },
  onError,
});
  • builder.init({ getSession, onError }): getSession: () => Promise<SocketSession>, where SocketSession is { session_token, socket_url, socket_path }. Other keys (session_id, expires_in) are ignored. getSession is called everywhere getSessionToken was called before: the first connect, renewal after session.ended with reason expired, and the single renewal after a connection_denied on a cached token. The 20-second timeout and the cancellation in authenticate() are unchanged.
  • The socket is created on the first connect(), because the address is known only after the first session. Transport reconnects keep using the cached session.
  • A new address means a new socket. If a renewed session has a different socket_url or socket_path, the SDK doesn't call the old socket's auth callback. It removes the old socket's listeners, disconnects it, opens a socket at the new address, and rejoins every active subscription.
  • Validation. socket_url must be an HTTP(S) origin with no credentials, path, query or fragment (the same check as before). socket_path must be an absolute path with no query or fragment, and can't start with //.
  • createPlatformClient() takes no arguments. No options are left. TypeScript callers that still pass { socketUrl, getSessionToken } get a compile error instead of having the values silently ignored. An optional parameter can be added later without a breaking change. PlatformClientOptions is removed.
  • A bad session is session_unavailable, whether the token, the URL or the path is invalid. connect() rejects with it and onError receives it. No TypeError is thrown. The code already meant that the session endpoint gave the SDK nothing usable.
  • Version 0.2.0, with a new CHANGELOG.md. JSDoc, examples, README.md, unit, type and package tests are updated. SocketSession is listed on the builder reference page.

Tests

PATH=/opt/homebrew/bin:$PATH npm test in packages/platform:

 Test Files  2 passed (2)
      Tests  42 passed (42)
ℹ pass 5
ℹ fail 0

npm run check:events reports builder.events.generated.ts is up to date. npm run create-docs, run after the tests, writes 20 messages to protocol/socket-messages.mdx. npm run lint is clean.

New unit tests cover: the path taken from the session, extra keys in the body ignored, renewal at a new address moving the socket and rejoining both subscriptions, a failed renewal, a late session after close(), and 11 invalid bodies.

Needs attention

🤖 Generated with Claude Code

@github-actions

github-actions Bot commented Oct 10, 2026 •

Copy link
Copy Markdown

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/sdk@0.8.53-pr.313.e45e431

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

npm i "@base44/sdk@npm:@base44-preview/sdk@0.8.53-pr.313.e45e431"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "@base44/sdk": "npm:@base44-preview/sdk@0.8.53-pr.313.e45e431"
  }
}

Preview published to npm registry — try new features instantly!

amitbardos and others added 9 commits October 11, 2026 15:40
…by default

The socketUrl and getSessionToken JSDoc link to the Create socket session
endpoint page. sync-asyncapi.mjs documents production as its default source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n endpoints

The events are the wire protocol a socket session carries, so the docs list
them in the Apps API's Socket sessions group, next to the endpoints that open
the session. Dropping `events` from the category map keeps copy-docs-local
from adding them to the Platform SDK Reference too. The page and its URL stay
where they are, so existing links keep working.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
events-to-mdx.mjs now renders two pages from asyncapi.json:

- protocol/socket-messages: every message on the connection, both
  directions, as it travels: the {room, data} envelope for the 18 the server
  sends, and the plain room string for join and leave. The docs list it in
  the Apps API's Socket sessions group, next to the session endpoints.
- events/builder-events: what the client adds. Which events reach onEvent,
  and what it does with the rest, from its own eventNames, roomNotices and
  sessionEndings. The fields live on the protocol page only.

Builder events is back in the Platform SDK Reference (events returns to the
category map). PlatformEvent's JSDoc links to the protocol page for payloads.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…l page

- The page lists the envelope's room and data as fields from the schema,
  in place of the hand-written "Each message is { room, data }".
- Each message shows the examples the document publishes: a full
  message.updated, session.ended with a null room, and the room string
  join and leave send.
- The beta notice shows once at the top instead of on every message.

asyncapi.json is synced with sync:asyncapi from the document
base44-dev/apper#29607 serves, and gen:events regenerated the types:
TaskProgressed.event_type is now the five task values, and current/total
are integers.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The builder events page repeated what the callbacks' JSDoc already says
(onSnapshot, both onError, PlatformEventMap) and listed the events a second
time. events-to-mdx.mjs now renders only protocol/socket-messages, the one
catalog of events and their payloads. onEvent links there, and events leaves
the category map.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ple per event

- Message format: the room and data envelope fields, with one short example
  beside them.
- Events from the server: a linked index of all 18, then each event's
  description, its example and its data fields, in that order.
- Messages from the browser: join and leave, the same way.

asyncapi.json is re-synced from base44-dev/apper#29607, which now publishes an
example for every message. PlatformSnapshot links to app.snapshot for its
fields.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
- Each event shows its data fields, then its example.
- The format section is "Event format": only what the server sends has the
  room and data envelope, join and leave send a plain string.
- The index of events is gone. It repeated each event's first sentence,
  and Mintlify's own table of contents already lists the headings.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
PlatformSnapshot listed every field of app.snapshot's data again. As
`Snapshot & { room }` instead of an interface, TypeDoc renders only its
description and `room`, and the description links to app.snapshot for the
rest. appended-articles.json follows it to type-aliases/, so it stays on the
builder page.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ough

builder.init() takes getSession, which returns the Create socket session
body unchanged. The socket opens at the session's socket_url and
socket_path on the first connect(), and moves when a renewed session has
a different address. createPlatformClient() takes no options; socketUrl,
getSessionToken and PlatformClientOptions are gone. An invalid session
rejects connect() with session_unavailable. Version 0.2.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@amitbardos
amitbardos force-pushed the amitb/platform-asyncapi-sync branch from bb9a3d5 to 10d8bae Compare October 11, 2026 12:41
@amitbardos amitbardos changed the title Sync Platform SDK events from production every week feat(platform)!: Socket messages page, and getSession with the socket path from the session Oct 11, 2026
amitbardos and others added 2 commits October 11, 2026 15:47
PlatformSnapshot is an interface extending Snapshot instead of the
intersection Snapshot & { room }, so the reference lists status,
messages, queue and room instead of "Snapshot & object". SocketSession
joins it under Type Definitions with the same field layout.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0.1.0 exported Base44PlatformClient with serverUrl, so the before
snippet uses that. The event type renames from the AsyncAPI codegen are
listed old to new.

Co-Authored-By: Claude Opus 5.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