@capxul/sdk-react 4.1.4 → 4.2.0-rc.10

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/README.md CHANGED
@@ -28,10 +28,12 @@ export function Providers({ children }: { children: React.ReactNode }) {
28
28
  session. Account and Organization readiness transitions refresh active
29
29
  authenticated queries.
30
30
  - `CapxulAuthenticationController` and `CapxulOnboardingController` select
31
- app-owned slots and render no SDK-owned DOM. Supplying the onboarding
32
- controller's `recoveryOptions` factory lets a fresh actor resume account
33
- prerequisites before the stored Organization replay; a failed prerequisite
34
- returns the same manual replay instead of looping.
31
+ app-owned slots and render no SDK-owned DOM. The onboarding controller keeps
32
+ no Organization submission: after a reload the Core SDK reads the pending
33
+ Organization from the backend and attaches it, so the app re-submits nothing.
34
+ A claimed identity with no Organization and no app-held form step reports
35
+ `organizationProgress` with `{ at: "loading", orgId: null }` until that
36
+ attach lands.
35
37
  - Rich-data hooks such as `useCapxulProfile`, `useCapxulOrgs`, members, roles,
36
38
  treasury, and money hooks remain TanStack Query projections. Personal
37
39
  holdings and activity reads start only after the Account is claimed.
@@ -0,0 +1,11 @@
1
+ {
2
+ "source": {
3
+ "commit": "a7e55e5f1c2af5567a8b285a4ef70b8b5a3289f6",
4
+ "tree": "91bf1b080c0006fe30131711c13c843afd627158",
5
+ "branch": "codex/programme-rc",
6
+ "repository": "https://github.com/Xelmar-tech/infrastructure",
7
+ "lockfileSha256": "5870f53b72706d103220c1bcf733cb4fb71196aea32a9cfbdc277d73cc959264"
8
+ },
9
+ "name": "@capxul/sdk-react",
10
+ "version": "4.2.0-rc.10"
11
+ }
@@ -25,6 +25,12 @@ interface OrganizationDetails {
25
25
  readonly country: string;
26
26
  readonly bio?: string;
27
27
  readonly size?: string;
28
+ /**
29
+ * #1955: the storage id `useCapxulUploadImage` handed back on file pick. The
30
+ * create call carries it, so the backend records the logo on the `orgs`
31
+ * insert instead of the app binding it afterwards.
32
+ */
33
+ readonly logoStorageId?: string;
28
34
  }
29
35
  interface CreateOrganizationSubmission {
30
36
  readonly profileDetails: ProfileDetails;
@@ -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 {
@@ -201,30 +230,116 @@ function normalizeOrganization(organization) {
201
230
  if (name.length === 0) return null;
202
231
  if (organization.bio !== void 0 && typeof organization.bio !== "string") return null;
203
232
  if (organization.size !== void 0 && typeof organization.size !== "string") return null;
233
+ if (organization.logoStorageId !== void 0 && (typeof organization.logoStorageId !== "string" || organization.logoStorageId.length === 0)) return null;
204
234
  try {
205
235
  return {
206
236
  name,
207
237
  handle: toHandle(handle),
208
238
  country: toCountryCode(organization.country),
209
239
  ...organization.bio === void 0 ? {} : { bio: organization.bio },
210
- ...organization.size === void 0 ? {} : { size: organization.size }
240
+ ...organization.size === void 0 ? {} : { size: organization.size },
241
+ ...organization.logoStorageId === void 0 ? {} : { logoStorageId: organization.logoStorageId }
211
242
  };
212
243
  } catch {
213
244
  return null;
214
245
  }
215
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");
216
256
  function createAuth(client, clearAuthenticatedQueries) {
217
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
+ });
218
297
  const read = async (invocation) => {
219
298
  const result = await runtime.send({ _tag: "ReadSession" }, invocation);
220
- 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;
221
302
  };
222
303
  const ensureAccount = async (invocation) => {
223
304
  const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
224
305
  return failure(result) ?? { ok: true };
225
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
+ });
226
336
  const reachClaimed = async (invocation) => {
227
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
+ }
228
343
  if (state.phase !== "authenticated" || state.account.at === "unknown") {
229
344
  const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
230
345
  const refused = failure(result);
@@ -236,6 +351,16 @@ function createAuth(client, clearAuthenticatedQueries) {
236
351
  reason: "WRONG_STATE"
237
352
  };
238
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
+ }
239
364
  const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
240
365
  const result = await runtime.send(event, invocation);
241
366
  const refused = failure(result);
@@ -256,13 +381,13 @@ function createAuth(client, clearAuthenticatedQueries) {
256
381
  ok: false,
257
382
  reason: "INVALID_INPUT"
258
383
  };
384
+ const refreshed = await read(invocation);
385
+ if (!refreshed.ok) return refreshed;
259
386
  const current = runtime.snapshot();
260
387
  if (current.phase !== "authenticated" || !current.profileComplete) {
261
388
  const completed = await runtime.completeProfile(submission.profileDetails, invocation);
262
389
  if (!completed.ok) return completed;
263
390
  }
264
- const refreshed = await read(invocation);
265
- if (!refreshed.ok) return refreshed;
266
391
  const claimed = await reachClaimed(invocation);
267
392
  return claimed.ok ? {
268
393
  ok: true,
@@ -339,12 +464,13 @@ function createAuth(client, clearAuthenticatedQueries) {
339
464
  }),
340
465
  createOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
341
466
  const current = runtime.snapshot();
467
+ const running = runningOrganization(current);
468
+ if (running !== null) return {
469
+ ok: true,
470
+ orgId: running
471
+ };
342
472
  if (current.phase === "authenticated" && current.account.at === "claimed") {
343
473
  const org = current.account.org;
344
- if (org !== null && (org.at === "loading" || org.at === "settingUp" || org.at === "ready")) return {
345
- ok: true,
346
- orgId: org.orgId
347
- };
348
474
  if (org?.at === "failed" && org.orgId !== null) {
349
475
  if (!org.retryable) return {
350
476
  ok: false,
@@ -359,6 +485,11 @@ function createAuth(client, clearAuthenticatedQueries) {
359
485
  }
360
486
  const prepared = await prepareOrganization(submission, invocation);
361
487
  if (!prepared.ok) return prepared;
488
+ const opened = runningOrganization(runtime.snapshot());
489
+ if (opened !== null) return {
490
+ ok: true,
491
+ orgId: opened
492
+ };
362
493
  const created = await runtime.send({
363
494
  _tag: "CreateOrganization",
364
495
  draft: prepared.organization
@@ -440,7 +571,7 @@ function CapxulIdentityProvider({ client, children }) {
440
571
  }, []);
441
572
  const value = useMemo(() => {
442
573
  if (client === null || runtime === null) return null;
443
- const send = (event, options) => runtime.send(event, controls(options));
574
+ const send = (event, options) => runtime.send(event, toInvocationControls(options));
444
575
  const clearAuthenticatedQueries = async () => {
445
576
  await queryClient.cancelQueries({ queryKey: capxulKeys.root });
446
577
  await queryClient.resetQueries({ queryKey: capxulKeys.root });
@@ -819,4 +950,4 @@ function organizationForm(props, state, auth, submitted) {
819
950
  });
820
951
  }
821
952
  //#endregion
822
- 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
@@ -1,4 +1,4 @@
1
- import { A as entered, C as CreateOrganizationFailure, D as OrganizationDetails, E as InvocationOptions, F as useCapxulTransitions, M as useCapxulDestination, N as useCapxulIdentity, O as ProfileDetails, P as useCapxulSend, S as CapxulSend, T as Destination, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulAuth, k as SendResult, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as CreateOrganizationSubmission, x as CapxulAuth, y as SignedOutState } from "./controllers-DIf8elqQ.mjs";
1
+ import { A as entered, C as CreateOrganizationFailure, D as OrganizationDetails, E as InvocationOptions, F as useCapxulTransitions, M as useCapxulDestination, N as useCapxulIdentity, O as ProfileDetails, P as useCapxulSend, S as CapxulSend, T as Destination, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulAuth, k as SendResult, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as CreateOrganizationSubmission, x as CapxulAuth, y as SignedOutState } from "./controllers-BWmKRFy6.mjs";
2
2
  import { ReactNode, RefCallback } from "react";
3
3
  import { QueryClient, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
4
4
  import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, BudgetId, CapxulClient, CapxulError, CapxulResult, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, IdentityDestination, InviteMemberInput, MemberView, Money, MoneyParseErrorReason, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, PartyId, Payment, PaymentDirection, PaymentDocumentRef, PaymentDocumentRender, PaymentStatus, PaymentTiming, PaymentType, PaymentsPayInput, PayrollGroupId, PayrollGroupInput, PayrollRunId, PayrollRunStatus, Permission, PermissionMethods, PermissionReadResult, Profile, RoleView, SubmittedPermissionExecution, isClaimed, isRestoring } from "@capxul/sdk";
@@ -222,6 +222,7 @@ type ProfileDraft = {
222
222
  readonly withdrawalAddress: string;
223
223
  readonly handle?: string;
224
224
  readonly payoutAddresses?: readonly PayoutDraftEntry[];
225
+ readonly imageStorageId?: string;
225
226
  };
226
227
  type OrganizationDraft = {
227
228
  readonly name: string;
@@ -229,6 +230,7 @@ type OrganizationDraft = {
229
230
  readonly country: string;
230
231
  readonly bio?: string;
231
232
  readonly size?: string;
233
+ readonly logoStorageId?: string;
232
234
  };
233
235
  type OnboardingOrigin = {
234
236
  readonly kind: "personal";
@@ -251,6 +253,8 @@ type OnboardingJourney = {
251
253
  readonly organization?: OrganizationDraft;
252
254
  readonly stableHandle?: string;
253
255
  readonly organizationId?: string;
256
+ /** #1955: what the organization submit sent, kept for resume. */
257
+ readonly submission?: CreateOrganizationSubmission;
254
258
  };
255
259
  /**
256
260
  * The app-facing projection input: where a resumed journey stands. Consumers
@@ -335,6 +339,21 @@ type UseCapxulImageUploadReturn = UseMutationResult<{
335
339
  */
336
340
  declare function useCapxulImageUpload(): UseCapxulImageUploadReturn;
337
341
  //#endregion
342
+ //#region src/headless/media/use-capxul-upload-image.d.ts
343
+ type UseCapxulUploadImageReturn = UseMutationResult<{
344
+ readonly storageId: string;
345
+ }, CapxulError, Blob>;
346
+ /**
347
+ * #1955: upload only. Hands back the storage id for a CREATE call to carry
348
+ * (`ProfileDetails.imageStorageId`, `OrganizationDetails.logoStorageId`).
349
+ *
350
+ * `useCapxulImageUpload` is upload+bind and stays as it is for the settings
351
+ * pages. It cannot serve onboarding: the row it binds to does not exist yet.
352
+ * Nothing is bound here, so nothing is invalidated either — the create call
353
+ * that carries the id owns the cache change.
354
+ */
355
+ declare function useCapxulUploadImage(): UseCapxulUploadImageReturn;
356
+ //#endregion
338
357
  //#region src/headless/contacts/use-contacts.d.ts
339
358
  type ContactsActor = {
340
359
  readonly kind: "personal";
@@ -364,9 +383,9 @@ interface Contact {
364
383
  interface ContactRow extends Contact {
365
384
  /** Ours: one initials rule, not one copy per screen. */
366
385
  readonly initials: string;
367
- readonly rename: (name: string) => void;
368
- readonly hide: () => void;
369
- readonly unhide: () => void;
386
+ readonly rename: (name: string, options?: InvocationOptions) => void;
387
+ readonly hide: (options?: InvocationOptions) => void;
388
+ readonly unhide: (options?: InvocationOptions) => void;
370
389
  }
371
390
  /** ADR-0023 R1: refusal CODES, never sentences — the app owns the words. */
372
391
  type ContactsRefusal = "loading" | "org-unavailable" | "unavailable";
@@ -402,7 +421,13 @@ interface ContactsListOptions {
402
421
  interface ContactsAddSlice {
403
422
  readonly value: string;
404
423
  readonly change: (text: string) => void;
405
- 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;
406
431
  readonly isSubmitting: boolean;
407
432
  readonly blocked: boolean;
408
433
  readonly blockedReason: ContactsAddBlockedReason | null;
@@ -412,9 +437,14 @@ interface ContactsAddSlice {
412
437
  //#region src/headless/contacts/contacts.d.ts
413
438
  interface CapxulContactsProps {
414
439
  readonly actor: ContactsActor;
415
- 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;
416
446
  /** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
417
- readonly onFailed: (error: CapxulError) => void;
447
+ readonly onFailed: (error: CapxulError, options?: InvocationOptions) => void;
418
448
  readonly children: ReactNode;
419
449
  }
420
450
  declare function Root$6({ actor, onAdded, onFailed, children }: CapxulContactsProps): import("react/jsx-runtime").JSX.Element;
@@ -526,7 +556,12 @@ interface ActivityRowsSlice {
526
556
  readonly rows: readonly ActivityRow[];
527
557
  readonly isLoading: boolean;
528
558
  readonly error: CapxulError | null;
529
- 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;
530
565
  /** Server read time of the newest page, so the app can say which read is older. */
531
566
  readonly observedAt: number | null;
532
567
  }
@@ -570,7 +605,8 @@ interface CsvExport {
570
605
  readonly truncated: boolean;
571
606
  }
572
607
  interface ActivityExportSlice {
573
- 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>;
574
610
  readonly isExporting: boolean;
575
611
  }
576
612
  //#endregion
@@ -1032,4 +1068,4 @@ declare const capxulKeys: {
1032
1068
  payment: (paymentId: string | undefined) => readonly ["capxul", "payments", string];
1033
1069
  };
1034
1070
  //#endregion
1035
- export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationFailure, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type HandleAvailability, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulHandleAvailabilityReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
1071
+ export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationFailure, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type HandleAvailability, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulHandleAvailabilityReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, type UseCapxulUploadImageReturn, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUploadImage };
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-Dzk5AvfL.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";
@@ -702,7 +702,8 @@ function isValidJourney(value) {
702
702
  "profile",
703
703
  "organization",
704
704
  "stableHandle",
705
- "organizationId"
705
+ "organizationId",
706
+ "submission"
706
707
  ])) return false;
707
708
  if (!isBoundedId(value.ownerId)) return false;
708
709
  if (!isBoundedId(value.journeyId) || !value.journeyId.startsWith("journey_")) return false;
@@ -712,6 +713,7 @@ function isValidJourney(value) {
712
713
  if (value.origin !== void 0 && !isOrigin(value.origin)) return false;
713
714
  if (value.profile !== void 0 && !isProfileDraft(value.profile)) return false;
714
715
  if (value.organization !== void 0 && !isOrganizationDraft(value.organization)) return false;
716
+ if (value.submission !== void 0 && !isCreateOrganizationSubmission(value.submission)) return false;
715
717
  if (value.stableHandle !== void 0 && !isDraftText(value.stableHandle)) return false;
716
718
  if (value.organizationId !== void 0 && !isBoundedId(value.organizationId)) return false;
717
719
  if (value.organization !== void 0 && value.stableHandle !== value.organization.handle) return false;
@@ -734,12 +736,33 @@ function isProfileDraft(value) {
734
736
  "country",
735
737
  "withdrawalAddress",
736
738
  "handle",
737
- "payoutAddresses"
739
+ "payoutAddresses",
740
+ "imageStorageId"
738
741
  ]) || !isDraftText(value.displayName) || !isDraftText(value.country) || !isDraftText(value.withdrawalAddress)) return false;
739
742
  if (value.handle !== void 0 && !isDraftText(value.handle)) return false;
740
743
  if (value.payoutAddresses !== void 0 && !isPayoutDraftList(value.payoutAddresses)) return false;
744
+ if (value.imageStorageId !== void 0 && !isBoundedId(value.imageStorageId)) return false;
741
745
  return true;
742
746
  }
747
+ /**
748
+ * The submitted organization (#1955). ONE validator now — the app's duplicate
749
+ * of it is deleted, so a submit cannot be written by two writers with
750
+ * disagreeing rules and then rejected here.
751
+ */
752
+ function isCreateOrganizationSubmission(value) {
753
+ if (!isRecord(value) || !hasOnlyKeys(value, ["profileDetails", "organization"])) return false;
754
+ const { profileDetails, organization } = value;
755
+ if (!isRecord(profileDetails) || !hasOnlyKeys(profileDetails, [
756
+ "displayName",
757
+ "country",
758
+ "handle",
759
+ "imageStorageId",
760
+ "payoutAddresses"
761
+ ]) || !isDraftText(profileDetails.displayName) || !isDraftText(profileDetails.country) || !isDraftText(profileDetails.handle)) return false;
762
+ if (profileDetails.imageStorageId !== void 0 && !isBoundedId(profileDetails.imageStorageId)) return false;
763
+ if (profileDetails.payoutAddresses !== void 0 && !isPayoutDraftList(profileDetails.payoutAddresses)) return false;
764
+ return isOrganizationDraft(organization);
765
+ }
743
766
  function isPayoutDraftList(value) {
744
767
  return Array.isArray(value) && value.length <= MAX_PAYOUT_DRAFT_ENTRIES && value.every((entry) => isRecord(entry) && hasOnlyKeys(entry, ["chain", "address"]) && (entry.chain === "evm" || entry.chain === "solana" || entry.chain === "starknet") && isDraftText(entry.address));
745
768
  }
@@ -749,10 +772,12 @@ function isOrganizationDraft(value) {
749
772
  "handle",
750
773
  "country",
751
774
  "bio",
752
- "size"
775
+ "size",
776
+ "logoStorageId"
753
777
  ]) || !isDraftText(value.name) || !isDraftText(value.handle) || !isDraftText(value.country)) return false;
754
778
  if (value.bio !== void 0 && !isDraftText(value.bio)) return false;
755
779
  if (value.size !== void 0 && !isDraftText(value.size)) return false;
780
+ if (value.logoStorageId !== void 0 && !isBoundedId(value.logoStorageId)) return false;
756
781
  return true;
757
782
  }
758
783
  function isDraftText(value) {
@@ -836,7 +861,26 @@ function useCapxulImageUpload() {
836
861
  });
837
862
  }
838
863
  //#endregion
864
+ //#region src/headless/media/use-capxul-upload-image.ts
865
+ /**
866
+ * #1955: upload only. Hands back the storage id for a CREATE call to carry
867
+ * (`ProfileDetails.imageStorageId`, `OrganizationDetails.logoStorageId`).
868
+ *
869
+ * `useCapxulImageUpload` is upload+bind and stays as it is for the settings
870
+ * pages. It cannot serve onboarding: the row it binds to does not exist yet.
871
+ * Nothing is bound here, so nothing is invalidated either — the create call
872
+ * that carries the id owns the cache change.
873
+ */
874
+ function useCapxulUploadImage() {
875
+ const client = useCapxulClientOrNull();
876
+ return useMutation({ mutationFn: async (blob) => {
877
+ return { storageId: unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.media.uploadImage).media.uploadImage(blob)).storageId };
878
+ } });
879
+ }
880
+ //#endregion
839
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 };
840
884
  function useContacts(input) {
841
885
  const { actor, onAdded, onFailed } = input;
842
886
  const client = useCapxulClientOrNull();
@@ -853,35 +897,40 @@ function useContacts(input) {
853
897
  const writeMutate = useMutation({
854
898
  mutationFn: async (command) => {
855
899
  const target = requireBook(book, `addressBook.${command.kind}`);
900
+ const controls = toInvocationControls(command.options);
856
901
  return unwrapCapxulResult(command.kind === "rename" ? await target.label({
857
902
  entryId: command.id,
858
903
  label: command.name
859
- }) : 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));
860
905
  },
861
906
  onSettled: invalidate,
862
- onError: onFailed
907
+ onError: (error, command) => onFailed(error, command.options)
863
908
  }).mutate;
864
909
  const [value, setValue] = useState("");
865
910
  const [addError, setAddError] = useState(null);
866
911
  const addContact = useMutation({
867
- 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))),
868
913
  onSettled: invalidate
869
914
  });
