@forgecart/sdk 1.2.0 → 1.2.2

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.
@@ -4,7 +4,7 @@
4
4
  * This file was automatically generated and should not be manually edited.
5
5
  * To regenerate, run: npm run codegen:ts
6
6
  *
7
- * Generated at: 2025-12-13T23:18:09.120Z
7
+ * Generated at: 2025-12-15T07:13:55.745Z
8
8
  * Generator version: 1.0.0
9
9
  *
10
10
  * 🤖 Generated with ForgeCart SDK Generator
@@ -464,12 +464,51 @@ export type UpdateCustomerNoteMutationResult = Types.UpdateCustomerNoteMutation;
464
464
  export type DeleteCustomerNoteMutationVariables = Types.DeleteCustomerNoteMutationVariables;
465
465
  export type DeleteCustomerNoteMutation = Types.DeleteCustomerNoteMutation;
466
466
  export type DeleteCustomerNoteMutationResult = Types.DeleteCustomerNoteMutation;
467
+ export type DeploymentsQueryVariables = Types.DeploymentsQueryVariables;
468
+ export type DeploymentsQuery = Types.DeploymentsQuery;
469
+ export type DeploymentsQueryResult = Types.DeploymentsQuery;
470
+ export type DeploymentQueryVariables = Types.DeploymentQueryVariables;
471
+ export type DeploymentQuery = Types.DeploymentQuery;
472
+ export type DeploymentQueryResult = Types.DeploymentQuery;
473
+ export type DeploymentEnvQueryVariables = Types.DeploymentEnvQueryVariables;
474
+ export type DeploymentEnvQuery = Types.DeploymentEnvQuery;
475
+ export type DeploymentEnvQueryResult = Types.DeploymentEnvQuery;
476
+ export type ChannelInfoQueryVariables = Types.ChannelInfoQueryVariables;
477
+ export type ChannelInfoQuery = Types.ChannelInfoQuery;
478
+ export type ChannelInfoQueryResult = Types.ChannelInfoQuery;
479
+ export type ValidateChannelTokenQueryVariables = Types.ValidateChannelTokenQueryVariables;
480
+ export type ValidateChannelTokenQuery = Types.ValidateChannelTokenQuery;
481
+ export type ValidateChannelTokenQueryResult = Types.ValidateChannelTokenQuery;
482
+ export type CreateDeploymentMutationVariables = Types.CreateDeploymentMutationVariables;
483
+ export type CreateDeploymentMutation = Types.CreateDeploymentMutation;
484
+ export type CreateDeploymentMutationResult = Types.CreateDeploymentMutation;
485
+ export type DeleteDeploymentMutationVariables = Types.DeleteDeploymentMutationVariables;
486
+ export type DeleteDeploymentMutation = Types.DeleteDeploymentMutation;
487
+ export type DeleteDeploymentMutationResult = Types.DeleteDeploymentMutation;
488
+ export type ScaleDeploymentMutationVariables = Types.ScaleDeploymentMutationVariables;
489
+ export type ScaleDeploymentMutation = Types.ScaleDeploymentMutation;
490
+ export type ScaleDeploymentMutationResult = Types.ScaleDeploymentMutation;
491
+ export type SetDeploymentEnvMutationVariables = Types.SetDeploymentEnvMutationVariables;
492
+ export type SetDeploymentEnvMutation = Types.SetDeploymentEnvMutation;
493
+ export type SetDeploymentEnvMutationResult = Types.SetDeploymentEnvMutation;
494
+ export type UnsetDeploymentEnvMutationVariables = Types.UnsetDeploymentEnvMutationVariables;
495
+ export type UnsetDeploymentEnvMutation = Types.UnsetDeploymentEnvMutation;
496
+ export type UnsetDeploymentEnvMutationResult = Types.UnsetDeploymentEnvMutation;
497
+ export type RefreshDeploymentStatusMutationVariables = Types.RefreshDeploymentStatusMutationVariables;
498
+ export type RefreshDeploymentStatusMutation = Types.RefreshDeploymentStatusMutation;
499
+ export type RefreshDeploymentStatusMutationResult = Types.RefreshDeploymentStatusMutation;
500
+ export type DeploymentLogsSubscriptionVariables = Types.DeploymentLogsSubscriptionVariables;
501
+ export type DeploymentLogsSubscription = Types.DeploymentLogsSubscription;
502
+ export type DeploymentLogsSubscriptionResult = Types.DeploymentLogsSubscription;
467
503
  export type EntityDuplicatorsQueryVariables = Types.EntityDuplicatorsQueryVariables;
