@bounded-sh/core 0.0.3 → 0.0.4

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
@@ -6594,6 +6594,73 @@ function serverTimestamp() {
6594
6594
  return { operation: 'time', value: 'now' };
6595
6595
  }
6596
6596
 
6597
+ /**
6598
+ * Time units in Bounded — read this once and never get a 1000× timestamp bug.
6599
+ *
6600
+ * **Bounded's policy/proof layer is Unix SECONDS.** `@time.now` in a rule,
6601
+ * `rollingSum` `windowSeconds`, `scheduledAt`, and any timestamp *field your
6602
+ * policy compares against `@time.now`* are all **seconds**. (This is also what
6603
+ * the chain uses — Solana's on-chain clock is `unix_timestamp` in seconds — so a
6604
+ * single seconds unit works for both onchain and offchain rules.)
6605
+ *
6606
+ * **JavaScript is MILLISECONDS.** `Date.now()`, `new Date().getTime()`, and the
6607
+ * auto-stamped system fields `_createdAt` / `_updatedAt` are all **ms**.
6608
+ *
6609
+ * Comparing across the two (e.g. `@time.now - myField` where `myField` was set
6610
+ * from `Date.now()`) is 1000× off, so a freshness / TTL check silently treats
6611
+ * every row as ancient (or far-future) and drops it — which reads as "realtime
6612
+ * isn't delivering" when the data is actually fine.
6613
+ *
6614
+ * **The rules:**
6615
+ * - To **write** a timestamp a policy will read, prefer **`serverTimestamp()`**
6616
+ * (from this package) — the *server* stamps it in seconds, so it matches
6617
+ * `@time.now` AND can't be forged by the client (use it for TTLs, rate windows,
6618
+ * anti-cheat). Use `now()` only when you need the value in client code before
6619
+ * the write.
6620
+ * - To **compare** timestamps in client/render code, use `now()` (seconds), not
6621
+ * `Date.now()` (ms), and `toSeconds()` to convert the ms system fields
6622
+ * (`_createdAt`/`_updatedAt`) or any `Date.now()` value first.
6623
+ */
6624
+ /**
6625
+ * Current time as a **Unix timestamp in seconds** — the unit Bounded policy rules
6626
+ * use (`@time.now`). Use this (not `Date.now()`) when you need a timestamp in
6627
+ * client code (e.g. a freshness check). For a value you *store* and a policy
6628
+ * reads, prefer the server-authoritative {@link serverTimestamp} instead.
6629
+ *
6630
+ * ```ts
6631
+ * // stale if >15s old — seconds vs seconds ✓
6632
+ * if (now() - doc.lastSeenSeconds > 15) renderStale();
6633
+ * ```
6634
+ */
6635
+ function now() {
6636
+ return Math.floor(Date.now() / 1000);
6637
+ }
6638
+ /**
6639
+ * Convert a JavaScript millisecond timestamp to Bounded's **seconds**. Accepts a
6640
+ * `Date`, or an ms number such as `Date.now()` or a doc's `_createdAt` /
6641
+ * `_updatedAt` system field.
6642
+ *
6643
+ * ```ts
6644
+ * // doc is >15s old (compare the ms system field in seconds):
6645
+ * if (now() - toSeconds(doc._updatedAt) > 15) renderStale();
6646
+ * ```
6647
+ */
6648
+ function toSeconds(msOrDate) {
6649
+ const ms = msOrDate instanceof Date ? msOrDate.getTime() : msOrDate;
6650
+ return Math.floor(ms / 1000);
6651
+ }
6652
+ /**
6653
+ * Convert a Bounded **seconds** timestamp back to JavaScript **milliseconds** —
6654
+ * e.g. to build a `Date` or do client-side date math/formatting.
6655
+ *
6656
+ * ```ts
6657
+ * new Date(toMillis(doc.createdAtSeconds)).toLocaleString();
6658
+ * ```
6659
+ */
6660
+ function toMillis(seconds) {
6661
+ return seconds * 1000;
6662
+ }
6663
+
6597
6664
  // ---------------------------------------------------------------------------
6598
6665
  // realtime-store.ts — Client-side state manager for realtime apps.
6599
6666
  //
@@ -7778,5 +7845,5 @@ function defineLiveModule(mod) {
7778
7845
  return mod;
7779
7846
  }
7780
7847
 
7781
- export { EFFECT_INTENT_ADDRESS, FunctionInvokeError, InsufficientBalanceError, LiveIntentError, ReactNativeSessionManager, RealtimeStore, ServerSessionManager, WebSessionManager, aggregate, buildSetDocumentsTransaction, clearCache, closeAllSubscriptions, convertRemainingAccounts, count, createSessionWithSignature, defineLiveModule, deriveUserIdentityFromIdToken, functions, genAuthNonce, genSolanaMessage, get, getActiveSessionManager, getCachedData, getConfig, getFiles, getIdToken, getMany, getRealtimeStore, getWebhookKeysUrl, hasActiveConnection, increment, init, invoke as invokeFunction, isEffectResult, live, intent as liveIntent, status as liveStatus, queryAggregate, reconnectWithNewAuth, refreshSession, resetRealtimeStore, revokeSession, runExpression, runExpressionMany, runQuery, runQueryMany, search, serverTimestamp, set, setFile, setMany, signAndSubmitTransaction, signMessage, signSessionCreateMessage, signTransaction, subscribe, subscribeView as subscribeLiveView, withEffects, wsDelete, wsGet, wsGetMany, wsQuery, wsSet };
7848
+ export { EFFECT_INTENT_ADDRESS, FunctionInvokeError, InsufficientBalanceError, LiveIntentError, ReactNativeSessionManager, RealtimeStore, ServerSessionManager, WebSessionManager, aggregate, buildSetDocumentsTransaction, clearCache, closeAllSubscriptions, convertRemainingAccounts, count, createSessionWithSignature, defineLiveModule, deriveUserIdentityFromIdToken, functions, genAuthNonce, genSolanaMessage, get, getActiveSessionManager, getCachedData, getConfig, getFiles, getIdToken, getMany, getRealtimeStore, getWebhookKeysUrl, hasActiveConnection, increment, init, invoke as invokeFunction, isEffectResult, live, intent as liveIntent, status as liveStatus, now, queryAggregate, reconnectWithNewAuth, refreshSession, resetRealtimeStore, revokeSession, runExpression, runExpressionMany, runQuery, runQueryMany, search, serverTimestamp, set, setFile, setMany, signAndSubmitTransaction, signMessage, signSessionCreateMessage, signTransaction, subscribe, subscribeView as subscribeLiveView, toMillis, toSeconds, withEffects, wsDelete, wsGet, wsGetMany, wsQuery, wsSet };
7782
7849
  //# sourceMappingURL=index.mjs.map