@recursiv/sdk 0.7.50 → 0.7.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -74,7 +74,7 @@ for await (const chunk of r.agents.chatStream(agent.id, { message: 'Hello!' }))
74
74
  ### AI Agents
75
75
  | Resource | Key methods |
76
76
  |----------|------------|
77
- | `r.agents` | `create`, `update`, `chat`, `chatStream`, `grantProjectAccess`, `conversations` |
77
+ | `r.agents` | `create`, `update`, `chat`, `chatStream`, `retryChatStream`, `grantProjectAccess`, `conversations` |
78
78
  | `r.e2ee` | `registerDevice`, `devices`, `revokeDevice`, `publishKeyPackages`, `keyPackageStatus`, `claimKeyPackage`, `appendEvent`, `events`, `acknowledge` (flag-gated E2EE v2 transport) |
79
79
  | `r.brain` | `sendMessage` |
80
80
  | `r.commands` | `execute`, `gatePrompt` |
@@ -84,34 +84,37 @@ for await (const chunk of r.agents.chatStream(agent.id, { message: 'Hello!' }))
84
84
  ### Identity & Auth
85
85
  | Resource | Key methods |
86
86
  |----------|------------|
87
- | `r.auth` | `signUp`, `signIn`, `getSession`, `signOut`, `createApiKey` (session reads/sign-out use explicit Bearer auth with a native/server Cookie fallback) |
87
+ | `r.auth` | `signUp`, `signIn`, `signInWithUsername`, `getSession`, `signOut`, `createApiKey`, `forgetPassword`, `resetPassword`; two-factor: `enableTwoFactor`, `verifyTwoFactor`, `disableTwoFactor`, `regenerateTwoFactorBackupCodes`, `requestTwoFactorEmailCode`, `completeTwoFactorSignIn`; OAuth consent: `exchangeSessionForCookie`, `getOAuthClientInfo` (session calls use explicit Bearer auth with a native/server Cookie fallback) |
88
88
  | `@recursiv/sdk/next` | `createRecursivAuth` — cookie-session server auth for Next.js App Router (see below) |
89
89
  | `r.users` | `me`, `get` |
90
90
  | `r.organizations` | `create`, `members`, `addMember`, `invite` |
91
- | `r.profiles` | `me`, `get`, `search`, `follow`, `unfollow` |
91
+ | `r.profiles` | `me`, `get`, `search`, `mentions`, `follow`, `unfollow`, `followers`/`following` (rows carry `is_following`, `follows_you`), `followingIds`, `block`, `unblock`, `blocked`, `mute`, `unmute`, `muted` |
92
92
 
93
93
  ### Social
94
94
  | Resource | Key methods |
95
95
  |----------|------------|
96
- | `r.posts` | `create`, `update`, `list`, `liked`, `search`, `react` |
97
- | `r.communities` | `create`, `join`, `members` |
98
- | `r.chat` | `send`, `dm`, `createGroup`, `messages` |
96
+ | `r.posts` | `create`, `update`, `list`, `liked`, `search`, `replies`, `react` |
97
+ | `r.communities` | `create`, `join`, `search`, `members` |
98
+ | `r.chat` | `send`, `dm`, `createGroup`, `messages` (cursor paging), `acceptRequest`, `declineRequest`, `leave`, `deleteConversation` |
99
99
  | `r.tags` | `create`, `list` |
100
100
  | `r.uploads` | `uploadMedia` — upload post/chat bytes end to end |
101
+ | `r.video` | `entitlement` (may the caller publish video, and how much is left), `createUpload`, `getStatus`, `getPlaybackToken` |
101
102
 
102
103
  ### Platform
103
104
  | Resource | Purpose |
104
105
  |----------|---------|
105
- | `r.settings` | User preferences (including app-scoped content choices), sessions, password management |
106
+ | `r.settings` | User preferences (including app-scoped content choices), sessions (`revokeOtherSessions` keeps this device), password management, email change (`requestConfirmationCode` for accounts with no password) |
106
107
  | `r.billing` | Usage tracking, subscriptions, checkout |
