@nurama/sdk 0.0.0-stage → 1.4.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 (220) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +1080 -2
  4. package/dist/BotClient.d.ts +66 -0
  5. package/dist/BotClient.d.ts.map +1 -0
  6. package/dist/BotClient.js +68 -0
  7. package/dist/BotClient.js.map +1 -0
  8. package/dist/NuramaClient.d.ts +448 -0
  9. package/dist/NuramaClient.d.ts.map +1 -0
  10. package/dist/NuramaClient.js +864 -0
  11. package/dist/NuramaClient.js.map +1 -0
  12. package/dist/browser/nurama-bot-sdk.js +11780 -0
  13. package/dist/browser/nurama-bot-sdk.min.js +1 -0
  14. package/dist/browser/nurama-sdk.js +11732 -0
  15. package/dist/browser/nurama-sdk.min.js +1 -0
  16. package/dist/routes/ai.d.ts +280 -0
  17. package/dist/routes/ai.d.ts.map +1 -0
  18. package/dist/routes/ai.js +173 -0
  19. package/dist/routes/ai.js.map +1 -0
  20. package/dist/routes/asset.d.ts +493 -0
  21. package/dist/routes/asset.d.ts.map +1 -0
  22. package/dist/routes/asset.js +848 -0
  23. package/dist/routes/asset.js.map +1 -0
  24. package/dist/routes/auth.d.ts +218 -0
  25. package/dist/routes/auth.d.ts.map +1 -0
  26. package/dist/routes/auth.js +454 -0
  27. package/dist/routes/auth.js.map +1 -0
  28. package/dist/routes/blogPosts.d.ts +17 -0
  29. package/dist/routes/blogPosts.d.ts.map +1 -0
  30. package/dist/routes/blogPosts.js +29 -0
  31. package/dist/routes/blogPosts.js.map +1 -0
  32. package/dist/routes/board.d.ts +187 -0
  33. package/dist/routes/board.d.ts.map +1 -0
  34. package/dist/routes/board.js +270 -0
  35. package/dist/routes/board.js.map +1 -0
  36. package/dist/routes/bot.d.ts +147 -0
  37. package/dist/routes/bot.d.ts.map +1 -0
  38. package/dist/routes/bot.js +157 -0
  39. package/dist/routes/bot.js.map +1 -0
  40. package/dist/routes/chat.d.ts +842 -0
  41. package/dist/routes/chat.d.ts.map +1 -0
  42. package/dist/routes/chat.js +863 -0
  43. package/dist/routes/chat.js.map +1 -0
  44. package/dist/routes/chatAi.d.ts +51 -0
  45. package/dist/routes/chatAi.d.ts.map +1 -0
  46. package/dist/routes/chatAi.js +109 -0
  47. package/dist/routes/chatAi.js.map +1 -0
  48. package/dist/routes/config.d.ts +11 -0
  49. package/dist/routes/config.d.ts.map +1 -0
  50. package/dist/routes/config.js +24 -0
  51. package/dist/routes/config.js.map +1 -0
  52. package/dist/routes/convo.d.ts +169 -0
  53. package/dist/routes/convo.d.ts.map +1 -0
  54. package/dist/routes/convo.js +284 -0
  55. package/dist/routes/convo.js.map +1 -0
  56. package/dist/routes/credits.d.ts +82 -0
  57. package/dist/routes/credits.d.ts.map +1 -0
  58. package/dist/routes/credits.js +49 -0
  59. package/dist/routes/credits.js.map +1 -0
  60. package/dist/routes/device.d.ts +74 -0
  61. package/dist/routes/device.d.ts.map +1 -0
  62. package/dist/routes/device.js +122 -0
  63. package/dist/routes/device.js.map +1 -0
  64. package/dist/routes/folder.d.ts +75 -0
  65. package/dist/routes/folder.d.ts.map +1 -0
  66. package/dist/routes/folder.js +99 -0
  67. package/dist/routes/folder.js.map +1 -0
  68. package/dist/routes/invite.d.ts +61 -0
  69. package/dist/routes/invite.d.ts.map +1 -0
  70. package/dist/routes/invite.js +86 -0
  71. package/dist/routes/invite.js.map +1 -0
  72. package/dist/routes/joinLink.d.ts +38 -0
  73. package/dist/routes/joinLink.d.ts.map +1 -0
  74. package/dist/routes/joinLink.js +81 -0
  75. package/dist/routes/joinLink.js.map +1 -0
  76. package/dist/routes/membership.d.ts +116 -0
  77. package/dist/routes/membership.d.ts.map +1 -0
  78. package/dist/routes/membership.js +183 -0
  79. package/dist/routes/membership.js.map +1 -0
  80. package/dist/routes/notification.d.ts +103 -0
  81. package/dist/routes/notification.d.ts.map +1 -0
  82. package/dist/routes/notification.js +89 -0
  83. package/dist/routes/notification.js.map +1 -0
  84. package/dist/routes/payment.d.ts +56 -0
  85. package/dist/routes/payment.d.ts.map +1 -0
  86. package/dist/routes/payment.js +78 -0
  87. package/dist/routes/payment.js.map +1 -0
  88. package/dist/routes/product.d.ts +43 -0
  89. package/dist/routes/product.d.ts.map +1 -0
  90. package/dist/routes/product.js +53 -0
  91. package/dist/routes/product.js.map +1 -0
  92. package/dist/routes/project.d.ts +821 -0
  93. package/dist/routes/project.d.ts.map +1 -0
  94. package/dist/routes/project.js +1153 -0
  95. package/dist/routes/project.js.map +1 -0
  96. package/dist/routes/public.d.ts +269 -0
  97. package/dist/routes/public.d.ts.map +1 -0
  98. package/dist/routes/public.js +412 -0
  99. package/dist/routes/public.js.map +1 -0
  100. package/dist/routes/scratch.d.ts +70 -0
  101. package/dist/routes/scratch.d.ts.map +1 -0
  102. package/dist/routes/scratch.js +67 -0
  103. package/dist/routes/scratch.js.map +1 -0
  104. package/dist/routes/settings.d.ts +102 -0
  105. package/dist/routes/settings.d.ts.map +1 -0
  106. package/dist/routes/settings.js +94 -0
  107. package/dist/routes/settings.js.map +1 -0
  108. package/dist/routes/shortlink.d.ts +79 -0
  109. package/dist/routes/shortlink.d.ts.map +1 -0
  110. package/dist/routes/shortlink.js +25 -0
  111. package/dist/routes/shortlink.js.map +1 -0
  112. package/dist/routes/socket.d.ts +108 -0
  113. package/dist/routes/socket.d.ts.map +1 -0
  114. package/dist/routes/socket.js +555 -0
  115. package/dist/routes/socket.js.map +1 -0
  116. package/dist/routes/storage.d.ts +44 -0
  117. package/dist/routes/storage.d.ts.map +1 -0
  118. package/dist/routes/storage.js +49 -0
  119. package/dist/routes/storage.js.map +1 -0
  120. package/dist/routes/subscription.d.ts +184 -0
  121. package/dist/routes/subscription.d.ts.map +1 -0
  122. package/dist/routes/subscription.js +219 -0
  123. package/dist/routes/subscription.js.map +1 -0
  124. package/dist/routes/supportChat.d.ts +40 -0
  125. package/dist/routes/supportChat.d.ts.map +1 -0
  126. package/dist/routes/supportChat.js +53 -0
  127. package/dist/routes/supportChat.js.map +1 -0
  128. package/dist/routes/supportTicket.d.ts +89 -0
  129. package/dist/routes/supportTicket.d.ts.map +1 -0
  130. package/dist/routes/supportTicket.js +54 -0
  131. package/dist/routes/supportTicket.js.map +1 -0
  132. package/dist/routes/tag.d.ts +72 -0
  133. package/dist/routes/tag.d.ts.map +1 -0
  134. package/dist/routes/tag.js +81 -0
  135. package/dist/routes/tag.js.map +1 -0
  136. package/dist/routes/task.d.ts +252 -0
  137. package/dist/routes/task.d.ts.map +1 -0
  138. package/dist/routes/task.js +284 -0
  139. package/dist/routes/task.js.map +1 -0
  140. package/dist/routes/taskRelation.d.ts +80 -0
  141. package/dist/routes/taskRelation.d.ts.map +1 -0
  142. package/dist/routes/taskRelation.js +71 -0
  143. package/dist/routes/taskRelation.js.map +1 -0
  144. package/dist/routes/token.d.ts +75 -0
  145. package/dist/routes/token.d.ts.map +1 -0
  146. package/dist/routes/token.js +51 -0
  147. package/dist/routes/token.js.map +1 -0
  148. package/dist/routes/user.d.ts +112 -0
  149. package/dist/routes/user.d.ts.map +1 -0
  150. package/dist/routes/user.js +151 -0
  151. package/dist/routes/user.js.map +1 -0
  152. package/dist/routes/version.d.ts +42 -0
  153. package/dist/routes/version.d.ts.map +1 -0
  154. package/dist/routes/version.js +38 -0
  155. package/dist/routes/version.js.map +1 -0
  156. package/dist/routes/webhook.d.ts +170 -0
  157. package/dist/routes/webhook.d.ts.map +1 -0
  158. package/dist/routes/webhook.js +173 -0
  159. package/dist/routes/webhook.js.map +1 -0
  160. package/dist/routes/workspace.d.ts +120 -0
  161. package/dist/routes/workspace.d.ts.map +1 -0
  162. package/dist/routes/workspace.js +199 -0
  163. package/dist/routes/workspace.js.map +1 -0
  164. package/dist/utils/uploadSessionManager.d.ts +133 -0
  165. package/dist/utils/uploadSessionManager.d.ts.map +1 -0
  166. package/dist/utils/uploadSessionManager.js +321 -0
  167. package/dist/utils/uploadSessionManager.js.map +1 -0
  168. package/dist/utils/urlParams.d.ts +35 -0
  169. package/dist/utils/urlParams.d.ts.map +1 -0
  170. package/dist/utils/urlParams.js +146 -0
  171. package/dist/utils/urlParams.js.map +1 -0
  172. package/dist/version.d.ts +15 -0
  173. package/dist/version.d.ts.map +1 -0
  174. package/dist/version.js +12 -0
  175. package/dist/version.js.map +1 -0
  176. package/package.json +87 -3
  177. package/src/BotClient.ts +113 -0
  178. package/src/NuramaClient.ts +1193 -0
  179. package/src/bot-browser-entry.js +15 -0
  180. package/src/browser-entry.js +20 -0
  181. package/src/routes/ai.ts +378 -0
  182. package/src/routes/asset.ts +1104 -0
  183. package/src/routes/auth.ts +587 -0
  184. package/src/routes/blogPosts.ts +29 -0
  185. package/src/routes/board.ts +403 -0
  186. package/src/routes/bot.ts +257 -0
  187. package/src/routes/chat.ts +1292 -0
  188. package/src/routes/chatAi.ts +125 -0
  189. package/src/routes/config.ts +31 -0
  190. package/src/routes/convo.ts +321 -0
  191. package/src/routes/credits.ts +112 -0
  192. package/src/routes/device.ts +133 -0
  193. package/src/routes/folder.ts +154 -0
  194. package/src/routes/invite.ts +133 -0
  195. package/src/routes/joinLink.ts +100 -0
  196. package/src/routes/membership.ts +237 -0
  197. package/src/routes/notification.ts +166 -0
  198. package/src/routes/payment.ts +104 -0
  199. package/src/routes/product.ts +67 -0
  200. package/src/routes/project.ts +1528 -0
  201. package/src/routes/public.ts +496 -0
  202. package/src/routes/scratch.ts +94 -0
  203. package/src/routes/settings.ts +152 -0
  204. package/src/routes/shortlink.ts +90 -0
  205. package/src/routes/socket.ts +739 -0
  206. package/src/routes/storage.ts +83 -0
  207. package/src/routes/subscription.ts +307 -0
  208. package/src/routes/supportChat.ts +62 -0
  209. package/src/routes/supportTicket.ts +114 -0
  210. package/src/routes/tag.ts +131 -0
  211. package/src/routes/task.ts +431 -0
  212. package/src/routes/taskRelation.ts +125 -0
  213. package/src/routes/token.ts +113 -0
  214. package/src/routes/user.ts +214 -0
  215. package/src/routes/version.ts +62 -0
  216. package/src/routes/webhook.ts +295 -0
  217. package/src/routes/workspace.ts +223 -0
  218. package/src/utils/uploadSessionManager.ts +407 -0
  219. package/src/utils/urlParams.ts +181 -0
  220. package/src/version.ts +22 -0
