@bounded-sh/client 0.0.3 → 0.0.5

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 (46) hide show
  1. package/dist/hooks/useQuery.d.ts +58 -0
  2. package/dist/{index-DyfiK3_X.esm.js → index-30RA_Bdf.esm.js} +268 -18
  3. package/dist/index-30RA_Bdf.esm.js.map +1 -0
  4. package/dist/{index-DJg-Dduo.esm.js → index-B9DtkVXb.esm.js} +2 -2
  5. package/dist/{index-DJg-Dduo.esm.js.map → index-B9DtkVXb.esm.js.map} +1 -1
  6. package/dist/{index-CYVVTWs4.js → index-CdqFc68L.js} +2 -2
  7. package/dist/{index-CYVVTWs4.js.map → index-CdqFc68L.js.map} +1 -1
  8. package/dist/{index-C2JpxGAC.js → index-CplhW55m.js} +2 -2
  9. package/dist/{index-C2JpxGAC.js.map → index-CplhW55m.js.map} +1 -1
  10. package/dist/{index-C2yvle9S.esm.js → index-DXdFMfDw.esm.js} +2 -2
  11. package/dist/{index-C2yvle9S.esm.js.map → index-DXdFMfDw.esm.js.map} +1 -1
  12. package/dist/{index-2UpSvA7V.js → index-ZYhdEVCA.js} +272 -17
  13. package/dist/index-ZYhdEVCA.js.map +1 -0
  14. package/dist/{index.browser-pymH6o1X.esm.js → index.browser-Cictefil.esm.js} +2 -2
  15. package/dist/{index.browser-pymH6o1X.esm.js.map → index.browser-Cictefil.esm.js.map} +1 -1
  16. package/dist/{index.browser-BTJZmhY1.js → index.browser-sADlt75X.js} +2 -2
  17. package/dist/{index.browser-BTJZmhY1.js.map → index.browser-sADlt75X.js.map} +1 -1
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.esm.js +1 -1
  20. package/dist/index.js +6 -1
  21. package/dist/index.js.map +1 -1
  22. package/dist/{index.native-BTjBgNiE.esm.js → index.native-C8GJTcIy.esm.js} +204 -14
  23. package/dist/index.native-C8GJTcIy.esm.js.map +1 -0
  24. package/dist/{index.native-BvsmNFXn.js → index.native-DpYQ8GUh.js} +207 -13
  25. package/dist/index.native-DpYQ8GUh.js.map +1 -0
  26. package/dist/index.native.d.ts +1 -1
  27. package/dist/index.native.esm.js +1 -1
  28. package/dist/index.native.js +5 -1
  29. package/dist/index.native.js.map +1 -1
  30. package/dist/{phantom-wallet-provider-BXMvoOrI.js → phantom-wallet-provider-B8gezRxB.js} +3 -3
  31. package/dist/{phantom-wallet-provider-BXMvoOrI.js.map → phantom-wallet-provider-B8gezRxB.js.map} +1 -1
  32. package/dist/{phantom-wallet-provider-CTossIFB.esm.js → phantom-wallet-provider-FOSnYV4t.esm.js} +3 -3
  33. package/dist/{phantom-wallet-provider-CTossIFB.esm.js.map → phantom-wallet-provider-FOSnYV4t.esm.js.map} +1 -1
  34. package/dist/{privy-wallet-provider-1qE_f-DF.esm.js → privy-wallet-provider-BPOjNW9O.esm.js} +3 -3
  35. package/dist/{privy-wallet-provider-1qE_f-DF.esm.js.map → privy-wallet-provider-BPOjNW9O.esm.js.map} +1 -1
  36. package/dist/{privy-wallet-provider-D64DJ3u4.js → privy-wallet-provider-DfR-7xpE.js} +3 -3
  37. package/dist/{privy-wallet-provider-D64DJ3u4.js.map → privy-wallet-provider-DfR-7xpE.js.map} +1 -1
  38. package/dist/{solana-mobile-wallet-provider-C1wQ1DRK.js → solana-mobile-wallet-provider-CBAeRxGQ.js} +2 -2
  39. package/dist/{solana-mobile-wallet-provider-C1wQ1DRK.js.map → solana-mobile-wallet-provider-CBAeRxGQ.js.map} +1 -1
  40. package/dist/{solana-mobile-wallet-provider-9M8U6AA7.esm.js → solana-mobile-wallet-provider-CoS-38SL.esm.js} +2 -2
  41. package/dist/{solana-mobile-wallet-provider-9M8U6AA7.esm.js.map → solana-mobile-wallet-provider-CoS-38SL.esm.js.map} +1 -1
  42. package/package.json +2 -2
  43. package/dist/index-2UpSvA7V.js.map +0 -1
  44. package/dist/index-DyfiK3_X.esm.js.map +0 -1
  45. package/dist/index.native-BTjBgNiE.esm.js.map +0 -1
  46. package/dist/index.native-BvsmNFXn.js.map +0 -1
package/dist/index.d.ts CHANGED
@@ -3,11 +3,13 @@ export type { LoginOptions } from "./global";
3
3
  export { getConfig } from "@bounded-sh/core";
4
4
  export { getAuthProvider, signInAnonymously, sendEmailOtp, verifyEmailOtp, linkEmail, loginWithPrivy } from "./auth";
5
5
  export { loginWithRedirect, linkWithRedirect, completeLoginFromRedirect, loginWithPopup, completeLoginInPopup } from "./auth";
6
- export { get, set, setMany, setFile, getFiles, search, queryAggregate, runQuery, runQueryMany, runExpression, runExpressionMany, signMessage, signTransaction, signAndSubmitTransaction, count, aggregate, GetOptions, SearchOptions, SetOptions, CountOptions, AggregateOptions, AggregateOperation, AggregateResult, AggregateSpec, AggregateRow, QueryAggregateOptions, } from "@bounded-sh/core";
6
+ export { get, getMany, docId, set, setMany, setFile, getFiles, search, queryAggregate, runQuery, runQueryMany, runExpression, runExpressionMany, signMessage, signTransaction, signAndSubmitTransaction, count, aggregate, GetOptions, SearchOptions, SetOptions, CountOptions, AggregateOptions, AggregateOperation, AggregateResult, AggregateSpec, AggregateRow, QueryAggregateOptions, } from "@bounded-sh/core";
7
7
  export type { GetOptions as BoundedGetOptions } from "@bounded-sh/core";
8
8
  export { subscribe } from "@bounded-sh/core";
9
9
  export * from "@bounded-sh/core";
10
10
  export { useAuth } from "./auth/hooks/useAuth";
11
+ export { useQuery } from "./hooks/useQuery";
12
+ export type { UseQueryOptions, UseQueryResult } from "./hooks/useQuery";
11
13
  export { deserializeTransaction } from "./auth/providers/sol/sol-utils";
12
14
  export { getIdToken } from "./utils";