107
- | `r.appSubscriptions` | Consumer app plans: `checkout`, `status`, `createPortalSession` |
108
- | `r.notifications` | Push notification tokens |
108
+ | `r.appSubscriptions` | Consumer app plans: `checkout`, `status`, `createPortalSession`, `previewTierChange`, `changeTier` |
109
+ | `r.boosts` | Promoted posts: `create`, `mine`, `balance`, `pause`, `resume`, `cancel`, `recordEvent`, `topup`, `confirmTopup`; admin `listPendingReview`, `review`, `grant` |
110
+ | `r.wallet` | Wallet, MINDS tokens (`getTokenBalance`, `getTokenLedger`), USD payouts (`getPayouts`, `startPayoutOnboarding`, `payoutLoginLink`) |
111
+ | `r.notifications` | Notification stream (`list`, `unreadCount`, `markAsRead`, `archive`, `markAllAsRead`) and push tokens |
109
112
  | `r.github` | GitHub integration |
110
113
  | `r.integrations` | External service connections |
111
114
  | `r.admin` | User management, stats, content reports (`listReports`, `resolveReport`, `dismissReport`) |
112
115
  | `r.dispatcher` | Task queue, claims, signals, outcomes, webhooks |
113
116
  | `r.goals` | Org goals with task rollups (group dispatcher tasks) |