870
915
  const addMutate = addContact.mutate;
871
916
  const blockedReason = refusal !== null ? "org-unavailable" : value.trim() === "" ? "empty" : null;
872
917
  const submitGate = useRef(false);
873
- const submit = useCallback(() => {
918
+ const submit = useCallback((options) => {
874
919
  if (blockedReason !== null || submitGate.current) return;
920
+ const attempt = toInvocationOptions(options);
875
921
  submitGate.current = true;
876
922
  setAddError(null);
877
- addMutate(refFromTypedText(value), {
923
+ addMutate({
924
+ ref: refFromTypedText(value),
925
+ ...carry(attempt)
926
+ }, {
878
927
  onSuccess: (entry) => {
879
928
  setValue("");
880
- onAdded(toContact(entry));
929
+ onAdded(toContact(entry), attempt);
881
930
  },
882
931
  onError: (error) => {
883
932
  setAddError(error.code === "INVALID_INPUT" ? "unresolved" : "failed");
884
- onFailed(error);
933
+ onFailed(error, attempt);
885
934
  },
886
935
  onSettled: () => {
887
936
  submitGate.current = false;
@@ -902,18 +951,21 @@ function useContacts(input) {
902
951
  book,
903
952
  scope,
904
953
  refusal,
905
- rename: useCallback((id, name) => writeMutate({
954
+ rename: useCallback((id, name, options) => writeMutate({
906
955
  kind: "rename",
907
956
  id,
908
- name
957
+ name,
958
+ ...carry(toInvocationOptions(options))
909
959
  }), [writeMutate]),
910
- hide: useCallback((id) => writeMutate({
960
+ hide: useCallback((id, options) => writeMutate({
911
961
  kind: "hide",
912
- id
962
+ id,
963
+ ...carry(toInvocationOptions(options))
913
964
  }), [writeMutate]),
914
- unhide: useCallback((id) => writeMutate({
965
+ unhide: useCallback((id, options) => writeMutate({
915
966
  kind: "unhide",
916
- id
967
+ id,
968
+ ...carry(toInvocationOptions(options))
917
969
  }), [writeMutate]),
918
970
  add: {
919
971
  value,
@@ -947,9 +999,9 @@ function useContactsList(engine, options) {
947
999
  if (entries === void 0) return [];
948
1000
  return (limit === void 0 ? entries : entries.slice(0, limit)).map((entry) => Object.assign(toContact(entry), {
949
1001
  initials: initialsOf(entry.label),
950
- rename: (name) => rename(entry.id, name),
951
- hide: () => hide(entry.id),
952
- 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)
953
1005
  }));
954
1006
  }, [
955
1007
  entries,
@@ -1525,6 +1577,12 @@ function useActivity(input) {
1525
1577
  if (filter !== void 0) params.filter = filter;
1526
1578
  return params;
1527
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
+ }, []);
1528
1586
  const query = useInfiniteQuery({
1529
1587
  queryKey: [
1530
1588
  ...capxulKeys.activity,
@@ -1534,7 +1592,7 @@ function useActivity(input) {
1534
1592
  filter ?? "none"
1535
1593
  ],
1536
1594
  queryFn: async ({ pageParam }) => {
1537
- 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()));
1538
1596
  },
1539
1597
  initialPageParam: void 0,
1540
1598
  getNextPageParam: (last) => last.cursor ?? void 0,
@@ -1582,14 +1640,15 @@ function useActivity(input) {
1582
1640
  observerRef.current = observer;
1583
1641
  }, [loadMore]);
1584
1642
  const [isExporting, setIsExporting] = useState(false);
1585
- const toCsv = useCallback(async () => {
1643
+ const toCsv = useCallback(async (options) => {
1586
1644
  setIsExporting(true);
1645
+ const controls = toInvocationControls(toInvocationOptions(options));
1587
1646
  try {
1588
1647
  const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list);
1589
1648
  const items = [];
1590
1649
  let cursor;
1591
1650
  for (let page = 0; page < EXPORT_PAGE_CEILING; page += 1) {
1592
- 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));
1593
1652
  items.push(...result.items);
1594
1653
  cursor = result.cursor ?? void 0;
1595
1654
  if (cursor === void 0) break;
@@ -1612,7 +1671,8 @@ function useActivity(input) {
1612
1671
  setDirection(void 0);
1613
1672
  setStatus([]);
1614
1673
  }, []);
1615
- const retry = useCallback(() => {
1674
+ const retry = useCallback((options) => {
1675
+ selectedRetry.current = toInvocationOptions(options);
1616
1676
  refetch();
1617
1677
  }, [refetch]);
1618
1678
  return {
@@ -2763,7 +2823,9 @@ async function executeRunDraft(candidate, work) {
2763
2823
  localStorage.setItem(storageKey(draft.scope), JSON.stringify(next));
2764
2824
  draft = next;
2765
2825
  }, clear);
2766
- clear();
2826
+ try {
2827
+ clear();
2828
+ } catch {}
2767
2829
  return run;
2768
2830
  });
2769
2831
  } catch (cause) {
@@ -3297,4 +3359,4 @@ const CapxulPayrollRun = Object.assign(Root, {
3297
3359
  Actions
3298
3360
  });
3299
3361
  //#endregion
3300
- export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
3362
+ export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUploadImage };
@@ -1,4 +1,4 @@
1
- import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-DIf8elqQ.mjs";
1
+ import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-BWmKRFy6.mjs";
2
2
  import * as React from "react";
3
3
  import { ReactNode } from "react";
4
4
  import { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, SeedTestIdentityInput, createCapxulTestClient } from "@capxul/sdk/testing";
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-Dzk5AvfL.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.1.4",
3
+ "version": "4.2.0-rc.10",
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.1.4"
29
+ "@capxul/sdk": "4.2.0-rc.10"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -44,8 +44,8 @@
44
44
  "vite-plus": "0.3.0",
45
45
  "vitest": "4.1.11",
46
46
  "@capxul/errors": "0.3.0",
47
- "@capxul/types": "0.3.0",
48
- "@capxul/typescript-config": "0.0.0"
47
+ "@capxul/typescript-config": "0.0.0",
48
+ "@capxul/types": "0.3.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@tanstack/react-query": "^5.66.9",