@capxul/sdk-react 4.2.0-rc.2 → 4.2.0-rc.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.
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "source": {
3
- "commit": "fe4f1c05f1de962a7a76825816bdff2beaf5fc88",
4
- "tree": "45b0c3cfdd39d23a4cfb1c1bcc047521f16bc12d",
3
+ "commit": "400e4b861e8c10091ad2d9e71fc0502fe222a801",
4
+ "tree": "c3afb8bb5f3ce69ee8aa1e8fbe811fe213627887",
5
5
  "branch": "codex/programme-rc",
6
6
  "repository": "https://github.com/Xelmar-tech/infrastructure",
7
7
  "lockfileSha256": "5870f53b72706d103220c1bcf733cb4fb71196aea32a9cfbdc277d73cc959264"
8
8
  },
9
9
  "name": "@capxul/sdk-react",
10
- "version": "4.2.0-rc.2"
10
+ "version": "4.2.0-rc.4"
11
11
  }
@@ -151,10 +151,35 @@ const capxulKeys = {
151
151
  ]
152
152
  };
153
153
  //#endregion
154
- //#region src/identity.tsx
155
- const MISSING_IDENTITY_PROVIDER = Symbol("MISSING_IDENTITY_PROVIDER");
156
- const IdentityContext = createContext(MISSING_IDENTITY_PROVIDER);
157
- function controls(options) {
154
+ //#region src/internal/invocation-controls.ts
155
+ /**
156
+ * Keep only the five public option fields, and only when they hold the right
157
+ * kind of value. A named action verb takes its attempt as an optional FIRST
158
+ * argument, so a screen that wires one straight to a DOM handler
159
+ * (`onClick={row.hide}`) hands us a React SyntheticEvent. That is not an
160
+ * attempt: it must reach neither the SDK call nor the callback echo.
161
+ */
162
+ function toInvocationOptions(options) {
163
+ if (typeof options !== "object" || options === null) return void 0;
164
+ const attempt = {};
165
+ if (typeof options.correlationId === "string") attempt.correlationId = options.correlationId;
166
+ if (typeof options.journeyId === "string") attempt.journeyId = options.journeyId;
167
+ if (typeof options.timeoutMs === "number") attempt.timeoutMs = options.timeoutMs;
168
+ if (typeof options.deadlineMs === "number") attempt.deadlineMs = options.deadlineMs;
169
+ if (options.signal instanceof AbortSignal) attempt.signal = options.signal;
170
+ return Object.keys(attempt).length === 0 ? void 0 : attempt;
171
+ }
172
+ /**
173
+ * Map the public camel-case invocation options onto the Core SDK's control
174
+ * spelling. ONE definition, because the identity facade and every headless
175
+ * engine must hand the SDK the same shape: a caller that captured one user
176
+ * attempt before it started gets that attempt's `correlation_id`/`journey_id`
177
+ * on whichever operation it starts (#1960 R02).
178
+ *
179
+ * It creates no identifiers. An absent option stays absent, so an automatic
180
+ * read keeps its own invocation context instead of borrowing an attempt's.
181
+ */
182
+ function toInvocationControls(options) {
158
183
  if (options === void 0) return void 0;
159
184
  return {
160
185
  ...options.signal === void 0 ? {} : { signal: options.signal },
@@ -164,12 +189,16 @@ function controls(options) {
164
189
  ...options.journeyId === void 0 ? {} : { journey_id: options.journeyId }
165
190
  };
166
191
  }
192
+ //#endregion
193
+ //#region src/identity.tsx
194
+ const MISSING_IDENTITY_PROVIDER = Symbol("MISSING_IDENTITY_PROVIDER");
195
+ const IdentityContext = createContext(MISSING_IDENTITY_PROVIDER);
167
196
  const failure = (result) => result.ok ? null : {
168
197
  ok: false,
169
198
  reason: result.refused
170
199
  };
171
200
  async function guarded(runtime, verb, options, run) {
172
- const invocation = controls(options);
201
+ const invocation = toInvocationControls(options);
173
202
  try {
174
203
  return await (runtime.runFacade?.(verb, invocation, run) ?? run(invocation));
175
204
  } catch {
@@ -215,18 +244,102 @@ function normalizeOrganization(organization) {
215
244
  return null;
216
245
  }
217
246
  }
247
+ /** The Organization id when its lane is already running or finished, else null. */
248
+ const runningOrganization = (state) => {
249
+ if (state.phase !== "authenticated" || state.account.at !== "claimed") return null;
250
+ const org = state.account.org;
251
+ return org !== null && (org.at === "loading" || org.at === "settingUp" || org.at === "ready") ? org.orgId : null;
252
+ };
253
+ /** A superseded session read waits at most this long for the winning read. */
254
+ const SESSION_SETTLE_LIMIT_MS = 3e4;
255
+ const accountInFlight = (state) => state.phase === "authenticated" && (state.account.at === "deriving" || state.account.at === "claiming");
218
256
  function createAuth(client, clearAuthenticatedQueries) {
219
257
  const runtime = client._internal.identity;
258
+ const settledSession = (invocation) => new Promise((resolve) => {
259
+ let done = false;
260
+ let stop = null;
261
+ let timer = null;
262
+ const onAbort = () => finish({
263
+ ok: false,
264
+ reason: "CANCELLED"
265
+ });
266
+ const finish = (result) => {
267
+ if (done) return;
268
+ done = true;
269
+ stop?.();
270
+ if (timer !== null) clearTimeout(timer);
271
+ invocation?.signal?.removeEventListener("abort", onAbort);
272
+ resolve(result);
273
+ };
274
+ if (invocation?.signal?.aborted) {
275
+ onAbort();
276
+ return;
277
+ }
278
+ invocation?.signal?.addEventListener("abort", onAbort, { once: true });
279
+ const unsubscribe = runtime.subscribeTransitions((record) => {
280
+ if (record.slot !== "identity:session") return;
281
+ if (record.outcome === "applied" && record.event === "SessionRead") finish({ ok: true });
282
+ else if (record.outcome === "failed" || record.outcome === "cancelled") finish({
283
+ ok: false,
284
+ reason: record.error_code
285
+ });
286
+ });
287
+ if (done) {
288
+ unsubscribe();
289
+ return;
290
+ }
291
+ stop = unsubscribe;
292
+ timer = setTimeout(() => finish({
293
+ ok: false,
294
+ reason: "UNKNOWN"
295
+ }), SESSION_SETTLE_LIMIT_MS);
296
+ });
220
297
  const read = async (invocation) => {
221
298
  const result = await runtime.send({ _tag: "ReadSession" }, invocation);
222
- return failure(result) ?? { ok: true };
299
+ const refused = failure(result);
300
+ if (refused === null) return { ok: true };
301
+ return refused.reason === "SUPERSEDED" ? settledSession(invocation) : refused;
223
302
  };
224
303
  const ensureAccount = async (invocation) => {
225
304
  const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
226
305
  return failure(result) ?? { ok: true };
227
306
  };
307
+ const settledAccount = (invocation) => new Promise((resolve) => {
308
+ let done = false;
309
+ let stop = null;
310
+ const onAbort = () => finish({
311
+ ok: false,
312
+ reason: "CANCELLED"
313
+ });
314
+ const finish = (result) => {
315
+ if (done) return;
316
+ done = true;
317
+ stop?.();
318
+ invocation?.signal?.removeEventListener("abort", onAbort);
319
+ resolve(result);
320
+ };
321
+ if (invocation?.signal?.aborted) {
322
+ onAbort();
323
+ return;
324
+ }
325
+ invocation?.signal?.addEventListener("abort", onAbort, { once: true });
326
+ const unsubscribe = runtime.subscribe((state) => {
327
+ if (!accountInFlight(state)) finish({ ok: true });
328
+ });
329
+ if (done) {
330
+ unsubscribe();
331
+ return;
332
+ }
333
+ stop = unsubscribe;
334
+ if (!accountInFlight(runtime.snapshot())) finish({ ok: true });
335
+ });
228
336
  const reachClaimed = async (invocation) => {
229
337
  let state = runtime.snapshot();
338
+ if (accountInFlight(state)) {
339
+ const settled = await settledAccount(invocation);
340
+ if (!settled.ok) return settled;
341
+ state = runtime.snapshot();
342
+ }
230
343
  if (state.phase !== "authenticated" || state.account.at === "unknown") {
231
344
  const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
232
345
  const refused = failure(result);
@@ -238,6 +351,16 @@ function createAuth(client, clearAuthenticatedQueries) {
238
351
  reason: "WRONG_STATE"
239
352
  };
240
353
  if (state.account.at === "claimed") return { ok: true };
354
+ if (accountInFlight(state)) {
355
+ const settled = await settledAccount(invocation);
356
+ if (!settled.ok) return settled;
357
+ state = runtime.snapshot();
358
+ if (state.phase !== "authenticated") return {
359
+ ok: false,
360
+ reason: "WRONG_STATE"
361
+ };
362
+ if (state.account.at === "claimed") return { ok: true };
363
+ }
241
364
  const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
242
365
  const result = await runtime.send(event, invocation);
243
366
  const refused = failure(result);
@@ -258,13 +381,13 @@ function createAuth(client, clearAuthenticatedQueries) {
258
381
  ok: false,
259
382
  reason: "INVALID_INPUT"
260
383
  };
384
+ const refreshed = await read(invocation);
385
+ if (!refreshed.ok) return refreshed;
261
386
  const current = runtime.snapshot();
262
387
  if (current.phase !== "authenticated" || !current.profileComplete) {
263
388
  const completed = await runtime.completeProfile(submission.profileDetails, invocation);
264
389
  if (!completed.ok) return completed;
265
390
  }
266
- const refreshed = await read(invocation);
267
- if (!refreshed.ok) return refreshed;
268
391
  const claimed = await reachClaimed(invocation);
269
392
  return claimed.ok ? {
270
393
  ok: true,
@@ -341,12 +464,13 @@ function createAuth(client, clearAuthenticatedQueries) {
341
464
  }),
342
465
  createOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
343
466
  const current = runtime.snapshot();
467
+ const running = runningOrganization(current);
468
+ if (running !== null) return {
469
+ ok: true,
470
+ orgId: running
471
+ };
344
472
  if (current.phase === "authenticated" && current.account.at === "claimed") {
345
473
  const org = current.account.org;
346
- if (org !== null && (org.at === "loading" || org.at === "settingUp" || org.at === "ready")) return {
347
- ok: true,
348
- orgId: org.orgId
349
- };
350
474
  if (org?.at === "failed" && org.orgId !== null) {
351
475
  if (!org.retryable) return {
352
476
  ok: false,
@@ -361,6 +485,11 @@ function createAuth(client, clearAuthenticatedQueries) {
361
485
  }
362
486
  const prepared = await prepareOrganization(submission, invocation);
363
487
  if (!prepared.ok) return prepared;
488
+ const opened = runningOrganization(runtime.snapshot());
489
+ if (opened !== null) return {
490
+ ok: true,
491
+ orgId: opened
492
+ };
364
493
  const created = await runtime.send({
365
494
  _tag: "CreateOrganization",
366
495
  draft: prepared.organization
@@ -442,7 +571,7 @@ function CapxulIdentityProvider({ client, children }) {
442
571
  }, []);
443
572
  const value = useMemo(() => {
444
573
  if (client === null || runtime === null) return null;
445
- const send = (event, options) => runtime.send(event, controls(options));
574
+ const send = (event, options) => runtime.send(event, toInvocationControls(options));
446
575
  const clearAuthenticatedQueries = async () => {
447
576
  await queryClient.cancelQueries({ queryKey: capxulKeys.root });
448
577
  await queryClient.resetQueries({ queryKey: capxulKeys.root });
@@ -821,4 +950,4 @@ function organizationForm(props, state, auth, submitted) {
821
950
  });
822
951
  }
823
952
  //#endregion
824
- export { useCapxulAuth as a, useCapxulIdentityOrNull as c, capxulKeys as d, useCapxulClientOrNull as f, entered as i, useCapxulSend as l, CapxulOnboardingController as n, useCapxulDestination as o, useCapxul as p, CapxulProvider as r, useCapxulIdentity as s, CapxulAuthenticationController as t, useCapxulTransitions as u };
953
+ export { useCapxulAuth as a, useCapxulIdentityOrNull as c, toInvocationControls as d, toInvocationOptions as f, useCapxul as h, entered as i, useCapxulSend as l, useCapxulClientOrNull as m, CapxulOnboardingController as n, useCapxulDestination as o, capxulKeys as p, CapxulProvider as r, useCapxulIdentity as s, CapxulAuthenticationController as t, useCapxulTransitions as u };
package/dist/index.d.mts CHANGED
@@ -383,9 +383,9 @@ interface Contact {
383
383
  interface ContactRow extends Contact {
384
384
  /** Ours: one initials rule, not one copy per screen. */
385
385
  readonly initials: string;
386
- readonly rename: (name: string) => void;
387
- readonly hide: () => void;
388
- readonly unhide: () => void;
386
+ readonly rename: (name: string, options?: InvocationOptions) => void;
387
+ readonly hide: (options?: InvocationOptions) => void;
388
+ readonly unhide: (options?: InvocationOptions) => void;
389
389
  }
390
390
  /** ADR-0023 R1: refusal CODES, never sentences — the app owns the words. */
391
391
  type ContactsRefusal = "loading" | "org-unavailable" | "unavailable";
@@ -421,7 +421,13 @@ interface ContactsListOptions {
421
421
  interface ContactsAddSlice {
422
422
  readonly value: string;
423
423
  readonly change: (text: string) => void;
424
- readonly submit: () => void;
424
+ /**
425
+ * #1960 R02: hand it the options the screen captured BEFORE the click. The
426
+ * same snapshot reaches the SDK add call and comes back on `onAdded`/
427
+ * `onFailed`, so the UI observation and the operation share one identity even
428
+ * when the reply lands after an account switch. Omitted stays omitted.
429
+ */
430
+ readonly submit: (options?: InvocationOptions) => void;
425
431
  readonly isSubmitting: boolean;
426
432
  readonly blocked: boolean;
427
433
  readonly blockedReason: ContactsAddBlockedReason | null;
@@ -431,9 +437,14 @@ interface ContactsAddSlice {
431
437
  //#region src/headless/contacts/contacts.d.ts
432
438
  interface CapxulContactsProps {
433
439
  readonly actor: ContactsActor;
434
- readonly onAdded: (contact: Contact) => void;
440
+ /**
441
+ * `options` is exactly what the caller handed `.Add.submit` or a row verb, so
442
+ * the screen's own observation of the finished action can reuse the attempt
443
+ * identity the SDK operation ran under (#1960 R02).
444
+ */
445
+ readonly onAdded: (contact: Contact, options?: InvocationOptions) => void;
435
446
  /** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
436
- readonly onFailed: (error: CapxulError) => void;
447
+ readonly onFailed: (error: CapxulError, options?: InvocationOptions) => void;
437
448
  readonly children: ReactNode;
438
449
  }
439
450
  declare function Root$6({ actor, onAdded, onFailed, children }: CapxulContactsProps): import("react/jsx-runtime").JSX.Element;
@@ -545,7 +556,12 @@ interface ActivityRowsSlice {
545
556
  readonly rows: readonly ActivityRow[];
546
557
  readonly isLoading: boolean;
547
558
  readonly error: CapxulError | null;
548
- readonly retry: () => void;
559
+ /**
560
+ * #1960 R02: pass the options captured before the retry was selected and the
561
+ * re-read runs under the same attempt identity as the UI observation. Omit
562
+ * them and the read keeps its own invocation context.
563
+ */
564
+ readonly retry: (options?: InvocationOptions) => void;
549
565
  /** Server read time of the newest page, so the app can say which read is older. */
550
566
  readonly observedAt: number | null;
551
567
  }
@@ -589,7 +605,8 @@ interface CsvExport {
589
605
  readonly truncated: boolean;
590
606
  }
591
607
  interface ActivityExportSlice {
592
- readonly toCsv: () => Promise<CsvExport>;
608
+ /** Same contract as `retry`: the export's pages run under the caller's attempt. */
609
+ readonly toCsv: (options?: InvocationOptions) => Promise<CsvExport>;
593
610
  readonly isExporting: boolean;
594
611
  }
595
612
  //#endregion
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as capxulKeys, f as useCapxulClientOrNull, i as entered, l as useCapxulSend, n as CapxulOnboardingController, o as useCapxulDestination, p as useCapxul, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-BPEhjKX9.mjs";
2
+ import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as toInvocationControls, f as toInvocationOptions, h as useCapxul, i as entered, l as useCapxulSend, m as useCapxulClientOrNull, n as CapxulOnboardingController, o as useCapxulDestination, p as capxulKeys, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-DaT-AGx6.mjs";
3
3
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
4
4
  import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
5
  import { CAPXUL_OPERATIONS, CapxulError, EVM_ADDRESS_RE, Errors, HANDLE_RE, PAYMENT_DIRECTIONS, PAYMENT_STATUSES, fingerprintPaymentIntent, formatMoney, isCapxulError, isClaimed, isClaimed as isClaimed$1, isMoneyParseError, isRestoring, isRestoring as isRestoring$1, parseMoney, paymentPhase, resolveIdentityDestination, toEvmAddress, toPartyId } from "@capxul/sdk";
@@ -879,6 +879,8 @@ function useCapxulUploadImage() {
879
879
  }
880
880
  //#endregion
881
881
  //#region src/headless/contacts/use-contacts.ts
882
+ /** One captured snapshot, or nothing — never a fabricated empty options object. */
883
+ const carry = (options) => options === void 0 ? {} : { options };
882
884
  function useContacts(input) {
883
885
  const { actor, onAdded, onFailed } = input;
884
886
  const client = useCapxulClientOrNull();
@@ -895,35 +897,40 @@ function useContacts(input) {
895
897
  const writeMutate = useMutation({
896
898
  mutationFn: async (command) => {
897
899
  const target = requireBook(book, `addressBook.${command.kind}`);
900
+ const controls = toInvocationControls(command.options);
898
901
  return unwrapCapxulResult(command.kind === "rename" ? await target.label({
899
902
  entryId: command.id,
900
903
  label: command.name
901
- }) : command.kind === "hide" ? await target.hide(command.id) : await target.unhide(command.id));
904
+ }, controls) : command.kind === "hide" ? await target.hide(command.id, controls) : await target.unhide(command.id, controls));
902
905
  },
903
906
  onSettled: invalidate,
904
- onError: onFailed
907
+ onError: (error, command) => onFailed(error, command.options)
905
908
  }).mutate;
906
909
  const [value, setValue] = useState("");
907
910
  const [addError, setAddError] = useState(null);
908
911
  const addContact = useMutation({
909
- mutationFn: async (ref) => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.add).add({ ref })),
912
+ mutationFn: async (command) => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.add).add({ ref: command.ref }, toInvocationControls(command.options))),
910
913
  onSettled: invalidate
911
914
  });
912
915
  const addMutate = addContact.mutate;
913
916
  const blockedReason = refusal !== null ? "org-unavailable" : value.trim() === "" ? "empty" : null;
914
917
  const submitGate = useRef(false);
915
- const submit = useCallback(() => {
918
+ const submit = useCallback((options) => {
916
919
  if (blockedReason !== null || submitGate.current) return;
920
+ const attempt = toInvocationOptions(options);
917
921
  submitGate.current = true;
918
922
  setAddError(null);
919
- addMutate(refFromTypedText(value), {
923
+ addMutate({
924
+ ref: refFromTypedText(value),
925
+ ...carry(attempt)
926
+ }, {
920
927
  onSuccess: (entry) => {
921
928
  setValue("");
922
- onAdded(toContact(entry));
929
+ onAdded(toContact(entry), attempt);
923
930
  },
924
931
  onError: (error) => {
925
932
  setAddError(error.code === "INVALID_INPUT" ? "unresolved" : "failed");
926
- onFailed(error);
933
+ onFailed(error, attempt);
927
934
  },
928
935
  onSettled: () => {
929
936
  submitGate.current = false;
@@ -944,18 +951,21 @@ function useContacts(input) {
944
951
  book,
945
952
  scope,
946
953
  refusal,
947
- rename: useCallback((id, name) => writeMutate({
954
+ rename: useCallback((id, name, options) => writeMutate({
948
955
  kind: "rename",
949
956
  id,
950
- name
957
+ name,
958
+ ...carry(toInvocationOptions(options))
951
959
  }), [writeMutate]),
952
- hide: useCallback((id) => writeMutate({
960
+ hide: useCallback((id, options) => writeMutate({
953
961
  kind: "hide",
954
- id
962
+ id,
963
+ ...carry(toInvocationOptions(options))
955
964
  }), [writeMutate]),
956
- unhide: useCallback((id) => writeMutate({
965
+ unhide: useCallback((id, options) => writeMutate({
957
966
  kind: "unhide",
958
- id
967
+ id,
968
+ ...carry(toInvocationOptions(options))
959
969
  }), [writeMutate]),
960
970
  add: {
961
971
  value,
@@ -989,9 +999,9 @@ function useContactsList(engine, options) {
989
999
  if (entries === void 0) return [];
990
1000
  return (limit === void 0 ? entries : entries.slice(0, limit)).map((entry) => Object.assign(toContact(entry), {
991
1001
  initials: initialsOf(entry.label),
992
- rename: (name) => rename(entry.id, name),
993
- hide: () => hide(entry.id),
994
- unhide: () => unhide(entry.id)
1002
+ rename: (name, attempt) => rename(entry.id, name, attempt),
1003
+ hide: (attempt) => hide(entry.id, attempt),
1004
+ unhide: (attempt) => unhide(entry.id, attempt)
995
1005
  }));
996
1006
  }, [
997
1007
  entries,
@@ -1567,6 +1577,12 @@ function useActivity(input) {
1567
1577
  if (filter !== void 0) params.filter = filter;
1568
1578
  return params;
1569
1579
  }, [actor, filter]);
1580
+ const selectedRetry = useRef(void 0);
1581
+ const takeSelectedRetry = useCallback(() => {
1582
+ const attempt = selectedRetry.current;
1583
+ selectedRetry.current = void 0;
1584
+ return toInvocationControls(attempt);
1585
+ }, []);
1570
1586
  const query = useInfiniteQuery({
1571
1587
  queryKey: [
1572
1588
  ...capxulKeys.activity,
@@ -1576,7 +1592,7 @@ function useActivity(input) {
1576
1592
  filter ?? "none"
1577
1593
  ],
1578
1594
  queryFn: async ({ pageParam }) => {
1579
- return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit)));
1595
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit), takeSelectedRetry()));
1580
1596
  },
1581
1597
  initialPageParam: void 0,
1582
1598
  getNextPageParam: (last) => last.cursor ?? void 0,
@@ -1624,14 +1640,15 @@ function useActivity(input) {
1624
1640
  observerRef.current = observer;
1625
1641
  }, [loadMore]);
1626
1642
  const [isExporting, setIsExporting] = useState(false);
1627
- const toCsv = useCallback(async () => {
1643
+ const toCsv = useCallback(async (options) => {
1628
1644
  setIsExporting(true);
1645
+ const controls = toInvocationControls(toInvocationOptions(options));
1629
1646
  try {
1630
1647
  const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list);
1631
1648
  const items = [];
1632
1649
  let cursor;
1633
1650
  for (let page = 0; page < EXPORT_PAGE_CEILING; page += 1) {
1634
- const result = unwrapCapxulResult(await bootstrapped.activity.list(listParams(cursor, EXPORT_PAGE_SIZE)));
1651
+ const result = unwrapCapxulResult(await bootstrapped.activity.list(listParams(cursor, EXPORT_PAGE_SIZE), controls));
1635
1652
  items.push(...result.items);
1636
1653
  cursor = result.cursor ?? void 0;
1637
1654
  if (cursor === void 0) break;
@@ -1654,7 +1671,8 @@ function useActivity(input) {
1654
1671
  setDirection(void 0);
1655
1672
  setStatus([]);
1656
1673
  }, []);
1657
- const retry = useCallback(() => {
1674
+ const retry = useCallback((options) => {
1675
+ selectedRetry.current = toInvocationOptions(options);
1658
1676
  refetch();
1659
1677
  }, [refetch]);
1660
1678
  return {
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-BPEhjKX9.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DaT-AGx6.mjs";
2
2
  import "react";
3
3
  import { jsx } from "react/jsx-runtime";
4
4
  import { createCapxulTestClient } from "@capxul/sdk/testing";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@capxul/sdk-react",
3
- "version": "4.2.0-rc.2",
3
+ "version": "4.2.0-rc.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
@@ -26,7 +26,7 @@
26
26
  "access": "public"
27
27
  },
28
28
  "dependencies": {
29
- "@capxul/sdk": "4.2.0-rc.2"
29
+ "@capxul/sdk": "4.2.0-rc.4"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -43,9 +43,9 @@
43
43
  "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
44
44
  "vite-plus": "0.3.0",
45
45
  "vitest": "4.1.11",
46
- "@capxul/errors": "0.3.0",
47
46
  "@capxul/typescript-config": "0.0.0",
48
- "@capxul/types": "0.3.0"
47
+ "@capxul/types": "0.3.0",
48
+ "@capxul/errors": "0.3.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@tanstack/react-query": "^5.66.9",