@@ -0,0 +1,555 @@
1
+ /* eslint-disable no-console */
2
+ /**
3
+ * Listener-set keys that the built-in socket handlers bound in connect()/
4
+ * connectPublic() dispatch to directly (rather than via a subscribe()-bound
5
+ * `socket.on`). When re-establishing subscriptions after an in-place reconnect
6
+ * these must be repopulated on the new connection's listener set, NOT re-run
7
+ * through subscribe() — doing so would bind a second `socket.on` dispatcher and
8
+ * fire each callback twice.
9
+ */
10
+ const LIFECYCLE_LISTENER_EVENTS = new Set([
11
+ 'disconnect',
12
+ 'tokenExpired',
13
+ 'tokenBlacklisted',
14
+ 'reconnect_failed',
15
+ 'reconnect',
16
+ ]);
17
+ export default function createSocketMethods(client) {
18
+ // Track active socket connections
19
+ const activeConnections = {};
20
+ // Extract configuration from client
21
+ const debug = client.debug;
22
+ /**
23
+ * Log helper for socket-related messages
24
+ */
25
+ const _log = (...args) => {
26
+ if (debug) {
27
+ console.log('[SOCKET]', ...args);
28
+ }
29
+ };
30
+ // We'll need to dynamically import socket.io-client since it's not available in all environments
31
+ const getSocketIO = async () => {
32
+ try {
33
+ // Handle different versions of socket.io-client
34
+ const socketModule = await import('socket.io-client');
35
+ // Socket.io 4.x exports the io function directly
36
+ return socketModule.default || socketModule;
37
+ }
38
+ catch (error) {
39
+ throw new Error('socket.io-client is not installed. Please install it with: npm install socket.io-client');
40
+ }
41
+ };
42
+ /**
43
+ * Get an authentication token for WebSocket connection.
44
+ * Returns the long-lived API key when the client is in bot mode, otherwise the JWT.
45
+ */
46
+ const getAuthToken = () => {
47
+ return client._apiKey || client._getAccessToken();
48
+ };
49
+ /** True when the client is authenticating with a bot API key. */
50
+ const isApiKeyMode = () => Boolean(client._apiKey);
51
+ /**
52
+ * Get the WebSocket server URL
53
+ *
54
+ * Priority:
55
+ * 1. Connection-specific websocketURL (from options)
56
+ * 2. Client-level websocketURL (from client options)
57
+ * 3. Use the baseURL directly - Socket.IO handles protocol conversion
58
+ */
59
+ const getWebSocketURL = (connectionOptions) => {
60
+ // 1. Check connection-specific override
61
+ if (connectionOptions?.websocketURL) {
62
+ return connectionOptions.websocketURL;
63
+ }
64
+ // 2. Check client-level websocketURL
65
+ if (client.websocketURL) {
66
+ return client.websocketURL;
67
+ }
68
+ // 3. Use baseURL directly - Socket.IO handles protocol conversion
69
+ return client.baseURL;
70
+ };
71
+ /**
72
+ * Connect to a socket channel
73
+ * @param channel Channel path to connect to (e.g., '/user/123')
74
+ * @param options Socket connection options
75
+ * @returns Promise that resolves with the socket channel
76
+ */
77
+ const connect = async (channel, options = {}) => {
78
+ _log(`Connecting to channel: ${channel}`);
79
+ // Default options
80
+ const socketOptions = {
81
+ autoRefresh: true,
82
+ autoReconnect: true,
83
+ autoReconnectOnTokenExpiry: true,
84
+ debug: client.debug,
85
+ ...options
86
+ };
87
+ // Check if already connected
88
+ if (activeConnections[channel]) {
89
+ _log(`Already connected to channel: ${channel}`);
90
+ return activeConnections[channel];
91
+ }
92
+ // Get access token
93
+ const token = getAuthToken();
94
+ if (!token) {
95
+ throw new Error('Authentication required. Please login first.');
96
+ }
97
+ // Get WebSocket URL using the helper function - no protocol conversion needed
98
+ const wsUrl = getWebSocketURL(options);
99
+ _log(`Using Socket.IO URL: ${wsUrl}`);
100
+ // Dynamically import socket.io-client
101
+ const io = await getSocketIO();
102
+ // Create socket connection with enhanced reconnection configuration
103
+ const socket = io(`${wsUrl}${channel}`, {
104
+ query: { token },
105
+ // Reconnection configuration for resilience
106
+ reconnection: socketOptions.autoReconnect,
107
+ reconnectionAttempts: 10, // Maximum reconnection attempts before giving up
108
+ reconnectionDelay: 1000, // Start with 1 second delay
109
+ reconnectionDelayMax: 30000, // Max delay of 30 seconds between attempts
110
+ randomizationFactor: 0.5, // Add jitter to avoid thundering herd problem
111
+ // Connection timeout
112
+ timeout: 20000, // 20 seconds to establish initial connection
113
+ // Transport configuration
114
+ transports: ['websocket', 'polling'], // Prefer WebSocket, fallback to polling
115
+ upgrade: true, // Allow transport upgrade
116
+ rememberUpgrade: true, // Remember successful upgrade
117
+ // Ping/pong for connection health
118
+ forceNew: false, // Reuse existing connection if available
119
+ });
120
+ // Create channel object
121
+ const socketChannel = {
122
+ socket,
123
+ channel,
124
+ listeners: {},
125
+ };
126
+ // Store connection immediately so subscribers can register socket.on handlers
127
+ // even before the connection is fully established. Socket.io preserves
128
+ // handlers across reconnections, so they will fire once connected.
129
+ activeConnections[channel] = socketChannel;
130
+ // Setup event listeners
131
+ return new Promise((resolve, reject) => {
132
+ let settled = false;
133
+ // Handle connection (initial or after reconnection)
134
+ socket.on('connect', () => {
135
+ _log(`Connected to channel: ${channel}`);
136
+ activeConnections[channel] = socketChannel;
137
+ if (!settled) {
138
+ settled = true;
139
+ resolve(socketChannel);
140
+ }
141
+ });
142
+ // Handle connection error — log but let socket.io retry
143
+ socket.on('connect_error', (error) => {
144
+ _log(`Connection error for channel ${channel}:`, error);
145
+ // Don't reject — socket.io's auto-reconnect will keep trying
146
+ // Resolve the promise so callers aren't blocked — subscriptions
147
+ // registered via socket.on will fire once the connection succeeds
148
+ if (!settled) {
149
+ settled = true;
150
+ resolve(socketChannel);
151
+ }
152
+ });
153
+ // Handle reconnection attempts
154
+ socket.on('reconnect_attempt', (attempt) => {
155
+ _log(`Reconnection attempt ${attempt} for channel: ${channel}`);
156
+ });
157
+ // Handle successful reconnection
158
+ socket.on('reconnect', (attempt) => {
159
+ _log(`Reconnected to channel ${channel} after ${attempt} attempts`);
160
+ // Ensure activeConnections is up to date after reconnect
161
+ activeConnections[channel] = socketChannel;
162
+ // Notify app-level onReconnect listeners so they can REST-refetch any
163
+ // gap of server->client messages missed while the transport was down
164
+ // (socket.io has no replay across a reconnect).
165
+ const reconnectListeners = socketChannel.listeners['reconnect'] || new Set();
166
+ reconnectListeners.forEach(listener => listener({ type: 'reconnect', attempt }));
167
+ });
168
+ // Handle reconnection failure — only reject when socket.io gives up entirely
169
+ socket.on('reconnect_failed', () => {
170
+ _log(`Reconnection failed for channel ${channel} after maximum attempts`);
171
+ // Emit to listeners for UI feedback
172
+ const eventListeners = socketChannel.listeners['reconnect_failed'] || new Set();
173
+ eventListeners.forEach(listener => listener({ type: 'reconnect_failed' }));
174
+ if (!settled) {
175
+ settled = true;
176
+ reject(new Error(`Connection to ${channel} failed after maximum reconnection attempts`));
177
+ }
178
+ });
179
+ // Handle token events
180
+ socket.on('tokenEvent', (event) => {
181
+ _log(`Token event on channel ${channel}:`, event);
182
+ if (event === 'TokenExpired' && socketOptions.autoReconnectOnTokenExpiry) {
183
+ // API keys don't expire client-side; if the server emits TokenExpired
184
+ // for a bot, treat it as terminal — there's nothing to refresh.
185
+ if (isApiKeyMode()) {
186
+ _log('Token expired event in API key mode — disconnecting (no refresh path)');
187
+ disconnect(channel);
188
+ const eventListeners = socketChannel.listeners['tokenExpired'] || new Set();
189
+ eventListeners.forEach(listener => listener({ type: 'tokenExpired' }));
190
+ return;
191
+ }
192
+ // Refresh token and reconnect
193
+ _log('Token expired, attempting to refresh and reconnect');
194
+ // Call the client's _refreshToken method (using 'as any' for TypeScript)
195
+ client._refreshToken()
196
+ .then(() => {
197
+ _log('Token refreshed, reconnecting');
198
+ // Preserve event subscriptions across the reconnect. connect()
199
+ // builds a brand-new socket whose listeners map starts empty, so
200
+ // without re-binding these the channel reconnects but silently
201
+ // stops delivering 'notification' events — the app-level
202
+ // subscription is lost until a full page reload. This fires on the
203
+ // server's token-expiry sweep (~every 30 min for a long-lived
204
+ // session), so the reconnect must carry the subscriptions over.
205
+ const preservedListeners = socketChannel.listeners;
206
+ disconnect(channel)
207
+ .then(() => connect(channel, options))
208
+ .then((newConnection) => {
209
+ Object.entries(preservedListeners).forEach(([listenerEvent, callbacks]) => {
210
+ callbacks.forEach((callback) => {
211
+ if (LIFECYCLE_LISTENER_EVENTS.has(listenerEvent)) {
212
+ // Built-in handlers on the fresh socket already dispatch
213
+ // these; just repopulate the set they read from.
214
+ if (!newConnection.listeners[listenerEvent]) {
215
+ newConnection.listeners[listenerEvent] = new Set();
216
+ }
217
+ newConnection.listeners[listenerEvent].add(callback);
218
+ }
219
+ else {
220
+ subscribe(channel, listenerEvent, callback);
221
+ }
222
+ });
223
+ });
224
+ // The fresh socket fired 'connect', not 'reconnect', so notify
225
+ // onReconnect listeners here too — a token-refresh reconnect is
226
+ // still a gap that needs the same REST catch-up.
227
+ (newConnection.listeners['reconnect'] || new Set()).forEach(listener => listener({ type: 'reconnect', reason: 'tokenRefresh' }));
228
+ })
229
+ .catch((error) => {
230
+ _log(`Failed to re-establish subscriptions after token refresh on ${channel}:`, error);
231
+ });
232
+ })
233
+ .catch((error) => {
234
+ _log('Failed to refresh token', error);
235
+ // Emit disconnect event to listeners
236
+ const eventListeners = socketChannel.listeners['tokenExpired'] || new Set();
237
+ eventListeners.forEach(listener => listener({ type: 'tokenExpired', error }));
238
+ });
239
+ }
240
+ else if (event === 'tokenBlacklisted') {
241
+ // Force disconnect
242
+ _log('Token blacklisted, disconnecting');
243
+ disconnect(channel);
244
+ // Emit disconnect event to listeners
245
+ const eventListeners = socketChannel.listeners['tokenBlacklisted'] || new Set();
246
+ eventListeners.forEach(listener => listener({ type: 'tokenBlacklisted' }));
247
+ }
248
+ });
249
+ // Handle disconnect
250
+ socket.on('disconnect', (reason) => {
251
+ _log(`Disconnected from channel ${channel}:`, reason);
252
+ // Emit disconnect event to listeners
253
+ const eventListeners = socketChannel.listeners['disconnect'] || new Set();
254
+ eventListeners.forEach(listener => listener({ type: 'disconnect', reason }));
255
+ // Remove from active connections
256
+ delete activeConnections[channel];
257
+ });
258
+ });
259
+ };
260
+ /**
261
+ * Connect to a public socket channel without authentication
262
+ * @param publicToken Public file system token (10-character alphanumeric)
263
+ * @param options Socket connection options
264
+ * @returns Promise that resolves with the socket channel
265
+ */
266
+ const connectPublic = async (publicToken, options = {}) => {
267
+ const channel = `public/${publicToken}`;
268
+ _log(`Connecting to public channel: ${channel}`);
269
+ // Default options
270
+ const socketOptions = {
271
+ autoReconnect: true,
272
+ debug: client.debug,
273
+ ...options
274
+ };
275
+ // Check if already connected
276
+ if (activeConnections[channel]) {
277
+ _log(`Already connected to public channel: ${channel}`);
278
+ return activeConnections[channel];
279
+ }
280
+ // Get WebSocket URL using the helper function
281
+ const wsUrl = getWebSocketURL(options);
282
+ _log(`Using Socket.IO URL for public connection: ${wsUrl}`);
283
+ // Dynamically import socket.io-client
284
+ const io = await getSocketIO();
285
+ // Create socket connection - no token needed for public channels
286
+ const socket = io(`${wsUrl}${channel}`, {
287
+ query: { publicToken },
288
+ // Reconnection configuration for resilience
289
+ reconnection: socketOptions.autoReconnect,
290
+ reconnectionAttempts: 10,
291
+ reconnectionDelay: 1000,
292
+ reconnectionDelayMax: 30000,
293
+ randomizationFactor: 0.5,
294
+ // Connection timeout
295
+ timeout: 20000,
296
+ // Transport configuration
297
+ transports: ['websocket', 'polling'],
298
+ upgrade: true,
299
+ rememberUpgrade: true,
300
+ forceNew: false,
301
+ });
302
+ // Create channel object
303
+ const socketChannel = {
304
+ socket,
305
+ channel,
306
+ listeners: {},
307
+ };
308
+ // Setup event listeners
309
+ return new Promise((resolve, reject) => {
310
+ // Handle connection
311
+ socket.on('connect', () => {
312
+ _log(`Connected to public channel: ${channel}`);
313
+ activeConnections[channel] = socketChannel;
314
+ resolve(socketChannel);
315
+ });
316
+ // Handle connection error
317
+ socket.on('connect_error', (error) => {
318
+ _log(`Connection error for public channel ${channel}:`, error);
319
+ reject(error);
320
+ });
321
+ // Handle reconnection attempts
322
+ socket.on('reconnect_attempt', (attempt) => {
323
+ _log(`Reconnection attempt ${attempt} for public channel: ${channel}`);
324
+ });
325
+ // Handle successful reconnection
326
+ socket.on('reconnect', (attempt) => {
327
+ _log(`Reconnected to public channel ${channel} after ${attempt} attempts`);
328
+ });
329
+ // Handle reconnection failure
330
+ socket.on('reconnect_failed', () => {
331
+ _log(`Reconnection failed for public channel ${channel} after maximum attempts`);
332
+ const eventListeners = socketChannel.listeners['reconnect_failed'] || new Set();
333
+ eventListeners.forEach(listener => listener({ type: 'reconnect_failed' }));
334
+ });
335
+ // Handle disconnect
336
+ socket.on('disconnect', (reason) => {
337
+ _log(`Disconnected from public channel ${channel}:`, reason);
338
+ // Emit disconnect event to listeners
339
+ const eventListeners = socketChannel.listeners['disconnect'] || new Set();
340
+ eventListeners.forEach(listener => listener({ type: 'disconnect', reason }));
341
+ // Remove from active connections
342
+ delete activeConnections[channel];
343
+ });
344
+ });
345
+ };
346
+ /**
347
+ * Disconnect from a socket channel
348
+ * @param channel Channel to disconnect from
349
+ */
350
+ const disconnect = async (channel) => {
351
+ const connection = activeConnections[channel];
352
+ if (connection) {
353
+ _log(`Disconnecting from channel: ${channel}`);
354
+ connection.socket.disconnect();
355
+ delete activeConnections[channel];
356
+ }
357
+ };
358
+ /**
359
+ * Subscribe to an event on a channel
360
+ * @param channel Channel to subscribe to
361
+ * @param event Event name to listen for
362
+ * @param callback Callback function to handle events
363
+ */
364
+ const subscribe = async (channel, event, callback) => {
365
+ // Get or create connection
366
+ let connection = activeConnections[channel];
367
+ if (!connection) {
368
+ connection = await connect(channel);
369
+ }
370
+ // Initialize listeners set for this event if needed
371
+ if (!connection.listeners[event]) {
372
+ connection.listeners[event] = new Set();
373
+ // Add socket listener for this event
374
+ connection.socket.on(event, (eventData) => {
375
+ _log(`Received event '${event}' on channel ${channel}:`, eventData);
376
+ // Call all registered callbacks
377
+ const eventListeners = connection.listeners[event] || new Set();
378
+ eventListeners.forEach(listener => listener(eventData));
379
+ });
380
+ }
381
+ // Add callback to listeners
382
+ connection.listeners[event].add(callback);
383
+ _log(`Subscribed to event '${event}' on channel ${channel}`);
384
+ };
385
+ /**
386
+ * Subscribe to an event on a public channel
387
+ * Automatically connects to the public channel if not already connected
388
+ * @param publicToken Public file system token (10-character alphanumeric)
389
+ * @param event Event name to listen for
390
+ * @param callback Callback function to handle events
391
+ */
392
+ const subscribePublic = async (publicToken, event, callback) => {
393
+ const channel = `public/${publicToken}`;
394
+ // Get or create public connection
395
+ let connection = activeConnections[channel];
396
+ if (!connection) {
397
+ connection = await connectPublic(publicToken);
398
+ }
399
+ // Initialize listeners set for this event if needed
400
+ if (!connection.listeners[event]) {
401
+ connection.listeners[event] = new Set();
402
+ // Add socket listener for this event
403
+ connection.socket.on(event, (eventData) => {
404
+ _log(`Received event '${event}' on public channel ${channel}:`, eventData);
405
+ // Call all registered callbacks
406
+ const eventListeners = connection.listeners[event] || new Set();
407
+ eventListeners.forEach(listener => listener(eventData));
408
+ });
409
+ }
410
+ // Add callback to listeners
411
+ connection.listeners[event].add(callback);
412
+ _log(`Subscribed to event '${event}' on public channel ${channel}`);
413
+ };
414
+ /**
415
+ * Unsubscribe from an event on a channel
416
+ * @param channel Channel to unsubscribe from
417
+ * @param event Event name to stop listening for
418
+ * @param callback Callback function to remove (if not provided, all callbacks will be removed)
419
+ */
420
+ /**
421
+ * Stop listening for an event on a channel. If `callback` is provided,
422
+ * only that specific listener is removed; otherwise every listener for
423
+ * that event is cleared.
424
+ *
425
+ * @param channel Channel to unsubscribe from
426
+ * @param event Event name to stop listening for
427
+ * @param callback Specific callback to remove (optional)
428
+ */
429
+ const unsubscribe = (channel, event, callback) => {
430
+ const connection = activeConnections[channel];
431
+ if (!connection || !connection.listeners[event]) {
432
+ return;
433
+ }
434
+ if (callback) {
435
+ // Remove specific callback
436
+ connection.listeners[event].delete(callback);
437
+ _log(`Unsubscribed specific callback from event '${event}' on channel ${channel}`);
438
+ }
439
+ else {
440
+ // Remove all callbacks
441
+ connection.listeners[event].clear();
442
+ connection.socket.off(event);
443
+ _log(`Unsubscribed all callbacks from event '${event}' on channel ${channel}`);
444
+ }
445
+ };
446
+ /**
447
+ * Check if connected to a channel
448
+ * @param channel Channel to check
449
+ * @returns True if connected, false otherwise
450
+ */
451
+ const isConnected = (channel) => {
452
+ return !!activeConnections[channel]?.socket.connected;
453
+ };
454
+ /**
455
+ * Emit an event to a connected channel
456
+ * @param channel Channel to emit to
457
+ * @param event Event name
458
+ * @param data Event data
459
+ */
460
+ const emit = (channel, event, data) => {
461
+ const connection = activeConnections[channel];
462
+ if (!connection?.socket.connected) {
463
+ _log(`Cannot emit to channel ${channel}: not connected`);
464
+ return;
465
+ }
466
+ _log(`Emitting '${event}' on channel ${channel}`);
467
+ connection.socket.emit(event, data);
468
+ };
469
+ /**
470
+ * Emit an event with a timeout-bounded server acknowledgement. Resolves
471
+ * `true` if the server acks within `timeoutMs`, `false` on timeout or
472
+ * transport error. Used by the FE WS layer (`WebSocketManager.probeChannel`)
473
+ * to actively verify a channel's liveness when `socket.connected` may be
474
+ * stale — most notably after a backgrounded tab returns to focus, where
475
+ * the flag can remain `true` for up to socket.io's own heartbeat window
476
+ * (~25–45s) even after the underlying TCP transport has died.
477
+ *
478
+ * Relies on socket.io v4's `socket.timeout(ms).emit(ev, data, cb)`
479
+ * pattern: the BE handler invokes `ack()` (its trailing callback arg);
480
+ * if no ack arrives within `timeoutMs` the cb is invoked with an Error.
481
+ */
482
+ const emitWithAck = (channel, event, data, timeoutMs) => {
483
+ const connection = activeConnections[channel];
484
+ if (!connection)
485
+ return Promise.resolve(false);
486
+ return new Promise((resolve) => {
487
+ try {
488
+ connection.socket.timeout(timeoutMs).emit(event, data, (err) => {
489
+ resolve(!err);
490
+ });
491
+ }
492
+ catch (error) {
493
+ _log(`emitWithAck error on channel ${channel}:`, error);
494
+ resolve(false);
495
+ }
496
+ });
497
+ };
498
+ /**
499
+ * Disconnect from all channels
500
+ */
501
+ const disconnectAll = async () => {
502
+ _log('Disconnecting from all channels');
503
+ const channels = Object.keys(activeConnections);
504
+ for (const channel of channels) {
505
+ await disconnect(channel);
506
+ }
507
+ };
508
+ /**
509
+ * Register a callback for when Socket.IO exhausts all reconnection attempts
510
+ * @param channel Channel to monitor
511
+ * @param callback Callback invoked when reconnection fails permanently
512
+ */
513
+ const onReconnectFailed = (channel, callback) => {
514
+ const connection = activeConnections[channel];
515
+ if (connection) {
516
+ // Add to the channel's listener set so the existing reconnect_failed
517
+ // handler in connect()/connectPublic() dispatches to it
518
+ if (!connection.listeners['reconnect_failed']) {
519
+ connection.listeners['reconnect_failed'] = new Set();
520
+ }
521
+ connection.listeners['reconnect_failed'].add(callback);
522
+ }
523
+ };
524
+ /**
525
+ * Register a callback for when the channel reconnects — a socket.io
526
+ * transport-level reconnect, or the token-refresh reconnect. Use it to recover
527
+ * any gap of server->client messages missed while the connection was down;
528
+ * socket.io does not replay those. Dispatched from the 'reconnect' handler in
529
+ * connect() and from the token-refresh path.
530
+ */
531
+ const onReconnect = (channel, callback) => {
532
+ const connection = activeConnections[channel];
533
+ if (connection) {
534
+ if (!connection.listeners['reconnect']) {
535
+ connection.listeners['reconnect'] = new Set();
536
+ }
537
+ connection.listeners['reconnect'].add(callback);
538
+ }
539
+ };
540
+ return {
541
+ connect,
542
+ connectPublic,
543
+ disconnect,
544
+ disconnectAll,
545
+ subscribe,
546
+ subscribePublic,
547
+ unsubscribe,
548
+ isConnected,
549
+ emit,
550
+ emitWithAck,
551
+ onReconnect,
552
+ onReconnectFailed,
553
+ };
554
+ }
555
+ //# sourceMappingURL=socket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"socket.js","sourceRoot":"","sources":["../../src/routes/socket.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+ export type ResourceType = 'user' | 'workspace' | 'project' | 'chat' | 'asset';
3
+ export interface GetStorageChartParams {
4
+ startDate?: number;
5
+ endDate?: number;
6
+ aggregationPeriod?: 'year' | 'month' | 'week' | 'day';
7
+ }
8
+ export interface ChartDataEntry {
9
+ period: string;
10
+ averageSizeInBytes: number;
11
+ }
12
+ export type ChartDataResponse = ChartDataEntry[];
13
+ export interface StorageRecord {
14
+ resourceId: string;
15
+ resourceType: ResourceType;
16
+ sizeInBytes: number;
17
+ id: string;
18
+ }
19
+ /**
20
+ * Defines storage-related methods for the NuramaClient.
21
+ * @param {NuramaClient} client - The NuramaClient instance.
22
+ * @returns {object} An object containing the storage-related methods.
23
+ */
24
+ export default function createStorageMethods(client: NuramaClient): {
25
+ /**
26
+ * Retrieves storage usage chart data for a specific resource.
27
+ * Requires authentication and permission.
28
+ * @param {ResourceType} resourceType - The type of the resource.
29
+ * @param {string} resourceId - The ID of the resource.
30
+ * @param {GetStorageChartParams} [params] - Optional query parameters for date range and aggregation.
31
+ * @returns {Promise<ChartDataResponse>} An array of chart data entries.
32
+ */
33
+ getStorageChart(resourceType: ResourceType, resourceId: string, params?: GetStorageChartParams): Promise<ChartDataResponse>;
34
+ /**
35
+ * Retrieves the latest storage record for a specific resource.
36
+ * Requires authentication and permission.
37
+ * @param {ResourceType} resourceType - The type of the resource.
38
+ * @param {string} resourceId - The ID of the resource.
39
+ * @returns {Promise<StorageRecord>} The latest storage record for the resource.
40
+ */
41
+ getStorageRecord(resourceType: ResourceType, resourceId: string): Promise<StorageRecord>;
42
+ };
43
+ export type StorageMethods = ReturnType<typeof createStorageMethods>;
44
+ //# sourceMappingURL=storage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../src/routes/storage.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAG9C,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAG/E,MAAM,WAAW,qBAAqB;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iBAAiB,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;CACzD;AAGD,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,cAAc,EAAE,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,YAAY,CAAC;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;CACd;AAID;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAAC,MAAM,EAAE,YAAY;IAE7D;;;;;;;WAOO;kCAES,YAAY,cACd,MAAM,WACT,qBAAqB,GAC7B,OAAO,CAAC,iBAAiB,CAAC;IAW7B;;;;;;WAMO;mCAES,YAAY,cACd,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC;EAU5B;AAGD,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAC"}