114
- | `r.protocols` | Private Minds safety: `sourceControls` (current enablement and saved choices), `setSourceControl`, `onSourceControlChange`, `reportSource`. Delegated accounts: `nativeSocialAccounts`, `startNativeSocialConnection`, `finishNativeSocialConnection`, `disconnectNativeSocialAccount`. Native follows: `nativeFollowState`, `prepareNativeFollow`, `submitNativeFollow`, `nativeFollowStatus` (native following or pending approval, distinct from a Minds feed subscription; preserve the complete signed Nostr list). Native reposts and undo: `nativeRepostState`, `prepareNativeRepost`, `submitNativeRepost`, `nativeRepostStatus` (public posts, explicit approval, connected account, no uncertain retries). Native likes and unlikes: `nativeLikeState`, `prepareNativeLike`, `submitNativeLike`, `nativeLikeStatus` (connected authority, app enablement and explicit approval; resume pending actions instead of duplicating them). Reviewed replies and optional linked posts: `prepareNativeReply`, `submitNativeReply`, `nativeReplyStatus`, `nativeReplyHistory`, `prepareNativeReplyRemoval`, `removeNativeReply` (require deployed API support and app enablement). Keyless shared post links: `sharedNetworks(projectId)`, `getSharedConversation(projectId, { protocol, post, readRef? })`. Member public reading: `searchPublicPosts` (selected account required for Bluesky/ActivityPub; public Nostr search), `getConnectedSocialConversation` (preserve result readerAccountId/readRef), `publicNetworks`, `searchPublicProfiles`, `getPublicProfile`, `getPublicAuthorFeed`, `getFollowingFeed`, `getPublicConversation`, `getPublicTrends`, `getPublicTrendFeed`; private app subscriptions: `listSubscriptions`, `subscribeToProfile`, `unsubscribeFromProfile`, `onSubscriptionChange`. `list` returns bounded adapter `maturity`, `limitations`, and exhaustive `supported`/`planned`/`unsupported` implementation capabilities (not provider health or enablement); settings, candidate refresh/status, search, and read-only quarantined candidate review via `listCandidates` / `getCandidate` |
117
+ | `r.protocols` | Private Minds safety: `sourceControls` (current enablement and saved choices; filter with `control`, each item may carry a `display` label), `setSourceControl`, `onSourceControlChange`, `reportSource`. Delegated accounts: `nativeSocialAccounts`, `startNativeSocialConnection`, `finishNativeSocialConnection`, `disconnectNativeSocialAccount`. Native follows: `nativeFollowStates` (every connected account's state for one source, one read), `nativeFollowState`, `prepareNativeFollow`, `submitNativeFollow`, `nativeFollowStatus` (native following or pending approval, distinct from a Minds feed subscription; preserve the complete signed Nostr list). Native reposts and undo: `nativeRepostState`, `prepareNativeRepost`, `submitNativeRepost`, `nativeRepostStatus` (public posts, explicit approval, connected account, no uncertain retries). Native likes and unlikes: `nativeLikeState`, `prepareNativeLike`, `submitNativeLike`, `nativeLikeStatus` (connected authority, app enablement and explicit approval; resume pending actions instead of duplicating them). Reviewed replies and optional linked posts: `prepareNativeReply`, `submitNativeReply`, `nativeReplyStatus`, `nativeReplyHistory`, `prepareNativeReplyRemoval`, `removeNativeReply` (require deployed API support and app enablement). Keyless shared post links: `sharedNetworks(projectId)`, `getSharedConversation(projectId, { protocol, post, readRef? })`. Member public reading: `searchPublicPosts` (selected account required for Bluesky/ActivityPub; public Nostr search), `getConnectedSocialConversation` (preserve result readerAccountId/readRef), `publicNetworks`, `searchPublicProfiles`, `getPublicProfile`, `getPublicAuthorFeed`, `getFollowingFeed`, `getPublicConversation`, `getPublicTrends`, `getPublicTrendFeed`; radar stories: `getPublicRadarStory` (one story by id with its posts), keyless `getSharedRadarStory(projectId, { cluster })` and `getSharedRadarPosts(projectId, { cluster })`; private app subscriptions: `listSubscriptions`, `subscribeToProfile`, `unsubscribeFromProfile`, `onSubscriptionChange`. `list` returns bounded adapter `maturity`, `limitations`, and exhaustive `supported`/`planned`/`unsupported` implementation capabilities (not provider health or enablement); settings, candidate refresh/status, search, and read-only quarantined candidate review via `listCandidates` / `getCandidate` |
115
118
 
116
119
  Full reference: see [llm.md](./llm.md) (ships with this package) or the type definitions in `dist/`.
117
120
 
@@ -472,6 +475,25 @@ participant selection is unfinished. `textTruncated` labels an abbreviated sourc
472
475
  preview. Preparation and submission never automatically retry; check the event ID
473
476
  after an uncertain result before choosing a retry of the identical signed event.
474
477
 
478
+ ### A Bluesky account on the app's own PDS
479
+
480
+ `createHostedIdentity` asks the app's own PDS to issue a Bluesky account for the
481
+ signed-in member. Only the label is sent; the app picks the domain.
482
+
483
+ ```ts
484
+ const { data: identity } = await r.protocols.createHostedIdentity({
485
+ protocol: 'atproto', handle: 'alice', email: 'alice@example.com',
486
+ })
487
+ // identity.handle is e.g. 'alice.pds.minds.com'. identity.password exists only in
488
+ // this response: show it to the member once and store it nowhere.
489
+ ```
490
+
491
+ The server either finishes the account or removes it again, so a failure never
492
+ leaves one half made. The call is never retried automatically. `handle_unavailable`
493
+ (409) means choose another label; the 503 codes `handle_dns_unavailable`,
494
+ `handle_unresolvable` and `handle_unverified` are operator setup and succeed
495
+ unchanged once it is done.
496
+
475
497
  ### Delegated Bluesky and ActivityPub accounts
476
498
 
477
499
  These methods require the same signed-in human app key throughout. The API must
@@ -497,6 +519,18 @@ native token is sent through these SDK methods. Start and callback are single-us
497
519
  requests and are never automatically retried. If a callback result is uncertain,
498
520
  refresh the account list before starting again.
499
521
 
522
+ In a native app, use the operator-configured native callback instead of the web
523
+ one when `nativeSocialAccounts()` lists the protocol in `nativeRedirects`:
524
+
525
+ ```ts
526
+ const { data: start } = await r.protocols.startNativeSocialConnection({
527
+ protocol: 'bluesky', identifier: 'alice.bsky.social', redirect: 'native',
528
+ })
529
+ const result = await WebBrowser.openAuthSessionAsync(start.authorizationUrl, start.callbackUrl)
530
+ // In the native callback route, read state, code, iss (or error) from result.url:
531
+ await r.protocols.finishNativeSocialConnection({ protocol: 'bluesky', state, code, iss })
532
+ ```
533
+
500
534
  Connection does not approve publication. The account's `capabilities` lists only
501
535
  implemented actions, currently empty for these adapters. Local disconnect takes
502
536
  effect even when `providerRevocation` is `unconfirmed`; the user can also revoke
@@ -594,6 +628,8 @@ blocks/mutes as well. All reply and account endpoints still require authenticati
594
628
 
595
629
  Standalone public publication uses `protocols.prepareNativePost({ clientMutationId, text, accountIds, media? })`, then explicitly approved `submitNativePost`. Keep the same mutation ID after uncertain preparation; previously attempted deliveries are reconciled without resending. `nativePostStatus` and paginated `nativePostHistory` expose private app/user-owned outcomes. Review current own posts with `prepareNativePostRemoval`, then approve exact removal IDs through `removeNativePost`. Check connected-account `publish_text` capabilities; only explicitly enabled apps may publish. Text is sent unchanged, public only, with each provider’s actual limits. Optional `media` is a `NativeMediaInput[]` of at most four already-uploaded Minds images (`{ url, alt?, width?, height?, mimeType? }`, JPEG/PNG/WebP/GIF, Minds-hosted HTTPS URLs only, a Mastodon GIF must be the only attachment). It additionally requires the account's `publish_media` capability; accounts connected before image permissions existed must reconnect. Pass the member's own `alt` — an omitted one is sent as an empty description, never an invented one — and read `receipt.media` (`{ count, alt_missing }`) after sending. These methods still do not accept a reply parent or caller-supplied authority.
596
630
 
631
+ To delete a post everywhere, link its network copies when you cross-post: pass `crossPostOf: post.id` (the member's own post in this app, from `sdk.posts`) to `prepareNativePost` and to `prepareNativeNostr(id, { action: 'publish', content, crossPostOf })`. Later, `nativePostHistory({ crossPostOf: post.id })` lists exactly that post's copies, each with `crossPostOf` set: delegated items are removed with `prepareNativePostRemoval`/`removeNativePost`, and `type: 'nostr'` items (original notes, which this SDK's history lists; the REST route returns them only with `include=nostr` or `crossPostOf`, so older apps keep the delegated-only shape) with the Nostr signing flow (`prepareNativeNostr(identityId, { action: 'delete', postId: eventId })`). Another member's post, or one from another app, answers `not_found`; copies prepared without `crossPostOf` stay unlinked.
632
+
597
633
  For Bluesky accounts advertising `quote`, prepare the same publication with `quote: { protocol: 'bluesky', nativeId: sourceAtUri }`. The server resolves the exact source CID using each connected account, checks quote permission and Minds safety, and rechecks before writing. Review each delivery’s `quote` alongside the account and comment before submitting. Changed or unavailable sources cannot publish; uncertain deliveries reconcile the original record key. ActivityPub/Nostr quotes are not provided by this method. Public post reads include at most one filtered `quote` with `state: 'available'` and `post`, or `state: 'unavailable'` without source content. Available quotes may include `embeddedReferences`: exact standalone source-reference lines in the unchanged outer `text`. Omit them only when the quoted original is actually visible; retain them for unavailable or locally hidden quotes. Nostr references are decoded and matched by the server, without following relay hints.
598
634
 
599
635
  Topic browsing can request `getPublicTrends({ protocol: "bluesky", includePreviews: true })`. Optional `SocialTrend.preview` is a real image-bearing post from that topic, never a generated illustration. The server samples at most eight posts for each of ten topics, with three concurrent reads and a shared 2.5-second deadline; missing images leave usable text topics. App moderation and user source controls filter previews on every request. Bluesky CDN image attachments, quote-with-media images, and unlabeled link-preview thumbnails are supported; omitted content retains the source link.
package/dist/index.d.ts CHANGED
@@ -51,6 +51,7 @@ import { SwarmsResource } from './resources/swarms.js';
51
51
  import { TemplatesResource } from './resources/templates.js';
52
52
  import { VideoResource } from './resources/video.js';
53
53
  import { AppSubscriptionsResource } from './resources/app-subscriptions.js';
54
+ import { BoostsResource } from './resources/boosts.js';
54
55
  import { MediaResource } from './resources/media.js';
55
56
  import { WebhooksResource } from './resources/webhooks.js';
56
57
  import { JobsResource } from './resources/jobs.js';
@@ -119,6 +120,7 @@ export declare class Recursiv {
119
120
  readonly discovery: DiscoveryResource;
120
121
  readonly video: VideoResource;
121
122
  readonly appSubscriptions: AppSubscriptionsResource;
123
+ readonly boosts: BoostsResource;
122
124
  readonly reports: ReportsResource;
123
125
  readonly moderation: ModerationResource;
124
126
  readonly linkPreview: LinkPreviewResource;
@@ -137,8 +139,9 @@ export declare class Recursiv {
137
139
  }
138
140
  export { HttpClient } from './client.js';
139
141
  export { RealtimeClient } from './realtime.js';
142
+ export type { RealtimeConnectOptions } from './realtime.js';
140
143
  export { AuthResource } from './resources/auth.js';
141
- export type { AuthSession, SignUpInput, SignInInput, SendOtpInput, VerifyOtpInput, CreateApiKeyInput, ApiKeyResult } from './resources/auth.js';
144
+ export type { AuthSession, SignUpInput, SignInInput, UsernameSignInInput, AppContext, ResetPasswordInput, TwoFactorConfirmation, TwoFactorEnrollment, TwoFactorChallenge, CompleteTwoFactorSignInInput, OAuthClientInfo, SendOtpInput, VerifyOtpInput, CreateApiKeyInput, ApiKeyResult, } from './resources/auth.js';
142
145
  export { PostsResource } from './resources/posts.js';
143
146
  export { UsersResource } from './resources/users.js';
144
147
  export { CommunitiesResource } from './resources/communities.js';
@@ -155,7 +158,7 @@ export { SandboxResource } from './resources/sandbox.js';
155
158
  export { ProfilesResource } from './resources/profiles.js';
156
159
  export { OrganizationsResource } from './resources/organizations.js';
157
160
  export { NotificationsResource } from './resources/notifications.js';
158
- export type { Notification, ListNotificationsParams, NotificationListResponse } from './resources/notifications.js';
161
+ export type { Notification, NotificationActor, NotificationCategory, NotificationPostPreview, NotificationScopeParams, NotificationUnreadCount, ListNotificationsParams, NotificationListResponse, } from './resources/notifications.js';
159
162
  export { SettingsResource } from './resources/settings.js';
160
163
  export { BillingResource } from './resources/billing.js';
161
164
  export { FreeTierResource } from './resources/free-tier.js';
@@ -177,9 +180,9 @@ export { WebhooksResource } from './resources/webhooks.js';
177
180
  export { JobsResource } from './resources/jobs.js';
178
181
  export { CuratorResource } from './resources/curator.js';
179
182
  export { VideoResource } from './resources/video.js';
180
- export type { VideoUploadCreds, CreateVideoUploadResult, VideoStatusInfo, VideoPlaybackToken, } from './resources/video.js';
183
+ export type { VideoUploadCreds, CreateVideoUploadResult, VideoStatusInfo, VideoPlaybackToken, VideoEntitlement, } from './resources/video.js';
181
184
  export { AppSubscriptionsResource } from './resources/app-subscriptions.js';
182
- export type { AppSubscriptionCheckoutResult, AppSubscriptionPortalResult, AppSubscriptionStatusResult, } from './resources/app-subscriptions.js';
185
+ export type { AppSubscriptionCheckoutResult, AppSubscriptionPortalResult, AppSubscriptionStatusResult, AppSubscriptionTierChangePreview, AppSubscriptionTierChangeResult, } from './resources/app-subscriptions.js';
183
186
  export type { CuratorSource, CuratorPrompt, CuratorRunInput, CuratorRunResult, CuratorTodayEdition, CuratorTodayExcerpt, CuratorTodayLeadImage, CuratorTodayRadar, CuratorTodayReaction, CuratorTodayResponse, CuratorTodaySource, CuratorTodayStory, } from './resources/curator.js';
184
187
  export { ReportsResource } from './resources/reports.js';
185
188
  export type { ReportTargetType, ReportStatus, CreateReportInput, ReportRecord, ResolveReportInput, } from './resources/reports.js';
@@ -196,9 +199,12 @@ export { OrganizationSecurityResource } from './resources/organization-security.
196
199
  export { UploadsResource } from './resources/uploads.js';
197
200
  export type { UploadMediaInput, UploadUrlInput, UploadUrlResult } from './resources/uploads.js';
198
201
  export { WalletResource } from './resources/wallet.js';
202
+ export type { LinkedTokenWallet, PayoutState, TokenBalance, TokenLedgerEntry } from './resources/wallet.js';
203
+ export { BoostsResource } from './resources/boosts.js';
204
+ export type { BoostBalance, BoostBalanceResponse, BoostCampaign, BoostCampaignResponse, BoostEventResult, BoostLedgerEntry, BoostLedgerKind, BoostRejectionReason, BoostReviewStatus, BoostStatus, BoostTopupCheckout, BoostTopupConfirmation, BoostTopupLimits, } from './resources/boosts.js';
199
205
  export { ProtocolsResource } from './resources/protocols.js';
200
206
  export { PROTOCOL_ADAPTER_MATURITIES, PROTOCOL_CAPABILITY_OPERATIONS, PROTOCOL_CAPABILITY_STATUSES, } from './resources/protocols.js';
201
- export type { SocialProfile, SocialSubscription, SocialSubscriptionChange, SocialProfilePage, SocialNetwork, SocialPost, SocialConversation, SocialTrend, SocialTrendProvenance, SocialTrends, SocialTrendFeed, SocialPopularProfiles, SocialAuthorFeed, SocialFollowingFeed, SocialFollowingSource, SearchPublicProfilesParams, SearchPublicPostsParams, SocialPostSearch, HostedProtocolConnections, HostedProtocol, HostedProtocolIdentity, HostedNostrChallenge, HostedNostrIdentityProof, NativeNostrPrepareInput, NativeNostrPrepared, NativeNostrAccount, NativeNostrPostState, NativeNostrReceipt, NativeSocialProtocol, FederationIdentity, FederationIdentityView, NativeSocialAccount, NativeSocialCallbackInput, NativeReplyPrepareInput, NativePostPrepareInput, NativeMediaInput, NativeMediaItem, NativePostBatch, NativePostHistory, NativeFollowSourceInput, NativeFollowPrepareInput, NativeFollowTarget, NativeFollowReceipt, NativeFollowState, NativeFollowReview, NativeLikeSourceInput, NativeRepostSourceInput, NativeLikePrepareInput, NativeRepostPrepareInput, NativeLikeTarget, NativeRepostTarget, NativeLikeReceipt, NativeRepostReceipt, NativeLikeState, NativeRepostState, NativeLikeReview, NativeRepostReview, NativeReplyReceipt, NativeReplyBatch, NativeReplyHistory, NativeDelegatedReplyHistoryItem, NativeNostrReplyResult, NativeNostrReplyHistoryItem, NativeReplyRemovalReceipt, NativeReplyRemovalPreview, SocialSourceRef, SocialSourceControl, SocialSourceControlChange, HostedPostPreview, ConnectHostedIdentityInput, PreviewHostedPostInput, PublishHostedPostInput, ListProtocolCandidatesParams, ProtocolAdapterMaturity, ProtocolAdapterMetadata, ProtocolCandidateListResponse, ProtocolCandidatePageMeta, ProtocolCapabilityOperation, ProtocolCapabilityStatus, ProtocolCollectionStatus, ProtocolIngestionReplayResult, ProtocolIngestionStatus, ProtocolQuarantinedCandidate, ProtocolRefreshResult, ProtocolSettings, ProtocolSettingsUpdateResult, ReplayProtocolIngestionJobInput, UpdateSettingsInput as UpdateProtocolSettingsInput, } from './resources/protocols.js';
207
+ export type { SocialProfile, SocialSubscription, SocialSubscriptionChange, SocialProfilePage, SocialRadar, SocialRadarCluster, SocialRadarMember, SocialRadarParams, SocialRadarPosts, SocialRadarStory, SocialNetwork, SocialPost, SocialConversation, SocialTrend, SocialTrendProvenance, SocialTrends, SocialTrendSourceIndex, SocialTrendFeed, SocialPopularProfiles, SocialAuthorFeed, SocialFollowingFeed, SocialFollowingSource, SearchPublicProfilesParams, SearchPublicPostsParams, SocialPostSearch, HostedProtocolConnections, HostedProtocol, HostedProtocolIdentity, HostedNostrChallenge, HostedNostrIdentityProof, NativeNostrPrepareInput, NativeNostrPrepared, NativeNostrAccount, NativeNostrPostState, NativeNostrReceipt, NativeSocialProtocol, FederationIdentity, FederationIdentityView, NativeSocialAccount, NativeSocialCallbackInput, NativeReplyPrepareInput, NativePostPrepareInput, NativeMediaInput, NativeMediaItem, NativePostBatch, NativePostHistory, NativeDelegatedPostHistoryItem, NativeNostrPostHistoryItem, NativeFollowSourceInput, NativeFollowPrepareInput, NativeFollowTarget, NativeFollowReceipt, NativeFollowState, NativeFollowAccount, NativeFollowStates, NativeFollowReview, NativeLikeSourceInput, NativeRepostSourceInput, NativeLikePrepareInput, NativeRepostPrepareInput, NativeLikeTarget, NativeRepostTarget, NativeLikeReceipt, NativeRepostReceipt, NativeLikeState, NativeRepostState, NativeLikeReview, NativeRepostReview, NativeReplyReceipt, NativeReplyBatch, NativeReplyHistory, NativeDelegatedReplyHistoryItem, NativeNostrReplyResult, NativeNostrReplyHistoryItem, NativeReplyRemovalReceipt, NativeReplyRemovalPreview, SocialSourceRef, SocialSourceControl, SocialSourceControlDisplay, SocialSourceControlChange, HostedPostPreview, ConnectHostedIdentityInput, CreateHostedIdentityInput, CreatedHostedProtocolIdentity, PreviewHostedPostInput, PublishHostedPostInput, ListProtocolCandidatesParams, ProtocolAdapterMaturity, ProtocolAdapterMetadata, ProtocolCandidateListResponse, ProtocolCandidatePageMeta, ProtocolCapabilityOperation, ProtocolCapabilityStatus, ProtocolCollectionStatus, ProtocolIngestionReplayResult, ProtocolIngestionStatus, ProtocolQuarantinedCandidate, ProtocolRefreshResult, ProtocolSettings, ProtocolSettingsUpdateResult, ReplayProtocolIngestionJobInput, UpdateSettingsInput as UpdateProtocolSettingsInput, } from './resources/protocols.js';
202
208
  export { InboxResource } from './resources/inbox.js';
203
209
  export { NetworkResource } from './resources/network.js';
204
210
  export { SimulatorResource } from './resources/simulator.js';
package/dist/index.js CHANGED
@@ -52,6 +52,7 @@ import { SwarmsResource } from './resources/swarms.js';
52
52
  import { TemplatesResource } from './resources/templates.js';
53
53
  import { VideoResource } from './resources/video.js';
54
54
  import { AppSubscriptionsResource } from './resources/app-subscriptions.js';
55
+ import { BoostsResource } from './resources/boosts.js';
55
56
  import { MediaResource } from './resources/media.js';
56
57
  import { WebhooksResource } from './resources/webhooks.js';
57
58
  import { JobsResource } from './resources/jobs.js';
@@ -120,6 +121,7 @@ export class Recursiv {
120
121
  discovery;
121
122
  video;
122
123
  appSubscriptions;
124
+ boosts;
123
125
  reports;
124
126
  moderation;
125
127
  linkPreview;
@@ -182,6 +184,7 @@ export class Recursiv {
182
184
  this.discovery = new DiscoveryResource(this.posts, this.protocols);
183
185
  this.video = new VideoResource(client);
184
186
  this.appSubscriptions = new AppSubscriptionsResource(client);
187
+ this.boosts = new BoostsResource(client);
185
188
  this.reports = new ReportsResource(client);
186
189
  this.moderation = new ModerationResource(client);
187
190
  this.linkPreview = new LinkPreviewResource(client);
@@ -246,6 +249,7 @@ export { ProjectSettingsResource } from './resources/project-settings.js';
246
249
  export { OrganizationSecurityResource } from './resources/organization-security.js';
247
250
  export { UploadsResource } from './resources/uploads.js';
248
251
  export { WalletResource } from './resources/wallet.js';
252
+ export { BoostsResource } from './resources/boosts.js';
249
253
  export { ProtocolsResource } from './resources/protocols.js';
250
254
  export { PROTOCOL_ADAPTER_MATURITIES, PROTOCOL_CAPABILITY_OPERATIONS, PROTOCOL_CAPABILITY_STATUSES, } from './resources/protocols.js';
251
255
  export { InboxResource } from './resources/inbox.js';
@@ -53,32 +53,102 @@ export interface RealtimeConnectOptions {
53
53
  * Use this when the API key must stay server-side (cookie-auth web apps):
54
54
  * expose a same-origin route that mints the token with the server-held key
55
55
  * and pass its fetcher here. Default: fetch with this client's own key
56
- * (REST `/realtime/ws-token`, tRPC fallback).
56
+ * (REST `/realtime/ws-token`).
57
+ *
58
+ * Throw an error whose `status` is 401 or 403 when the credential itself is
59
+ * refused; the client then stops reconnecting until `connect()` is called
60
+ * again. Returning `undefined` (or throwing anything else) counts as a
61
+ * transient failure and is retried with backoff.
57
62
  */
58
63
  getToken?: () => Promise<string | undefined>;
64
+ /** First reconnect delay in ms. Default 2000. */
65
+ reconnectionDelay?: number;
66
+ /** Longest reconnect delay in ms. Default 30000. */
67
+ reconnectionDelayMax?: number;
68
+ /** Jitter applied to each reconnect delay, as a fraction of it (0 to 1). Default 0.5. */
69
+ randomizationFactor?: number;
59
70
  }
71
+ /**
72
+ * WebSocket client for chat and presence.
73
+ *
74
+ * One socket at a time, and it survives the ways a socket dies:
75
+ * - a transport drop (network blip, sleep, backgrounding, API restart) is
76
+ * retried by socket.io with jittered backoff;
77
+ * - the server ending the connection because its token expired, or refusing
78
+ * a reconnect handshake (spent or expired token, rate limit), is retried
79
+ * here with the same backoff, since socket.io does not retry either;
80
+ * - every attempt authenticates with its own token (the server accepts each
81
+ * token once), and a failed token fetch sends none rather than a spent one;
82
+ * - listeners registered with `on()`/`onMessage()`… and rooms joined with
83
+ * `joinConversation()` are re-applied to every connection, including a
84
+ * socket rebuilt by a later `connect()`.
85
+ *
86
+ * Reconnecting stops only on `disconnect()` or when the token source refuses
87
+ * the credential (401/403).
88
+ */
60
89
  export declare class RealtimeClient {
61
90
  private socket;
62
91
  private client;
63
92
  private connectionPromise;
64
93
  private tokenProvider;
94
+ private backoff;
95
+ /** Every subscription, attached to each socket this client builds. */
96
+ private readonly listeners;
97
+ /** Conversation rooms to join on every connect. */
98
+ private readonly rooms;
99
+ /** connect() callers waiting on a socket that is reconnecting. */
100
+ private waiters;
101
+ private recoveryTimer;
102
+ private recoveryAttempts;
103
+ private credentialRefused;
104
+ /** Bumped by disconnect(), so a connect() still in flight does not revive a socket. */
105
+ private generation;
106
+ /**
107
+ * The socket whose first handshake a connect() is awaiting. Closing a socket
108
+ * that never connected makes socket.io emit nothing, so discardSocket()
109
+ * settles that connect() through this.
110
+ */
111
+ private pendingOpen;
65
112
  constructor(client: HttpClient);
66
113
  private fetchTokenWithClientKey;
114
+ /** A token for one reconnect attempt. Never throws: no token means the attempt is refused and retried. */
115
+ private mintToken;
67
116
  /**
68
117
  * Connects to the WebSocket server using a temporary WebSocket token.
118
+ * Resolves with the connected socket.
69
119
  *
70
- * Reconnect-safe by design:
71
- * - the connection promise is cleared after settling, so a later call
72
- * builds a fresh socket instead of returning a dead one;
73
- * - `connect_error` only tears down the INITIAL attempt — after the first
74
- * successful connect, socket.io's auto-reconnection owns recovery and
75
- * transient errors never disable it;
76
- * - auth uses socket.io's function form, so every (re)connection attempt
77
- * fetches a fresh token via `options.getToken` or the client's key.
120
+ * Safe to call as often as you like: a connected socket is returned as is,
121
+ * a socket that is reconnecting is waited on (the promise rejects if that
122
+ * attempt fails, while the client keeps retrying), and only a socket that
123
+ * has stopped for good is replaced.
78
124
  */
79
125
  connect(options?: RealtimeConnectOptions): Promise<Socket>;
126
+ private applyBackoff;
127
+ private openSocket;
128
+ /** Room rejoin, waiter settlement and recovery from the disconnects socket.io leaves alone. */
129
+ private watchLifecycle;
130
+ private scheduleRecovery;
131
+ /** Exponential backoff with jitter, bounded by reconnectionDelayMax. */
132
+ private recoveryDelay;
133
+ private waitForConnect;
134
+ private discardSocket;
135
+ /**
136
+ * Close the connection and stop reconnecting. Joined rooms are forgotten;
137
+ * listeners stay registered and attach to the next connection.
138
+ */
80
139
  disconnect(): void;
81
140
  getSocket(): Socket | null;
141
+ /**
142
+ * Listen for any server event, including the lifecycle events `connect`
143
+ * (initial and every reconnect: refetch what you may have missed) and
144
+ * `disconnect`. The listener stays attached across reconnects and socket
145
+ * replacement. Returns an unsubscribe function.
146
+ *
147
+ * Server events include `notification`, `feed_update`,
148
+ * `conversation_created`, `chat_message`, `chat_typing` and `agent_thinking`.
149
+ */
150
+ on<T = unknown>(event: string, listener: (payload: T) => void): () => void;
151
+ /** Join a conversation room now, and again after every reconnect, until you leave it. */
82
152
  joinConversation(conversationId: string): void;
83
153
  leaveConversation(conversationId: string): void;
84
154
  sendTyping(conversationId: string): void;