@bernierllc/chat-suite 1.4.0 → 2.0.1

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/CHANGELOG.md CHANGED
@@ -3,6 +3,25 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.0.1](https://github.com/bernierllc/tools/compare/@bernierllc/chat-suite@1.5.0...@bernierllc/chat-suite@2.0.1) (2026-05-20)
7
+
8
+ **Note:** Version bump only for package @bernierllc/chat-suite
9
+
10
+
11
+
12
+
13
+
14
+ # 1.5.0 (2026-05-20)
15
+
16
+
17
+ ### Features
18
+
19
+ * **validators-a11y-focus-order:** es2022, errors.ts with error.cause ([cfa9604](https://github.com/bernierllc/tools/commit/cfa96049636732b7961b5dab3a2a1cdc8a2a9480))
20
+
21
+
22
+
23
+
24
+
6
25
  # 1.4.0 (2026-05-20)
7
26
 
8
27
 
@@ -0,0 +1,42 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+
9
+ import { ChatSuiteError } from '../../src/errors';
10
+
11
+ describe('ChatSuiteError (ES2022)', () => {
12
+ it('preserves cause chain via native Error.cause', () => {
13
+ const original = new Error('boom');
14
+ const wrapped = new ChatSuiteError('outer failure', {
15
+ code: 'PROVIDER_ERROR',
16
+ cause: original
17
+ });
18
+
19
+ expect(wrapped).toBeInstanceOf(ChatSuiteError);
20
+ expect(wrapped).toBeInstanceOf(Error);
21
+ expect(wrapped.message).toBe('outer failure');
22
+ expect(wrapped.code).toBe('PROVIDER_ERROR');
23
+ expect(wrapped.cause).toBe(original);
24
+ });
25
+
26
+ it('defaults code to CHAT_SUITE_ERROR when not provided', () => {
27
+ const err = new ChatSuiteError('something went wrong');
28
+ expect(err.code).toBe('CHAT_SUITE_ERROR');
29
+ expect(err.cause).toBeUndefined();
30
+ expect(err.context).toBeUndefined();
31
+ expect(err.name).toBe('ChatSuiteError');
32
+ });
33
+
34
+ it('preserves structured context', () => {
35
+ const err = new ChatSuiteError('routing failed', {
36
+ code: 'ROUTING_ERROR',
37
+ context: { providerType: 'slack', attempts: 3 }
38
+ });
39
+ expect(err.context).toEqual({ providerType: 'slack', attempts: 3 });
40
+ expect(err.code).toBe('ROUTING_ERROR');
41
+ });
42
+ });
package/dist/ChatSuite.js CHANGED
@@ -22,9 +22,15 @@ const neverhub_1 = require("./neverhub");
22
22
  * Main chat suite orchestration class
23
23
  */
24
24
  class ChatSuite {
25
+ configManager;
26
+ userManager;
27
+ healthMonitor;
28
+ providerManager;
29
+ messageOrchestrator;
30
+ neverhubAdapter;
31
+ neverhubConnected = false;
32
+ initialized = false;
25
33
  constructor(config) {
26
- this.neverhubConnected = false;
27
- this.initialized = false;
28
34
  this.configManager = new ConfigManager_1.ConfigManager(config);
29
35
  this.userManager = new UserManager_1.UserManager();
30
36
  this.healthMonitor = new HealthMonitor_1.HealthMonitor();
@@ -44,7 +50,7 @@ class ChatSuite {
44
50
  // 2. Initialize ChatKit provider (always required)
45
51
  const chatKitResult = await this.initializeChatKitProvider(config);
46
52
  if (!chatKitResult.success) {
47
- throw new error_handling_1.ChatSuiteError(error_handling_1.ChatSuiteErrorType.INITIALIZATION_ERROR, `Failed to initialize ChatKit: ${chatKitResult.error}`);
53
+ throw new error_handling_1.ChatSuiteError(`Failed to initialize ChatKit: ${chatKitResult.error}`, { code: 'INITIALIZATION_ERROR' });
48
54
  }
49
55
  // 3. Initialize message bridge (if configured)
50
56
  if (config.messageBridge) {
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Typed error code union for chat-suite errors.
3
+ *
4
+ * Replaces the previous `ChatSuiteErrorType` enum (removed in 2.0.0).
5
+ * Consumers should use the string literal directly, e.g. `'MESSAGE_ERROR'`.
6
+ */
7
+ export type ChatSuiteErrorCode = 'CHAT_SUITE_ERROR' | 'PROVIDER_ERROR' | 'ROUTING_ERROR' | 'CONFIGURATION_ERROR' | 'INITIALIZATION_ERROR' | 'MESSAGE_ERROR' | 'NEVERHUB_ERROR';
8
+ /**
9
+ * Options bag accepted by `ChatSuiteError`.
10
+ *
11
+ * - `cause`: chained underlying error (ES2022 Error.cause).
12
+ * - `code`: a typed error code from {@link ChatSuiteErrorCode}.
13
+ * - `context`: arbitrary structured context.
14
+ */
15
+ export interface ChatSuiteErrorOptions {
16
+ cause?: Error;
17
+ code?: ChatSuiteErrorCode;
18
+ context?: Record<string, unknown>;
19
+ }
20
+ /**
21
+ * Custom error class for chat suite errors.
22
+ *
23
+ * Uses native ES2022 `Error.cause` for error chaining — read the underlying
24
+ * error via `error.cause`. Structured context lives on `error.context`.
25
+ */
26
+ export declare class ChatSuiteError extends Error {
27
+ readonly code: ChatSuiteErrorCode;
28
+ readonly context?: Record<string, unknown>;
29
+ constructor(message: string, options?: ChatSuiteErrorOptions);
30
+ }
31
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB,GAC1B,kBAAkB,GAClB,gBAAgB,GAChB,eAAe,GACf,qBAAqB,GACrB,sBAAsB,GACtB,eAAe,GACf,gBAAgB,CAAC;AAErB;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;;GAKG;AACH,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAC;IACzC,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEtC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;CAS7D"}
package/dist/errors.js ADDED
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ /*
3
+ Copyright (c) 2025 Bernier LLC
4
+
5
+ This file is licensed to the client under a limited-use license.
6
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
7
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.ChatSuiteError = void 0;
11
+ /**
12
+ * Custom error class for chat suite errors.
13
+ *
14
+ * Uses native ES2022 `Error.cause` for error chaining — read the underlying
15
+ * error via `error.cause`. Structured context lives on `error.context`.
16
+ */
17
+ class ChatSuiteError extends Error {
18
+ code;
19
+ context;
20
+ constructor(message, options) {
21
+ super(message, options?.cause ? { cause: options.cause } : undefined);
22
+ this.name = 'ChatSuiteError';
23
+ this.code = options?.code ?? 'CHAT_SUITE_ERROR';
24
+ if (options?.context !== undefined) {
25
+ this.context = options.context;
26
+ }
27
+ Error.captureStackTrace?.(this, this.constructor);
28
+ }
29
+ }
30
+ exports.ChatSuiteError = ChatSuiteError;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { ChatSuite } from './ChatSuite';
2
+ export { ChatSuiteError, type ChatSuiteErrorCode, type ChatSuiteErrorOptions } from './errors';
2
3
  export * from './types';
3
4
  export * from './services';
4
5
  export * from './providers';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAGlB,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC;AAG3B,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -21,10 +21,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
21
21
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
22
22
  };
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
- exports.ChatSuite = void 0;
24
+ exports.ChatSuiteError = exports.ChatSuite = void 0;
25
25
  // Main export
26
26
  var ChatSuite_1 = require("./ChatSuite");
27
27
  Object.defineProperty(exports, "ChatSuite", { enumerable: true, get: function () { return ChatSuite_1.ChatSuite; } });
28
+ // Errors
29
+ var errors_1 = require("./errors");
30
+ Object.defineProperty(exports, "ChatSuiteError", { enumerable: true, get: function () { return errors_1.ChatSuiteError; } });
28
31
  // Types
29
32
  __exportStar(require("./types"), exports);
30
33
  // Services
@@ -15,12 +15,16 @@ const chatkit_adapter_1 = require("@bernierllc/chatkit-adapter");
15
15
  * ChatKit provider implementation
16
16
  */
17
17
  class ChatKitProvider {
18
+ config;
19
+ type = 'chatkit';
20
+ name = '@bernierllc/chatkit-adapter';
21
+ adapter;
22
+ initialized = false;
23
+ errorCount = 0;
24
+ lastError;
25
+ initTime;
18
26
  constructor(config = {}) {
19
27
  this.config = config;
20
- this.type = 'chatkit';
21
- this.name = '@bernierllc/chatkit-adapter';
22
- this.initialized = false;
23
- this.errorCount = 0;
24
28
  }
25
29
  /**
26
30
  * Initialize the ChatKit provider
@@ -15,9 +15,7 @@ exports.getAvailableProviders = getAvailableProviders;
15
15
  * These are optional peer dependencies and will be implemented when those packages are available
16
16
  */
17
17
  class ExternalProvider {
18
- constructor() {
19
- this.initialized = false;
20
- }
18
+ initialized = false;
21
19
  async initialize() {
22
20
  throw new Error(`${this.name} provider is not implemented yet. ` +
23
21
  `Install ${this.name} package to enable this provider.`);
@@ -64,10 +62,10 @@ class ExternalProvider {
64
62
  * ```
65
63
  */
66
64
  class SlackProvider extends ExternalProvider {
65
+ type = 'slack';
66
+ name = '@bernierllc/chat-integration-slack';
67
67
  constructor(_config) {
68
68
  super();
69
- this.type = 'slack';
70
- this.name = '@bernierllc/chat-integration-slack';
71
69
  }
72
70
  }
73
71
  exports.SlackProvider = SlackProvider;
@@ -92,10 +90,10 @@ exports.SlackProvider = SlackProvider;
92
90
  * ```
93
91
  */
94
92
  class DiscordProvider extends ExternalProvider {
93
+ type = 'discord';
94
+ name = '@bernierllc/chat-integration-discord';
95
95
  constructor(_config) {
96
96
  super();
97
- this.type = 'discord';
98
- this.name = '@bernierllc/chat-integration-discord';
99
97
  }
100
98
  }
101
99
  exports.DiscordProvider = DiscordProvider;
@@ -121,10 +119,10 @@ exports.DiscordProvider = DiscordProvider;
121
119
  * ```
122
120
  */
123
121
  class TeamsProvider extends ExternalProvider {
122
+ type = 'teams';
123
+ name = '@bernierllc/chat-integration-teams';
124
124
  constructor(_config) {
125
125
  super();
126
- this.type = 'teams';
127
- this.name = '@bernierllc/chat-integration-teams';
128
126
  }
129
127
  }
130
128
  exports.TeamsProvider = TeamsProvider;
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigManager.d.ts","sourceRoot":"","sources":["../../src/services/ConfigManager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAmC;gBAE9C,aAAa,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKpD;;OAEG;IACI,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAI7C;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAM5D;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,MAAM,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAIvE;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;IACI,cAAc,IAAI,IAAI;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACI,MAAM,IAAI,MAAM;IAIvB;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAYpC"}
1
+ {"version":3,"file":"ConfigManager.d.ts","sourceRoot":"","sources":["../../src/services/ConfigManager.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIhD;;GAEG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,eAAe,CAAmC;gBAE9C,aAAa,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC;IAKpD;;OAEG;IACI,SAAS,IAAI,QAAQ,CAAC,eAAe,CAAC;IAI7C;;OAEG;IACI,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,eAAe,CAAC,GAAG,IAAI;IAM5D;;OAEG;IACI,GAAG,CAAC,CAAC,SAAS,MAAM,eAAe,EAAE,GAAG,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC;IAIvE;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAIrD;;OAEG;IACI,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIxC;;OAEG;IACI,cAAc,IAAI,IAAI;IAI7B;;OAEG;IACI,KAAK,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAU7B;;OAEG;IACI,MAAM,IAAI,MAAM;IAIvB;;OAEG;IACI,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;CAcpC"}
@@ -14,8 +14,9 @@ const error_handling_1 = require("../utils/error-handling");
14
14
  * Manages chat suite configuration with validation and inheritance
15
15
  */
16
16
  class ConfigManager {
17
+ config;
18
+ configOverrides = new Map();
17
19
  constructor(initialConfig) {
18
- this.configOverrides = new Map();
19
20
  this.config = (0, config_inheritance_1.mergeConfigs)(config_inheritance_1.DEFAULT_SUITE_CONFIG, initialConfig || {});
20
21
  this.validateConfiguration();
21
22
  }
@@ -70,7 +71,7 @@ class ConfigManager {
70
71
  validateConfiguration(config = this.config) {
71
72
  const validation = (0, config_inheritance_1.validateConfig)(config);
72
73
  if (!validation.valid) {
73
- throw new error_handling_1.ChatSuiteError(error_handling_1.ChatSuiteErrorType.CONFIGURATION_ERROR, `Configuration validation failed: ${validation.errors.join(', ')}`);
74
+ throw new error_handling_1.ChatSuiteError(`Configuration validation failed: ${validation.errors.join(', ')}`, { code: 'CONFIGURATION_ERROR' });
74
75
  }
75
76
  }
76
77
  /**
@@ -88,7 +89,10 @@ class ConfigManager {
88
89
  this.updateConfig(parsed);
89
90
  }
90
91
  catch (error) {
91
- throw new error_handling_1.ChatSuiteError(error_handling_1.ChatSuiteErrorType.CONFIGURATION_ERROR, 'Failed to parse configuration JSON', error instanceof Error ? error : undefined);
92
+ throw new error_handling_1.ChatSuiteError('Failed to parse configuration JSON', {
93
+ code: 'CONFIGURATION_ERROR',
94
+ cause: error instanceof Error ? error : undefined
95
+ });
92
96
  }
93
97
  }
94
98
  }
@@ -12,9 +12,9 @@ exports.HealthMonitor = void 0;
12
12
  * Monitors health of all chat suite components
13
13
  */
14
14
  class HealthMonitor {
15
- constructor() {
16
- this.providers = new Map();
17
- }
15
+ providers = new Map();
16
+ lastHealthCheck;
17
+ healthCheckInterval;
18
18
  /**
19
19
  * Register a provider for health monitoring
20
20
  */
@@ -14,9 +14,8 @@ const error_handling_1 = require("../utils/error-handling");
14
14
  * Orchestrates messages across all providers
15
15
  */
16
16
  class MessageOrchestrator {
17
- constructor() {
18
- this.messages = new Map();
19
- }
17
+ messageBridge;
18
+ messages = new Map();
20
19
  /**
21
20
  * Set message bridge for cross-platform sync
22
21
  */
@@ -101,7 +100,7 @@ class MessageOrchestrator {
101
100
  async bridgeMessage(sourceProvider, targetProvider, message) {
102
101
  try {
103
102
  if (!this.messageBridge) {
104
- throw new error_handling_1.ChatSuiteError(error_handling_1.ChatSuiteErrorType.CONFIGURATION_ERROR, 'Message bridge not configured');
103
+ throw new error_handling_1.ChatSuiteError('Message bridge not configured', { code: 'CONFIGURATION_ERROR' });
105
104
  }
106
105
  if (!this.messageBridge.shouldBridge(sourceProvider.type, targetProvider.type)) {
107
106
  return {
@@ -13,10 +13,8 @@ const error_handling_1 = require("../utils/error-handling");
13
13
  * Manages all chat providers
14
14
  */
15
15
  class ProviderManager {
16
- constructor() {
17
- this.providers = new Map();
18
- this.initializedProviders = new Set();
19
- }
16
+ providers = new Map();
17
+ initializedProviders = new Set();
20
18
  /**
21
19
  * Register a provider
22
20
  */
@@ -171,7 +169,7 @@ class ProviderManager {
171
169
  */
172
170
  unregisterProvider(providerType) {
173
171
  if (this.initializedProviders.has(providerType)) {
174
- throw new error_handling_1.ChatSuiteError(error_handling_1.ChatSuiteErrorType.PROVIDER_ERROR, `Cannot unregister initialized provider ${providerType}. Shutdown first.`);
172
+ throw new error_handling_1.ChatSuiteError(`Cannot unregister initialized provider ${providerType}. Shutdown first.`, { code: 'PROVIDER_ERROR' });
175
173
  }
176
174
  const deleted = this.providers.delete(providerType);
177
175
  if (!deleted) {
@@ -13,6 +13,7 @@ const user_mapping_1 = require("../utils/user-mapping");
13
13
  * Manages users across all chat providers
14
14
  */
15
15
  class UserManager {
16
+ mapper;
16
17
  constructor() {
17
18
  this.mapper = new user_mapping_1.UserMapper();
18
19
  }
@@ -1,27 +1,14 @@
1
1
  import type { SuiteResult } from '../types';
2
+ import { ChatSuiteError, type ChatSuiteErrorCode, type ChatSuiteErrorOptions } from '../errors';
3
+ export { ChatSuiteError };
4
+ export type { ChatSuiteErrorCode, ChatSuiteErrorOptions };
2
5
  /**
3
- * Chat suite error types
6
+ * Safely execute an async operation and return a SuiteResult.
7
+ *
8
+ * The optional `errorCode` parameter is used to prefix the returned error
9
+ * string (matching the previous `${type}: message` format).
4
10
  */
5
- export declare enum ChatSuiteErrorType {
6
- PROVIDER_ERROR = "PROVIDER_ERROR",
7
- ROUTING_ERROR = "ROUTING_ERROR",
8
- CONFIGURATION_ERROR = "CONFIGURATION_ERROR",
9
- INITIALIZATION_ERROR = "INITIALIZATION_ERROR",
10
- MESSAGE_ERROR = "MESSAGE_ERROR",
11
- NEVERHUB_ERROR = "NEVERHUB_ERROR"
12
- }
13
- /**
14
- * Custom error class for chat suite errors
15
- */
16
- export declare class ChatSuiteError extends Error {
17
- type: ChatSuiteErrorType;
18
- originalError?: Error | undefined;
19
- constructor(type: ChatSuiteErrorType, message: string, originalError?: Error | undefined);
20
- }
21
- /**
22
- * Safely execute an async operation and return a SuiteResult
23
- */
24
- export declare function safeExecute<T>(operation: () => Promise<T>, errorType?: ChatSuiteErrorType): Promise<SuiteResult<T>>;
11
+ export declare function safeExecute<T>(operation: () => Promise<T>, errorCode?: ChatSuiteErrorCode): Promise<SuiteResult<T>>;
25
12
  /**
26
13
  * Retry an operation with exponential backoff
27
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;GAEG;AACH,oBAAY,kBAAkB;IAC5B,cAAc,mBAAmB;IACjC,aAAa,kBAAkB;IAC/B,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;CAClC;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IAE9B,IAAI,EAAE,kBAAkB;IAExB,aAAa,CAAC,EAAE,KAAK;gBAFrB,IAAI,EAAE,kBAAkB,EAC/B,OAAO,EAAE,MAAM,EACR,aAAa,CAAC,EAAE,KAAK,YAAA;CAM/B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,kBAAqD,GAC/D,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAWzB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAYxD"}
1
+ {"version":3,"file":"error-handling.d.ts","sourceRoot":"","sources":["../../src/utils/error-handling.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EACL,cAAc,EACd,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,CAAC;AAC1B,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,CAAC;AAE1D;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,CAAC,EACjC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,SAAS,GAAE,kBAAoC,GAC9C,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAWzB;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,CAAC,EACpC,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,UAAU,GAAE,MAAU,EACtB,SAAS,GAAE,MAAa,GACvB,OAAO,CAAC,CAAC,CAAC,CAiBZ;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,GACb,MAAM,CAQR;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAWxD"}
@@ -7,40 +7,20 @@ The client may use and modify this code *only within the scope of the project it
7
7
  Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ChatSuiteError = exports.ChatSuiteErrorType = void 0;
10
+ exports.ChatSuiteError = void 0;
11
11
  exports.safeExecute = safeExecute;
12
12
  exports.retryOperation = retryOperation;
13
13
  exports.formatError = formatError;
14
14
  exports.isRetryableError = isRetryableError;
15
+ const errors_1 = require("../errors");
16
+ Object.defineProperty(exports, "ChatSuiteError", { enumerable: true, get: function () { return errors_1.ChatSuiteError; } });
15
17
  /**
16
- * Chat suite error types
18
+ * Safely execute an async operation and return a SuiteResult.
19
+ *
20
+ * The optional `errorCode` parameter is used to prefix the returned error
21
+ * string (matching the previous `${type}: message` format).
17
22
  */
18
- var ChatSuiteErrorType;
19
- (function (ChatSuiteErrorType) {
20
- ChatSuiteErrorType["PROVIDER_ERROR"] = "PROVIDER_ERROR";
21
- ChatSuiteErrorType["ROUTING_ERROR"] = "ROUTING_ERROR";
22
- ChatSuiteErrorType["CONFIGURATION_ERROR"] = "CONFIGURATION_ERROR";
23
- ChatSuiteErrorType["INITIALIZATION_ERROR"] = "INITIALIZATION_ERROR";
24
- ChatSuiteErrorType["MESSAGE_ERROR"] = "MESSAGE_ERROR";
25
- ChatSuiteErrorType["NEVERHUB_ERROR"] = "NEVERHUB_ERROR";
26
- })(ChatSuiteErrorType || (exports.ChatSuiteErrorType = ChatSuiteErrorType = {}));
27
- /**
28
- * Custom error class for chat suite errors
29
- */
30
- class ChatSuiteError extends Error {
31
- constructor(type, message, originalError) {
32
- super(message);
33
- this.type = type;
34
- this.originalError = originalError;
35
- this.name = 'ChatSuiteError';
36
- Object.setPrototypeOf(this, ChatSuiteError.prototype);
37
- }
38
- }
39
- exports.ChatSuiteError = ChatSuiteError;
40
- /**
41
- * Safely execute an async operation and return a SuiteResult
42
- */
43
- async function safeExecute(operation, errorType = ChatSuiteErrorType.MESSAGE_ERROR) {
23
+ async function safeExecute(operation, errorCode = 'MESSAGE_ERROR') {
44
24
  try {
45
25
  const data = await operation();
46
26
  return { success: true, data };
@@ -49,7 +29,7 @@ async function safeExecute(operation, errorType = ChatSuiteErrorType.MESSAGE_ERR
49
29
  const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
50
30
  return {
51
31
  success: false,
52
- error: `${errorType}: ${errorMessage}`
32
+ error: `${errorCode}: ${errorMessage}`
53
33
  };
54
34
  }
55
35
  }
@@ -76,8 +56,8 @@ async function retryOperation(operation, maxRetries = 3, baseDelay = 1000) {
76
56
  * Create a standardized error message
77
57
  */
78
58
  function formatError(context, error) {
79
- if (error instanceof ChatSuiteError) {
80
- return `[${context}] ${error.type}: ${error.message}`;
59
+ if (error instanceof errors_1.ChatSuiteError) {
60
+ return `[${context}] ${error.code}: ${error.message}`;
81
61
  }
82
62
  if (error instanceof Error) {
83
63
  return `[${context}] ${error.message}`;
@@ -88,9 +68,8 @@ function formatError(context, error) {
88
68
  * Check if an error is retryable
89
69
  */
90
70
  function isRetryableError(error) {
91
- if (error instanceof ChatSuiteError) {
92
- return error.type === ChatSuiteErrorType.PROVIDER_ERROR ||
93
- error.type === ChatSuiteErrorType.MESSAGE_ERROR;
71
+ if (error instanceof errors_1.ChatSuiteError) {
72
+ return error.code === 'PROVIDER_ERROR' || error.code === 'MESSAGE_ERROR';
94
73
  }
95
74
  if (error instanceof Error) {
96
75
  const message = error.message.toLowerCase();
@@ -12,10 +12,11 @@ exports.MessageBridge = void 0;
12
12
  * Message bridge for cross-platform synchronization
13
13
  */
14
14
  class MessageBridge {
15
+ config;
16
+ bridgedMessages = new Map();
17
+ channelMappings = new Map();
15
18
  constructor(config) {
16
19
  this.config = config;
17
- this.bridgedMessages = new Map();
18
- this.channelMappings = new Map();
19
20
  if (config.channelMappings) {
20
21
  this.channelMappings = config.channelMappings;
21
22
  }
@@ -13,10 +13,8 @@ exports.createUnifiedId = createUnifiedId;
13
13
  * User mapping storage
14
14
  */
15
15
  class UserMapper {
16
- constructor() {
17
- this.identities = new Map();
18
- this.providerIndex = new Map(); // provider:userId -> unifiedId
19
- }
16
+ identities = new Map();
17
+ providerIndex = new Map(); // provider:userId -> unifiedId
20
18
  /**
21
19
  * Create or update a user identity
22
20
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bernierllc/chat-suite",
3
- "version": "1.4.0",
3
+ "version": "2.0.1",
4
4
  "description": "Comprehensive chat orchestration suite with AI-powered routing",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -21,7 +21,7 @@
21
21
  "zod": "^3.22.0",
22
22
  "@bernierllc/chat-ai-router": "1.6.0",
23
23
  "@bernierllc/chat-analytics": "1.6.0",
24
- "@bernierllc/chatkit-adapter": "1.4.0",
24
+ "@bernierllc/chatkit-adapter": "1.5.0",
25
25
  "@bernierllc/neverhub-adapter": "0.4.0"
26
26
  },
27
27
  "peerDependenciesMeta": {
package/src/ChatSuite.ts CHANGED
@@ -25,7 +25,7 @@ import { ProviderManager } from './services/ProviderManager';
25
25
  import { MessageOrchestrator } from './services/MessageOrchestrator';
26
26
  import { ChatKitProvider } from './providers/ChatKitProvider';
27
27
  import { MessageBridge } from './utils/message-bridge';
28
- import { ChatSuiteError, ChatSuiteErrorType } from './utils/error-handling';
28
+ import { ChatSuiteError } from './utils/error-handling';
29
29
  import {
30
30
  registerWithNeverHub,
31
31
  unregisterFromNeverHub,
@@ -74,8 +74,8 @@ export class ChatSuite {
74
74
  const chatKitResult = await this.initializeChatKitProvider(config);
75
75
  if (!chatKitResult.success) {
76
76
  throw new ChatSuiteError(
77
- ChatSuiteErrorType.INITIALIZATION_ERROR,
78
- `Failed to initialize ChatKit: ${chatKitResult.error}`
77
+ `Failed to initialize ChatKit: ${chatKitResult.error}`,
78
+ { code: 'INITIALIZATION_ERROR' }
79
79
  );
80
80
  }
81
81
 
package/src/errors.ts ADDED
@@ -0,0 +1,56 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+
9
+ /**
10
+ * Typed error code union for chat-suite errors.
11
+ *
12
+ * Replaces the previous `ChatSuiteErrorType` enum (removed in 2.0.0).
13
+ * Consumers should use the string literal directly, e.g. `'MESSAGE_ERROR'`.
14
+ */
15
+ export type ChatSuiteErrorCode =
16
+ | 'CHAT_SUITE_ERROR'
17
+ | 'PROVIDER_ERROR'
18
+ | 'ROUTING_ERROR'
19
+ | 'CONFIGURATION_ERROR'
20
+ | 'INITIALIZATION_ERROR'
21
+ | 'MESSAGE_ERROR'
22
+ | 'NEVERHUB_ERROR';
23
+
24
+ /**
25
+ * Options bag accepted by `ChatSuiteError`.
26
+ *
27
+ * - `cause`: chained underlying error (ES2022 Error.cause).
28
+ * - `code`: a typed error code from {@link ChatSuiteErrorCode}.
29
+ * - `context`: arbitrary structured context.
30
+ */
31
+ export interface ChatSuiteErrorOptions {
32
+ cause?: Error;
33
+ code?: ChatSuiteErrorCode;
34
+ context?: Record<string, unknown>;
35
+ }
36
+
37
+ /**
38
+ * Custom error class for chat suite errors.
39
+ *
40
+ * Uses native ES2022 `Error.cause` for error chaining — read the underlying
41
+ * error via `error.cause`. Structured context lives on `error.context`.
42
+ */
43
+ export class ChatSuiteError extends Error {
44
+ public readonly code: ChatSuiteErrorCode;
45
+ public readonly context?: Record<string, unknown>;
46
+
47
+ constructor(message: string, options?: ChatSuiteErrorOptions) {
48
+ super(message, options?.cause ? { cause: options.cause } : undefined);
49
+ this.name = 'ChatSuiteError';
50
+ this.code = options?.code ?? 'CHAT_SUITE_ERROR';
51
+ if (options?.context !== undefined) {
52
+ this.context = options.context;
53
+ }
54
+ Error.captureStackTrace?.(this, this.constructor);
55
+ }
56
+ }
package/src/index.ts CHANGED
@@ -9,6 +9,13 @@ Redistribution or use in other products or commercial offerings is not permitted
9
9
  // Main export
10
10
  export { ChatSuite } from './ChatSuite';
11
11
 
12
+ // Errors
13
+ export {
14
+ ChatSuiteError,
15
+ type ChatSuiteErrorCode,
16
+ type ChatSuiteErrorOptions
17
+ } from './errors';
18
+
12
19
  // Types
13
20
  export * from './types';
14
21
 
@@ -8,7 +8,7 @@ Redistribution or use in other products or commercial offerings is not permitted
8
8
 
9
9
  import type { ChatSuiteConfig } from '../types';
10
10
  import { DEFAULT_SUITE_CONFIG, mergeConfigs, validateConfig } from '../utils/config-inheritance';
11
- import { ChatSuiteError, ChatSuiteErrorType } from '../utils/error-handling';
11
+ import { ChatSuiteError } from '../utils/error-handling';
12
12
 
13
13
  /**
14
14
  * Manages chat suite configuration with validation and inheritance
@@ -81,8 +81,8 @@ export class ConfigManager {
81
81
  const validation = validateConfig(config);
82
82
  if (!validation.valid) {
83
83
  throw new ChatSuiteError(
84
- ChatSuiteErrorType.CONFIGURATION_ERROR,
85
- `Configuration validation failed: ${validation.errors.join(', ')}`
84
+ `Configuration validation failed: ${validation.errors.join(', ')}`,
85
+ { code: 'CONFIGURATION_ERROR' }
86
86
  );
87
87
  }
88
88
  }
@@ -103,9 +103,11 @@ export class ConfigManager {
103
103
  this.updateConfig(parsed);
104
104
  } catch (error) {
105
105
  throw new ChatSuiteError(
106
- ChatSuiteErrorType.CONFIGURATION_ERROR,
107
106
  'Failed to parse configuration JSON',
108
- error instanceof Error ? error : undefined
107
+ {
108
+ code: 'CONFIGURATION_ERROR',
109
+ cause: error instanceof Error ? error : undefined
110
+ }
109
111
  );
110
112
  }
111
113
  }
@@ -17,7 +17,7 @@ import type {
17
17
  } from '../types';
18
18
  import { MessagePriority, MessageStatus } from '../types';
19
19
  import { MessageBridge } from '../utils/message-bridge';
20
- import { ChatSuiteError, ChatSuiteErrorType, retryOperation } from '../utils/error-handling';
20
+ import { ChatSuiteError, retryOperation } from '../utils/error-handling';
21
21
 
22
22
  /**
23
23
  * Orchestrates messages across all providers
@@ -135,8 +135,8 @@ export class MessageOrchestrator {
135
135
  try {
136
136
  if (!this.messageBridge) {
137
137
  throw new ChatSuiteError(
138
- ChatSuiteErrorType.CONFIGURATION_ERROR,
139
- 'Message bridge not configured'
138
+ 'Message bridge not configured',
139
+ { code: 'CONFIGURATION_ERROR' }
140
140
  );
141
141
  }
142
142
 
@@ -7,7 +7,7 @@ Redistribution or use in other products or commercial offerings is not permitted
7
7
  */
8
8
 
9
9
  import type { Provider, ProviderType, SuiteResult } from '../types';
10
- import { ChatSuiteError, ChatSuiteErrorType } from '../utils/error-handling';
10
+ import { ChatSuiteError } from '../utils/error-handling';
11
11
 
12
12
  /**
13
13
  * Provider registration information
@@ -204,8 +204,8 @@ export class ProviderManager {
204
204
  public unregisterProvider(providerType: ProviderType): SuiteResult<void> {
205
205
  if (this.initializedProviders.has(providerType)) {
206
206
  throw new ChatSuiteError(
207
- ChatSuiteErrorType.PROVIDER_ERROR,
208
- `Cannot unregister initialized provider ${providerType}. Shutdown first.`
207
+ `Cannot unregister initialized provider ${providerType}. Shutdown first.`,
208
+ { code: 'PROVIDER_ERROR' }
209
209
  );
210
210
  }
211
211
 
@@ -7,40 +7,24 @@ Redistribution or use in other products or commercial offerings is not permitted
7
7
  */
8
8
 
9
9
  import type { SuiteResult } from '../types';
10
+ import {
11
+ ChatSuiteError,
12
+ type ChatSuiteErrorCode,
13
+ type ChatSuiteErrorOptions
14
+ } from '../errors';
10
15
 
11
- /**
12
- * Chat suite error types
13
- */
14
- export enum ChatSuiteErrorType {
15
- PROVIDER_ERROR = 'PROVIDER_ERROR',
16
- ROUTING_ERROR = 'ROUTING_ERROR',
17
- CONFIGURATION_ERROR = 'CONFIGURATION_ERROR',
18
- INITIALIZATION_ERROR = 'INITIALIZATION_ERROR',
19
- MESSAGE_ERROR = 'MESSAGE_ERROR',
20
- NEVERHUB_ERROR = 'NEVERHUB_ERROR'
21
- }
22
-
23
- /**
24
- * Custom error class for chat suite errors
25
- */
26
- export class ChatSuiteError extends Error {
27
- constructor(
28
- public type: ChatSuiteErrorType,
29
- message: string,
30
- public originalError?: Error
31
- ) {
32
- super(message);
33
- this.name = 'ChatSuiteError';
34
- Object.setPrototypeOf(this, ChatSuiteError.prototype);
35
- }
36
- }
16
+ export { ChatSuiteError };
17
+ export type { ChatSuiteErrorCode, ChatSuiteErrorOptions };
37
18
 
38
19
  /**
39
- * Safely execute an async operation and return a SuiteResult
20
+ * Safely execute an async operation and return a SuiteResult.
21
+ *
22
+ * The optional `errorCode` parameter is used to prefix the returned error
23
+ * string (matching the previous `${type}: message` format).
40
24
  */
41
25
  export async function safeExecute<T>(
42
26
  operation: () => Promise<T>,
43
- errorType: ChatSuiteErrorType = ChatSuiteErrorType.MESSAGE_ERROR
27
+ errorCode: ChatSuiteErrorCode = 'MESSAGE_ERROR'
44
28
  ): Promise<SuiteResult<T>> {
45
29
  try {
46
30
  const data = await operation();
@@ -49,7 +33,7 @@ export async function safeExecute<T>(
49
33
  const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
50
34
  return {
51
35
  success: false,
52
- error: `${errorType}: ${errorMessage}`
36
+ error: `${errorCode}: ${errorMessage}`
53
37
  };
54
38
  }
55
39
  }
@@ -88,7 +72,7 @@ export function formatError(
88
72
  error: unknown
89
73
  ): string {
90
74
  if (error instanceof ChatSuiteError) {
91
- return `[${context}] ${error.type}: ${error.message}`;
75
+ return `[${context}] ${error.code}: ${error.message}`;
92
76
  }
93
77
  if (error instanceof Error) {
94
78
  return `[${context}] ${error.message}`;
@@ -101,8 +85,7 @@ export function formatError(
101
85
  */
102
86
  export function isRetryableError(error: unknown): boolean {
103
87
  if (error instanceof ChatSuiteError) {
104
- return error.type === ChatSuiteErrorType.PROVIDER_ERROR ||
105
- error.type === ChatSuiteErrorType.MESSAGE_ERROR;
88
+ return error.code === 'PROVIDER_ERROR' || error.code === 'MESSAGE_ERROR';
106
89
  }
107
90
  if (error instanceof Error) {
108
91
  const message = error.message.toLowerCase();
package/tsconfig.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "ES2020",
3
+ "target": "ES2022",
4
4
  "module": "commonjs",
5
- "lib": ["ES2020"],
6
- "types": ["node"],
5
+ "lib": ["ES2022"],
6
+ "types": ["node", "jest"],
7
7
  "declaration": true,
8
8
  "declarationMap": true,
9
9
  "outDir": "./dist",