Skip to content

Document the actors module to the standard of the other published modules - #273

Draft
daniellekorn wants to merge 2 commits into
sdk-jsdoc-stylefrom
sdk-actors-docs
Draft

Document the actors module to the standard of the other published modules#273
daniellekorn wants to merge 2 commits into
sdk-jsdoc-stylefrom
sdk-actors-docs

Conversation

@daniellekorn

@daniellekorn daniellekorn commented Sep 6, 2026

Copy link
Copy Markdown
Collaborator

Follow-up to #272, which held the actors page back from base44-dev/mintlify-docs#1997 because it was not publishable. This writes the docs and un-holds it.

Note

Based on sdk-jsdoc-style (#272), not main. Merge #272 first and this retargets to main automatically.

What was wrong

The actors page published as 18 lines: a truncated type signature, two sentences, and one snippet. connect(), subscribe(), send(), close(), and unsubscribe() did not appear on it at all.

The JSDoc was not really the problem. ActorRef, Connection, ActorConnectOptions, and ActorRegistry were missing from types-to-expose.json, so every method was stripped before rendering and the page had nowhere to put them. A renamed module page is treated as exposed regardless of that file, which is why the module page itself survived while all of its content was removed.

before after
Page lines 18 339
Documented methods 0 of 5 5 of 5
@example 1 9
@param 0 3
@returns 0 2
Capability bullets 0 5
Auth modes stated no yes

@param covers connect(options), subscribe(callback), and send(data). close() and unsubscribe() take no arguments and return void, so they carry a description and an example only.

Every behavioural claim, traced to the code

Claim in the docs Verified against
connect() is idempotent while open, returning the same connection actors.ts:232 if (conn) return conn
A fresh connect() after close() works actors.ts:235 if (conn === c) conn = null
send() before open is buffered and flushed on open partysocket _messageQueue enqueues when not open
send() after close() is dropped silently actors.ts:205 if (this.closed) return
close() tears down socket, heartbeat, and all listeners actors.ts:209-219
close() is safe to call more than once actors.ts:210 if (this.closed) return
Any number of listeners, each receives every message actors.ts:174 loops this.listeners; 197 listeners.add
unsubscribe() removes one listener, leaves the rest live actors.ts:199 listeners.delete(callback)
Permanent failure closes the connection and reports to onError actors.ts:128-137 terminal statuses call this.close() then onMintError, wired at client.ts:218 onMintError: options?.onError
Recovery needs a fresh connect() and a re-subscribe actors.ts:216 listeners.clear(), new Connection gets an empty set
Reconnects with backoff, recovers half-open sockets actors.ts:177-193 heartbeat, DEAD_MS watchdog, ws.reconnect() when OPEN but silent
options.id becomes the actor's conn.id actors.ts:101 then 271 ["_pk", connectionId]
Not available on asServiceRole client.ts:270 serviceRoleModules has no actors key

One claim was wrong, and is corrected here

An earlier draft said "Connecting anonymously requires a browser environment." That was inferred from the comment at actors.ts:54 (422 = no principal, e.g. anonymous outside a browser), and it is wrong.

422 is in PROXY_FALLBACK_STATUSES (actors.ts:59), not TERMINAL_MINT_STATUSES (:65, which is 400/403/404). So an anonymous connect outside a browser does not fail. The direct mint returns 422 and the SDK falls back to the platform proxy, which the same comment block describes as having looser validation and as "always safe" to fall back to.

The sentence now states only what the code shows, which is that the module is available in anonymous and user modes and is absent from asServiceRole.

Changes

Pipeline. Exposes the four types and appends them into the actors page, matching how connectors and entities carry their supporting types, so the nav keeps listing only modules. ActorSubscription and ActorClient stay unexposed on purpose: ActorSubscription already renders inline as the return type of subscribe(), and appending it too produced a duplicate unsubscribe() section.

Writing. A module overview explaining what an Actor instance actually is, a capability list, the supported authentication modes, and the lifecycle note that connections stay open until closed. Each example opens with a // comment, because the pipeline promotes that comment to the code-block title and an example without one loses its first line of code.

Links. Cross-references use explicit same-page anchors, such as [connect()](#connect).

Every type on this page is appended into it, so {@link Connection.close} resolves to Connection.mdx#close, a file the pipeline then unlinks, and it would 404. A bare {@link close} does resolve to a working anchor and is kept, which is the pattern entities uses, but that only works between members of the same interface.

A hand-written markdown anchor works across interfaces and survives the pipeline unchanged, so the cross-references are real links rather than dead code spans. All seven anchors used (#connect, #subscribe, #send, #close, #connection, #actorregistry, #actorconnectoptions) are checked against the headings on the assembled page.

Plain code spans remain in exactly two situations: the target has no heading because it is not appended (ActorNameRegistry, ActorSubscription), or the reference would point at the section it already sits in. ActorSubscription's own description is the clearest case of the latter, since it renders inside subscribe()'s Returns block and a link to subscribe() there would be circular.

Still worth a second opinion

The table above is what the SDK does. What the server does with a connection is outside this repo, so someone who owns the subsystem (#212, #260) should confirm:

  • Whether an anonymous connect outside a browser actually succeeds over the proxy fallback, or fails further upstream. The SDK will attempt it; the docs now say nothing either way.
  • Whether "a named server-side object with persistent state, addressed by id" is how you would describe an Actor to a developer meeting the concept for the first time.

Verification

  • npx tsc --noEmit clean
  • No links pointing at pages that do not exist
  • Nav still lists modules only, with actors restored to it

Pre-existing, not fixed here

Six examples in integrations.mdx and auth.mdx have no leading comment, so their first line of code is being consumed as the title and is missing from the rendered block. Four of them start with try {, so the published sample is a try block with no try. Worth its own PR, since each needs a real title written rather than a mechanical fix.

@github-actions

github-actions Bot commented Sep 6, 2026

Copy link
Copy Markdown

🚀 Package Preview Available!


Install this PR's preview build with npm:

npm i @base44-preview/sdk@0.8.46-pr.273.678702b

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.46-pr.273.678702b"

Or add it to your package.json dependencies:

{
  "dependencies": {
    "@base44/sdk": "npm:@base44-preview/sdk@0.8.46-pr.273.678702b"
  }
}

Preview published to npm registry — try new features instantly!

@github-actions github-actions Bot added the docs-draft PR has auto-drafted documentation suggestions label Sep 6, 2026
@daniellekorn
daniellekorn force-pushed the sdk-actors-docs branch 3 times, most recently from 6b31e58 to a27da6a Compare September 6, 2026 06:57
… modules

The actors page published as 18 lines: a truncated type signature, two
sentences and one snippet. connect(), subscribe(), send(), close() and
unsubscribe() did not appear at all.

Adds a module overview covering what an Actor instance is, a capability
list, the supported authentication modes, and the note that connections
stay open until closed. Every public method now has a description, @PARAM,
@returns and at least one @example, and each example opens with a comment
so the pipeline renders it as the code-block title.

Cross-references use explicit same-page anchors such as [connect()](#connect).
Every type on this page is appended into it, so {@link Connection.close}
resolves to a file the pipeline then unlinks and would 404, while a bare
{@link close} resolves to a working anchor and is kept. Plain code spans are
used only where no heading exists (ActorNameRegistry, ActorSubscription) or
where the reference would point at the section it already sits in.

Every behavioural claim is checked against src/modules/actors.ts and
src/client.ts rather than inferred. See the PR description for the
line-by-line trace.
ActorRef, Connection, ActorConnectOptions and ActorRegistry were absent
from types-to-expose.json, so every method on the actors module was
stripped before rendering and the page had nowhere to put them.

Exposes them and appends them into the actors page, matching how
connectors and entities carry their supporting types, so the nav keeps
listing only modules. ActorSubscription and ActorClient stay unexposed:
ActorSubscription already renders inline as the return type of subscribe()
and appending it too produced a duplicate unsubscribe() section.

Also drops the actors suppression added while the JSDoc was missing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs-draft PR has auto-drafted documentation suggestions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant