@pooflabs/core 0.0.48 → 0.0.49

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/dist/index.mjs CHANGED
@@ -4744,6 +4744,7 @@ async function getOrCreateConnection(appId, isServer) {
4744
4744
  subscriptions: new Map(),
4745
4745
  pendingSubscriptions: new Map(),
4746
4746
  pendingUnsubscriptions: new Map(),
4747
+ pendingRequests: new Map(),
4747
4748
  isConnecting: false,
4748
4749
  isConnected: false,
4749
4750
  appId,
@@ -4842,11 +4843,17 @@ async function getOrCreateConnection(appId, isServer) {
4842
4843
  clearInterval(connection.tokenRefreshTimer);
4843
4844
  connection.tokenRefreshTimer = null;
4844
4845
  }
4846
+ // Reject all pending WS CRUD requests on disconnect (fail fast)
4847
+ for (const [id, pending] of connection.pendingRequests) {
4848
+ clearTimeout(pending.timer);
4849
+ pending.reject(new Error('WebSocket disconnected'));
4850
+ }
4851
+ connection.pendingRequests.clear();
4845
4852
  });
4846
4853
  return connection;
4847
4854
  }
4848
4855
  function handleServerMessage(connection, message) {
4849
- var _a;
4856
+ var _a, _b;
4850
4857
  switch (message.type) {
4851
4858
  case 'subscribed': {
4852
4859
  const subscription = connection.subscriptions.get(message.subscriptionId);
@@ -4891,8 +4898,45 @@ function handleServerMessage(connection, message) {
4891
4898
  }
4892
4899
  break;
4893
4900
  }
4901
+ case 'response': {
4902
+ const pendingReq = connection.pendingRequests.get(message.requestId);
4903
+ if (pendingReq) {
4904
+ connection.pendingRequests.delete(message.requestId);
4905
+ clearTimeout(pendingReq.timer);
4906
+ if (message.status >= 400) {
4907
+ pendingReq.reject(new Error(`Request failed with status ${message.status}`));
4908
+ }
4909
+ else {
4910
+ pendingReq.resolve(message.data);
4911
+ }
4912
+ }
4913
+ break;
4914
+ }
4915
+ case 'setResponse': {
4916
+ const pendingSet = connection.pendingRequests.get(message.requestId);
4917
+ if (pendingSet) {
4918
+ connection.pendingRequests.delete(message.requestId);
4919
+ clearTimeout(pendingSet.timer);
4920
+ if (message.statusCode >= 400) {
4921
+ pendingSet.reject(new Error(((_a = message.body) === null || _a === void 0 ? void 0 : _a.message) || `Set failed with status ${message.statusCode}`));
4922
+ }
4923
+ else {
4924
+ pendingSet.resolve(message.body);
4925
+ }
4926
+ }
4927
+ break;
4928
+ }
4894
4929
  case 'error': {
4895
4930
  console.error('[WS v2] Server error:', message.code, message.message);
4931
+ // Handle CRUD request errors (requestId present)
4932
+ if (message.requestId) {
4933
+ const pendingReq = connection.pendingRequests.get(message.requestId);
4934
+ if (pendingReq) {
4935
+ connection.pendingRequests.delete(message.requestId);
4936
+ clearTimeout(pendingReq.timer);
4937
+ pendingReq.reject(new Error(`${message.code}: ${message.message}`));
4938
+ }
4939
+ }
4896
4940
  if (message.subscriptionId) {
4897
4941
  // Reject pending subscription if this is a subscription error
4898
4942
  const pending = connection.pendingSubscriptions.get(message.subscriptionId);
@@ -4904,7 +4948,7 @@ function handleServerMessage(connection, message) {
4904
4948
  const subscription = connection.subscriptions.get(message.subscriptionId);
4905
4949
  if (subscription) {
4906
4950
  for (const callback of subscription.callbacks) {
4907
- (_a = callback.onError) === null || _a === void 0 ? void 0 : _a.call(callback, new Error(`${message.code}: ${message.message}`));
4951
+ (_b = callback.onError) === null || _b === void 0 ? void 0 : _b.call(callback, new Error(`${message.code}: ${message.message}`));
4908
4952
  }
4909
4953
  }
4910
4954
  }
@@ -5193,6 +5237,97 @@ async function doReconnectWithNewAuth() {
5193
5237
  }
5194
5238
  }
5195
5239
  }
5240
+ // ============ CRUD over WebSocket ============
5241
+ const WS_REQUEST_TIMEOUT_MS = 30000;
5242
+ function generateRequestId() {
5243
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
5244
+ }
5245
+ /**
5246
+ * Returns true if there is an active v2 WebSocket connection open.
5247
+ */
5248
+ function hasActiveConnection() {
5249
+ for (const connection of connections.values()) {
5250
+ if (connection.ws && connection.isConnected) {
5251
+ return true;
5252
+ }
5253
+ }
5254
+ return false;
5255
+ }
5256
+ async function sendRequest(msgBuilder) {
5257
+ const config = await getConfig();
5258
+ const appId = config.appId;
5259
+ const connection = await getOrCreateConnection(appId, config.isServer);
5260
+ // Wait for the connection to be open (getOrCreateConnection may return
5261
+ // while still connecting).
5262
+ if (!connection.isConnected && connection.ws) {
5263
+ await new Promise((resolve, reject) => {
5264
+ const timeout = setTimeout(() => {
5265
+ var _a;
5266
+ (_a = connection.ws) === null || _a === void 0 ? void 0 : _a.removeEventListener('open', onOpen);
5267
+ reject(new Error('WebSocket connection timeout'));
5268
+ }, 10000);
5269
+ const onOpen = () => { clearTimeout(timeout); resolve(); };
5270
+ if (connection.isConnected) {
5271
+ clearTimeout(timeout);
5272
+ resolve();
5273
+ return;
5274
+ }
5275
+ connection.ws.addEventListener('open', onOpen);
5276
+ });
5277
+ }
5278
+ if (!connection.ws || !connection.isConnected) {
5279
+ throw new Error('WebSocket connection not available');
5280
+ }
5281
+ const requestId = generateRequestId();
5282
+ const message = msgBuilder(requestId);
5283
+ return new Promise((resolve, reject) => {
5284
+ const timer = setTimeout(() => {
5285
+ connection.pendingRequests.delete(requestId);
5286
+ reject(new Error(`WebSocket request timed out after ${WS_REQUEST_TIMEOUT_MS}ms`));
5287
+ }, WS_REQUEST_TIMEOUT_MS);
5288
+ connection.pendingRequests.set(requestId, { resolve, reject, timer });
5289
+ try {
5290
+ connection.ws.send(JSON.stringify(message));
5291
+ }
5292
+ catch (error) {
5293
+ connection.pendingRequests.delete(requestId);
5294
+ clearTimeout(timer);
5295
+ reject(error);
5296
+ }
5297
+ });
5298
+ }
5299
+ async function wsGet(path) {
5300
+ return sendRequest((requestId) => ({
5301
+ type: 'get',
5302
+ requestId,
5303
+ path,
5304
+ }));
5305
+ }
5306
+ async function wsSet(documents) {
5307
+ return sendRequest((requestId) => ({
5308
+ type: 'set',
5309
+ requestId,
5310
+ documents,
5311
+ }));
5312
+ }
5313
+ async function wsQuery(path, opts) {
5314
+ return sendRequest((requestId) => (Object.assign(Object.assign(Object.assign(Object.assign({ type: 'query', requestId,
5315
+ path }, ((opts === null || opts === void 0 ? void 0 : opts.filter) ? { filter: opts.filter } : {})), ((opts === null || opts === void 0 ? void 0 : opts.sort) ? { sort: opts.sort } : {})), ((opts === null || opts === void 0 ? void 0 : opts.limit) !== undefined ? { limit: opts.limit } : {})), ((opts === null || opts === void 0 ? void 0 : opts.includeSubPaths) ? { includeSubPaths: opts.includeSubPaths } : {}))));
5316
+ }
5317
+ async function wsDelete(path) {
5318
+ return sendRequest((requestId) => ({
5319
+ type: 'delete',
5320
+ requestId,
5321
+ path,
5322
+ }));
5323
+ }
5324
+ async function wsGetMany(paths) {
5325
+ return sendRequest((requestId) => ({
5326
+ type: 'getMany',
5327
+ requestId,
5328
+ paths,
5329
+ }));
5330
+ }
5196
5331
 
5197
5332
  /**
5198
5333
  * WebSocket Subscription Module
@@ -5447,5 +5582,5 @@ class ReactNativeSessionManager {
5447
5582
  }
5448
5583
  ReactNativeSessionManager.TAROBASE_SESSION_STORAGE_KEY = "tarobase_session_storage";
5449
5584
 
5450
- export { InsufficientBalanceError, ReactNativeSessionManager, ServerSessionManager, WebSessionManager, aggregate, buildSetDocumentsTransaction, clearCache, closeAllSubscriptions, convertRemainingAccounts, count, createSessionWithPrivy, createSessionWithSignature, genAuthNonce, genSolanaMessage, get, getCachedData, getConfig, getFiles, getIdToken, getMany, init, reconnectWithNewAuth, refreshSession, runExpression, runExpressionMany, runQuery, runQueryMany, set, setFile, setMany, signAndSubmitTransaction, signMessage, signSessionCreateMessage, signTransaction, subscribe };
5585
+ export { InsufficientBalanceError, ReactNativeSessionManager, ServerSessionManager, WebSessionManager, aggregate, buildSetDocumentsTransaction, clearCache, closeAllSubscriptions, convertRemainingAccounts, count, createSessionWithPrivy, createSessionWithSignature, genAuthNonce, genSolanaMessage, get, getCachedData, getConfig, getFiles, getIdToken, getMany, hasActiveConnection, init, reconnectWithNewAuth, refreshSession, runExpression, runExpressionMany, runQuery, runQueryMany, set, setFile, setMany, signAndSubmitTransaction, signMessage, signSessionCreateMessage, signTransaction, subscribe, wsDelete, wsGet, wsGetMany, wsQuery, wsSet };
5451
5586
  //# sourceMappingURL=index.mjs.map