@emeryld/rrroutes-client 2.6.9 → 2.6.11

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.cjs CHANGED
@@ -44,10 +44,145 @@ __export(index_exports, {
44
44
  });
45
45
  module.exports = __toCommonJS(index_exports);
46
46
 
47
- // src/routesV3.client.ts
48
- var import_rrroutes_contract5 = require("@emeryld/rrroutes-contract");
49
- var import_react_query4 = require("@tanstack/react-query");
50
- var import_react4 = require("react");
47
+ // src/routesV3.client.batch.ts
48
+ var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
49
+ var import_react_query = require("@tanstack/react-query");
50
+ var import_react = require("react");
51
+ function buildBatchBranch(leaves, options, deps) {
52
+ const {
53
+ fetchRaw,
54
+ queryClient,
55
+ validateResponses,
56
+ getBuiltLeaf,
57
+ encodeLeafKey,
58
+ toArgsTuple: toArgsTuple2
59
+ } = deps;
60
+ const batchMethod = options.method ?? "POST";
61
+ const defaultHeaders = options.headers;
62
+ const getQueryKeys = (input) => {
63
+ const out = {};
64
+ const argsByLeaf = input ?? {};
65
+ for (const [alias, built] of Object.entries(leaves)) {
66
+ const args = argsByLeaf[alias];
67
+ out[alias] = built.getQueryKeys(...toArgsTuple2(args));
68
+ }
69
+ return out;
70
+ };
71
+ const invalidateBranch = async (input) => {
72
+ const argsByLeaf = input ?? {};
73
+ await Promise.all(
74
+ Object.entries(leaves).map(([alias, built]) => {
75
+ const args = argsByLeaf[alias];
76
+ return built.invalidate(...toArgsTuple2(args));
77
+ })
78
+ );
79
+ };
80
+ const setDataBranch = (input) => {
81
+ const out = {};
82
+ for (const [alias, def] of Object.entries(input)) {
83
+ if (!def) continue;
84
+ const built = leaves[alias];
85
+ if (!built) continue;
86
+ out[alias] = built.setData(def.updater, ...toArgsTuple2(def.args));
87
+ }
88
+ return out;
89
+ };
90
+ const fetchBranch = async (input) => {
91
+ const payload = {};
92
+ for (const [aliasRaw, built] of Object.entries(leaves)) {
93
+ const leaf = getBuiltLeaf(built);
94
+ const encodedLeaf = encodeLeafKey(leaf);
95
+ const alias = aliasRaw;
96
+ const branchInput = input[alias];
97
+ const query = branchInput?.query;
98
+ const params = branchInput?.params;
99
+ const body = branchInput?.body;
100
+ payload[aliasRaw] = {
101
+ encodedLeaf,
102
+ ...params !== void 0 ? { params } : {},
103
+ ...query !== void 0 ? { query } : {},
104
+ ...body !== void 0 ? { body } : {}
105
+ };
106
+ }
107
+ const batchResponse = await fetchRaw({
108
+ path: options.path,
109
+ method: batchMethod,
110
+ body: payload,
111
+ headers: defaultHeaders
112
+ });
113
+ const rawData = batchResponse.data;
114
+ if (!rawData || typeof rawData !== "object" || Array.isArray(rawData)) {
115
+ throw new Error(
116
+ "Batch response must be a plain object keyed by branch aliases."
117
+ );
118
+ }
119
+ const mapped = {};
120
+ for (const [aliasRaw, built] of Object.entries(leaves)) {
121
+ if (!(aliasRaw in rawData)) {
122
+ throw new Error(`Batch response missing alias "${aliasRaw}".`);
123
+ }
124
+ const leaf = getBuiltLeaf(built);
125
+ const rawLeafData = rawData[aliasRaw];
126
+ const parsedLeafData = validateResponses && leaf.cfg.outputSchema ? (0, import_rrroutes_contract.lowProfileParse)(leaf.cfg.outputSchema, rawLeafData) : rawLeafData;
127
+ if (validateResponses && !leaf.cfg.outputSchema) {
128
+ throw new Error(
129
+ `No output schema defined for leaf ${leaf.method.toUpperCase()} ${leaf.path}, cannot validate batch response.`
130
+ );
131
+ }
132
+ ;
133
+ mapped[aliasRaw] = parsedLeafData;
134
+ }
135
+ return mapped;
136
+ };
137
+ const useEndpoint = (input, rqOpts) => {
138
+ const queryKeys = getQueryKeys(input);
139
+ const branchQueryKey = [
140
+ "batch",
141
+ String(batchMethod).toLowerCase(),
142
+ options.path,
143
+ queryKeys
144
+ ];
145
+ const { onReceive, ...useQueryOptions } = rqOpts ?? {};
146
+ const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
147
+ const notifyOnReceive = (0, import_react.useCallback)(
148
+ (data) => {
149
+ onReceive?.(data);
150
+ listenersRef.current.forEach((listener) => listener(data));
151
+ },
152
+ [onReceive]
153
+ );
154
+ const registerOnReceive = (0, import_react.useCallback)(
155
+ (listener) => {
156
+ listenersRef.current.add(listener);
157
+ return () => {
158
+ listenersRef.current.delete(listener);
159
+ };
160
+ },
161
+ []
162
+ );
163
+ const queryResult = (0, import_react_query.useQuery)(
164
+ {
165
+ ...useQueryOptions,
166
+ queryKey: branchQueryKey,
167
+ placeholderData: useQueryOptions.placeholderData ?? import_react_query.keepPreviousData,
168
+ queryFn: async () => {
169
+ const result = await fetchBranch(input);
170
+ notifyOnReceive(result);
171
+ return result;
172
+ }
173
+ },
174
+ queryClient
175
+ );
176
+ return { ...queryResult, onReceive: registerOnReceive };
177
+ };
178
+ return {
179
+ fetch: fetchBranch,
180
+ useEndpoint,
181
+ getQueryKeys,
182
+ invalidate: invalidateBranch,
183
+ setData: setDataBranch
184
+ };
185
+ }
51
186
 