468
504
  export type EntityDuplicatorsQuery = Types.EntityDuplicatorsQuery;
469
505
  export type EntityDuplicatorsQueryResult = Types.EntityDuplicatorsQuery;
470
506
  export type DuplicateEntityMutationVariables = Types.DuplicateEntityMutationVariables;
471
507
  export type DuplicateEntityMutation = Types.DuplicateEntityMutation;
472
508
  export type DuplicateEntityMutationResult = Types.DuplicateEntityMutation;
509
+ export type EntityEventSubscriptionVariables = Types.EntityEventSubscriptionVariables;
510
+ export type EntityEventSubscription = Types.EntityEventSubscription;
511
+ export type EntityEventSubscriptionResult = Types.EntityEventSubscription;
473
512
  export type FacetQueryVariables = Types.FacetQueryVariables;
474
513
  export type FacetQuery = Types.FacetQuery;
475
514
  export type FacetQueryResult = Types.FacetQuery;
@@ -4450,6 +4489,108 @@ const deleteCustomerNoteDocument = `mutation deleteCustomerNote($id: ID!) {
4450
4489
  }
4451
4490
  }`;
4452
4491
 
4492
+ const deploymentsDocument = `query Deployments {
4493
+ deployments {
4494
+ id
4495
+ type
4496
+ status
4497
+ url
4498
+ instances
4499
+ lastDeployedAt
4500
+ errorMessage
4501
+ }
4502
+ }`;
4503
+
4504
+ const deploymentDocument = `query Deployment($type: DeploymentType!) {
4505
+ deployment(type: $type) {
4506
+ id
4507
+ type
4508
+ status
4509
+ url
4510
+ instances
4511
+ lastDeployedAt
4512
+ errorMessage
4513
+ }
4514
+ }`;
4515
+
4516
+ const deploymentEnvDocument = `query DeploymentEnv($type: DeploymentType!) {
4517
+ deploymentEnv(type: $type) {
4518
+ key
4519
+ value
4520
+ }
4521
+ }`;
4522
+
4523
+ const channelInfoDocument = `query ChannelInfo {
4524
+ channelInfo {
4525
+ id
4526
+ code
4527
+ name
4528
+ domain
4529
+ hasApplication
4530
+ applicationName
4531
+ }
4532
+ }`;
4533
+
4534
+ const validateChannelTokenDocument = `query ValidateChannelToken {
4535
+ validateChannelToken
4536
+ }`;
4537
+
4538
+ const createDeploymentDocument = `mutation CreateDeployment($input: CreateDeploymentInput!) {
4539
+ createDeployment(input: $input) {
4540
+ id
4541
+ type
4542
+ status
4543
+ url
4544
+ instances
4545
+ lastDeployedAt
4546
+ errorMessage
4547
+ }
4548
+ }`;
4549
+
4550
+ const deleteDeploymentDocument = `mutation DeleteDeployment($type: DeploymentType!) {
4551
+ deleteDeployment(type: $type)
4552
+ }`;
4553
+
4554
+ const scaleDeploymentDocument = `mutation ScaleDeployment($input: ScaleDeploymentInput!) {
4555
+ scaleDeployment(input: $input) {
4556
+ id
4557
+ type
4558
+ status
4559
+ url
4560
+ instances
4561
+ lastDeployedAt
4562
+ errorMessage
4563
+ }
4564
+ }`;
4565
+
4566
+ const setDeploymentEnvDocument = `mutation SetDeploymentEnv($input: SetEnvInput!) {
4567
+ setDeploymentEnv(input: $input)
4568
+ }`;
4569
+
4570
+ const unsetDeploymentEnvDocument = `mutation UnsetDeploymentEnv($input: UnsetEnvInput!) {
4571
+ unsetDeploymentEnv(input: $input)
4572
+ }`;
4573
+
4574
+ const refreshDeploymentStatusDocument = `mutation RefreshDeploymentStatus($type: DeploymentType!) {
4575
+ refreshDeploymentStatus(type: $type) {
4576
+ id
4577
+ type
4578
+ status
4579
+ url
4580
+ instances
4581
+ lastDeployedAt
4582
+ errorMessage
4583
+ }
4584
+ }`;
4585
+
4586
+ const deploymentLogsDocument = `subscription DeploymentLogs($type: DeploymentType!) {
4587
+ deploymentLogs(type: $type) {
4588
+ timestamp
4589
+ message
4590
+ type
4591
+ }
4592
+ }`;
4593
+
4453
4594
  const entityDuplicatorsDocument = `query entityDuplicators {
4454
4595
  entityDuplicators {
4455
4596
  code
@@ -4481,6 +4622,19 @@ const duplicateEntityDocument = `mutation duplicateEntity($input: DuplicateEntit
4481
4622
  }