13
15
  export { setPlatform, getPlatform } from "./platform";
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- export { U as DEFAULT_TEST_ADDRESS, $ as EFFECT_INTENT_ADDRESS, a0 as FunctionInvokeError, a1 as InsufficientBalanceError, a2 as LiveIntentError, T as MockAuthProvider, V as OffchainAuthProvider, S as PhantomWalletProvider, _ as PrivyExpoProvider, Z as PrivyWalletProvider, a3 as ReactNativeSessionManager, a4 as RealtimeStore, a5 as ServerSessionManager, W as SolanaMobileWalletProvider, a6 as WebSessionManager, L as aggregate, a7 as buildSetDocumentsTransaction, a8 as clearCache, a9 as closeAllSubscriptions, r as completeLoginFromRedirect, u as completeLoginInPopup, aa as convertRemainingAccounts, K as count, ab as createSessionWithSignature, ac as defineLiveModule, ad as deriveUserIdentityFromIdToken, O as deserializeTransaction, ae as functions, af as genAuthNonce, ag as genSolanaMessage, w as get, ah as getActiveSessionManager, e as getAuthLoading, j as getAuthProvider, ai as getCachedData, h as getConfig, c as getCurrentUser, A as getFiles, P as getIdToken, aj as getMany, R as getPlatform, ak as getRealtimeStore, al as getWebhookKeysUrl, am as hasActiveConnection, an as increment, i as init, ao as invokeFunction, ap as isEffectResult, X as isMobileWalletAvailable, m as linkEmail, q as linkWithRedirect, aq as live, ar as liveIntent, as as liveStatus, l as login, t as loginWithPopup, n as loginWithPrivy, p as loginWithRedirect, f as logout, d as onAuthLoadingChanged, o as onAuthStateChanged, C as queryAggregate, at as reconnectWithNewAuth, au as refreshSession, Y as registerMobileWalletAdapter, av as resetRealtimeStore, aw as revokeSession, F as runExpression, G as runExpressionMany, D as runQuery, E as runQueryMany, B as search, k as sendEmailOtp, ax as serverTimestamp, x as set, z as setFile, y as setMany, Q as setPlatform, J as signAndSubmitTransaction, s as signInAnonymously, H as signMessage, ay as signSessionCreateMessage, I as signTransaction, M as subscribe, az as subscribeLiveView, N as useAuth, v as verifyEmailOtp, aA as withEffects, aB as wsDelete, aC as wsGet, aD as wsGetMany, aE as wsQuery, aF as wsSet } from './index-DyfiK3_X.esm.js';
1
+ export { X as DEFAULT_TEST_ADDRESS, a2 as EFFECT_INTENT_ADDRESS, a3 as FunctionInvokeError, a4 as InsufficientBalanceError, a5 as LiveIntentError, W as MockAuthProvider, Y as OffchainAuthProvider, V as PhantomWalletProvider, a1 as PrivyExpoProvider, a0 as PrivyWalletProvider, a6 as ReactNativeSessionManager, a7 as RealtimeStore, a8 as ServerSessionManager, Z as SolanaMobileWalletProvider, a9 as WebSessionManager, N as aggregate, aa as buildSetDocumentsTransaction, ab as clearCache, ac as closeAllSubscriptions, r as completeLoginFromRedirect, u as completeLoginInPopup, ad as convertRemainingAccounts, M as count, ae as createSessionWithSignature, af as defineLiveModule, ag as deriveUserIdentityFromIdToken, R as deserializeTransaction, y as docId, ah as functions, ai as genAuthNonce, aj as genSolanaMessage, w as get, ak as getActiveSessionManager, e as getAuthLoading, j as getAuthProvider, al as getCachedData, h as getConfig, c as getCurrentUser, C as getFiles, S as getIdToken, x as getMany, U as getPlatform, am as getRealtimeStore, an as getWebhookKeysUrl, ao as hasActiveConnection, ap as increment, i as init, aq as invokeFunction, ar as isEffectResult, _ as isMobileWalletAvailable, m as linkEmail, q as linkWithRedirect, as as live, at as liveIntent, au as liveStatus, l as login, t as loginWithPopup, n as loginWithPrivy, p as loginWithRedirect, f as logout, av as now, d as onAuthLoadingChanged, o as onAuthStateChanged, E as queryAggregate, aw as reconnectWithNewAuth, ax as refreshSession, $ as registerMobileWalletAdapter, ay as resetRealtimeStore, az as revokeSession, H as runExpression, I as runExpressionMany, F as runQuery, G as runQueryMany, D as search, k as sendEmailOtp, aA as serverTimestamp, z as set, B as setFile, A as setMany, T as setPlatform, L as signAndSubmitTransaction, s as signInAnonymously, J as signMessage, aB as signSessionCreateMessage, K as signTransaction, O as subscribe, aC as subscribeLiveView, aD as toMillis, aE as toSeconds, P as useAuth, Q as useQuery, v as verifyEmailOtp, aF as withEffects, aG as wsDelete, aH as wsGet, aI as wsGetMany, aJ as wsQuery, aK as wsSet } from './index-30RA_Bdf.esm.js';
2
2
  import 'axios';
3
3
  import '@solana/web3.js';
4
4
  import '@coral-xyz/anchor';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-2UpSvA7V.js');
3
+ var index = require('./index-ZYhdEVCA.js');
4
4
  require('axios');
5
5
  require('@solana/web3.js');
6
6
  require('@coral-xyz/anchor');
@@ -37,6 +37,7 @@ exports.createSessionWithSignature = index.createSessionWithSignature;
37
37
  exports.defineLiveModule = index.defineLiveModule;
38
38
  exports.deriveUserIdentityFromIdToken = index.deriveUserIdentityFromIdToken;
39
39
  exports.deserializeTransaction = index.deserializeTransaction;
40
+ exports.docId = index.docId;
40
41
  exports.functions = index.functions;
41
42
  exports.genAuthNonce = index.genAuthNonce;
42
43
  exports.genSolanaMessage = index.genSolanaMessage;
@@ -69,6 +70,7 @@ exports.loginWithPopup = index.loginWithPopup;
69
70
  exports.loginWithPrivy = index.loginWithPrivy;
70
71
  exports.loginWithRedirect = index.loginWithRedirect;
71
72
  exports.logout = index.logout;
73
+ exports.now = index.now;
72
74
  exports.onAuthLoadingChanged = index.onAuthLoadingChanged;
73
75
  exports.onAuthStateChanged = index.onAuthStateChanged;
74
76
  exports.queryAggregate = index.queryAggregate;
