@ioka-technologies/asyncapi-ts-client-template 0.0.35 → 0.0.41

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ioka-technologies/asyncapi-ts-client-template",
3
- "version": "0.0.35",
3
+ "version": "0.0.41",
4
4
  "description": "TypeScript AsyncAPI client generator template compatible with rust-asyncapi patterns",
5
5
  "main": "template/index.js",
6
6
  "scripts": {
@@ -24,6 +24,10 @@
24
24
  "rust-asyncapi"
25
25
  ],
26
26
  "author": "AsyncAPI TypeScript Generator",
27
+ "repository": {
28
+ "type": "git",
29
+ "url": "https://github.com/Ioka-Technologies/asyncapi-template"
30
+ },
27
31
  "license": "Apache-2.0",
28
32
  "dependencies": {
29
33
  "@asyncapi/generator-react-sdk": "^1.0.20"
@@ -142,14 +142,23 @@ import * as Models from './models';
142
142
  export class ${clientName} {
143
143
  private transport: Transport;
144
144
  private config: TransportConfig;
145
+ private connectPromise: Promise<void> | null = null;
145
146
 
146
147
  constructor(config: TransportConfig) {
147
148
  this.config = config;
148
149
  this.transport = TransportFactory.create(config);
149
150
  }
150
151
 
151
- async connect(): Promise<void> {
152
- await this.transport.connect();
152
+ connect(): Promise<void> {
153
+ if (this.transport.isConnected()) {
154
+ return Promise.resolve();
155
+ }
156
+ if (!this.connectPromise) {
157
+ this.connectPromise = this.transport.connect().finally(() => {
158
+ this.connectPromise = null;
159
+ });
160
+ }
161
+ return this.connectPromise;
153
162
  }
154
163
 
155
164
  async disconnect(): Promise<void> {
@@ -185,6 +194,29 @@ export class ${clientName} {
185
194
  return this.config.auth;
186
195
  }
187
196
 
197
+ /**
198
+ * Check if the transport is currently connected
199
+ */
200
+ isConnected(): boolean {
201
+ return this.transport.isConnected();
202
+ }
203
+
204
+ /**
205
+ * Register a callback for when the transport reconnects after a disconnect.
206
+ * Returns an unsubscribe function.
207
+ */
208
+ onReconnected(callback: () => void): () => void {
209
+ return this.transport.onReconnected(callback);
210
+ }
211
+
212
+ /**
213
+ * Register a callback for when the transport disconnects unexpectedly.
214
+ * Returns an unsubscribe function.
215
+ */
216
+ onDisconnected(callback: (reason: string) => void): () => void {
217
+ return this.transport.onDisconnected(callback);
218
+ }
219
+
188
220
  // Generated operation methods
189
221
  `;
190
222
 
@@ -473,8 +505,8 @@ export class ${clientName} {
473
505
 
474
506
  if (hasReply) {
475
507
  // Request/Response pattern - send and wait for response
476
- const requestPayloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
477
- const responseType = replyMessageTypes.length > 0 ? `Models.${replyMessageTypes[0]}Payload` : 'any';
508
+ const requestPayloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
509
+ const responseType = replyMessageTypes.length > 0 ? `Models.${replyMessageTypes[0]}` : 'any';
478
510
 
479
511
  content += `
480
512
  /**
@@ -496,7 +528,7 @@ export class ${clientName} {
496
528
  `;
497
529
  } else {
498
530
  // Regular send operation (fire and forget)
499
- const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
531
+ const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
500
532
  content += `
501
533
  /**
502
534
  * ${methodName} - Send operation (fire and forget)
@@ -539,7 +571,7 @@ export class ${clientName} {
539
571
  const methodName = sanitizeMethodName(operationId);
540
572
 
541
573
  // Generate receive method (event listener setup)
542
- const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
574
+ const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
543
575
  content += `
544
576
  /**
545
577
  * ${methodName} - Receive operation
@@ -708,8 +740,8 @@ export class ${serviceName} {
708
740
  }
709
741
 
710
742
  if (hasReply) {
711
- const requestPayloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
712
- const responseType = replyMessageTypes.length > 0 ? `Models.${replyMessageTypes[0]}Payload` : 'any';
743
+ const requestPayloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
744
+ const responseType = replyMessageTypes.length > 0 ? `Models.${replyMessageTypes[0]}` : 'any';
713
745
 
714
746
  content += `
715
747
  /**
@@ -729,7 +761,7 @@ export class ${serviceName} {
729
761
  }
730
762
  `;
731
763
  } else {
732
- const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
764
+ const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
733
765
  content += `
734
766
  /**
735
767
  * ${methodName} - Send operation (fire and forget)
@@ -767,7 +799,7 @@ export class ${serviceName} {
767
799
  }
768
800
  } else if (action === 'receive') {
769
801
  // Generate receive method (event listener setup) for dynamic channels
770
- const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}Payload` : 'any';
802
+ const payloadType = messageTypes.length > 0 ? `Models.${messageTypes[0]}` : 'any';
771
803
  content += `
772
804
  /**
773
805
  * ${methodName} - Receive operation
@@ -7,7 +7,8 @@ export default function ({ asyncapi, params }) {
7
7
  {`export * from './client';
8
8
  export * from './models';
9
9
  export * from './runtime/types';
10
- export * from './runtime/errors';`}
10
+ export * from './runtime/errors';
11
+ export { RECONNECT_PRESETS, ReconnectPreset, getReconnectPreset } from './runtime/retry/presets';`}
11
12
  </File>
12
13
  );
13
14
  }
@@ -5,6 +5,7 @@ export default function ({ asyncapi, params }) {
5
5
  return (
6
6
  <File name="presets.ts">
7
7
  {`import { RetryConfig, RetryPreset } from './types';
8
+ import { ReconnectConfig } from '../types';
8
9
 
9
10
  /**
10
11
  * Predefined retry configuration presets
@@ -75,6 +76,57 @@ export function mergeRetryConfig(preset: RetryPreset, overrides: Partial<RetryCo
75
76
  ...overrides
76
77
  };
77
78
  }
79
+
80
+ /**
81
+ * Predefined reconnection configuration presets for WebSocket transport
82
+ */
83
+ export type ReconnectPreset = 'aggressive' | 'balanced' | 'conservative' | 'none';
84
+
85
+ export const RECONNECT_PRESETS: Record<ReconnectPreset, Required<ReconnectConfig>> = {
86
+ /** Aggressive reconnection - fast retries, unlimited attempts */
87
+ aggressive: {
88
+ enabled: true,
89
+ maxAttempts: 0,
90
+ baseDelay: 500,
91
+ maxDelay: 10000,
92
+ backoffMultiplier: 1.5,
93
+ jitter: true,
94
+ },
95
+ /** Balanced reconnection - moderate retries, unlimited attempts */
96
+ balanced: {
97
+ enabled: true,
98
+ maxAttempts: 0,
99
+ baseDelay: 1000,
100
+ maxDelay: 30000,
101
+ backoffMultiplier: 2,
102
+ jitter: true,
103
+ },
104
+ /** Conservative reconnection - slow retries, limited attempts */
105
+ conservative: {
106
+ enabled: true,
107
+ maxAttempts: 10,
108
+ baseDelay: 2000,
109
+ maxDelay: 60000,
110
+ backoffMultiplier: 2,
111
+ jitter: true,
112
+ },
113
+ /** No reconnection */
114
+ none: {
115
+ enabled: false,
116
+ maxAttempts: 0,
117
+ baseDelay: 0,
118
+ maxDelay: 0,
119
+ backoffMultiplier: 0,
120
+ jitter: false,
121
+ },
122
+ };
123
+
124
+ /**
125
+ * Get reconnect configuration from preset name
126
+ */
127
+ export function getReconnectPreset(preset: ReconnectPreset): Required<ReconnectConfig> {
128
+ return RECONNECT_PRESETS[preset];
129
+ }
78
130
  `}
79
131
  </File>
80
132
  );
@@ -195,6 +195,34 @@ export class HttpTransport implements Transport {
195
195
  }
196
196
  }
197
197
 
198
+ /**
199
+ * Check if the transport is currently connected.
200
+ * HTTP transport is always considered connected.
201
+ */
202
+ isConnected(): boolean {
203
+ return true;
204
+ }
205
+
206
+ /**
207
+ * Register a callback for when the transport reconnects after a disconnect.
208
+ * HTTP transport does not have persistent connections, so this is a no-op.
209
+ * Returns an unsubscribe function.
210
+ */
211
+ onReconnected(callback: () => void): () => void {
212
+ // No-op for HTTP transport
213
+ return () => {};
214
+ }
215
+
216
+ /**
217
+ * Register a callback for when the transport disconnects unexpectedly.
218
+ * HTTP transport does not have persistent connections, so this is a no-op.
219
+ * Returns an unsubscribe function.
220
+ */
221
+ onDisconnected(callback: (reason: string) => void): () => void {
222
+ // No-op for HTTP transport
223
+ return () => {};
224
+ }
225
+
198
226
  subscribe(channel: string, operation: string, callback: (envelope: MessageEnvelope) => void): () => void {
199
227
  // HTTP transport doesn't support real-time subscriptions
200
228
  // This is a placeholder implementation that logs a warning