@bunbase-ae/react-sdk 2.13.3-next.304.484953e → 2.14.1-next.321.8b883e8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunbase-ae/react-sdk",
3
- "version": "2.13.3-next.304.484953e",
3
+ "version": "2.14.1-next.321.8b883e8",
4
4
  "type": "module",
5
5
  "description": "React hooks for BunBase — caching, mutations, auth, realtime",
6
6
  "license": "UNLICENSED",
@@ -37,7 +37,7 @@
37
37
  "peerDependencies": {
38
38
  "react": ">=19",
39
39
  "react-dom": ">=19",
40
- "@bunbase-ae/js": ">=2.13.3-next.304.484953e"
40
+ "@bunbase-ae/js": ">=2.14.1-next.321.8b883e8"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/react": "19.2.14",
@@ -0,0 +1,30 @@
1
+ // Realtime cache-sync — shared between useList(realtime: true) and useRealtime(invalidateCache: true).
2
+ //
3
+ // update → write the record to its get-key (instant UI), invalidate list-keys
4
+ // delete → invalidate the record's get-key + list-keys
5
+ // create → invalidate list-keys only (can't safely insert into sorted/filtered lists)
6
+ //
7
+ // Note: the per-record cache key is keyed off `record._id` — the server's
8
+ // BunBaseRecord uses `_id` (with leading underscore), not `id`. Earlier
9
+ // inline copies of this block read `record.id` and silently wrote to
10
+ // `<col>:get:undefined`.
11
+
12
+ import type { RealtimeEvent } from "@bunbase-ae/js";
13
+ import type { QueryCache } from "./cache";
14
+
15
+ export function applyRealtimeCacheSync<T extends Record<string, unknown>>(
16
+ cache: QueryCache,
17
+ event: RealtimeEvent<T>,
18
+ ): void {
19
+ const col = event.collection;
20
+ const id = event.record._id;
21
+ if (event.event === "update") {
22
+ cache.setData(`${col}:get:${id}`, event.record);
23
+ cache.invalidate(`${col}:list`);
24
+ } else if (event.event === "delete") {
25
+ cache.invalidate(`${col}:get:${id}`);
26
+ cache.invalidate(`${col}:list`);
27
+ } else {
28
+ cache.invalidate(`${col}:list`);
29
+ }
30
+ }
package/src/useList.ts CHANGED
@@ -4,6 +4,7 @@ import type { BunBaseRecord, ListQuery, ListResult, WithExpand } from "@bunbase-
4
4
  import { useCallback, useEffect, useReducer, useRef } from "react";
5
5
  import { useBunBase } from "./Context";
6
6
  import type { CacheEntry } from "./cache";
7
+ import { applyRealtimeCacheSync } from "./realtimeCacheSync";
7
8
 
8
9
  // Stable JSON — sorts keys so query object identity doesn't matter.
9
10
  function stableKey(value: unknown): string {
@@ -115,22 +116,10 @@ export function useList<
115
116
  }, [cache, cacheKey, staleTime, options.refetchInterval, enabled]);
116
117
 
117
118
  // Realtime: smart cache sync on any collection change.
118
- // update → write directly to get cache (instant) + invalidate list
119
- // delete → remove get cache entry + invalidate list
120
- // create → invalidate list only (can't safely insert into sorted/filtered list)
121
119
  useEffect(() => {
122
120
  if (!options.realtime || !enabled) return;
123
121
  return client.realtime.subscribe(`collection:${collection}`, (event) => {
124
- const id = event.record.id;
125
- if (event.event === "update") {
126
- cache.setData(`${collection}:get:${id}`, event.record);
127
- cache.invalidate(`${collection}:list`);
128
- } else if (event.event === "delete") {
129
- cache.invalidate(`${collection}:get:${id}`);
130
- cache.invalidate(`${collection}:list`);
131
- } else {
132
- cache.invalidate(`${collection}:list`);
133
- }
122
+ applyRealtimeCacheSync(cache, event);
134
123
  });
135
124
  }, [client, collection, cache, options.realtime, enabled]);
136
125
 
@@ -5,6 +5,7 @@
5
5
  import type { RealtimeEvent, SubscribeOptions } from "@bunbase-ae/js";
6
6
  import { useCallback, useEffect, useRef, useState } from "react";
7
7
  import { useBunBase } from "./Context";
8
+ import { applyRealtimeCacheSync } from "./realtimeCacheSync";
8
9
 
9
10
  // ─── useRealtime ─────────────────────────────────────────────────────────────
10
11
 
@@ -47,20 +48,7 @@ export function useRealtime<T extends Record<string, unknown> = Record<string, u
47
48
  (event) => {
48
49
  cbRef.current?.(event);
49
50
  if (optsRef.current.invalidateCache) {
50
- const col = event.collection;
51
- const id = event.record.id;
52
- if (event.event === "update") {
53
- // Write updated record directly to get cache — instant UI, no round-trip.
54
- cache.setData(`${col}:get:${id}`, event.record);
55
- // Invalidate list cache so any ordering/filter changes are reflected.
56
- cache.invalidate(`${col}:list`);
57
- } else if (event.event === "delete") {
58
- cache.invalidate(`${col}:get:${id}`);
59
- cache.invalidate(`${col}:list`);
60
- } else {
61
- // create — can't safely insert into sorted/filtered lists.
62
- cache.invalidate(`${col}:list`);
63
- }
51
+ applyRealtimeCacheSync(cache, event);
64
52
  }
65
53
  },
66
54
  { events, filter, ids },