@cstar.help/js 0.13.0 → 0.15.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.
@@ -343,6 +343,7 @@ var ChatClient = class {
343
343
  this.customerId = null;
344
344
  this.authMode = null;
345
345
  this.pollingTimers = /* @__PURE__ */ new Map();
346
+ this.stateListeners = /* @__PURE__ */ new Set();
346
347
  this.realtimeManager = null;
347
348
  this.presenceManager = null;
348
349
  this.realtimeReady = false;
@@ -383,6 +384,7 @@ var ChatClient = class {
383
384
  this.teamId = response.data.teamId;
384
385
  this.customerId = response.data.customer.id;
385
386
  this.authMode = "hmac";
387
+ this.notifyStateChanged();
386
388
  if (this.realtimeEnabled) {
387
389
  this.realtimeInitPromise = this.initRealtime(
388
390
  response.data.customer.id,
@@ -442,11 +444,35 @@ var ChatClient = class {
442
444
  this.teamId = params.teamId;
443
445
  }
444
446
  this.authMode = "session";
447
+ this.notifyStateChanged();
445
448
  if (this.realtimeEnabled) {
446
449
  const customerName = params.customerName ?? "";
447
450
  this.realtimeInitPromise = this.initRealtimeFromSession(customerName);
448
451
  }
449
452
  }
453
+ /**
454
+ * Subscribe to client state changes (auth mode flips, identify, disconnect).
455
+ * Fires after the mutation, so listeners reading `getAuthMode()` /
456
+ * `getCustomerId()` see the new value.
457
+ *
458
+ * Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
459
+ * and `ChatState` (Svelte) to re-render when consumers mutate the client
460
+ * outside of the framework wrappers.
461
+ */
462
+ subscribe(listener) {
463
+ this.stateListeners.add(listener);
464
+ return () => {
465
+ this.stateListeners.delete(listener);
466
+ };
467
+ }
468
+ notifyStateChanged() {
469
+ for (const listener of this.stateListeners) {
470
+ try {
471
+ listener();
472
+ } catch {
473
+ }
474
+ }
475
+ }
450
476
  /**
451
477
  * Returns the auth mode the client is currently using, or `null` before
452
478
  * any authenticated call has resolved one. Useful for branching UI
@@ -509,6 +535,7 @@ var ChatClient = class {
509
535
  this.teamId = null;
510
536
  this.customerId = null;
511
537
  this.authMode = null;
538
+ this.notifyStateChanged();
512
539
  }
513
540
  /**
514
541
  * @internal Make an authenticated request to the widget API.
@@ -546,7 +573,9 @@ var ChatClient = class {
546
573
  const responseHeaders = response.headers && typeof response.headers.get === "function" ? response.headers : null;
547
574
  const headerMode = responseHeaders?.get("X-Cstar-Auth-Mode") ?? null;
548
575
  if (headerMode === "hmac" || headerMode === "session") {
576
+ const previous = this.authMode;
549
577
  this.authMode = headerMode;
578
+ if (previous !== headerMode) this.notifyStateChanged();
550
579
  }
551
580
  const requestId = responseHeaders?.get("X-Request-Id") ?? null;
552
581
  if (!response.ok) {
@@ -633,6 +662,27 @@ var ChatClient = class {
633
662
  getTeamId() {
634
663
  return this.teamId;
635
664
  }
665
+ /**
666
+ * Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
667
+ * has been cached yet. Used by `tickets.list` and friends so that a
668
+ * caller who constructed `new ChatClient({ teamSlug, publishableKey })`
669
+ * doesn't have to manually call `loginWithCredentials` before reading
670
+ * public data.
671
+ *
672
+ * Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
673
+ * `"Missing teamId"` when the chat client was teamSlug-only because the
674
+ * tickets sub-resource read `getTeamId()` synchronously and bailed.
675
+ */
676
+ async ensureTeamId() {
677
+ if (this.teamId) return this.teamId;
678
+ if (!this.teamSlug) {
679
+ throw new ChatClientAuthError(
680
+ "Missing teamId. Construct ChatClient with `teamSlug` or call `setTeamId()` / `identify()` / `loginWithCredentials()` first."
681
+ );
682
+ }
683
+ this.teamId = await this.resolveTeamIdFromSlug();
684
+ return this.teamId;
685
+ }
636
686
  /** @internal Set team ID from identify response or other source. */
637
687
  setTeamId(teamId) {
638
688
  this.teamId = teamId;
@@ -718,8 +768,10 @@ var TicketsApi = class {
718
768
  }
719
769
  /** List tickets for the identified customer. */
720
770
  async list(params) {
721
- const teamId = this.chat.getTeamId();
722
- if (!teamId) throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
771
+ if (this.chat.getAuthMode() === null) {
772
+ throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
773
+ }
774
+ const teamId = await this.chat.ensureTeamId();
723
775
  const response = await this.chat.fetch("/api/widget/conversations", {
724
776
  method: "GET",
725
777
  query: {
@@ -728,16 +780,21 @@ var TicketsApi = class {
728
780
  cursor: params?.cursor
729
781
  }
730
782
  });
783
+ const data = response.data.tickets ?? response.data.conversations ?? [];
784
+ const cursor = response.data.cursor;
785
+ const hasMore = response.data.hasMore;
731
786
  return {
732
- tickets: response.data.tickets ?? response.data.conversations ?? [],
733
- cursor: response.data.cursor,
734
- hasMore: response.data.hasMore
787
+ data,
788
+ pagination: { cursor, hasMore },
789
+ hasMore
735
790
  };
736
791
  }
737
792
  /** Create a new ticket. */
738
793
  async create(params) {
739
- const teamId = this.chat.getTeamId();
740
- if (!teamId) throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
794
+ if (this.chat.getAuthMode() === null) {
795
+ throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
796
+ }
797
+ const teamId = await this.chat.ensureTeamId();
741
798
  const response = await this.chat.fetch("/api/widget/tickets", {
742
799
  method: "POST",
743
800
  body: {
@@ -107,10 +107,24 @@ interface Ticket {
107
107
  */
108
108
  messages?: Message[];
109
109
  }
110
- /** Paginated ticket list response. */
110
+ /**
111
+ * Paginated ticket list response.
112
+ *
113
+ * As of `@cstar.help/js@0.14.0` the canonical fields match the admin SDK and
114
+ * library SDK envelopes (`{ data, pagination, hasMore }`). Closes F-037.
115
+ *
116
+ * Breaking change in 0.15.0 (B-11): the deprecated `tickets` and `cursor`
117
+ * top-level aliases are removed. Read `data` and `pagination.cursor`.
118
+ */
111
119
  interface TicketListResponse {
112
- tickets: Ticket[];
113
- cursor: string | null;
120
+ /** Tickets on this page. */
121
+ data: Ticket[];
122
+ /** Pagination cursor + a flag for whether more pages exist. */
123
+ pagination: {
124
+ cursor: string | null;
125
+ hasMore: boolean;
126
+ };
127
+ /** Convenience copy of `pagination.hasMore`. */
114
128
  hasMore: boolean;
115
129
  }
116
130
  /** A message on a ticket. */
@@ -345,6 +359,12 @@ declare class ChatClientNetworkError extends ChatClientError {
345
359
  * `ChatClientServerError`, `ChatClientNetworkError`. Each carries
346
360
  * `requestId` for correlating with server-side logs.
347
361
  */
362
+ /**
363
+ * Listener for client-state changes (auth-mode flips, identity assignment,
364
+ * disconnects). Fires once after the underlying state mutates so a UI layer
365
+ * can re-read `getAuthMode()` / `getCustomerId()` and re-render. Closes F-041.
366
+ */
367
+ type ChatStateListener = () => void;
348
368
  declare class ChatClient {
349
369
  private readonly baseUrl;
350
370
  private readonly teamSlug;
@@ -355,6 +375,7 @@ declare class ChatClient {
355
375
  private customerId;
356
376
  private authMode;
357
377
  private pollingTimers;
378
+ private stateListeners;
358
379
  private realtimeManager;
359
380
  private presenceManager;
360
381
  private realtimeReady;
@@ -397,6 +418,17 @@ declare class ChatClient {
397
418
  * every request — there is no client-side validation here.
398
419
  */
399
420
  loginWithSession(params: LoginWithSessionParams): Promise<void>;
421
+ /**
422
+ * Subscribe to client state changes (auth mode flips, identify, disconnect).
423
+ * Fires after the mutation, so listeners reading `getAuthMode()` /
424
+ * `getCustomerId()` see the new value.
425
+ *
426
+ * Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
427
+ * and `ChatState` (Svelte) to re-render when consumers mutate the client
428
+ * outside of the framework wrappers.
429
+ */
430
+ subscribe(listener: ChatStateListener): () => void;
431
+ private notifyStateChanged;
400
432
  /**
401
433
  * Returns the auth mode the client is currently using, or `null` before
402
434
  * any authenticated call has resolved one. Useful for branching UI
@@ -453,6 +485,18 @@ declare class ChatClient {
453
485
  private initRealtimeFromSession;
454
486
  /** @internal Get the stored team ID for requests that need it. */
455
487
  getTeamId(): string | null;
488
+ /**
489
+ * Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
490
+ * has been cached yet. Used by `tickets.list` and friends so that a
491
+ * caller who constructed `new ChatClient({ teamSlug, publishableKey })`
492
+ * doesn't have to manually call `loginWithCredentials` before reading
493
+ * public data.
494
+ *
495
+ * Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
496
+ * `"Missing teamId"` when the chat client was teamSlug-only because the
497
+ * tickets sub-resource read `getTeamId()` synchronously and bailed.
498
+ */
499
+ ensureTeamId(): Promise<string>;
456
500
  /** @internal Set team ID from identify response or other source. */
457
501
  setTeamId(teamId: string): void;
458
502
  /** @internal Wait for realtime to be initialized (for testing). */
@@ -509,4 +553,4 @@ declare class MessagesApi {
509
553
  send(ticketId: string, content: string): Promise<Message>;
510
554
  }
511
555
 
512
- export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
556
+ export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type ChatStateListener, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
@@ -107,10 +107,24 @@ interface Ticket {
107
107
  */
108
108
  messages?: Message[];
109
109
  }
110
- /** Paginated ticket list response. */
110
+ /**
111
+ * Paginated ticket list response.
112
+ *
113
+ * As of `@cstar.help/js@0.14.0` the canonical fields match the admin SDK and
114
+ * library SDK envelopes (`{ data, pagination, hasMore }`). Closes F-037.
115
+ *
116
+ * Breaking change in 0.15.0 (B-11): the deprecated `tickets` and `cursor`
117
+ * top-level aliases are removed. Read `data` and `pagination.cursor`.
118
+ */
111
119
  interface TicketListResponse {
112
- tickets: Ticket[];
113
- cursor: string | null;
120
+ /** Tickets on this page. */
121
+ data: Ticket[];
122
+ /** Pagination cursor + a flag for whether more pages exist. */
123
+ pagination: {
124
+ cursor: string | null;
125
+ hasMore: boolean;
126
+ };
127
+ /** Convenience copy of `pagination.hasMore`. */
114
128
  hasMore: boolean;
115
129
  }
116
130
  /** A message on a ticket. */
@@ -345,6 +359,12 @@ declare class ChatClientNetworkError extends ChatClientError {
345
359
  * `ChatClientServerError`, `ChatClientNetworkError`. Each carries
346
360
  * `requestId` for correlating with server-side logs.
347
361
  */
362
+ /**
363
+ * Listener for client-state changes (auth-mode flips, identity assignment,
364
+ * disconnects). Fires once after the underlying state mutates so a UI layer
365
+ * can re-read `getAuthMode()` / `getCustomerId()` and re-render. Closes F-041.
366
+ */
367
+ type ChatStateListener = () => void;
348
368
  declare class ChatClient {
349
369
  private readonly baseUrl;
350
370
  private readonly teamSlug;
@@ -355,6 +375,7 @@ declare class ChatClient {
355
375
  private customerId;
356
376
  private authMode;
357
377
  private pollingTimers;
378
+ private stateListeners;
358
379
  private realtimeManager;
359
380
  private presenceManager;
360
381
  private realtimeReady;
@@ -397,6 +418,17 @@ declare class ChatClient {
397
418
  * every request — there is no client-side validation here.
398
419
  */
399
420
  loginWithSession(params: LoginWithSessionParams): Promise<void>;
421
+ /**
422
+ * Subscribe to client state changes (auth mode flips, identify, disconnect).
423
+ * Fires after the mutation, so listeners reading `getAuthMode()` /
424
+ * `getCustomerId()` see the new value.
425
+ *
426
+ * Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
427
+ * and `ChatState` (Svelte) to re-render when consumers mutate the client
428
+ * outside of the framework wrappers.
429
+ */
430
+ subscribe(listener: ChatStateListener): () => void;
431
+ private notifyStateChanged;
400
432
  /**
401
433
  * Returns the auth mode the client is currently using, or `null` before
402
434
  * any authenticated call has resolved one. Useful for branching UI
@@ -453,6 +485,18 @@ declare class ChatClient {
453
485
  private initRealtimeFromSession;
454
486
  /** @internal Get the stored team ID for requests that need it. */
455
487
  getTeamId(): string | null;
488
+ /**
489
+ * Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
490
+ * has been cached yet. Used by `tickets.list` and friends so that a
491
+ * caller who constructed `new ChatClient({ teamSlug, publishableKey })`
492
+ * doesn't have to manually call `loginWithCredentials` before reading
493
+ * public data.
494
+ *
495
+ * Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
496
+ * `"Missing teamId"` when the chat client was teamSlug-only because the
497
+ * tickets sub-resource read `getTeamId()` synchronously and bailed.
498
+ */
499
+ ensureTeamId(): Promise<string>;
456
500
  /** @internal Set team ID from identify response or other source. */
457
501
  setTeamId(teamId: string): void;
458
502
  /** @internal Wait for realtime to be initialized (for testing). */
@@ -509,4 +553,4 @@ declare class MessagesApi {
509
553
  send(ticketId: string, content: string): Promise<Message>;
510
554
  }
511
555
 
512
- export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
556
+ export { type ChatAuthMode, ChatClient, ChatClientAuthError, ChatClientError, ChatClientNetworkError, ChatClientRateLimitError, ChatClientServerError, type ChatConfig, type ChatStateListener, type IdentifyParams, type IdentifyResult, type LoginWithCredentialsParams, type LoginWithCredentialsResult, type LoginWithSessionParams, type Message, type MessageCallback, type RealtimeTokenResponse, type Ticket, type TicketCreateParams, type TicketListParams, type TicketListResponse, type TypingCallback, type TypingPayload };
@@ -302,6 +302,7 @@ var ChatClient = class {
302
302
  this.customerId = null;
303
303
  this.authMode = null;
304
304
  this.pollingTimers = /* @__PURE__ */ new Map();
305
+ this.stateListeners = /* @__PURE__ */ new Set();
305
306
  this.realtimeManager = null;
306
307
  this.presenceManager = null;
307
308
  this.realtimeReady = false;
@@ -342,6 +343,7 @@ var ChatClient = class {
342
343
  this.teamId = response.data.teamId;
343
344
  this.customerId = response.data.customer.id;
344
345
  this.authMode = "hmac";
346
+ this.notifyStateChanged();
345
347
  if (this.realtimeEnabled) {
346
348
  this.realtimeInitPromise = this.initRealtime(
347
349
  response.data.customer.id,
@@ -401,11 +403,35 @@ var ChatClient = class {
401
403
  this.teamId = params.teamId;
402
404
  }
403
405
  this.authMode = "session";
406
+ this.notifyStateChanged();
404
407
  if (this.realtimeEnabled) {
405
408
  const customerName = params.customerName ?? "";
406
409
  this.realtimeInitPromise = this.initRealtimeFromSession(customerName);
407
410
  }
408
411
  }
412
+ /**
413
+ * Subscribe to client state changes (auth mode flips, identify, disconnect).
414
+ * Fires after the mutation, so listeners reading `getAuthMode()` /
415
+ * `getCustomerId()` see the new value.
416
+ *
417
+ * Returns an unsubscribe function. Closes F-041 — used by `useChat` (React)
418
+ * and `ChatState` (Svelte) to re-render when consumers mutate the client
419
+ * outside of the framework wrappers.
420
+ */
421
+ subscribe(listener) {
422
+ this.stateListeners.add(listener);
423
+ return () => {
424
+ this.stateListeners.delete(listener);
425
+ };
426
+ }
427
+ notifyStateChanged() {
428
+ for (const listener of this.stateListeners) {
429
+ try {
430
+ listener();
431
+ } catch {
432
+ }
433
+ }
434
+ }
409
435
  /**
410
436
  * Returns the auth mode the client is currently using, or `null` before
411
437
  * any authenticated call has resolved one. Useful for branching UI
@@ -468,6 +494,7 @@ var ChatClient = class {
468
494
  this.teamId = null;
469
495
  this.customerId = null;
470
496
  this.authMode = null;
497
+ this.notifyStateChanged();
471
498
  }
472
499
  /**
473
500
  * @internal Make an authenticated request to the widget API.
@@ -505,7 +532,9 @@ var ChatClient = class {
505
532
  const responseHeaders = response.headers && typeof response.headers.get === "function" ? response.headers : null;
506
533
  const headerMode = responseHeaders?.get("X-Cstar-Auth-Mode") ?? null;
507
534
  if (headerMode === "hmac" || headerMode === "session") {
535
+ const previous = this.authMode;
508
536
  this.authMode = headerMode;
537
+ if (previous !== headerMode) this.notifyStateChanged();
509
538
  }
510
539
  const requestId = responseHeaders?.get("X-Request-Id") ?? null;
511
540
  if (!response.ok) {
@@ -592,6 +621,27 @@ var ChatClient = class {
592
621
  getTeamId() {
593
622
  return this.teamId;
594
623
  }
624
+ /**
625
+ * Resolve a team ID, lazily looking it up from `teamSlug` if no team ID
626
+ * has been cached yet. Used by `tickets.list` and friends so that a
627
+ * caller who constructed `new ChatClient({ teamSlug, publishableKey })`
628
+ * doesn't have to manually call `loginWithCredentials` before reading
629
+ * public data.
630
+ *
631
+ * Closes NEW-v3-05 — `TicketsState(chatClient)` previously errored
632
+ * `"Missing teamId"` when the chat client was teamSlug-only because the
633
+ * tickets sub-resource read `getTeamId()` synchronously and bailed.
634
+ */
635
+ async ensureTeamId() {
636
+ if (this.teamId) return this.teamId;
637
+ if (!this.teamSlug) {
638
+ throw new ChatClientAuthError(
639
+ "Missing teamId. Construct ChatClient with `teamSlug` or call `setTeamId()` / `identify()` / `loginWithCredentials()` first."
640
+ );
641
+ }
642
+ this.teamId = await this.resolveTeamIdFromSlug();
643
+ return this.teamId;
644
+ }
595
645
  /** @internal Set team ID from identify response or other source. */
596
646
  setTeamId(teamId) {
597
647
  this.teamId = teamId;
@@ -677,8 +727,10 @@ var TicketsApi = class {
677
727
  }
678
728
  /** List tickets for the identified customer. */
679
729
  async list(params) {
680
- const teamId = this.chat.getTeamId();
681
- if (!teamId) throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
730
+ if (this.chat.getAuthMode() === null) {
731
+ throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
732
+ }
733
+ const teamId = await this.chat.ensureTeamId();
682
734
  const response = await this.chat.fetch("/api/widget/conversations", {
683
735
  method: "GET",
684
736
  query: {
@@ -687,16 +739,21 @@ var TicketsApi = class {
687
739
  cursor: params?.cursor
688
740
  }
689
741
  });
742
+ const data = response.data.tickets ?? response.data.conversations ?? [];
743
+ const cursor = response.data.cursor;
744
+ const hasMore = response.data.hasMore;
690
745
  return {
691
- tickets: response.data.tickets ?? response.data.conversations ?? [],
692
- cursor: response.data.cursor,
693
- hasMore: response.data.hasMore
746
+ data,
747
+ pagination: { cursor, hasMore },
748
+ hasMore
694
749
  };
695
750
  }
696
751
  /** Create a new ticket. */
697
752
  async create(params) {
698
- const teamId = this.chat.getTeamId();
699
- if (!teamId) throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
753
+ if (this.chat.getAuthMode() === null) {
754
+ throw new ChatClientAuthError("Not identified. Call chat.identify() first.");
755
+ }
756
+ const teamId = await this.chat.ensureTeamId();
700
757
  const response = await this.chat.fetch("/api/widget/tickets", {
701
758
  method: "POST",
702
759
  body: {
@@ -20,7 +20,20 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/community/index.ts
21
21
  var community_exports = {};
22
22
  __export(community_exports, {
23
- CommunityClient: () => CommunityClient
23
+ CStarAuthenticationError: () => CStarAuthenticationError,
24
+ CStarConflictError: () => CStarConflictError,
25
+ CStarError: () => CStarError,
26
+ CStarFeatureDisabledError: () => CStarFeatureDisabledError,
27
+ CStarNotFoundError: () => CStarNotFoundError,
28
+ CStarPermissionError: () => CStarPermissionError,
29
+ CStarRateLimitError: () => CStarRateLimitError,
30
+ CStarRealtimeUnavailableError: () => CStarRealtimeUnavailableError,
31
+ CStarServerError: () => CStarServerError,
32
+ CStarValidationError: () => CStarValidationError,
33
+ CommunityClient: () => CommunityClient,
34
+ ErrorType: () => ErrorType,
35
+ parseError: () => parseError,
36
+ parsePublicError: () => parsePublicError
24
37
  });
25
38
  module.exports = __toCommonJS(community_exports);
26
39
 
@@ -61,7 +74,7 @@ function normalizeArgs(messageOrStatus, maybeBody, defaults) {
61
74
  }
62
75
  };
63
76
  }
64
- var CStarError = class extends Error {
77
+ var CStarErrorImpl = class extends Error {
65
78
  constructor(messageOrStatus, body) {
66
79
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body);
67
80
  super(resolved.message);
@@ -74,7 +87,7 @@ var CStarError = class extends Error {
74
87
  this.statusCode = statusCode;
75
88
  }
76
89
  };
77
- var CStarAuthenticationError = class extends CStarError {
90
+ var CStarAuthenticationErrorImpl = class extends CStarErrorImpl {
78
91
  constructor(messageOrStatus, body) {
79
92
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
80
93
  type: ErrorType.AUTHENTICATION_ERROR,
@@ -85,7 +98,7 @@ var CStarAuthenticationError = class extends CStarError {
85
98
  this.name = "CStarAuthenticationError";
86
99
  }
87
100
  };
88
- var CStarRateLimitError = class extends CStarError {
101
+ var CStarRateLimitErrorImpl = class extends CStarErrorImpl {
89
102
  constructor(messageOrStatus, body, retryAfter) {
90
103
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
91
104
  type: ErrorType.RATE_LIMIT_ERROR,
@@ -97,7 +110,7 @@ var CStarRateLimitError = class extends CStarError {
97
110
  this.retryAfter = retryAfter ?? 60;
98
111
  }
99
112
  };
100
- var CStarNotFoundError = class extends CStarError {
113
+ var CStarNotFoundErrorImpl = class extends CStarErrorImpl {
101
114
  constructor(messageOrStatus, body) {
102
115
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
103
116
  type: ErrorType.NOT_FOUND_ERROR,
@@ -108,7 +121,7 @@ var CStarNotFoundError = class extends CStarError {
108
121
  this.name = "CStarNotFoundError";
109
122
  }
110
123
  };
111
- var CStarValidationError = class extends CStarError {
124
+ var CStarValidationErrorImpl = class extends CStarErrorImpl {
112
125
  constructor(messageOrStatus, body) {
113
126
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
114
127
  type: ErrorType.INVALID_REQUEST_ERROR,
@@ -119,7 +132,7 @@ var CStarValidationError = class extends CStarError {
119
132
  this.name = "CStarValidationError";
120
133
  }
121
134
  };
122
- var CStarPermissionError = class extends CStarError {
135
+ var CStarPermissionErrorImpl = class extends CStarErrorImpl {
123
136
  constructor(messageOrStatus, body) {
124
137
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
125
138
  type: ErrorType.PERMISSION_ERROR,
@@ -130,7 +143,7 @@ var CStarPermissionError = class extends CStarError {
130
143
  this.name = "CStarPermissionError";
131
144
  }
132
145
  };
133
- var CStarConflictError = class extends CStarError {
146
+ var CStarConflictErrorImpl = class extends CStarErrorImpl {
134
147
  constructor(messageOrStatus, body) {
135
148
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
136
149
  type: ErrorType.CONFLICT_ERROR,
@@ -141,7 +154,7 @@ var CStarConflictError = class extends CStarError {
141
154
  this.name = "CStarConflictError";
142
155
  }
143
156
  };
144
- var CStarServerError = class extends CStarError {
157
+ var CStarServerErrorImpl = class extends CStarErrorImpl {
145
158
  constructor(messageOrStatus, body) {
146
159
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
147
160
  type: ErrorType.SERVER_ERROR,
@@ -152,7 +165,7 @@ var CStarServerError = class extends CStarError {
152
165
  this.name = "CStarServerError";
153
166
  }
154
167
  };
155
- var CStarFeatureDisabledError = class extends CStarError {
168
+ var CStarFeatureDisabledErrorImpl = class extends CStarErrorImpl {
156
169
  constructor(messageOrStatus, body) {
157
170
  const { statusCode, body: resolved } = normalizeArgs(messageOrStatus, body, {
158
171
  type: ErrorType.FEATURE_NOT_CONFIGURED,
@@ -165,6 +178,42 @@ var CStarFeatureDisabledError = class extends CStarError {
165
178
  this.enableUrl = resolved.enable_url ?? "";
166
179
  }
167
180
  };
181
+ var CStarRealtimeUnavailableErrorImpl = class extends CStarErrorImpl {
182
+ constructor(message) {
183
+ const resolved = message ?? "EventSource is not available in this environment. Real-time subscriptions only work in the browser. Move the call to a client-only path (`useEffect` / `onMount`), or pass an `eventSource` polyfill via the realtime options. See https://cstar.help/developers/sdk/realtime#ssr";
184
+ super(0, {
185
+ type: ErrorType.API_ERROR,
186
+ code: "realtime_unavailable",
187
+ message: resolved,
188
+ doc_url: "https://cstar.help/developers/sdk/realtime#ssr"
189
+ });
190
+ this.name = "CStarRealtimeUnavailableError";
191
+ }
192
+ };
193
+ var REGISTRY_KEY = /* @__PURE__ */ Symbol.for("@cstar.help/js/errors/v1");
194
+ var globalSlot = globalThis;
195
+ var registry = globalSlot[REGISTRY_KEY] ?? (globalSlot[REGISTRY_KEY] = {
196
+ CStarError: CStarErrorImpl,
197
+ CStarAuthenticationError: CStarAuthenticationErrorImpl,
198
+ CStarRateLimitError: CStarRateLimitErrorImpl,
199
+ CStarNotFoundError: CStarNotFoundErrorImpl,
200
+ CStarValidationError: CStarValidationErrorImpl,
201
+ CStarPermissionError: CStarPermissionErrorImpl,
202
+ CStarConflictError: CStarConflictErrorImpl,
203
+ CStarServerError: CStarServerErrorImpl,
204
+ CStarFeatureDisabledError: CStarFeatureDisabledErrorImpl,
205
+ CStarRealtimeUnavailableError: CStarRealtimeUnavailableErrorImpl
206
+ });
207
+ var CStarError = registry.CStarError;
208
+ var CStarAuthenticationError = registry.CStarAuthenticationError;
209
+ var CStarRateLimitError = registry.CStarRateLimitError;
210
+ var CStarNotFoundError = registry.CStarNotFoundError;
211
+ var CStarValidationError = registry.CStarValidationError;
212
+ var CStarPermissionError = registry.CStarPermissionError;
213
+ var CStarConflictError = registry.CStarConflictError;
214
+ var CStarServerError = registry.CStarServerError;
215
+ var CStarFeatureDisabledError = registry.CStarFeatureDisabledError;
216
+ var CStarRealtimeUnavailableError = registry.CStarRealtimeUnavailableError;
168
217
  function parsePublicError(status, body, fallbackMessage) {
169
218
  const obj = body && typeof body === "object" ? body : null;
170
219
  const errVal = obj?.error;
@@ -529,5 +578,18 @@ var CommunityClient = class {
529
578
  };
530
579
  // Annotate the CommonJS export names for ESM import in node:
531
580
  0 && (module.exports = {
532
- CommunityClient
581
+ CStarAuthenticationError,
582
+ CStarConflictError,
583
+ CStarError,
584
+ CStarFeatureDisabledError,
585
+ CStarNotFoundError,
586
+ CStarPermissionError,
587
+ CStarRateLimitError,
588
+ CStarRealtimeUnavailableError,
589
+ CStarServerError,
590
+ CStarValidationError,
591
+ CommunityClient,
592
+ ErrorType,
593
+ parseError,
594
+ parsePublicError
533
595
  });