52
187
  // src/routesV3.client.fetch.ts
53
188
  var HttpError = class extends Error {
@@ -101,12 +236,12 @@ var defaultFetcher = async (req) => {
101
236
  };
102
237
 
103
238
  // src/routesV3.client.get.ts
104
- var import_rrroutes_contract2 = require("@emeryld/rrroutes-contract");
105
- var import_react_query = require("@tanstack/react-query");
106
- var import_react = require("react");
239
+ var import_rrroutes_contract3 = require("@emeryld/rrroutes-contract");
240
+ var import_react_query2 = require("@tanstack/react-query");
241
+ var import_react2 = require("react");
107
242
 
108
243
  // src/routesV3.client.shared.ts
109
- var import_rrroutes_contract = require("@emeryld/rrroutes-contract");
244
+ var import_rrroutes_contract2 = require("@emeryld/rrroutes-contract");
110
245
  var toUpper = (m) => m.toUpperCase();
111
246
  function toSearchString(query) {
112
247
  if (!query) return "";
@@ -156,9 +291,9 @@ function toArgsTuple(args) {
156
291
  return typeof args === "undefined" ? [] : [args];
157
292
  }
158
293
  function buildUrl(leaf, baseUrl, params, query) {
159
- const normalizedParams = leaf.cfg.paramsSchema ? (0, import_rrroutes_contract.lowProfileParse)(leaf.cfg.paramsSchema, params) : {};
160
- const normalizedQuery = leaf.cfg.querySchema ? (0, import_rrroutes_contract.lowProfileParse)(leaf.cfg.querySchema, query) : {};
161
- const path = (0, import_rrroutes_contract.compilePath)(
294
+ const normalizedParams = leaf.cfg.paramsSchema ? (0, import_rrroutes_contract2.lowProfileParse)(leaf.cfg.paramsSchema, params) : {};
295
+ const normalizedQuery = leaf.cfg.querySchema ? (0, import_rrroutes_contract2.lowProfileParse)(leaf.cfg.querySchema, query) : {};
296
+ const path = (0, import_rrroutes_contract2.compilePath)(
162
297
  leaf.path,
163
298
  normalizedParams ?? {}
164
299
  );
@@ -325,7 +460,7 @@ function compileRawPath(path, params) {
325
460
  if (placeholders.size === 0) {
326
461
  return path;
327
462
  }
328
- return (0, import_rrroutes_contract.compilePath)(path, paramObj);
463
+ return (0, import_rrroutes_contract2.compilePath)(path, paramObj);
329
464
  }
330
465
 
331
466
  // src/routesV3.client.get.ts
@@ -348,7 +483,7 @@ function buildGetLeaf(leaf, rqOpts, env) {
348
483
  const a = extractArgs(tuple);
349
484
  const params = a?.params;
350
485
  const query = a?.query;
351
- return (0, import_rrroutes_contract2.buildCacheKey)({
486
+ return (0, import_rrroutes_contract3.buildCacheKey)({
352
487
  leaf,
353
488
  params,
354
489
  query
@@ -392,7 +527,7 @@ function buildGetLeaf(leaf, rqOpts, env) {
392
527
  options.body,
393
528
  leafCfg.bodyFiles
394
529
  );
395
- const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract2.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
530
+ const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract3.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
396
531
  if (isMultipart && normalizedBody && typeof normalizedBody === "object") {
397
532
  payload = toFormData(
398
533
  {
@@ -449,7 +584,7 @@ function buildGetLeaf(leaf, rqOpts, env) {
449
584
  `No output schema defined for leaf ${leafLabel}, cannot validate response.`
450
585
  );
451
586
  }
452
- out.data = (0, import_rrroutes_contract2.lowProfileParse)(
587
+ out.data = (0, import_rrroutes_contract3.lowProfileParse)(
453
588
  leafCfg.outputSchema,
454
589
  out.data
455
590
  );
@@ -516,12 +651,12 @@ function buildGetLeaf(leaf, rqOpts, env) {
516
651
  keys: queryKeys
517
652
  });
518
653
  const buildOptions = rqOpts ?? {};
519
- const listenersRef = (0, import_react.useRef)(/* @__PURE__ */ new Set());
520
- const notifyOnReceive = (0, import_react.useCallback)((data) => {
654
+ const listenersRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
655
+ const notifyOnReceive = (0, import_react2.useCallback)((data) => {
521
656
  buildOptions?.onReceive?.(data);
522
657
  listenersRef.current.forEach((listener) => listener(data));
523
658
  }, []);
524
- const registerOnReceive = (0, import_react.useCallback)(
659
+ const registerOnReceive = (0, import_react2.useCallback)(
525
660
  (listener) => {
526
661
  listenersRef.current.add(listener);
527
662
  return () => {
@@ -530,11 +665,11 @@ function buildGetLeaf(leaf, rqOpts, env) {
530
665
  },
531
666
  []
532
667
  );
533
- const queryResult = (0, import_react_query.useQuery)(
668
+ const queryResult = (0, import_react_query2.useQuery)(
534
669
  {
535
670
  ...buildOptions,
536
671
  queryKey: getQueryKeys(...tuple),
537
- placeholderData: import_react_query.keepPreviousData,
672
+ placeholderData: import_react_query2.keepPreviousData,
538
673
  queryFn: () => fetchEndpoint(tuple, {
539
674
  onReceive: notifyOnReceive
540
675
  })
@@ -553,9 +688,9 @@ function buildGetLeaf(leaf, rqOpts, env) {
553
688
  }
554
689
 
555
690
  // src/routesV3.client.infiniteGet.ts
556
- var import_rrroutes_contract3 = require("@emeryld/rrroutes-contract");
557
- var import_react_query2 = require("@tanstack/react-query");
558
- var import_react2 = require("react");
691
+ var import_rrroutes_contract4 = require("@emeryld/rrroutes-contract");
692
+ var import_react_query3 = require("@tanstack/react-query");
693
+ var import_react3 = require("react");
559
694
  function mergePageOutputs(prev, next) {
560
695
  if (prev == null) return next;
561
696
  if (next == null) return prev;
@@ -621,7 +756,7 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
621
756
  const params = a?.params;
622
757
  const query = a?.query;
623
758
  const qForKey = stripKey(query, feedCursorParam);
624
- return (0, import_rrroutes_contract3.buildCacheKey)({
759
+ return (0, import_rrroutes_contract4.buildCacheKey)({
625
760
  leaf,
626
761
  params,
627
762
  query: qForKey
@@ -665,7 +800,7 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
665
800
  options.body,
666
801
  leafCfg.bodyFiles
667
802
  );
668
- const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract3.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
803
+ const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract4.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
669
804
  if (isMultipart && normalizedBody && typeof normalizedBody === "object") {
670
805
  payload = toFormData(
671
806
  {
@@ -722,7 +857,7 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
722
857
  `No output schema defined for leaf ${leafLabel}, cannot validate response.`
723
858
  );
724
859
  }
725
- out.data = (0, import_rrroutes_contract3.lowProfileParse)(
860
+ out.data = (0, import_rrroutes_contract4.lowProfileParse)(
726
861
  leafCfg.outputSchema,
727
862
  out.data
728
863
  );
@@ -791,12 +926,12 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
791
926
  const params = args?.params;
792
927
  const query = args?.query;
793
928
  const buildOptions = feedQueryOptions ?? {};
794
- const listenersRef = (0, import_react2.useRef)(/* @__PURE__ */ new Set());
795
- const notifyOnReceive = (0, import_react2.useCallback)((data) => {
929
+ const listenersRef = (0, import_react3.useRef)(/* @__PURE__ */ new Set());
930
+ const notifyOnReceive = (0, import_react3.useCallback)((data) => {
796
931
  buildOptions?.onReceive?.(data);
797
932
  listenersRef.current.forEach((listener) => listener(data));
798
933
  }, []);
799
- const registerOnReceive = (0, import_react2.useCallback)(
934
+ const registerOnReceive = (0, import_react3.useCallback)(
800
935
  (listener) => {
801
936
  listenersRef.current.add(listener);
802
937
  return () => {
@@ -811,10 +946,10 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
811
946
  params,
812
947
  query
813
948
  );
814
- const queryResult = (0, import_react_query2.useInfiniteQuery)(
949
+ const queryResult = (0, import_react_query3.useInfiniteQuery)(
815
950
  {
816
951
  ...buildOptions,
817
- placeholderData: buildOptions.placeholderData ?? import_react_query2.keepPreviousData,
952
+ placeholderData: buildOptions.placeholderData ?? import_react_query3.keepPreviousData,
818
953
  initialPageParam: feedInitialPageParam,
819
954
  getNextPageParam: (lastPage) => cursorFromPage(lastPage),
820
955
  queryKey: queryKeys,
@@ -907,9 +1042,9 @@ function buildInfiniteGetLeaf(leaf, rqOpts, env) {
907
1042
  }
908
1043
 
909
1044
  // src/routesV3.client.mutation.ts
910
- var import_rrroutes_contract4 = require("@emeryld/rrroutes-contract");
911
- var import_react_query3 = require("@tanstack/react-query");
912
- var import_react3 = require("react");
1045
+ var import_rrroutes_contract5 = require("@emeryld/rrroutes-contract");
1046
+ var import_react_query4 = require("@tanstack/react-query");
1047
+ var import_react4 = require("react");
913
1048
  function buildMutationLeaf(leaf, rqOpts, env) {
914
1049
  const leafCfg = leaf.cfg;
915
1050
  const method = toUpper(leaf.method);
@@ -929,7 +1064,7 @@ function buildMutationLeaf(leaf, rqOpts, env) {
929
1064
  const a = extractArgs(tuple);
930
1065
  const params = a?.params;
931
1066
  const query = a?.query;
932
- return (0, import_rrroutes_contract4.buildCacheKey)({
1067
+ return (0, import_rrroutes_contract5.buildCacheKey)({
933
1068
  leaf,
934
1069
  params,
935
1070
  query
@@ -973,7 +1108,7 @@ function buildMutationLeaf(leaf, rqOpts, env) {
973
1108
  options.body,
974
1109
  leafCfg.bodyFiles
975
1110
  );
976
- const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract4.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
1111
+ const normalizedBody = leafCfg.bodySchema ? (0, import_rrroutes_contract5.lowProfileParse)(leafCfg.bodySchema, regularBody) : regularBody;
977
1112
  if (isMultipart && normalizedBody && typeof normalizedBody === "object") {
978
1113
  payload = toFormData(
979
1114
  {
@@ -1030,7 +1165,7 @@ function buildMutationLeaf(leaf, rqOpts, env) {
1030
1165
  `No output schema defined for leaf ${leafLabel}, cannot validate response.`
1031
1166
  );
1032
1167
  }
1033
- out.data = (0, import_rrroutes_contract4.lowProfileParse)(
1168
+ out.data = (0, import_rrroutes_contract5.lowProfileParse)(
1034
1169
  leafCfg.outputSchema,
1035
1170
  out.data
1036
1171
  );
@@ -1097,11 +1232,11 @@ function buildMutationLeaf(leaf, rqOpts, env) {
1097
1232
  variant: "mutation",
1098
1233
  keys: mutationKey
1099
1234
  });
1100
- const listenersRef = (0, import_react3.useRef)(/* @__PURE__ */ new Set());
1101
- const notifyListeners = (0, import_react3.useCallback)((data) => {
1235
+ const listenersRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
1236
+ const notifyListeners = (0, import_react4.useCallback)((data) => {
1102
1237
  listenersRef.current.forEach((listener) => listener(data));
1103
1238
  }, []);
1104
- const registerOnReceive = (0, import_react3.useCallback)(
1239
+ const registerOnReceive = (0, import_react4.useCallback)(
1105
1240
  (listener) => {
1106
1241
  listenersRef.current.add(listener);
1107
1242
  return () => {
@@ -1110,7 +1245,7 @@ function buildMutationLeaf(leaf, rqOpts, env) {
1110
1245
  },
1111
1246
  []
1112
1247
  );
1113
- const mutationResult = (0, import_react_query3.useMutation)(
1248
+ const mutationResult = (0, import_react_query4.useMutation)(
1114
1249
  {
1115
1250
  ...mutationBuildOptions ?? {},
1116
1251
  mutationKey,
@@ -1340,146 +1475,14 @@ function createRouteClient(opts) {
1340
1475
  throw error;
1341
1476
  }
1342
1477
  };
1343
- const buildBranchInternal = (leaves, options) => {
1344
- const batchMethod = options.method ?? "POST";
1345
- const defaultHeaders = options.headers;
1346
- const getQueryKeys = (input) => {
1347
- const out = {};
1348
- const argsByLeaf = input ?? {};
1349
- for (const [alias, built] of Object.entries(leaves)) {
1350
- const args = argsByLeaf[alias];
1351
- out[alias] = built.getQueryKeys(...toArgsTuple2(args));
1352
- }
1353
- return out;
1354
- };
1355
- const invalidateBranch = async (input) => {
1356
- const argsByLeaf = input ?? {};
1357
- await Promise.all(
1358
- Object.entries(leaves).map(([alias, built]) => {
1359
- const args = argsByLeaf[alias];
1360
- return built.invalidate(...toArgsTuple2(args));
1361
- })
1362
- );
1363
- };
1364
- const setDataBranch = (input) => {
1365
- const out = {};
1366
- for (const [alias, def] of Object.entries(input)) {
1367
- if (!def) continue;
1368
- const built = leaves[alias];
1369
- if (!built) continue;
1370
- out[alias] = built.setData(
1371
- def.updater,
1372
- ...toArgsTuple2(def.args)
1373
- );
1374
- }
1375
- return out;
1376
- };
1377
- const fetchBranch = async (input) => {
1378
- const payload = {};
1379
- const keyByAlias = /* @__PURE__ */ new Map();
1380
- for (const [aliasRaw, built] of Object.entries(leaves)) {
1381
- const alias = aliasRaw;
1382
- const leaf = getBuiltLeaf(built);
1383
- const encodedLeaf = encodeLeafKey(leaf);
1384
- keyByAlias.set(alias, encodedLeaf);
1385
- const branchInput = input[alias];
1386
- const query = branchInput?.query;
1387
- const params = branchInput?.params;
1388
- const body = branchInput?.body;
1389
- payload[encodedLeaf] = {
1390
- ...params !== void 0 ? { params } : {},
1391
- ...query !== void 0 ? { query } : {},
1392
- ...body !== void 0 ? { body } : {}
1393
- };
1394
- }
1395
- const batchResponse = await fetchRaw({
1396
- path: options.path,
1397
- method: batchMethod,
1398
- body: payload,
1399
- headers: defaultHeaders
1400
- });
1401
- const rawData = batchResponse.data;
1402
- if (!rawData || typeof rawData !== "object" || Array.isArray(rawData)) {
1403
- throw new Error(
1404
- "Batch response must be a plain object keyed by encoded route keys."
1405
- );
1406
- }
1407
- const mapped = {};
1408
- for (const [aliasRaw, built] of Object.entries(leaves)) {
1409
- const alias = aliasRaw;
1410
- const encodedLeaf = keyByAlias.get(alias);
1411
- if (!encodedLeaf) {
1412
- throw new Error(
1413
- `Internal batch error: missing encoded key for alias "${String(alias)}".`
1414
- );
1415
- }
1416
- if (!(encodedLeaf in rawData)) {
1417
- throw new Error(`Batch response missing key "${encodedLeaf}".`);
1418
- }
1419
- const leaf = getBuiltLeaf(built);
1420
- const rawLeafData = rawData[encodedLeaf];
1421
- const parsedLeafData = validateResponses && leaf.cfg.outputSchema ? (0, import_rrroutes_contract5.lowProfileParse)(leaf.cfg.outputSchema, rawLeafData) : rawLeafData;
1422
- if (validateResponses && !leaf.cfg.outputSchema) {
1423
- throw new Error(
1424
- `No output schema defined for leaf ${leaf.method.toUpperCase()} ${leaf.path}, cannot validate batch response.`
1425
- );
1426
- }
1427
- ;
1428
- mapped[aliasRaw] = parsedLeafData;
1429
- }
1430
- return mapped;
1431
- };
1432
- const useEndpoint = (input, rqOpts) => {
1433
- const queryKeys = getQueryKeys(input);
1434
- const branchQueryKey = [
1435
- "batch",
1436
- String(batchMethod).toLowerCase(),
1437
- options.path,
1438
- queryKeys
1439
- ];
1440
- const { onReceive, ...useQueryOptions } = rqOpts ?? {};
1441
- const listenersRef = (0, import_react4.useRef)(
1442
- /* @__PURE__ */ new Set()
1443
- );
1444
- const notifyOnReceive = (0, import_react4.useCallback)(
1445
- (data) => {
1446
- onReceive?.(data);
1447
- listenersRef.current.forEach((listener) => listener(data));
1448
- },
1449
- [onReceive]
1450
- );
1451
- const registerOnReceive = (0, import_react4.useCallback)(
1452
- (listener) => {
1453
- listenersRef.current.add(listener);
1454
- return () => {
1455
- listenersRef.current.delete(listener);
1456
- };
1457
- },
1458
- []
1459
- );
1460
- const queryResult = (0, import_react_query4.useQuery)(
1461
- {
1462
- ...useQueryOptions,
1463
- queryKey: branchQueryKey,
1464
- placeholderData: useQueryOptions.placeholderData ?? import_react_query4.keepPreviousData,
1465
- queryFn: async () => {
1466
- const result = await fetchBranch(input);
1467
- notifyOnReceive(result);
1468
- return result;
1469
- }
1470
- },
1471
- queryClient
1472
- );
1473
- return { ...queryResult, onReceive: registerOnReceive };
1474
- };
1475
- return {
1476
- fetch: fetchBranch,
1477
- useEndpoint,
1478
- getQueryKeys,
1479
- invalidate: invalidateBranch,
1480
- setData: setDataBranch
1481
- };
1482
- };
1478
+ const buildBranchInternal = (leaves, options) => buildBatchBranch(leaves, options, {
1479
+ fetchRaw,
1480
+ queryClient,
1481
+ validateResponses,
1482
+ getBuiltLeaf,
1483
+ encodeLeafKey,
1484
+ toArgsTuple: toArgsTuple2
1485
+ });
1483
1486
  return {
1484
1487
  queryClient,
1485
1488
  invalidate,
@@ -1505,8 +1508,9 @@ var React = __toESM(require("react"), 1);
1505
1508
  var SocketCtx = React.createContext(null);
1506
1509
  function useSocketClient() {
1507
1510
  const ctx = React.useContext(SocketCtx);
1508
- if (!ctx)
1509
- throw new Error("SocketClient not found. Wrap with <SocketProvider>.");
1511
+ if (!ctx) {
1512
+ return null;
1513
+ }
1510
1514
  return ctx;
1511
1515
  }
1512
1516
 
@@ -1535,6 +1539,7 @@ function useSocketConnection(args) {
1535
1539
  []
1536
1540
  );
1537
1541
  React2.useEffect(() => {
1542
+ if (!client) return;
1538
1543
  if (autoJoin && normalizedRooms.length > 0)
1539
1544
  void client.joinRooms(normalizedRooms, args.joinMeta).catch((error) => reportAsyncError("joinRooms", error));
1540
1545
  const unsubscribe = client.on(event, (payload, meta) => {
@@ -2724,12 +2729,12 @@ function mergeRoomState(prev, toRoomsResult) {
2724
2729
  leaveMeta: toRoomsResult.leaveMeta ?? prev.leaveMeta
2725
2730
  };
2726
2731
  }
2727
- function roomsFromData(data, toRooms) {
2732
+ function roomsFromData(data, args, toRooms) {
2728
2733
  if (data == null) return { rooms: [] };
2729
2734
  let state = { rooms: [] };
2730
2735
  const add = (input) => {
2731
2736
  const mergeForValue = (value) => {
2732
- state = mergeRoomState(state, toRooms(value));
2737
+ state = mergeRoomState(state, toRooms(value, ...args));
2733
2738
  };
2734
2739
  if (Array.isArray(input)) {
2735
2740
  input.forEach((entry) => mergeForValue(entry));
@@ -2774,7 +2779,11 @@ function buildSocketedRoute(options) {
2774
2779
  );
2775
2780
  const argsKey = (0, import_react5.useMemo)(() => safeJsonKey(useArgs[0] ?? null), [useArgs]);
2776
2781
  const [roomState, setRoomState] = (0, import_react5.useState)(
2777
- () => roomsFromData(endpointResult.data, toRooms)
2782
+ () => roomsFromData(
2783
+ endpointResult.data,
2784
+ useArgs,
2785
+ toRooms
2786
+ )
2778
2787
  );
2779
2788
  const renderCountRef = (0, import_react5.useRef)(0);
2780
2789
  const clientReadyRef = (0, import_react5.useRef)(null);
@@ -2828,7 +2837,10 @@ function buildSocketedRoute(options) {
2828
2837
  });
2829
2838
  const unsubscribe = endpointResult.onReceive((data) => {
2830
2839
  setRoomState((prev) => {
2831
- const next = mergeRoomState(prev, toRoomsRef.current(data));
2840
+ const next = mergeRoomState(
2841
+ prev,
2842
+ toRoomsRef.current(data, ...useArgs)
2843
+ );
2832
2844
  return roomStateEqual(prev, next) ? prev : next;
2833
2845
  });
2834
2846
  });
@@ -2845,7 +2857,7 @@ function buildSocketedRoute(options) {
2845
2857
  toRoomsRef: describeObjectReference(toRooms)
2846
2858
  }
2847
2859
  });
2848
- const next = roomsFromData(endpointDataRef.current, toRooms);
2860
+ const next = roomsFromData(endpointDataRef.current, useArgs, toRooms);
2849
2861
  setRoomState((prev) => roomStateEqual(prev, next) ? prev : next);
2850
2862
  }, [argsKey, toRooms, debug]);
2851
2863
  (0, import_react5.useEffect)(() => {
@@ -2975,6 +2987,7 @@ function buildSocketedRoute(options) {
2975
2987
  }
2976
2988
  const nextRoomState = roomsFromData(
2977
2989
  next,
2990
+ useArgs,
2978
2991
  toRooms
2979
2992
  );
2980
2993
  setRoomState(