@bernierllc/chat-suite 1.0.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.
Files changed (105) hide show
  1. package/.eslintrc.js +26 -0
  2. package/README.md +542 -0
  3. package/__tests__/integration/ChatSuite.test.ts +235 -0
  4. package/__tests__/unit/ConfigManager.test.ts +122 -0
  5. package/__tests__/unit/MessageOrchestrator.test.ts +223 -0
  6. package/__tests__/unit/UserManager.test.ts +208 -0
  7. package/dist/ChatSuite.d.ts +76 -0
  8. package/dist/ChatSuite.d.ts.map +1 -0
  9. package/dist/ChatSuite.js +273 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +37 -0
  13. package/dist/neverhub/discovery.d.ts +40 -0
  14. package/dist/neverhub/discovery.d.ts.map +1 -0
  15. package/dist/neverhub/discovery.js +106 -0
  16. package/dist/neverhub/event-handlers.d.ts +38 -0
  17. package/dist/neverhub/event-handlers.d.ts.map +1 -0
  18. package/dist/neverhub/event-handlers.js +125 -0
  19. package/dist/neverhub/index.d.ts +4 -0
  20. package/dist/neverhub/index.d.ts.map +1 -0
  21. package/dist/neverhub/index.js +26 -0
  22. package/dist/neverhub/service-registration.d.ts +29 -0
  23. package/dist/neverhub/service-registration.d.ts.map +1 -0
  24. package/dist/neverhub/service-registration.js +66 -0
  25. package/dist/providers/ChatKitProvider.d.ts +53 -0
  26. package/dist/providers/ChatKitProvider.d.ts.map +1 -0
  27. package/dist/providers/ChatKitProvider.js +167 -0
  28. package/dist/providers/ExternalProviders.d.ts +101 -0
  29. package/dist/providers/ExternalProviders.d.ts.map +1 -0
  30. package/dist/providers/ExternalProviders.js +153 -0
  31. package/dist/providers/index.d.ts +3 -0
  32. package/dist/providers/index.d.ts.map +1 -0
  33. package/dist/providers/index.js +25 -0
  34. package/dist/services/ConfigManager.d.ts +50 -0
  35. package/dist/services/ConfigManager.d.ts.map +1 -0
  36. package/dist/services/ConfigManager.js +95 -0
  37. package/dist/services/HealthMonitor.d.ts +58 -0
  38. package/dist/services/HealthMonitor.d.ts.map +1 -0
  39. package/dist/services/HealthMonitor.js +148 -0
  40. package/dist/services/MessageOrchestrator.d.ts +63 -0
  41. package/dist/services/MessageOrchestrator.d.ts.map +1 -0
  42. package/dist/services/MessageOrchestrator.js +212 -0
  43. package/dist/services/ProviderManager.d.ts +83 -0
  44. package/dist/services/ProviderManager.d.ts.map +1 -0
  45. package/dist/services/ProviderManager.js +204 -0
  46. package/dist/services/UserManager.d.ts +61 -0
  47. package/dist/services/UserManager.d.ts.map +1 -0
  48. package/dist/services/UserManager.js +141 -0
  49. package/dist/services/index.d.ts +6 -0
  50. package/dist/services/index.d.ts.map +1 -0
  51. package/dist/services/index.js +28 -0
  52. package/dist/types/index.d.ts +4 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/index.js +26 -0
  55. package/dist/types/message-types.d.ts +80 -0
  56. package/dist/types/message-types.d.ts.map +1 -0
  57. package/dist/types/message-types.js +32 -0
  58. package/dist/types/provider-types.d.ts +96 -0
  59. package/dist/types/provider-types.d.ts.map +1 -0
  60. package/dist/types/provider-types.js +9 -0
  61. package/dist/types/suite-types.d.ts +101 -0
  62. package/dist/types/suite-types.d.ts.map +1 -0
  63. package/dist/types/suite-types.js +9 -0
  64. package/dist/utils/config-inheritance.d.ts +24 -0
  65. package/dist/utils/config-inheritance.d.ts.map +1 -0
  66. package/dist/utils/config-inheritance.js +167 -0
  67. package/dist/utils/error-handling.d.ts +37 -0
  68. package/dist/utils/error-handling.d.ts.map +1 -0
  69. package/dist/utils/error-handling.js +102 -0
  70. package/dist/utils/index.d.ts +5 -0
  71. package/dist/utils/index.d.ts.map +1 -0
  72. package/dist/utils/index.js +27 -0
  73. package/dist/utils/message-bridge.d.ts +68 -0
  74. package/dist/utils/message-bridge.d.ts.map +1 -0
  75. package/dist/utils/message-bridge.js +126 -0
  76. package/dist/utils/user-mapping.d.ts +63 -0
  77. package/dist/utils/user-mapping.d.ts.map +1 -0
  78. package/dist/utils/user-mapping.js +110 -0
  79. package/jest.config.cjs +30 -0
  80. package/package.json +67 -0
  81. package/src/ChatSuite.ts +347 -0
  82. package/src/index.ts +25 -0
  83. package/src/neverhub/discovery.ts +137 -0
  84. package/src/neverhub/event-handlers.ts +141 -0
  85. package/src/neverhub/index.ts +11 -0
  86. package/src/neverhub/service-registration.ts +89 -0
  87. package/src/providers/ChatKitProvider.ts +193 -0
  88. package/src/providers/ExternalProviders.ts +171 -0
  89. package/src/providers/index.ts +10 -0
  90. package/src/services/ConfigManager.ts +112 -0
  91. package/src/services/HealthMonitor.ts +169 -0
  92. package/src/services/MessageOrchestrator.ts +271 -0
  93. package/src/services/ProviderManager.ts +247 -0
  94. package/src/services/UserManager.ts +176 -0
  95. package/src/services/index.ts +13 -0
  96. package/src/types/index.ts +11 -0
  97. package/src/types/message-types.ts +94 -0
  98. package/src/types/provider-types.ts +116 -0
  99. package/src/types/suite-types.ts +117 -0
  100. package/src/utils/config-inheritance.ts +189 -0
  101. package/src/utils/error-handling.ts +114 -0
  102. package/src/utils/index.ts +12 -0
  103. package/src/utils/message-bridge.ts +164 -0
  104. package/src/utils/user-mapping.ts +132 -0
  105. package/tsconfig.json +31 -0