4482
4623
  }`;
4483
4624
 
4625
+ const entityEventDocument = `subscription entityEvent($categories: [EventCategory!]) {
4626
+ entityEvent(categories: $categories) {
4627
+ channelId
4628
+ eventName
4629
+ eventClass
4630
+ type
4631
+ entityId
4632
+ entity
4633
+ input
4634
+ timestamp
4635
+ }
4636
+ }`;
4637
+
4484
4638
  const facetDocument = `query facet($id: ID!) {
4485
4639
  facet(id: $id) {
4486
4640
  id
@@ -8354,6 +8508,72 @@ class BaseGraphQLClient {
8354
8508
  }
8355
8509
  }
8356
8510
 
8511
+ // Event handler types for SDK subscriptions
8512
+ export type EventCallback<T = EntityEventPayload> = (event: T) => void;
8513
+ export type BlockingEventCallback<T = EntityEventPayload> = (event: T) => Promise<void>;
8514
+
8515
+ export interface EventSubscription {
8516
+ unsubscribe: () => void;
8517
+ }
8518
+
8519
+ interface EventHandlerRegistry {
8520
+ handlers: Map<string, Set<EventCallback>>;
8521
+ blockingHandlers: Map<string, Set<BlockingEventCallback>>;
8522
+ }
8523
+
8524
+ // Entity event payload from server
8525
+ export interface EntityEventPayload {
8526
+ channelId: string;
8527
+ eventName: string;
8528
+ eventClass: string;
8529
+ type: string;
8530
+ entityId: string | null;
8531
+ entity: unknown;
8532
+ input: unknown;
8533
+ timestamp: string;
8534
+ }
8535
+
8536
+ // Event categories for filtering
8537
+ export const ProductEvents = [
8538
+ 'product.created', 'product.updated', 'product.deleted',
8539
+ 'product.variant.created', 'product.variant.updated', 'product.variant.deleted',
8540
+ 'product.option.created', 'product.option.updated', 'product.option.deleted',
8541
+ 'product.optionGroup.created', 'product.optionGroup.updated', 'product.optionGroup.deleted',
8542
+ 'product.variant.price.updated',
8543
+ ] as const;
8544
+
8545
+ export const OrderEvents = [
8546
+ 'order.stateTransition', 'order.placementStateTransition', 'order.line.event',
8547
+ 'order.paymentStateTransition', 'order.refundStateTransition',
8548
+ 'order.coupon.applied', 'order.coupon.removed',
8549
+ ] as const;
8550
+
8551
+ export const CustomerEvents = [
8552
+ 'customer.created', 'customer.updated', 'customer.deleted',
8553
+ 'customer.address.created', 'customer.address.updated', 'customer.address.deleted',
8554
+ 'customer.groupChange', 'customer.login', 'customer.loginfail',
8555
+ ] as const;
8556
+
8557
+ export const FulfillmentEvents = [
8558
+ 'fulfillment.created', 'fulfillment.stateTransition',
8559
+ ] as const;
8560
+
8561
+ export const PaymentEvents = [
8562
+ 'payment.stateTransition', 'payment.method.created', 'payment.method.updated', 'payment.method.deleted',
8563
+ ] as const;
8564
+
8565
+ export const CatalogEvents = [
8566
+ 'collection.created', 'collection.updated', 'collection.deleted', 'collection.modification',
8567
+ 'facet.created', 'facet.updated', 'facet.deleted',
8568
+ 'facetValue.created', 'facetValue.updated', 'facetValue.deleted',
8569
+ 'asset.created', 'asset.updated', 'asset.deleted',
8570
+ ] as const;
8571
+
8572
+ export const AllEvents = [
8573
+ ...ProductEvents, ...OrderEvents, ...CustomerEvents,
8574
+ ...FulfillmentEvents, ...PaymentEvents, ...CatalogEvents,
8575
+ ] as const;
8576
+
8357
8577
  /**
8358
8578
  * Administrator operations
8359
8579
  */
@@ -8397,9 +8617,18 @@ class AdministratorOperations {
8397
8617
 
8398
8618
  /**
8399
8619
  * login mutation
8620
+ * Automatically sets the auth token on successful login
8400
8621
  */
8401
8622
  async login(variables: Types.LoginMutationVariables): Promise<Types.LoginMutation> {
8402
- return await this.client.request<Types.LoginMutation>(loginDocument, variables);
8623
+ const response = await this.client.request<Types.LoginMutation>(loginDocument, variables);
8624
+
8625
+ // Auto-set auth token if login was successful
8626
+ const loginResult = (response as any)?.login;
8627
+ if (loginResult && loginResult.__typename === 'CurrentUser' && loginResult.sessionToken) {
8628
+ this.client.setAuthToken(loginResult.sessionToken);
8629
+ }
8630
+
8631
+ return response;
8403
8632
  }
8404
8633
 
8405
8634
  /**
@@ -9432,6 +9661,100 @@ class CustomerOperations {
9432
9661
  }
9433
9662
  }
9434
9663
 
9664
+ /**
9665
+ * Deployment operations
9666
+ */
9667
+ class DeploymentOperations {
9668
+ constructor(private client: BaseGraphQLClient) {}
9669
+
9670
+ /**
9671
+ * Deployments query
9672
+ */
9673
+ async deployments(): Promise<Types.DeploymentsQuery> {
9674
+ return await this.client.request<Types.DeploymentsQuery>(deploymentsDocument);
9675
+ }
9676
+
9677
+ /**
9678
+ * Deployment query
9679
+ */
9680
+ async deployment(variables: Types.DeploymentQueryVariables): Promise<Types.DeploymentQuery> {
9681
+ return await this.client.request<Types.DeploymentQuery>(deploymentDocument, variables);
9682
+ }
9683
+
9684
+ /**
9685
+ * DeploymentEnv query
9686
+ */
9687
+ async deploymentEnv(variables: Types.DeploymentEnvQueryVariables): Promise<Types.DeploymentEnvQuery> {
9688
+ return await this.client.request<Types.DeploymentEnvQuery>(deploymentEnvDocument, variables);
9689
+ }
9690
+
9691
+ /**
9692
+ * ChannelInfo query
9693
+ */
9694
+ async channelInfo(): Promise<Types.ChannelInfoQuery> {
9695
+ return await this.client.request<Types.ChannelInfoQuery>(channelInfoDocument);
9696
+ }
9697
+
9698
+ /**
9699
+ * ValidateChannelToken query
9700
+ */
9701
+ async validateChannelToken(): Promise<Types.ValidateChannelTokenQuery> {
9702
+ return await this.client.request<Types.ValidateChannelTokenQuery>(validateChannelTokenDocument);
9703
+ }
9704
+
9705
+ /**
9706
+ * CreateDeployment mutation
9707
+ */
9708
+ async createDeployment(variables: Types.CreateDeploymentMutationVariables): Promise<Types.CreateDeploymentMutation> {
9709
+ return await this.client.request<Types.CreateDeploymentMutation>(createDeploymentDocument, variables);
9710
+ }
9711
+
9712
+ /**
9713
+ * DeleteDeployment mutation
9714
+ */
9715
+ async deleteDeployment(variables: Types.DeleteDeploymentMutationVariables): Promise<Types.DeleteDeploymentMutation> {
9716
+ return await this.client.request<Types.DeleteDeploymentMutation>(deleteDeploymentDocument, variables);
9717
+ }
9718
+
9719
+ /**
9720
+ * ScaleDeployment mutation
9721
+ */
9722
+ async scaleDeployment(variables: Types.ScaleDeploymentMutationVariables): Promise<Types.ScaleDeploymentMutation> {
9723
+ return await this.client.request<Types.ScaleDeploymentMutation>(scaleDeploymentDocument, variables);
9724
+ }
9725
+
9726
+ /**
9727
+ * SetDeploymentEnv mutation
9728
+ */
9729
+ async setDeploymentEnv(variables: Types.SetDeploymentEnvMutationVariables): Promise<Types.SetDeploymentEnvMutation> {
9730
+ return await this.client.request<Types.SetDeploymentEnvMutation>(setDeploymentEnvDocument, variables);
9731
+ }
9732
+
9733
+ /**
9734
+ * UnsetDeploymentEnv mutation
9735
+ */
9736
+ async unsetDeploymentEnv(variables: Types.UnsetDeploymentEnvMutationVariables): Promise<Types.UnsetDeploymentEnvMutation> {
9737
+ return await this.client.request<Types.UnsetDeploymentEnvMutation>(unsetDeploymentEnvDocument, variables);
9738
+ }
9739
+
9740
+ /**
9741
+ * RefreshDeploymentStatus mutation
9742
+ */
9743
+ async refreshDeploymentStatus(variables: Types.RefreshDeploymentStatusMutationVariables): Promise<Types.RefreshDeploymentStatusMutation> {
9744
+ return await this.client.request<Types.RefreshDeploymentStatusMutation>(refreshDeploymentStatusDocument, variables);
9745
+ }
9746
+
9747
+ /**
9748
+ * DeploymentLogs subscription
9749
+ */
9750
+ async *deploymentLogs(variables: Types.DeploymentLogsSubscriptionVariables): AsyncIterableIterator<Types.DeploymentLogsSubscription> {
9751
+ const iterator = this.client.subscribe<Types.DeploymentLogsSubscription>(deploymentLogsDocument, variables);
9752
+ for await (const data of iterator) {
9753
+ yield data;
9754
+ }
9755
+ }
9756
+ }
9757
+
9435
9758
  /**
9436
9759
  * EntityDuplication operations
9437
9760
  */
@@ -9453,6 +9776,23 @@ class EntityDuplicationOperations {
9453
9776
  }
9454
9777
  }
9455
9778
 
9779
+ /**
9780
+ * EntityEvents operations
9781
+ */
9782
+ class EntityEventsOperations {
9783
+ constructor(private client: BaseGraphQLClient) {}
9784
+
9785
+ /**
9786
+ * entityEvent subscription
9787
+ */
9788
+ async *entityEvent(variables: Types.EntityEventSubscriptionVariables): AsyncIterableIterator<Types.EntityEventSubscription> {
9789
+ const iterator = this.client.subscribe<Types.EntityEventSubscription>(entityEventDocument, variables);
9790
+ for await (const data of iterator) {
9791
+ yield data;
9792
+ }
9793
+ }
9794
+ }
9795
+
9456
9796
  /**
9457
9797
  * Facet operations
9458
9798
  */
@@ -10726,7 +11066,9 @@ export class AdminNamespace {
10726
11066
  readonly customFields: CustomFieldsOperations;
10727
11067
  readonly customerGroup: CustomerGroupOperations;
10728
11068
  readonly customer: CustomerOperations;
11069
+ readonly deployment: DeploymentOperations;
10729
11070
  readonly entityDuplication: EntityDuplicationOperations;
11071
+ readonly entityEvents: EntityEventsOperations;
10730
11072
  readonly facet: FacetOperations;
10731
11073
  readonly fulfillment: FulfillmentOperations;
10732
11074
  readonly globalSettings: GlobalSettingsOperations;
@@ -10750,6 +11092,25 @@ export class AdminNamespace {
10750
11092
  readonly tax: TaxOperations;
10751
11093
  readonly zone: ZoneOperations;
10752
11094
 
11095
+ // Event handler registry and state
11096
+ private eventRegistry: EventHandlerRegistry = {
11097
+ handlers: new Map(),
11098
+ blockingHandlers: new Map(),
11099
+ };
11100
+ private eventSubscription: AsyncIterableIterator<{ entityEvent: EntityEventPayload }> | null = null;
11101
+ private isListening = false;
11102
+ private retryCount = 0;
11103
+ private abortController: AbortController | null = null;
11104
+
11105
+ // Reconnection configuration
11106
+ private static readonly RECONNECT_CONFIG = {
11107
+ maxRetries: 5,
11108
+ baseDelayMs: 1000,
11109
+ maxDelayMs: 30000,
11110
+ backoffMultiplier: 2,
11111
+ };
11112
+ private static readonly BLOCKING_TIMEOUT_MS = 1000;
11113
+
10753
11114
  constructor(config: SDKConfig) {
10754
11115
  this.client = new BaseGraphQLClient(config);
10755
11116
 
@@ -10763,7 +11124,9 @@ export class AdminNamespace {
10763
11124
  this.customFields = new CustomFieldsOperations(this.client);
10764
11125
  this.customerGroup = new CustomerGroupOperations(this.client);
10765
11126
  this.customer = new CustomerOperations(this.client);
11127
+ this.deployment = new DeploymentOperations(this.client);
10766
11128
  this.entityDuplication = new EntityDuplicationOperations(this.client);
11129
+ this.entityEvents = new EntityEventsOperations(this.client);
10767
11130
  this.facet = new FacetOperations(this.client);
10768
11131
  this.fulfillment = new FulfillmentOperations(this.client);
10769
11132
  this.globalSettings = new GlobalSettingsOperations(this.client);
@@ -10809,4 +11172,173 @@ export class AdminNamespace {
10809
11172
  dispose(): void {
10810
11173
  this.client.dispose();
10811
11174
  }
11175
+
11176
+ /**
11177
+ * Register a non-blocking event handler
11178
+ * The callback will be called for each matching event without waiting
11179
+ */
11180
+ registerEventHandler(
11181
+ eventName: string,
11182
+ callback: EventCallback
11183
+ ): EventSubscription {
11184
+ if (!this.eventRegistry.handlers.has(eventName)) {
11185
+ this.eventRegistry.handlers.set(eventName, new Set());
11186
+ }
11187
+ this.eventRegistry.handlers.get(eventName)!.add(callback);
11188
+
11189
+ void this.ensureEventListening();
11190
+
11191
+ return {
11192
+ unsubscribe: () => {
11193
+ this.eventRegistry.handlers.get(eventName)?.delete(callback);
11194
+ },
11195
+ };
11196
+ }
11197
+
11198
+ /**
11199
+ * Register a blocking event handler
11200
+ * The callback must complete within 1000ms or it will timeout
11201
+ */
11202
+ registerBlockingEventHandler(
11203
+ eventName: string,
11204
+ callback: BlockingEventCallback
11205
+ ): EventSubscription {
11206
+ if (!this.eventRegistry.blockingHandlers.has(eventName)) {
11207
+ this.eventRegistry.blockingHandlers.set(eventName, new Set());
11208
+ }
11209
+ this.eventRegistry.blockingHandlers.get(eventName)!.add(callback);
11210
+
11211
+ void this.ensureEventListening();
11212
+
11213
+ return {
11214
+ unsubscribe: () => {
11215
+ this.eventRegistry.blockingHandlers.get(eventName)?.delete(callback);
11216
+ },
11217
+ };
11218
+ }
11219
+
11220
+ /**
11221
+ * Start listening to events with retry logic
11222
+ */
11223
+ private async ensureEventListening(): Promise<void> {
11224
+ if (this.isListening) return;
11225
+ this.isListening = true;
11226
+ this.retryCount = 0;
11227
+ this.abortController = new AbortController();
11228
+
11229
+ await this.startSubscription();
11230
+ }
11231
+
11232
+ private async startSubscription(): Promise<void> {
11233
+ try {
11234
+ this.eventSubscription = this.client.subscribe<{ entityEvent: EntityEventPayload }>(
11235
+ entityEventDocument,
11236
+ {}
11237
+ );
11238
+
11239
+ // Reset retry count on successful connection
11240
+ this.retryCount = 0;
11241
+
11242
+ // Process events
11243
+ for await (const result of this.eventSubscription!) {
11244
+ if (!this.isListening) break;
11245
+ const event = result.entityEvent;
11246
+ await this.dispatchEvent(event);
11247
+ }
11248
+ } catch (error) {
11249
+ if (this.isListening) {
11250
+ console.error('Event subscription error:', error);
11251
+ await this.handleReconnect();
11252
+ }
11253
+ }
11254
+ }
11255
+
11256
+ private async handleReconnect(): Promise<void> {
11257
+ const { maxRetries, baseDelayMs, maxDelayMs, backoffMultiplier } = AdminNamespace.RECONNECT_CONFIG;
11258
+
11259
+ if (this.retryCount >= maxRetries) {
11260
+ this.isListening = false;
11261
+ throw new Error(`Max reconnection attempts (${maxRetries}) exceeded`);
11262
+ }
11263
+
11264
+ // Calculate delay with exponential backoff
11265
+ const delay = Math.min(
11266
+ baseDelayMs * Math.pow(backoffMultiplier, this.retryCount),
11267
+ maxDelayMs
11268
+ );
11269
+
11270
+ this.retryCount++;
11271
+ console.log(`Reconnecting in ${delay}ms (attempt ${this.retryCount}/${maxRetries})`);
11272
+
11273
+ await new Promise(resolve => setTimeout(resolve, delay));
11274
+ await this.startSubscription();
11275
+ }
11276
+
11277
+ /**
11278
+ * Dispatch event to registered handlers
11279
+ */
11280
+ private async dispatchEvent(event: EntityEventPayload): Promise<void> {
11281
+ const eventName = event.eventName;
11282
+
11283
+ // Non-blocking handlers (fire-and-forget)
11284
+ const handlers = this.eventRegistry.handlers.get(eventName);
11285
+ if (handlers) {
11286
+ for (const handler of handlers) {
11287
+ try {
11288
+ handler(event);
11289
+ } catch (error) {
11290
+ console.error(`Error in event handler for ${eventName}:`, error);
11291
+ }
11292
+ }
11293
+ }
11294
+
11295
+ // Blocking handlers (with timeout)
11296
+ const blockingHandlers = this.eventRegistry.blockingHandlers.get(eventName);
11297
+ if (blockingHandlers) {
11298
+ for (const handler of blockingHandlers) {
11299
+ try {
11300
+ await this.executeWithTimeout(
11301
+ handler(event),
11302
+ AdminNamespace.BLOCKING_TIMEOUT_MS,
11303
+ `Blocking handler for ${eventName} exceeded ${AdminNamespace.BLOCKING_TIMEOUT_MS}ms`
11304
+ );
11305
+ } catch (error) {
11306
+ console.error(`Error in blocking event handler for ${eventName}:`, error);
11307
+ throw error; // Re-throw for blocking handlers
11308
+ }
11309
+ }
11310
+ }
11311
+ }
11312
+
11313
+ /**
11314
+ * Execute promise with timeout
11315
+ */
11316
+ private async executeWithTimeout<T>(
11317
+ promise: Promise<T>,
11318
+ timeoutMs: number,
11319
+ errorMessage: string
11320
+ ): Promise<T> {
11321
+ return Promise.race([
11322
+ promise,
11323
+ new Promise<never>((_, reject) =>
11324
+ setTimeout(() => reject(new Error(errorMessage)), timeoutMs)
11325
+ ),
11326
+ ]);
11327
+ }
11328
+
11329
+ /**
11330
+ * Stop all event listening
11331
+ */
11332
+ stopEventListening(): void {
11333
+ this.isListening = false;
11334
+ this.retryCount = 0;
11335
+ if (this.abortController) {
11336
+ this.abortController.abort();
11337
+ this.abortController = null;
11338
+ }
11339
+ this.eventSubscription = null;
11340
+ this.eventRegistry.handlers.clear();
11341
+ this.eventRegistry.blockingHandlers.clear();
11342
+ }
11343
+
10812
11344
  }