deepspace 0.22.1 → 0.23.0

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/dist/index.d.ts CHANGED
@@ -659,6 +659,17 @@ declare const ROLE_ANONYMOUS = "viewer";
659
659
  declare const ROLE_DEFAULT = "member";
660
660
  /** Admin role */
661
661
  declare const ROLE_ADMIN = "admin";
662
+ /**
663
+ * Reported when a record id resolves to nothing.
664
+ *
665
+ * This crosses the DO boundary as a response body and callers branch on it,
666
+ * so it is a contract rather than prose. `getChat` in particular treats it as
667
+ * "no such chat" and returns null — the same answer it gives for a chat owned
668
+ * by someone else, which is what stops chat ids being enumerable. If a room
669
+ * reworded this independently, a miss would start throwing while a cross-user
670
+ * hit kept returning null, and that difference is an existence oracle.
671
+ */
672
+ declare const RECORD_NOT_FOUND = "Record not found";
662
673
 
663
674
  /**
664
675
  * Typed wire-protocol layer — discriminated unions, typed builders, and a
@@ -2820,10 +2831,14 @@ interface RoomUser {
2820
2831
  lastSeenAt?: string;
2821
2832
  }
2822
2833
  type RoomConnectionState = 'connecting' | 'connected' | 'disconnected';
2823
- /** A server-rejected optimistic write. */
2834
+ /** A rejected optimistic write. */
2824
2835
  interface WriteError {
2825
- /** RBAC denial or data validation/other rejection. */
2826
- kind: 'permission' | 'validation';
2836
+ /**
2837
+ * `permission` — RBAC denial; `validation` — data validation/other server
2838
+ * rejection; `not_ready` — rejected client-side because the room could not
2839
+ * accept writes yet (gate the control on `ready` from `useMutations()`).
2840
+ */
2841
+ kind: 'permission' | 'validation' | 'not_ready';
2827
2842
  /** Short human-readable summary, safe to show end users. */
2828
2843
  title: string;
2829
2844
  /** Longer human-readable explanation; may be empty. */
@@ -2841,8 +2856,9 @@ interface RecordProviderProps {
2841
2856
  /** Auth token provider for WS connections. */
2842
2857
  getAuthToken?: () => Promise<string | null>;
2843
2858
  /**
2844
- * Receives server-rejected optimistic writes. Wire this to app UI so users
2845
- * see denied or invalid changes. Defaults to a deduplicated console error.
2859
+ * Receives every rejected write — denied or invalid by the server, and
2860
+ * attempted before the room was ready. Wire this to app UI so users see
2861
+ * changes that didn't land. Defaults to a deduplicated console error.
2846
2862
  */
2847
2863
  onWriteError?: (error: WriteError) => void;
2848
2864
  }
@@ -5057,4 +5073,4 @@ declare const ACCOUNT_STORAGE_LIMIT_BYTES: {
5057
5073
  declare function storageLimitForTier(tier: string | null | undefined): number;
5058
5074
  declare function formatBytes(bytes: number): string;
5059
5075
 
5060
- export { ACCOUNT_STORAGE_LIMIT_BYTES, APP_LOG_EVENT_KEYS, ASYNC_RESOURCE_DEFAULTS, type AdHocChargeOpts, type AiStreamAction, type AiStreamChunk, type ApiErrorIssue, type AppLogEvent, type AppLogEventKey, type AppLogsResponse, type AppMigrationIdsValidation, type AsyncResourceDefaults, type AsyncResourceState, type AsyncResourceStatus, AuthGate, type AuthGateProps, AuthOverlay, Awareness, type AwarenessState, type AwarenessStates, type BaseMessage, type CanvasShapeClient, type Channel, type ChannelInvitation, type ChannelMember, type ChargeOnceOpts, type ChargeOnceResult, type ClientErrorKind, type ClientErrorReport, type ClientErrorReporterOptions, type ClientMessage, type CollectionSchema, type ConnectionAttachment, type ConnectionStatus, type ContentSegment, type ConversationObject, type CronHistoryEntry, type CronMutationResult, type CronTaskState, DEEPSPACE_AGENT_PROFILES, DEEPSPACE_AI_DEFAULTS, DEEPSPACE_AI_MODELS, DEEPSPACE_MODEL_CATALOG_PROVENANCE, DEEPSPACE_THEME_PROPERTIES, DEFAULT_USER_COLORS, type DeepSpaceAIModel, type DeepSpaceAIModelId, type DeepSpaceAIProvider, type DeepSpaceAgentProfile, type DeepSpaceAgentProfileId, type DeepSpaceAgentSupport, DeepSpaceAuthProvider, type DeepSpaceThemeConfig, DeepSpaceThemeProvider, type DeepSpaceThemeProviderProps, type DeriveLoadStateInput, ENV, type Environment, type FileAttachment, type GroupedReaction, GuestBanner, type HandlerContext, type InboxEntry, type IntegrationResponse, type JobStatusView, type JobView, LOG_LEVELS, type LinkPreviewData, type LoadState, type LoadStateAuthInput, type LoadStateStatusInput, type LogLevel, MSG, MSG_AWARENESS, MSG_SYNC, MSG_SYNC_STEP1, MSG_SYNC_STEP2, MSG_SYNC_UPDATE, MSG_YJS_AWARENESS, MSG_YJS_SYNC, type MemberRecord, type Message, type MessageHandlers, type MessageRecord, type MsgType, type NormalizedApiError, type PagedResourceFetchArgs, type PagedResourcePage, type PagedResourceState, type PagedResourceStatus, type PlanInfo, PlatformApiError, PlatformContext, type PlatformContextValue, PlatformProvider, type PlatformWSOptions, type PlatformWSResult, type PresencePeerClient, PricingTable, type PricingTablePlan, type PricingTablePrice, type ProductChargeOpts, type ProtocolMessage, type Purchase, type Query, type R2FileInfo, type R2FileListPage, type R2Scope, type R2UploadResult, ROLES, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_CONFIG, ROLE_DEFAULT, type Reaction, type ReactionRecord, type ReadCursorRecord, type ReadReceipt, type RecordData, RecordProvider, type RecordProviderProps, RecordRoomNotReadyError, RecordScope, type RequestOptions, type ResolvedDeepSpaceAgentModel, type Role, type RoomUser, SECURE_ROOM_BOUNDARIES_MIGRATION_ID, type ScopeEntry, ScopeRegistryProvider, type ServerMessage, SignedIn, SignedOut, type SubscribeOpts, type SubscribeResult, type SubscriptionState, type SubscriptionStatus, type SyncResult, type UseAsyncResourceOptions, type UseAuthProfileReadyOptions, type UseAuthStatusOptions, type UseCanvasResult, type UseCheckoutOpts, type UseCronMonitorResult, type UseJobsResult, type UsePagedResourceOptions, type UsePresenceRoomResult, type UseR2FilesReturn, type UseVoiceAgentOptions, type UseVoiceAgentResult, type UseYjsFieldResult, type UseYjsRoomResult, type UseYjsTextResult, type User, type UserCredits, type UserInfo, type UserKarma, type UserProfile, type ViewportClient, type VoiceStatus, type VoiceTranscriptEntry, WORKER_OWNED_NOT_FOUND_MIGRATION_ID, type WriteError, applyDeepSpaceTheme, applyUIThemeTokens, authClient, canAutoLoadPagedResource, clampPagedResourceItems, clearAuthToken, clearDeepSpaceTheme, clientBuild, createDecoder, createEncoder, decodeAiStreamChunk, deriveLoadState, detectEnvironment, dispatch, encode, encodeAwarenessMessage, encodeSyncStep1, encodeSyncStep2, encodeUpdate, formatBytes, formatFileSize, formatFullTimestamp, formatMessageTime, getApiUrl, getAuthToken, getAuthUrl, getConversationDisplayName, getConversationParticipantIds, getDeepSpaceAIModel, getEnvironmentConfig, getMessageType, getPagedResourceCooldownMs, getPlatformWorkerUrl, getThreadCounts, getUserColor, groupReactionsForMessage, handleAwarenessMessage, handleSyncMessage, hasContent, installClientErrorReporter, integration, isAsyncResourceSlow, isDMConversation, isDarkColor, isImageFile, isLocalDev, isProduction, listDeepSpaceAgentModels, parseMessageMetadata, parseSseLine, readThemeFromDOM, readVarUint, readVarUint8Array, reportClientError, resetEnvironmentCache, resolveDeepSpaceAgentModel, serverBuild, shouldGroupMessages, signIn, signOut, storageLimitForTier, toConnectionStatus, toUint8Array, useAsyncResource, useAuth, useAuthProfileReady, useAuthStatus, useAuthUser, useCanvas, useChannelMembers, useChannels, useCheckout, useCommunities, useConversation, useConversations, useCronMonitor, useDisplayName, useInbox, useIsDarkTheme, useJobs, useMessages, useMutations, usePagedResource, usePlatform, usePlatformWS, usePosts, usePresence, usePresenceRoom, useQuery, useR2Files, useReactions, useReadReceipts, useRecordContext, useSession, useSubscription, useUser, useUserLookup, useUsers, useVoiceAgent, useYjsField, useYjsRoom, useYjsText, validateAppMigrationIds, writeVarUint, writeVarUint8Array };
5076
+ export { ACCOUNT_STORAGE_LIMIT_BYTES, APP_LOG_EVENT_KEYS, ASYNC_RESOURCE_DEFAULTS, type AdHocChargeOpts, type AiStreamAction, type AiStreamChunk, type ApiErrorIssue, type AppLogEvent, type AppLogEventKey, type AppLogsResponse, type AppMigrationIdsValidation, type AsyncResourceDefaults, type AsyncResourceState, type AsyncResourceStatus, AuthGate, type AuthGateProps, AuthOverlay, Awareness, type AwarenessState, type AwarenessStates, type BaseMessage, type CanvasShapeClient, type Channel, type ChannelInvitation, type ChannelMember, type ChargeOnceOpts, type ChargeOnceResult, type ClientErrorKind, type ClientErrorReport, type ClientErrorReporterOptions, type ClientMessage, type CollectionSchema, type ConnectionAttachment, type ConnectionStatus, type ContentSegment, type ConversationObject, type CronHistoryEntry, type CronMutationResult, type CronTaskState, DEEPSPACE_AGENT_PROFILES, DEEPSPACE_AI_DEFAULTS, DEEPSPACE_AI_MODELS, DEEPSPACE_MODEL_CATALOG_PROVENANCE, DEEPSPACE_THEME_PROPERTIES, DEFAULT_USER_COLORS, type DeepSpaceAIModel, type DeepSpaceAIModelId, type DeepSpaceAIProvider, type DeepSpaceAgentProfile, type DeepSpaceAgentProfileId, type DeepSpaceAgentSupport, DeepSpaceAuthProvider, type DeepSpaceThemeConfig, DeepSpaceThemeProvider, type DeepSpaceThemeProviderProps, type DeriveLoadStateInput, ENV, type Environment, type FileAttachment, type GroupedReaction, GuestBanner, type HandlerContext, type InboxEntry, type IntegrationResponse, type JobStatusView, type JobView, LOG_LEVELS, type LinkPreviewData, type LoadState, type LoadStateAuthInput, type LoadStateStatusInput, type LogLevel, MSG, MSG_AWARENESS, MSG_SYNC, MSG_SYNC_STEP1, MSG_SYNC_STEP2, MSG_SYNC_UPDATE, MSG_YJS_AWARENESS, MSG_YJS_SYNC, type MemberRecord, type Message, type MessageHandlers, type MessageRecord, type MsgType, type NormalizedApiError, type PagedResourceFetchArgs, type PagedResourcePage, type PagedResourceState, type PagedResourceStatus, type PlanInfo, PlatformApiError, PlatformContext, type PlatformContextValue, PlatformProvider, type PlatformWSOptions, type PlatformWSResult, type PresencePeerClient, PricingTable, type PricingTablePlan, type PricingTablePrice, type ProductChargeOpts, type ProtocolMessage, type Purchase, type Query, type R2FileInfo, type R2FileListPage, type R2Scope, type R2UploadResult, RECORD_NOT_FOUND, ROLES, ROLE_ADMIN, ROLE_ANONYMOUS, ROLE_CONFIG, ROLE_DEFAULT, type Reaction, type ReactionRecord, type ReadCursorRecord, type ReadReceipt, type RecordData, RecordProvider, type RecordProviderProps, RecordRoomNotReadyError, RecordScope, type RequestOptions, type ResolvedDeepSpaceAgentModel, type Role, type RoomUser, SECURE_ROOM_BOUNDARIES_MIGRATION_ID, type ScopeEntry, ScopeRegistryProvider, type ServerMessage, SignedIn, SignedOut, type SubscribeOpts, type SubscribeResult, type SubscriptionState, type SubscriptionStatus, type SyncResult, type UseAsyncResourceOptions, type UseAuthProfileReadyOptions, type UseAuthStatusOptions, type UseCanvasResult, type UseCheckoutOpts, type UseCronMonitorResult, type UseJobsResult, type UsePagedResourceOptions, type UsePresenceRoomResult, type UseR2FilesReturn, type UseVoiceAgentOptions, type UseVoiceAgentResult, type UseYjsFieldResult, type UseYjsRoomResult, type UseYjsTextResult, type User, type UserCredits, type UserInfo, type UserKarma, type UserProfile, type ViewportClient, type VoiceStatus, type VoiceTranscriptEntry, WORKER_OWNED_NOT_FOUND_MIGRATION_ID, type WriteError, applyDeepSpaceTheme, applyUIThemeTokens, authClient, canAutoLoadPagedResource, clampPagedResourceItems, clearAuthToken, clearDeepSpaceTheme, clientBuild, createDecoder, createEncoder, decodeAiStreamChunk, deriveLoadState, detectEnvironment, dispatch, encode, encodeAwarenessMessage, encodeSyncStep1, encodeSyncStep2, encodeUpdate, formatBytes, formatFileSize, formatFullTimestamp, formatMessageTime, getApiUrl, getAuthToken, getAuthUrl, getConversationDisplayName, getConversationParticipantIds, getDeepSpaceAIModel, getEnvironmentConfig, getMessageType, getPagedResourceCooldownMs, getPlatformWorkerUrl, getThreadCounts, getUserColor, groupReactionsForMessage, handleAwarenessMessage, handleSyncMessage, hasContent, installClientErrorReporter, integration, isAsyncResourceSlow, isDMConversation, isDarkColor, isImageFile, isLocalDev, isProduction, listDeepSpaceAgentModels, parseMessageMetadata, parseSseLine, readThemeFromDOM, readVarUint, readVarUint8Array, reportClientError, resetEnvironmentCache, resolveDeepSpaceAgentModel, serverBuild, shouldGroupMessages, signIn, signOut, storageLimitForTier, toConnectionStatus, toUint8Array, useAsyncResource, useAuth, useAuthProfileReady, useAuthStatus, useAuthUser, useCanvas, useChannelMembers, useChannels, useCheckout, useCommunities, useConversation, useConversations, useCronMonitor, useDisplayName, useInbox, useIsDarkTheme, useJobs, useMessages, useMutations, usePagedResource, usePlatform, usePlatformWS, usePosts, usePresence, usePresenceRoom, useQuery, useR2Files, useReactions, useReadReceipts, useRecordContext, useSession, useSubscription, useUser, useUserLookup, useUsers, useVoiceAgent, useYjsField, useYjsRoom, useYjsText, validateAppMigrationIds, writeVarUint, writeVarUint8Array };
package/dist/index.js CHANGED
@@ -615,6 +615,7 @@ var MSG_YJS_AWARENESS = 23;
615
615
  var ROLE_ANONYMOUS = "viewer";
616
616
  var ROLE_DEFAULT = "member";
617
617
  var ROLE_ADMIN = "admin";
618
+ var RECORD_NOT_FOUND = "Record not found";
618
619
 
619
620
  // src/shared/protocol/messages.ts
620
621
  var EMPTY = Object.freeze({});
@@ -1376,20 +1377,14 @@ function RecordProviderState({
1376
1377
  fetchUser,
1377
1378
  allowAnonymous = false,
1378
1379
  getAuthToken: getAuthTokenProp,
1379
- onPermissionError: onPermissionErrorProp,
1380
- onValidationError: onValidationErrorProp
1380
+ onWriteError: onWriteErrorProp
1381
1381
  }) {
1382
1382
  const [userProfile, setUserProfile] = useState3(null);
1383
1383
  const [userProfileLoading, setUserProfileLoading] = useState3(true);
1384
- const onPermissionErrorRef = useRef4(onPermissionErrorProp);
1385
- onPermissionErrorRef.current = onPermissionErrorProp;
1386
- const onValidationErrorRef = useRef4(onValidationErrorProp);
1387
- onValidationErrorRef.current = onValidationErrorProp;
1388
- const onPermissionError = useCallback2((title, detail) => {
1389
- onPermissionErrorRef.current?.(title, detail);
1390
- }, []);
1391
- const onValidationError = useCallback2((title, detail) => {
1392
- onValidationErrorRef.current?.(title, detail);
1384
+ const onWriteErrorRef = useRef4(onWriteErrorProp);
1385
+ onWriteErrorRef.current = onWriteErrorProp;
1386
+ const onWriteError = useCallback2((error) => {
1387
+ onWriteErrorRef.current(error);
1393
1388
  }, []);
1394
1389
  const refetchUserProfile = useCallback2(async () => {
1395
1390
  try {
@@ -1427,8 +1422,7 @@ function RecordProviderState({
1427
1422
  refetchUserProfile,
1428
1423
  allowAnonymous,
1429
1424
  getAuthToken: getAuthTokenProp,
1430
- onPermissionError,
1431
- onValidationError
1425
+ onWriteError
1432
1426
  }),
1433
1427
  [
1434
1428
  userProfile,
@@ -1436,8 +1430,7 @@ function RecordProviderState({
1436
1430
  refetchUserProfile,
1437
1431
  allowAnonymous,
1438
1432
  getAuthTokenProp,
1439
- onPermissionError,
1440
- onValidationError
1433
+ onWriteError
1441
1434
  ]
1442
1435
  );
1443
1436
  return /* @__PURE__ */ jsx6(RecordAuthContext.Provider, { value: authValue, children: /* @__PURE__ */ jsx6(ScopeRegistryProvider, { children }) });
@@ -1533,16 +1526,13 @@ function RecordProvider({
1533
1526
  }
1534
1527
  return /* @__PURE__ */ jsx6(Fragment5, { children: null });
1535
1528
  }
1536
- const onPermissionError = (title, detail) => onWriteError({ kind: "permission", title, detail });
1537
- const onValidationError = (title, detail) => onWriteError({ kind: "validation", title, detail });
1538
1529
  return /* @__PURE__ */ jsx6(
1539
1530
  RecordProviderState,
1540
1531
  {
1541
1532
  fetchUser,
1542
1533
  allowAnonymous,
1543
1534
  getAuthToken: getAuthTokenFn,
1544
- onPermissionError,
1545
- onValidationError,
1535
+ onWriteError,
1546
1536
  children
1547
1537
  }
1548
1538
  );
@@ -2205,12 +2195,8 @@ function ScopeConnection({
2205
2195
  userProfileRef.current = auth?.userProfile ?? null;
2206
2196
  const getAuthTokenRef = useRef5(auth?.getAuthToken ?? null);
2207
2197
  getAuthTokenRef.current = auth?.getAuthToken ?? null;
2208
- const authCallbacksRef = useRef5({
2209
- onPermissionError: auth?.onPermissionError,
2210
- onValidationError: auth?.onValidationError
2211
- });
2212
- authCallbacksRef.current.onPermissionError = auth?.onPermissionError;
2213
- authCallbacksRef.current.onValidationError = auth?.onValidationError;
2198
+ const onWriteErrorRef = useRef5(auth?.onWriteError);
2199
+ onWriteErrorRef.current = auth?.onWriteError;
2214
2200
  const allowAnonymous = auth?.allowAnonymous ?? false;
2215
2201
  const userProfileId = auth?.userProfile?.id ?? null;
2216
2202
  const userProfileLoading = auth?.userProfileLoading ?? false;
@@ -2235,8 +2221,8 @@ function ScopeConnection({
2235
2221
  setUsersLoaded(true);
2236
2222
  },
2237
2223
  onSchemas: setDiscoveredSchemas,
2238
- onPermissionError: (title, detail) => authCallbacksRef.current.onPermissionError?.(title, detail),
2239
- onValidationError: (title, detail) => authCallbacksRef.current.onValidationError?.(title, detail)
2224
+ onPermissionError: (title, detail) => onWriteErrorRef.current?.({ kind: "permission", title, detail }),
2225
+ onValidationError: (title, detail) => onWriteErrorRef.current?.({ kind: "validation", title, detail })
2240
2226
  }
2241
2227
  });
2242
2228
  socketRef.current = socket;
@@ -2519,6 +2505,7 @@ import { useCallback as useCallback5, useContext as useContext4, useMemo as useM
2519
2505
  function useMutations(collection) {
2520
2506
  const registry = useScopeRegistry();
2521
2507
  const recordCtx = useContext4(RecordContext);
2508
+ const onWriteError = useRecordAuth()?.onWriteError;
2522
2509
  const scopeEntry = registry?.resolve(collection) ?? null;
2523
2510
  const preferLocal = recordCtx?.registeredCollections?.has(collection) ?? false;
2524
2511
  const sendMessage = preferLocal ? recordCtx.sendMessage : scopeEntry?.sendMessage ?? recordCtx?.sendMessage;
@@ -2530,8 +2517,14 @@ function useMutations(collection) {
2530
2517
  );
2531
2518
  }
2532
2519
  const assertReady = useCallback5(() => {
2533
- if (!ready) throw new RecordRoomNotReadyError(collection);
2534
- }, [ready, collection]);
2520
+ if (ready) return;
2521
+ onWriteError?.({
2522
+ kind: "not_ready",
2523
+ title: "Not saved \u2014 still connecting",
2524
+ detail: `The room backing "${collection}" was not ready to accept writes yet, so the change was dropped. Gate the action on the \`ready\` flag from useMutations('${collection}') (e.g. \`disabled={!ready}\`) and retry once it is true.`
2525
+ });
2526
+ throw new RecordRoomNotReadyError(collection);
2527
+ }, [ready, collection, onWriteError]);
2535
2528
  const create = useCallback5(
2536
2529
  async (data) => {
2537
2530
  assertReady();
@@ -6504,6 +6497,7 @@ export {
6504
6497
  PlatformContext,
6505
6498
  PlatformProvider,
6506
6499
  PricingTable,
6500
+ RECORD_NOT_FOUND,
6507
6501
  ROLES,
6508
6502
  ROLE_ADMIN,
6509
6503
  ROLE_ANONYMOUS,