@@ -0,0 +1,164 @@
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 type { ProviderType, ProviderMessage, MessageBridgeConfig } from '../types';
10
+
11
+ /**
12
+ * Bridged message information
13
+ */
14
+ export interface BridgedMessage {
15
+ originalMessageId: string;
16
+ sourceProvider: ProviderType;
17
+ targetProvider: ProviderType;
18
+ targetMessageId?: string;
19
+ timestamp: Date;
20
+ }
21
+
22
+ /**
23
+ * Message bridge for cross-platform synchronization
24
+ */
25
+ export class MessageBridge {
26
+ private bridgedMessages: Map<string, BridgedMessage[]> = new Map();
27
+ private channelMappings: Map<string, string> = new Map();
28
+
29
+ constructor(private config: MessageBridgeConfig) {
30
+ if (config.channelMappings) {
31
+ this.channelMappings = config.channelMappings;
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Check if message should be bridged
37
+ */
38
+ public shouldBridge(sourceProvider: ProviderType, targetProvider: ProviderType): boolean {
39
+ if (!this.config.enabled) {
40
+ return false;
41
+ }
42
+
43
+ return this.config.sourceProviders.includes(sourceProvider) &&
44
+ this.config.targetProviders.includes(targetProvider);
45
+ }
46
+
47
+ /**
48
+ * Transform message for target provider
49
+ */
50
+ public transformMessage(
51
+ message: ProviderMessage,
52
+ sourceProvider: ProviderType,
53
+ targetProvider: ProviderType
54
+ ): ProviderMessage {
55
+ const transformed: ProviderMessage = {
56
+ ...message,
57
+ metadata: {
58
+ ...message.metadata,
59
+ bridged: true,
60
+ sourceProvider,
61
+ originalContent: message.content
62
+ }
63
+ };
64
+
65
+ // Map channel if mapping exists
66
+ if (message.channelId) {
67
+ const mappedChannel = this.getMappedChannel(message.channelId, sourceProvider, targetProvider);
68
+ if (mappedChannel) {
69
+ transformed.channelId = mappedChannel;
70
+ }
71
+ }
72
+
73
+ // Add source provider prefix to content
74
+ transformed.content = `[From ${sourceProvider}] ${message.content}`;
75
+
76
+ return transformed;
77
+ }
78
+
79
+ /**
80
+ * Record a bridged message
81
+ */
82
+ public recordBridgedMessage(bridgedMessage: BridgedMessage): void {
83
+ const existing = this.bridgedMessages.get(bridgedMessage.originalMessageId) || [];
84
+ existing.push(bridgedMessage);
85
+ this.bridgedMessages.set(bridgedMessage.originalMessageId, existing);
86
+ }
87
+
88
+ /**
89
+ * Get all bridges for a message
90
+ */
91
+ public getBridges(originalMessageId: string): BridgedMessage[] {
92
+ return this.bridgedMessages.get(originalMessageId) || [];
93
+ }
94
+
95
+ /**
96
+ * Add channel mapping
97
+ */
98
+ public addChannelMapping(sourceChannel: string, targetChannel: string): void {
99
+ this.channelMappings.set(sourceChannel, targetChannel);
100
+ }
101
+
102
+ /**
103
+ * Get mapped channel
104
+ */
105
+ public getMappedChannel(
106
+ sourceChannel: string,
107
+ _sourceProvider: ProviderType,
108
+ _targetProvider: ProviderType
109
+ ): string | undefined {
110
+ return this.channelMappings.get(sourceChannel);
111
+ }
112
+
113
+ /**
114
+ * Check if reactions should be synced
115
+ */
116
+ public shouldSyncReactions(): boolean {
117
+ return this.config.syncReactions ?? false;
118
+ }
119
+
120
+ /**
121
+ * Check if edits should be synced
122
+ */
123
+ public shouldSyncEdits(): boolean {
124
+ return this.config.syncEdits ?? false;
125
+ }
126
+
127
+ /**
128
+ * Check if deletions should be synced
129
+ */
130
+ public shouldSyncDeletions(): boolean {
131
+ return this.config.syncDeletions ?? false;
132
+ }
133
+
134
+ /**
135
+ * Clear all bridged message records
136
+ */
137
+ public clear(): void {
138
+ this.bridgedMessages.clear();
139
+ }
140
+
141
+ /**
142
+ * Get statistics
143
+ */
144
+ public getStats(): {
145
+ totalBridged: number;
146
+ bridgesByProvider: Map<ProviderType, number>;
147
+ } {
148
+ const bridgesByProvider = new Map<ProviderType, number>();
149
+ let total = 0;
150
+
151
+ this.bridgedMessages.forEach(bridges => {
152
+ bridges.forEach(bridge => {
153
+ const count = bridgesByProvider.get(bridge.targetProvider) || 0;
154
+ bridgesByProvider.set(bridge.targetProvider, count + 1);
155
+ total++;
156
+ });
157
+ });
158
+
159
+ return {
160
+ totalBridged: total,
161
+ bridgesByProvider
162
+ };
163
+ }
164
+ }
@@ -0,0 +1,132 @@
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 type { ProviderType } from '../types';
10
+
11
+ /**
12
+ * User identity across platforms
13
+ */
14
+ export interface UserIdentity {
15
+ unifiedId: string;
16
+ platformIds: Map<ProviderType, string>;
17
+ displayName?: string;
18
+ email?: string;
19
+ metadata?: Record<string, unknown>;
20
+ }
21
+
22
+ /**
23
+ * User mapping storage
24
+ */
25
+ export class UserMapper {
26
+ private identities: Map<string, UserIdentity> = new Map();
27
+ private providerIndex: Map<string, string> = new Map(); // provider:userId -> unifiedId
28
+
29
+ /**
30
+ * Create or update a user identity
31
+ */
32
+ public mapUser(identity: UserIdentity): void {
33
+ this.identities.set(identity.unifiedId, identity);
34
+
35
+ // Update provider index
36
+ identity.platformIds.forEach((platformUserId, provider) => {
37
+ const key = this.getProviderKey(provider, platformUserId);
38
+ this.providerIndex.set(key, identity.unifiedId);
39
+ });
40
+ }
41
+
42
+ /**
43
+ * Get unified user ID from platform-specific ID
44
+ */
45
+ public getUnifiedId(provider: ProviderType, platformUserId: string): string | undefined {
46
+ const key = this.getProviderKey(provider, platformUserId);
47
+ return this.providerIndex.get(key);
48
+ }
49
+
50
+ /**
51
+ * Get platform-specific user ID from unified ID
52
+ */
53
+ public getPlatformId(unifiedId: string, provider: ProviderType): string | undefined {
54
+ const identity = this.identities.get(unifiedId);
55
+ return identity?.platformIds.get(provider);
56
+ }
57
+
58
+ /**
59
+ * Get full user identity
60
+ */
61
+ public getIdentity(unifiedId: string): UserIdentity | undefined {
62
+ return this.identities.get(unifiedId);
63
+ }
64
+
65
+ /**
66
+ * Add platform ID to existing user
67
+ */
68
+ public addPlatformId(unifiedId: string, provider: ProviderType, platformUserId: string): boolean {
69
+ const identity = this.identities.get(unifiedId);
70
+ if (!identity) {
71
+ return false;
72
+ }
73
+
74
+ identity.platformIds.set(provider, platformUserId);
75
+ this.mapUser(identity);
76
+ return true;
77
+ }
78
+
79
+ /**
80
+ * Remove user identity
81
+ */
82
+ public removeUser(unifiedId: string): boolean {
83
+ const identity = this.identities.get(unifiedId);
84
+ if (!identity) {
85
+ return false;
86
+ }
87
+
88
+ // Remove from provider index
89
+ identity.platformIds.forEach((platformUserId, provider) => {
90
+ const key = this.getProviderKey(provider, platformUserId);
91
+ this.providerIndex.delete(key);
92
+ });
93
+
94
+ return this.identities.delete(unifiedId);
95
+ }
96
+
97
+ /**
98
+ * Get all users
99
+ */
100
+ public getAllUsers(): UserIdentity[] {
101
+ return Array.from(this.identities.values());
102
+ }
103
+
104
+ /**
105
+ * Clear all mappings
106
+ */
107
+ public clear(): void {
108
+ this.identities.clear();
109
+ this.providerIndex.clear();
110
+ }
111
+
112
+ /**
113
+ * Get number of mapped users
114
+ */
115
+ public size(): number {
116
+ return this.identities.size;
117
+ }
118
+
119
+ /**
120
+ * Create provider key for indexing
121
+ */
122
+ private getProviderKey(provider: ProviderType, platformUserId: string): string {
123
+ return `${provider}:${platformUserId}`;
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Create a new unified user ID
129
+ */
130
+ export function createUnifiedId(): string {
131
+ return `user_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
132
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "commonjs",
5
+ "lib": ["ES2020"],
6
+ "types": ["node"],
7
+ "declaration": true,
8
+ "declarationMap": true,
9
+ "outDir": "./dist",
10
+ "rootDir": "./src",
11
+ "strict": true,
12
+ "esModuleInterop": true,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "moduleResolution": "node",
17
+ "noImplicitAny": true,
18
+ "strictNullChecks": true,
19
+ "strictFunctionTypes": true,
20
+ "strictBindCallApply": true,
21
+ "strictPropertyInitialization": true,
22
+ "noImplicitThis": true,
23
+ "alwaysStrict": true,
24
+ "noUnusedLocals": true,
25
+ "noUnusedParameters": true,
26
+ "noImplicitReturns": true,
27
+ "noFallthroughCasesInSwitch": true
28
+ },
29
+ "include": ["src/**/*"],
30
+ "exclude": ["node_modules", "dist", "__tests__"]
31
+ }