@@ -95,7 +97,10 @@ exports.signSessionCreateMessage = index.signSessionCreateMessage;
95
97
  exports.signTransaction = index.signTransaction;
96
98
  exports.subscribe = index.subscribe;
97
99
  exports.subscribeLiveView = index.subscribeView;
100
+ exports.toMillis = index.toMillis;
101
+ exports.toSeconds = index.toSeconds;
98
102
  exports.useAuth = index.useAuth;
103
+ exports.useQuery = index.useQuery;
99
104
  exports.verifyEmailOtp = index.verifyEmailOtp;
100
105
  exports.withEffects = index.withEffects;
101
106
  exports.wsDelete = index.wsDelete;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -10630,6 +10630,87 @@ const pendingRequests = {};
10630
10630
  const GET_CACHE_TTL = 500; // Adjust this value as needed (in milliseconds)
10631
10631
  // Last time we cleaned up the cache
10632
10632
  let lastCacheCleanup = Date.now();
10633
+ /**
10634
+ * Return the leaf document key (last path segment) for a document path.
10635
+ *
10636
+ * Bounded rows carry `_id` (and `pathId`) set to the FULL document path
10637
+ * (e.g. `"rooms/r1/prompts/8rd49se3sg"`). Apps that build a child path from a
10638
+ * row naturally want the bare doc key, not the whole path — using the full path
10639
+ * doubles it (`rooms/r1/prompts/rooms/r1/prompts/8rd.../votes/...`) → 403/404.
10640
+ * `docId` extracts that leaf key. Tolerates leading slashes and a trailing `*`.
10641
+ *
10642
+ * @example docId("rooms/r1/prompts/8rd49se3sg") // "8rd49se3sg"
10643
+ */
10644
+ function docId(path) {
10645
+ if (typeof path !== 'string')
10646
+ return '';
10647
+ let p = path.startsWith('/') ? path.slice(1) : path;
10648
+ if (p.endsWith('*') && p.length > 1)
10649
+ p = p.slice(0, -1);
10650
+ if (p.endsWith('/'))
10651
+ p = p.slice(0, -1);
10652
+ const segments = p.split('/').filter(Boolean);
10653
+ return segments.length ? segments[segments.length - 1] : '';
10654
+ }
10655
+ /**
10656
+ * Additively attach a convenience bare `id` (the leaf doc key) to a returned row.
10657
+ *
10658
+ * Rows already carry `_id`/`pathId` = the full document path; this leaves those
10659
+ * untouched and adds `id` = the last path segment so `row.id` is the doc key apps
10660
+ * expect. No-ops for non-objects, arrays, and rows that already define `id`
10661
+ * (never clobber a user field named `id`). Source for the leaf is `_id` (falling
10662
+ * back to `pathId`/`relativePath`/`absolutePath`).
10663
+ */
10664
+ function withBareId(row) {
10665
+ var _a, _b, _c;
10666
+ if (!row || typeof row !== 'object' || Array.isArray(row))
10667
+ return row;
10668
+ const r = row;
10669
+ if ('id' in r)
10670
+ return row; // don't clobber an explicit user field
10671
+ const source = (_c = (_b = (_a = r._id) !== null && _a !== void 0 ? _a : r.pathId) !== null && _b !== void 0 ? _b : r.relativePath) !== null && _c !== void 0 ? _c : r.absolutePath;
10672
+ if (typeof source !== 'string' || source.length === 0)
10673
+ return row;
10674
+ const leaf = docId(source);
10675
+ if (!leaf)
10676
+ return row;
10677
+ return Object.assign(Object.assign({}, r), { id: leaf });
10678
+ }
10679
+ /**
10680
+ * Normalize a raw read response from the worker into the SDK's stable shape and
10681
+ * attach the bare `id` to every returned row (Bug 1 + Bug 2).
10682
+ *
10683
+ * - Single-document path: returns EXACTLY ONE shape — the resolved document, or
10684
+ * `null` if missing (Firebase/Mongo convention). Unwraps the ambiguous
10685
+ * `{ data, status }` envelope the worker sometimes emits for a single doc so a
10686
+ * single-doc `get` never sometimes-returns the doc and sometimes the envelope.
10687
+ * - Collection path: preserves the `{ data, nextCursor, ... }` envelope and maps
10688
+ * the bare `id` onto each row in `data`.
10689
+ */
10690
+ function normalizeReadResult(responseData, pathIsDocument) {
10691
+ if (pathIsDocument) {
10692
+ let doc = responseData;
10693
+ // Unwrap the single-doc envelope `{ data, status }` (Bug 2). A real document
10694
+ // never has the exact shape `{ data, status }` with nothing else meaningful,
10695
+ // so detect the envelope by `data` being present alongside a numeric `status`.
10696
+ if (doc && typeof doc === 'object' && !Array.isArray(doc) &&
10697
+ 'data' in doc && 'status' in doc && typeof doc.status === 'number') {
10698
+ doc = doc.data;
10699
+ }
10700
+ if (doc === undefined || doc === null)
10701
+ return null;
10702
+ return withBareId(doc);
10703
+ }
10704
+ // Collection read. The worker body is `{ data: rows[], nextCursor?, status? }`.
10705
+ if (responseData && typeof responseData === 'object' && !Array.isArray(responseData) && Array.isArray(responseData.data)) {
10706
+ return Object.assign(Object.assign({}, responseData), { data: responseData.data.map((row) => withBareId(row)) });
10707
+ }
10708
+ // Some paths return a bare array of rows — map id onto each.
10709
+ if (Array.isArray(responseData)) {
10710
+ return responseData.map((row) => withBareId(row));
10711
+ }
10712
+ return responseData;
10713
+ }
10633
10714
  function hashForKey$1(value) {
10634
10715
  let h = 5381;
10635
10716
  for (let i = 0; i < value.length; i++) {
@@ -11054,7 +11135,7 @@ async function get(path, opts = {}) {
11054
11135
  if (hasActiveConnection()) {
11055
11136
  if (pathIsDocument) {
11056
11137
  const wsResult = await wsGet(normalizedPath);
11057
- const responseData = wsResult;
11138
+ const responseData = normalizeReadResult(wsResult, true);
11058
11139
  if (!opts.bypassCache) {
11059
11140
  getCache[cacheKey] = { data: responseData, expiresAt: now + GET_CACHE_TTL };
11060
11141
  }
@@ -11066,7 +11147,7 @@ async function get(path, opts = {}) {
11066
11147
  sort: undefined,
11067
11148
  includeSubPaths: opts.includeSubPaths,
11068
11149
  });
11069
- const responseData = wsResult;
11150
+ const responseData = normalizeReadResult(wsResult, false);
11070
11151
  if (!opts.bypassCache) {
11071
11152
  getCache[cacheKey] = { data: responseData, expiresAt: now + GET_CACHE_TTL };
11072
11153
  }
@@ -11097,7 +11178,11 @@ async function get(path, opts = {}) {
11097
11178
  const apiPath = `items?path=${path}${promptQueryParam}${filterParam}${sortParam}${includeSubPathsParam}${shapeParam}${limitParam}${cursorParam}`;
11098
11179
  response = await makeApiRequest('GET', apiPath, null, opts._overrides);
11099
11180
  }
11100
- const responseData = response.data;
11181
+ // Normalize the worker's raw body into the SDK's stable shape:
11182
+ // - single-doc path → the resolved document or null (Bug 2), and
11183
+ // - collection path → `{ data, nextCursor }` preserved,
11184
+ // with the bare `id` (leaf doc key) attached to every returned row (Bug 1).
11185
+ const responseData = normalizeReadResult(response.data, pathIsDocument);
11101
11186
  // Cache the response (unless bypassing cache)
11102
11187
  if (!opts.bypassCache) {
11103
11188
  getCache[cacheKey] = {
@@ -11195,11 +11280,16 @@ async function getMany(paths, opts = {}) {
11195
11280
  const normalizedPath = uncachedPaths[i];
11196
11281
  const serverResult = serverResultsMap.get(normalizedPath);
11197
11282
  if (serverResult) {
11198
- results[originalIndex] = serverResult;
11199
- if (!serverResult.error && !opts.bypassCache) {
11283
+ // getMany batches single-doc paths — attach the bare `id` (leaf doc
11284
+ // key) to each returned doc, additive (Bug 1), matching get().
11285
+ const normalizedResult = serverResult.error
11286
+ ? serverResult
11287
+ : Object.assign(Object.assign({}, serverResult), { data: withBareId(serverResult.data) });
11288
+ results[originalIndex] = normalizedResult;
11289
+ if (!normalizedResult.error && !opts.bypassCache) {
11200
11290
  const cacheKey = `${principalKey}|${normalizedPath}:`;
11201
11291
  getCache[cacheKey] = {
11202
- data: serverResult.data,
11292
+ data: normalizedResult.data,
11203
11293
  expiresAt: now + GET_CACHE_TTL
11204
11294
  };
11205
11295
  }
@@ -11744,6 +11834,7 @@ var operations = /*#__PURE__*/Object.freeze({
11744
11834
  aggregate: aggregate,
11745
11835
  clearReadCacheForAuthChange: clearReadCacheForAuthChange,
11746
11836
  count: count,
11837
+ docId: docId,
11747
11838
  get: get,
11748
11839
  getFiles: getFiles,
11749
11840
  getMany: getMany,
@@ -12331,14 +12422,46 @@ function handleServerMessage(connection, message) {
12331
12422
  }
12332
12423
  }
12333
12424
  }
12425
+ /**
12426
+ * Additively attach the bare `id` (leaf doc key) to a subscription row (Bug 1).
12427
+ * Rows carry `_id`/`pathId` = the full document path; this leaves those as-is and
12428
+ * adds `id` = the last path segment so `row.id` is the doc key apps expect. No-ops
12429
+ * for non-objects and rows that already define `id`.
12430
+ */
12431
+ function withSubscriptionId(row) {
12432
+ var _a, _b, _c;
12433
+ if (!row || typeof row !== 'object' || Array.isArray(row))
12434
+ return row;
12435
+ if ('id' in row)
12436
+ return row;
12437
+ const source = (_c = (_b = (_a = row._id) !== null && _a !== void 0 ? _a : row.pathId) !== null && _b !== void 0 ? _b : row.relativePath) !== null && _c !== void 0 ? _c : row.absolutePath;
12438
+ if (typeof source !== 'string' || source.length === 0)
12439
+ return row;
12440
+ const leaf = docId(source);
12441
+ if (!leaf)
12442
+ return row;
12443
+ return Object.assign(Object.assign({}, row), { id: leaf });
12444
+ }
12445
+ /**
12446
+ * The `onData` payload follows the path: a collection delivers a bare array of
12447
+ * rows, a single-doc path delivers the document (or null). Attach the bare `id`
12448
+ * to each returned row in either case, additive (Bug 1).
12449
+ */
12450
+ function addIdsToSubscriptionData(data) {
12451
+ if (Array.isArray(data))
12452
+ return data.map(withSubscriptionId);
12453
+ return withSubscriptionId(data);
12454
+ }
12334
12455
  function notifyCallbacks(subscription, data) {
12335
12456
  var _a;
12457
+ // Attach the bare `id` (leaf doc key) to every delivered row (Bug 1).
12458
+ const decorated = addIdsToSubscriptionData(data);
12336
12459
  // Snapshot the callbacks array so that unsubscriptions during
12337
12460
  // notification don't cause callbacks to be skipped.
12338
12461
  const callbacks = subscription.callbacks.slice();
12339
12462
  for (const callback of callbacks) {
12340
12463
  try {
12341
- (_a = callback.onData) === null || _a === void 0 ? void 0 : _a.call(callback, data);
12464
+ (_a = callback.onData) === null || _a === void 0 ? void 0 : _a.call(callback, decorated);
12342
12465
  }
12343
12466
  catch (error) {
12344
12467
  console.error('[WS v2] Error in subscription callback:', error);
@@ -12429,7 +12552,7 @@ async function subscribeV2(path, subscriptionOptions, roomRoutePath) {
12429
12552
  if (cachedEntry && Date.now() - cachedEntry.timestamp < CACHE_TTL && subscriptionOptions.onData) {
12430
12553
  setTimeout(() => {
12431
12554
  var _a;
12432
- (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, cachedEntry.data);
12555
+ (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, addIdsToSubscriptionData(cachedEntry.data));
12433
12556
  }, 0);
12434
12557
  }
12435
12558
  // Get or create connection for this routing target (room-scoped when a
@@ -12459,7 +12582,7 @@ async function subscribeV2(path, subscriptionOptions, roomRoutePath) {
12459
12582
  if (existingSubscription.lastData !== undefined && subscriptionOptions.onData) {
12460
12583
  setTimeout(() => {
12461
12584
  var _a;
12462
- (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, existingSubscription.lastData);
12585
+ (_a = subscriptionOptions.onData) === null || _a === void 0 ? void 0 : _a.call(subscriptionOptions, addIdsToSubscriptionData(existingSubscription.lastData));
12463
12586
  }, 0);
12464
12587
  }
12465
12588
  return async () => {
@@ -12967,6 +13090,73 @@ function serverTimestamp() {
12967
13090
  return { operation: 'time', value: 'now' };
12968
13091
  }
12969
13092
 
13093
+ /**
13094
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
13095
+ *
13096
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
13097
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
13098
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
13099
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
13100
+ * single seconds unit works for both onchain and offchain rules.)
13101
+ *
13102
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
13103
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
13104
+ *
13105
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
13106
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
13107
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
13108
+ * isn't delivering" when the data is actually fine.
13109
+ *
13110
+ * **The rules:**
13111
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
13112
+ * (from this package) — the *server* stamps it in seconds, so it matches
13113
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
13114
+ * anti-cheat). Use `now()` only when you need the value in client code before
13115
+ * the write.
13116
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
13117
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
13118
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
13119
+ */
13120
+ /**
13121
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
13122
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
13123
+ * client code (e.g. a freshness check). For a value you *store* and a policy
13124
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
13125
+ *
13126
+ * ```ts
13127
+ * // stale if >15s old — seconds vs seconds ✓
13128
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
13129
+ * ```
13130
+ */
13131
+ function now() {
13132
+ return Math.floor(Date.now() / 1000);
13133
+ }
13134
+ /**
13135
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
13136
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
13137
+ * `_updatedAt` system field.
13138
+ *
13139
+ * ```ts
13140
+ * // doc is >15s old (compare the ms system field in seconds):
13141
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
13142
+ * ```
13143
+ */
13144
+ function toSeconds(msOrDate) {
13145
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
13146
+ return Math.floor(ms / 1000);
13147
+ }
13148
+ /**
13149
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
13150
+ * e.g. to build a `Date` or do client-side date math/formatting.
13151
+ *
13152
+ * ```ts
13153
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
13154
+ * ```
13155
+ */
13156
+ function toMillis(seconds) {
13157
+ return seconds * 1000;
13158
+ }
13159
+
12970
13160
  // ---------------------------------------------------------------------------
12971
13161
  // realtime-store.ts — Client-side state manager for realtime apps.
12972
13162
  //
@@ -21033,17 +21223,17 @@ function clearIncompatibleSession() {
21033
21223
  // Lazy loaders for web-only providers.
21034
21224
  // Using dynamic import() ensures Metro (RN) never resolves these modules.
21035
21225
  async function loadPhantomWalletProvider() {
21036
- const mod = await import('./phantom-wallet-provider-CTossIFB.esm.js');
21226
+ const mod = await import('./phantom-wallet-provider-FOSnYV4t.esm.js');
21037
21227
  return { PhantomWalletProvider: mod.PhantomWalletProvider };
21038
21228
  }
21039
21229
  // Web Privy provider (depends on react-dom + @privy-io/react-auth). Lazy so Metro
21040
21230
  // never bundles it into the RN build — RN uses the @privy-io/expo provider instead.
21041
21231
  async function loadPrivyWalletProvider() {
21042
- const mod = await import('./privy-wallet-provider-1qE_f-DF.esm.js');
21232
+ const mod = await import('./privy-wallet-provider-BPOjNW9O.esm.js');
21043
21233
  return mod.PrivyWalletProvider;
21044
21234
  }
21045
21235
  async function loadSolanaMobileWalletProvider() {
21046
- const mod = await import('./solana-mobile-wallet-provider-9M8U6AA7.esm.js');
21236
+ const mod = await import('./solana-mobile-wallet-provider-CoS-38SL.esm.js');
21047
21237
  return mod.SolanaMobileWalletProvider;
21048
21238
  }
21049
21239
  async function hotSwapToMWAProvider(config) {
@@ -22022,5 +22212,5 @@ class PrivyExpoProvider {
22022
22212
  }
22023
22213
  }
22024
22214
 
22025
- export { aggregate as $, signInAnonymously as A, sendEmailOtp as B, verifyEmailOtp as C, linkEmail as D, loginWithPrivy as E, loginWithRedirect as F, linkWithRedirect as G, completeLoginFromRedirect as H, loginWithPopup as I, completeLoginInPopup as J, get as K, set as L, setMany as M, setFile as N, getFiles as O, search as P, queryAggregate as Q, runQuery as R, SOLANA_DEVNET_RPC_URL as S, runQueryMany as T, runExpression as U, runExpressionMany as V, WebSessionManager as W, signMessage as X, signTransaction as Y, signAndSubmitTransaction as Z, count as _, buildSetDocumentsTransaction as a, subscribe as a0, useAuth as a1, deserializeTransaction as a2, getIdToken as a3, setPlatform as a4, MockAuthProvider as a5, DEFAULT_TEST_ADDRESS as a6, OffchainAuthProvider as a7, PrivyExpoProvider as a8, EFFECT_INTENT_ADDRESS as a9, serverTimestamp as aA, signSessionCreateMessage as aB, subscribeView as aC, withEffects as aD, wsDelete as aE, wsGet as aF, wsGetMany as aG, wsQuery as aH, wsSet as aI, index as aJ, FunctionInvokeError as aa, InsufficientBalanceError as ab, LiveIntentError as ac, ReactNativeSessionManager as ad, RealtimeStore as ae, ServerSessionManager as af, clearCache as ag, closeAllSubscriptions as ah, defineLiveModule as ai, deriveUserIdentityFromIdToken as aj, functions as ak, getCachedData as al, getMany as am, getRealtimeStore as an, getWebhookKeysUrl as ao, hasActiveConnection as ap, increment as aq, invoke as ar, isEffectResult as as, live as at, intent as au, status as av, reconnectWithNewAuth as aw, refreshSession as ax, resetRealtimeStore as ay, revokeSession as az, bufferExports as b, convertRemainingAccounts as c, confirmAndCheckTransaction as d, SOLANA_MAINNET_RPC_URL as e, SURFNET_RPC_URL$1 as f, detectMobile as g, detectAndroid as h, getPlatform as i, setAuthLoading as j, genAuthNonce as k, genSolanaMessage as l, createSessionWithSignature as m, getActiveSessionManager as n, bs582 as o, getDefaultExportFromCjs$1 as p, init as q, getCurrentUser as r, setCurrentUser as s, onAuthStateChanged as t, onAuthLoadingChanged as u, getAuthLoading as v, login as w, logout as x, getConfig as y, getAuthProvider as z };
22026
- //# sourceMappingURL=index.native-BTjBgNiE.esm.js.map
22215
+ export { signAndSubmitTransaction as $, signInAnonymously as A, sendEmailOtp as B, verifyEmailOtp as C, linkEmail as D, loginWithPrivy as E, loginWithRedirect as F, linkWithRedirect as G, completeLoginFromRedirect as H, loginWithPopup as I, completeLoginInPopup as J, get as K, getMany as L, docId as M, set as N, setMany as O, setFile as P, getFiles as Q, search as R, SOLANA_DEVNET_RPC_URL as S, queryAggregate as T, runQuery as U, runQueryMany as V, WebSessionManager as W, runExpression as X, runExpressionMany as Y, signMessage as Z, signTransaction as _, buildSetDocumentsTransaction as a, count as a0, aggregate as a1, subscribe as a2, useAuth as a3, deserializeTransaction as a4, getIdToken as a5, setPlatform as a6, MockAuthProvider as a7, DEFAULT_TEST_ADDRESS as a8, OffchainAuthProvider as a9, resetRealtimeStore as aA, revokeSession as aB, serverTimestamp as aC, signSessionCreateMessage as aD, subscribeView as aE, toMillis as aF, toSeconds as aG, withEffects as aH, wsDelete as aI, wsGet as aJ, wsGetMany as aK, wsQuery as aL, wsSet as aM, index as aN, PrivyExpoProvider as aa, EFFECT_INTENT_ADDRESS as ab, FunctionInvokeError as ac, InsufficientBalanceError as ad, LiveIntentError as ae, ReactNativeSessionManager as af, RealtimeStore as ag, ServerSessionManager as ah, clearCache as ai, closeAllSubscriptions as aj, defineLiveModule as ak, deriveUserIdentityFromIdToken as al, functions as am, getCachedData as an, getRealtimeStore as ao, getWebhookKeysUrl as ap, hasActiveConnection as aq, increment as ar, invoke as as, isEffectResult as at, live as au, intent as av, status as aw, now as ax, reconnectWithNewAuth as ay, refreshSession as az, bufferExports as b, convertRemainingAccounts as c, confirmAndCheckTransaction as d, SOLANA_MAINNET_RPC_URL as e, SURFNET_RPC_URL$1 as f, detectMobile as g, detectAndroid as h, getPlatform as i, setAuthLoading as j, genAuthNonce as k, genSolanaMessage as l, createSessionWithSignature as m, getActiveSessionManager as n, bs582 as o, getDefaultExportFromCjs$1 as p, init as q, getCurrentUser as r, setCurrentUser as s, onAuthStateChanged as t, onAuthLoadingChanged as u, getAuthLoading as v, login as w, logout as x, getConfig as y, getAuthProvider as z };
22216
+ //# sourceMappingURL=index.native-C8GJTcIy.esm.js.map