@capxul/sdk-react 4.2.0-rc.9 → 4.20.0-beta.1

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.
@@ -37,6 +37,24 @@ function useCapxulClientOrNull() {
37
37
  }
38
38
  //#endregion
39
39
  //#region src/internal/reactivity-keys.ts
40
+ /**
41
+ * The account a read is answered FOR, as a key segment (#2007 R19).
42
+ *
43
+ * A read whose answer depends on who is asking belongs to the (scope, account)
44
+ * pair, not to the scope. Replacing one claimed account with another is not a
45
+ * state-label change. Keying is what
46
+ * makes the new person miss rather than read the previous person's answer.
47
+ * `undefined` while no account is claimed — no such read may run then anyway.
48
+ */
49
+ function actingAccount(identity) {
50
+ return identity !== null && identity.phase === "authenticated" && identity.account.at === "claimed" ? identity.account.address : void 0;
51
+ }
52
+ /** Keep invalidation prefixes shared, but never share a personal result across accounts.
53
+ * Session reads also run before an Account is claimed (for example `orgs()`).
54
+ */
55
+ function accountKey(key, identity) {
56
+ return [...key, actingAccount(identity) ?? (identity?.phase === "authenticated" ? identity.session.authUserId : null)];
57
+ }
40
58
  const capxulKeys = {
41
59
  root: ["capxul"],
42
60
  profile: ["capxul", "profile"],
@@ -80,11 +98,12 @@ const capxulKeys = {
80
98
  orgId ?? "pending",
81
99
  "permissions"
82
100
  ],
83
- orgMe: (orgId) => [
101
+ orgMe: (orgId, account) => [
84
102
  "capxul",
85
103
  "org",
86
104
  orgId ?? "pending",
87
- "me"
105
+ "me",
106
+ account ?? "pending"
88
107
  ],
89
108
  orgLifecycle: (orgId) => [
90
109
  "capxul",
@@ -555,9 +574,16 @@ function CapxulIdentityProvider({ client, children }) {
555
574
  }, [client, runtime]);
556
575
  useEffect(() => {
557
576
  if (runtime === null) return;
577
+ let previousAccount = actingAccount(runtime.snapshot());
558
578
  return runtime.subscribeTransitions((record) => {
559
579
  const state = runtime.snapshot();
560
- if (record.outcome === "applied" && record.from !== record.to && (record.to === "authenticated:claimed" || record.to === "authenticated:claimed:ready")) queryClient.invalidateQueries({ queryKey: capxulKeys.root });
580
+ const account = actingAccount(state);
581
+ const accountChanged = previousAccount !== void 0 && account !== void 0 && account !== previousAccount;
582
+ previousAccount = account;
583
+ if (record.outcome === "applied" && (record.from !== record.to || accountChanged) && (record.to === "authenticated:claimed" || record.to === "authenticated:claimed:ready")) queryClient.invalidateQueries({
584
+ queryKey: capxulKeys.root,
585
+ ...accountChanged ? { refetchType: "none" } : {}
586
+ });
561
587
  for (const listener of listeners.current) try {
562
588
  listener(record, state);
563
589
  } catch {
@@ -950,4 +976,4 @@ function organizationForm(props, state, auth, submitted) {
950
976
  });
951
977
  }
952
978
  //#endregion
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 };
979
+ export { useCapxul as _, useCapxulAuth as a, useCapxulIdentityOrNull as c, toInvocationControls as d, toInvocationOptions as f, useCapxulClientOrNull as g, capxulKeys as h, entered as i, useCapxulSend as l, actingAccount as m, CapxulOnboardingController as n, useCapxulDestination as o, accountKey as p, CapxulProvider as r, useCapxulIdentity as s, CapxulAuthenticationController as t, useCapxulTransitions as u };
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
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
- 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";
4
+ import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, BudgetId, CapxulClient, CapxulError, CapxulResult, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, IdentityDestination, IdentityState, 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";
5
5
  //#region src/provider.d.ts
6
6
  type CapxulProviderSharedProps = {
7
7
  /** Bring your own QueryClient; otherwise the provider creates one. */
@@ -200,12 +200,21 @@ type UseCapxulCreateOrgReturn = UseMutationResult<OrgView, CapxulError, CreateOr
200
200
  declare function useCapxulCreateOrg(): UseCapxulCreateOrgReturn;
201
201
  //#endregion
202
202
  //#region src/hooks/use-capxul-invite-member.d.ts
203
+ /**
204
+ * R06 (#1964): `options` is the browser attempt the caller captured before the
205
+ * person pressed Send. It reaches the SDK operation unchanged, so the durable
206
+ * `org_invite_sent` and the later `org_invite_progressed` carry that attempt's
207
+ * correlation. Absent, the invitation keeps its own invocation context.
208
+ */
209
+ type UseCapxulInviteMemberInput = InviteMemberInput & {
210
+ readonly options?: InvocationOptions;
211
+ };
203
212
  /**
204
213
  * Invite a member to an Organization by email. The hook uses the closed-over `orgId`.
205
214
  * It binds directly to
206
215
  * `capxul.org(orgId).invite(input)`. On success, invalidates the member list.
207
216
  */
208
- type UseCapxulInviteMemberReturn = UseMutationResult<MemberView, CapxulError, InviteMemberInput>;
217
+ type UseCapxulInviteMemberReturn = UseMutationResult<MemberView, CapxulError, UseCapxulInviteMemberInput>;
209
218
  declare function useCapxulInviteMember(orgId: OrgId | undefined): UseCapxulInviteMemberReturn;
210
219
  //#endregion
211
220
  //#region src/headless/journey/journey-state.d.ts
@@ -516,6 +525,7 @@ type SummaryWindow = "all" | "last30days" | ActivityRange;
516
525
  * in its own words.
517
526
  */
518
527
  interface ActivitySummarySlice {
528
+ readonly readWarning?: ActivityPage["readWarning"];
519
529
  readonly currency: string | null;
520
530
  readonly moneyIn: string | null;
521
531
  readonly moneyOut: string | null;
@@ -552,6 +562,7 @@ interface ActivitySearchSlice {
552
562
  readonly change: (text: string) => void;
553
563
  }
554
564
  interface ActivityRowsSlice {
565
+ readonly readWarning?: ActivityPage["readWarning"];
555
566
  /** Already filtered and already searched. */
556
567
  readonly rows: readonly ActivityRow[];
557
568
  readonly isLoading: boolean;
@@ -599,6 +610,7 @@ interface ActivityDetailSlice {
599
610
  readonly error: CapxulError | null;
600
611
  }
601
612
  interface CsvExport {
613
+ readonly readWarning?: ActivityPage["readWarning"];
602
614
  readonly text: string;
603
615
  readonly rowCount: number;
604
616
  /** The 5,000-row ceiling was reached and rows were left unread. */
@@ -833,8 +845,19 @@ type DashboardScope = {
833
845
  readonly orgId?: string;
834
846
  };
835
847
  type DashboardAccessPhase = "checking" | "error" | "redirect" | "granted";
848
+ /**
849
+ * Which of the three probes produced the error the screen is showing. The
850
+ * error code alone cannot say: a provider failure reads the same whether the
851
+ * session read, the membership list or the lifecycle read raised it, and a
852
+ * consumer that reports a displayed gate error has to keep those apart
853
+ * (#1963 R05-2). It names the SOURCE only; `retry` still re-runs every failed
854
+ * probe, exactly as before.
855
+ */
856
+ type DashboardAccessProbe = "session" | "membership" | "lifecycle";
836
857
  interface DashboardAccessErrorSlice {
837
858
  readonly error: CapxulError;
859
+ /** The probe the surfaced error came from, in the frozen precedence order. */
860
+ readonly probe: DashboardAccessProbe;
838
861
  /** Re-runs each failed probe. */
839
862
  readonly retry: () => void;
840
863
  }
@@ -853,6 +876,12 @@ declare function Checking({ children }: {
853
876
  declare function DashboardError({ children }: {
854
877
  readonly children: (slice: DashboardAccessErrorSlice) => ReactNode;
855
878
  }): import("react/jsx-runtime").JSX.Element | null;
879
+ /**
880
+ * Hands the destination and draws nothing. Reaching this part is a REQUEST to
881
+ * navigate, never an arrival: the app may cancel or supersede it, so nothing
882
+ * here — and nothing a consumer hangs off it — may claim a completed redirect
883
+ * (#1963 R05-1). The destination page's own normalized pageview proves arrival.
884
+ */
856
885
  declare function Redirect({ children }: {
857
886
  readonly children: (slice: DashboardAccessRedirectSlice) => ReactNode;
858
887
  }): import("react/jsx-runtime").JSX.Element | null;
@@ -891,8 +920,14 @@ interface PayrollSummarySlice {
891
920
  }
892
921
  interface PayrollGroupsSlice {
893
922
  readonly groups: readonly PayrollGroupRow[];
894
- readonly save: (input: PayrollGroupInput) => Promise<CapxulResult<PayrollGroupRow>>;
895
- readonly remove: (id: PayrollGroupId) => Promise<CapxulResult<void>>;
923
+ /**
924
+ * R13 (#1968): `options` is the browser attempt the caller captured before the
925
+ * employer pressed the button. It reaches the SDK operation unchanged, so the
926
+ * group's `ui_payroll_action_completed` and the durable `payroll_group_changed`
927
+ * share one correlation. Absent, the write keeps its own invocation context.
928
+ */
929
+ readonly save: (input: PayrollGroupInput, options?: InvocationOptions) => Promise<CapxulResult<PayrollGroupRow>>;
930
+ readonly remove: (id: PayrollGroupId, options?: InvocationOptions) => Promise<CapxulResult<void>>;
896
931
  readonly isSaving: boolean;
897
932
  readonly isLoading: boolean;
898
933
  readonly error: CapxulError | null;
@@ -984,7 +1019,14 @@ interface PayrollRunSummarySlice {
984
1019
  interface PayrollRunActionsSlice {
985
1020
  readonly recovery: "none" | "restoring" | "required" | "unavailable";
986
1021
  readonly recoveryError: CapxulError | null;
987
- readonly submit: () => void;
1022
+ /**
1023
+ * R13 (#1968): `options` is the browser attempt captured before the employer
1024
+ * confirmed. It reaches `authorizeRun` unchanged, so the sheet's own
1025
+ * `ui_payroll_action_completed` and the durable `payroll_run_transitioned`
1026
+ * rows share one correlation. It is NEVER written into the persisted draft —
1027
+ * a restored run keeps its own identity, not a stale attempt's.
1028
+ */
1029
+ readonly submit: (options?: InvocationOptions) => void;
988
1030
  readonly isSubmitting: boolean;
989
1031
  readonly blocked: boolean;
990
1032
  readonly blockedReason: CapxulPayrollRunBlockedReason | null;
@@ -1053,7 +1095,7 @@ declare const capxulKeys: {
1053
1095
  orgRoles: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "roles"];
1054
1096
  orgTreasury: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "treasury"];
1055
1097
  orgPermissions: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "permissions"];
1056
- orgMe: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "me"];
1098
+ orgMe: (orgId: OrgId | undefined, account: string | undefined) => readonly ["capxul", "org", "pending" | OrgId, "me", string];
1057
1099
  orgLifecycle: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "lifecycle"];
1058
1100
  contacts: (scope: string) => readonly ["capxul", "contacts", string];
1059
1101
  contactsList: (scope: string, includeHidden: boolean) => readonly ["capxul", "contacts", string, "all" | "visible"];
@@ -1068,4 +1110,4 @@ declare const capxulKeys: {
1068
1110
  payment: (paymentId: string | undefined) => readonly ["capxul", "payments", string];
1069
1111
  };
1070
1112
  //#endregion
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 };
1113
+ 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 DashboardAccessProbe, 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 UseCapxulInviteMemberInput, 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 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";
2
+ import { _ as useCapxul, a as useCapxulAuth, c as useCapxulIdentityOrNull, d as toInvocationControls, f as toInvocationOptions, g as useCapxulClientOrNull, h as capxulKeys, i as entered, l as useCapxulSend, m as actingAccount, n as CapxulOnboardingController, o as useCapxulDestination, p as accountKey, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-DXmEHrnw.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";
@@ -47,8 +47,9 @@ function useCapxulProfile() {
47
47
  //#region src/hooks/use-capxul-account-balance.ts
48
48
  function useCapxulAccountBalance(options) {
49
49
  const client = useCapxulClientOrNull();
50
+ const identity = useCapxulIdentityOrNull();
50
51
  return useQuery({
51
- queryKey: capxulKeys.accountBalance,
52
+ queryKey: accountKey(capxulKeys.accountBalance, identity),
52
53
  queryFn: async () => {
53
54
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.accounts.read).accounts.read());
54
55
  },
@@ -302,7 +303,7 @@ function useCapxulPayments(options) {
302
303
  const client = useCapxulClientOrNull();
303
304
  const identity = useCapxulIdentityOrNull();
304
305
  return useQuery({
305
- queryKey: capxulKeys.payments,
306
+ queryKey: accountKey(capxulKeys.payments, identity),
306
307
  queryFn: async () => {
307
308
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.list).payments.list());
308
309
  },
@@ -311,8 +312,9 @@ function useCapxulPayments(options) {
311
312
  }
312
313
  function useCapxulPayment(paymentId, options) {
313
314
  const client = useCapxulClientOrNull();
315
+ const identity = useCapxulIdentityOrNull();
314
316
  return useQuery({
315
- queryKey: capxulKeys.payment(paymentId),
317
+ queryKey: accountKey(capxulKeys.payment(paymentId), identity),
316
318
  queryFn: async () => {
317
319
  if (paymentId === void 0) throw Errors.invalidInput("paymentId", "required for payments.get");
318
320
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.payments.get).payments.get(paymentId));
@@ -430,7 +432,7 @@ function useCapxulActivity(params) {
430
432
  const client = useCapxulClientOrNull();
431
433
  const identity = useCapxulIdentityOrNull();
432
434
  return useQuery({
433
- queryKey: [...capxulKeys.activity, params ?? {}],
435
+ queryKey: accountKey([...capxulKeys.activity, params ?? {}], identity),
434
436
  queryFn: async () => {
435
437
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(params));
436
438
  },
@@ -441,7 +443,7 @@ function useCapxulActivityDetail(reference, actor) {
441
443
  const client = useCapxulClientOrNull();
442
444
  const identity = useCapxulIdentityOrNull();
443
445
  return useQuery({
444
- queryKey: capxulKeys.activityDetail(reference, actor),
446
+ queryKey: accountKey(capxulKeys.activityDetail(reference, actor), identity),
445
447
  queryFn: async () => {
446
448
  if (reference === void 0) throw Errors.invalidInput("reference", "required for activity.get");
447
449
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.get).activity.get(reference, actor === void 0 ? void 0 : { actor }));
@@ -466,7 +468,7 @@ function useCapxulHoldings(params) {
466
468
  const identity = useCapxulIdentityOrNull();
467
469
  const actor = params?.actor;
468
470
  return useQuery({
469
- queryKey: capxulKeys.holdings(actor),
471
+ queryKey: accountKey(capxulKeys.holdings(actor), identity),
470
472
  queryFn: async () => {
471
473
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.holdings.current).holdings.current(actor === void 0 ? void 0 : { actor }));
472
474
  },
@@ -477,8 +479,9 @@ function useCapxulHoldings(params) {
477
479
  //#region src/hooks/use-capxul-orgs.ts
478
480
  function useCapxulOrgs(options) {
479
481
  const client = useCapxulClientOrNull();
482
+ const identity = useCapxulIdentityOrNull();
480
483
  return useQuery({
481
- queryKey: capxulKeys.orgs,
484
+ queryKey: accountKey(capxulKeys.orgs, identity),
482
485
  queryFn: async () => {
483
486
  return unwrapCapxulResult(await requireBootstrappedClient(client, "orgs").orgs());
484
487
  },
@@ -517,9 +520,10 @@ function useCapxulOrgRoles(orgId, options) {
517
520
  //#region src/hooks/use-capxul-org-treasury.ts
518
521
  function useCapxulOrgTreasury(orgId, options) {
519
522
  const client = useCapxulClientOrNull();
523
+ const identity = useCapxulIdentityOrNull();
520
524
  const enabled = options?.enabled ?? true;
521
525
  return useQuery({
522
- queryKey: capxulKeys.orgTreasury(orgId),
526
+ queryKey: accountKey(capxulKeys.orgTreasury(orgId), identity),
523
527
  queryFn: async () => {
524
528
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgTreasury");
525
529
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.treasury).org(orgId).treasury());
@@ -547,9 +551,9 @@ function useCapxulInviteMember(orgId) {
547
551
  const client = useCapxulClientOrNull();
548
552
  const queryClient = useQueryClient();
549
553
  return useMutation({
550
- mutationFn: async (input) => {
554
+ mutationFn: async ({ options, ...input }) => {
551
555
  if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulInviteMember");
552
- return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.invite).org(orgId).invite(input));
556
+ return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.invite).org(orgId).invite(input, toInvocationControls(options)));
553
557
  },
554
558
  onSuccess: async () => {
555
559
  if (orgId === void 0) return;
@@ -880,7 +884,7 @@ function useCapxulUploadImage() {
880
884
  //#endregion
881
885
  //#region src/headless/contacts/use-contacts.ts
882
886
  /** One captured snapshot, or nothing — never a fabricated empty options object. */
883
- const carry = (options) => options === void 0 ? {} : { options };
887
+ const carry$1 = (options) => options === void 0 ? {} : { options };
884
888
  function useContacts(input) {
885
889
  const { actor, onAdded, onFailed } = input;
886
890
  const client = useCapxulClientOrNull();
@@ -922,7 +926,7 @@ function useContacts(input) {
922
926
  setAddError(null);
923
927
  addMutate({
924
928
  ref: refFromTypedText(value),
925
- ...carry(attempt)
929
+ ...carry$1(attempt)
926
930
  }, {
927
931
  onSuccess: (entry) => {
928
932
  setValue("");
@@ -955,17 +959,17 @@ function useContacts(input) {
955
959
  kind: "rename",
956
960
  id,
957
961
  name,
958
- ...carry(toInvocationOptions(options))
962
+ ...carry$1(toInvocationOptions(options))
959
963
  }), [writeMutate]),
960
964
  hide: useCallback((id, options) => writeMutate({
961
965
  kind: "hide",
962
966
  id,
963
- ...carry(toInvocationOptions(options))
967
+ ...carry$1(toInvocationOptions(options))
964
968
  }), [writeMutate]),
965
969
  unhide: useCallback((id, options) => writeMutate({
966
970
  kind: "unhide",
967
971
  id,
968
- ...carry(toInvocationOptions(options))
972
+ ...carry$1(toInvocationOptions(options))
969
973
  }), [writeMutate]),
970
974
  add: {
971
975
  value,
@@ -983,10 +987,11 @@ function useContacts(input) {
983
987
  * query key, so React Query issues ONE request for them.
984
988
  */
985
989
  function useContactsList(engine, options) {
990
+ const identity = useCapxulIdentityOrNull();
986
991
  const includeHidden = options.show === "all";
987
992
  const { book, refusal } = engine;
988
993
  const query = useQuery({
989
- queryKey: capxulKeys.contactsList(engine.scope, includeHidden),
994
+ queryKey: accountKey(capxulKeys.contactsList(engine.scope, includeHidden), identity),
990
995
  queryFn: async () => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.list).list({ includeHidden })),
991
996
  enabled: book !== null
992
997
  });
@@ -1175,9 +1180,10 @@ function activityDetailKey(actor, reference) {
1175
1180
  }
1176
1181
  function useActivityDetail(reference, actor) {
1177
1182
  const client = useCapxulClientOrNull();
1183
+ const identity = useCapxulIdentityOrNull();
1178
1184
  const enabled = useActivityEnabled() && reference !== void 0;
1179
1185
  const detail = useQuery({
1180
- queryKey: capxulKeys.activityDetail(reference, actor),
1186
+ queryKey: accountKey(capxulKeys.activityDetail(reference, actor), identity),
1181
1187
  queryFn: async () => {
1182
1188
  if (reference === void 0) throw Errors.invalidInput("reference", "required for activity.get");
1183
1189
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.get).activity.get(reference, actor === void 0 ? void 0 : { actor }));
@@ -1332,10 +1338,11 @@ function useUtcDay(active) {
1332
1338
  }
1333
1339
  function useActivitySummary(actor, window) {
1334
1340
  const client = useCapxulClientOrNull();
1341
+ const identity = useCapxulIdentityOrNull();
1335
1342
  const enabled = useActivityEnabled();
1336
1343
  const range = resolveWindow(window, useUtcDay(window === "last30days") * DAY_MS);
1337
1344
  const summary = useQuery({
1338
- queryKey: capxulKeys.activitySummary(actor, range),
1345
+ queryKey: accountKey(capxulKeys.activitySummary(actor, range), identity),
1339
1346
  queryFn: async () => {
1340
1347
  const params = {};
1341
1348
  if (actor !== void 0) params.actor = actor;
@@ -1345,7 +1352,7 @@ function useActivitySummary(actor, window) {
1345
1352
  enabled
1346
1353
  });
1347
1354
  const primary = useQuery({
1348
- queryKey: [...capxulKeys.holdings(actor), "primary"],
1355
+ queryKey: accountKey([...capxulKeys.holdings(actor), "primary"], identity),
1349
1356
  queryFn: async () => {
1350
1357
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.holdings.primary).holdings.primary(actor === void 0 ? void 0 : { actor }));
1351
1358
  },
@@ -1367,7 +1374,8 @@ function useActivitySummary(actor, window) {
1367
1374
  pending: null,
1368
1375
  count: summary.data?.count ?? 0,
1369
1376
  isLoading,
1370
- error: asCapxulError$1(summary.error)
1377
+ error: asCapxulError$1(summary.error),
1378
+ ...summary.data?.readWarning === void 0 ? {} : { readWarning: summary.data.readWarning }
1371
1379
  };
1372
1380
  const display = (raw) => formatMoney({
1373
1381
  currency: bucket.currency,
@@ -1382,7 +1390,8 @@ function useActivitySummary(actor, window) {
1382
1390
  pending: display(bucket.pendingIn),
1383
1391
  count: summary.data?.count ?? 0,
1384
1392
  isLoading,
1385
- error: asCapxulError$1(summary.error)
1393
+ error: asCapxulError$1(summary.error),
1394
+ ...summary.data?.readWarning === void 0 ? {} : { readWarning: summary.data.readWarning }
1386
1395
  };
1387
1396
  }
1388
1397
  //#endregion
@@ -1548,6 +1557,8 @@ function clampPageSize(pageSize) {
1548
1557
  function useActivity(input) {
1549
1558
  const { actor, pageSize } = input;
1550
1559
  const client = useCapxulClientOrNull();
1560
+ const identity = useCapxulIdentityOrNull();
1561
+ const account = actingAccount(identity);
1551
1562
  const enabled = useActivityEnabled();
1552
1563
  const limit = clampPageSize(pageSize);
1553
1564
  const warned = useRef(false);
@@ -1584,13 +1595,13 @@ function useActivity(input) {
1584
1595
  return toInvocationControls(attempt);
1585
1596
  }, []);
1586
1597
  const query = useInfiniteQuery({
1587
- queryKey: [
1598
+ queryKey: accountKey([
1588
1599
  ...capxulKeys.activity,
1589
1600
  "list",
1590
1601
  actor ?? "self",
1591
1602
  limit,
1592
1603
  filter ?? "none"
1593
- ],
1604
+ ], identity),
1594
1605
  queryFn: async ({ pageParam }) => {
1595
1606
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit), takeSelectedRetry()));
1596
1607
  },
@@ -1598,6 +1609,30 @@ function useActivity(input) {
1598
1609
  getNextPageParam: (last) => last.cursor ?? void 0,
1599
1610
  enabled
1600
1611
  });
1612
+ const queryClient = useQueryClient();
1613
+ useEffect(() => {
1614
+ if (!enabled || client === null) return;
1615
+ let stop;
1616
+ let cancelled = false;
1617
+ client.activity.subscribe(() => {
1618
+ if (cancelled) return;
1619
+ queryClient.invalidateQueries({ queryKey: capxulKeys.activity });
1620
+ }, actor === void 0 ? void 0 : { actor }).then((result) => {
1621
+ if (!result.ok) return;
1622
+ if (cancelled) result.value();
1623
+ else stop = result.value;
1624
+ });
1625
+ return () => {
1626
+ cancelled = true;
1627
+ stop?.();
1628
+ };
1629
+ }, [
1630
+ account,
1631
+ actor,
1632
+ client,
1633
+ enabled,
1634
+ queryClient
1635
+ ]);
1601
1636
  const pages = query.data?.pages;
1602
1637
  const rows = useMemo(() => {
1603
1638
  return (pages?.flatMap((page) => page.items) ?? []).map((item) => toActivityRow(item, actor)).filter((row) => matchesSearch(row, searchText));
@@ -1646,16 +1681,19 @@ function useActivity(input) {
1646
1681
  try {
1647
1682
  const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list);
1648
1683
  const items = [];
1684
+ let readWarning;
1649
1685
  let cursor;
1650
1686
  for (let page = 0; page < EXPORT_PAGE_CEILING; page += 1) {
1651
1687
  const result = unwrapCapxulResult(await bootstrapped.activity.list(listParams(cursor, EXPORT_PAGE_SIZE), controls));
1688
+ readWarning ??= result.readWarning;
1652
1689
  items.push(...result.items);
1653
1690
  cursor = result.cursor ?? void 0;
1654
1691
  if (cursor === void 0) break;
1655
1692
  }
1656
1693
  return {
1657
1694
  ...buildCsv(items, actor, searchText),
1658
- truncated: cursor !== void 0
1695
+ truncated: cursor !== void 0,
1696
+ ...readWarning === void 0 ? {} : { readWarning }
1659
1697
  };
1660
1698
  } finally {
1661
1699
  setIsExporting(false);
@@ -1674,7 +1712,16 @@ function useActivity(input) {
1674
1712
  const retry = useCallback((options) => {
1675
1713
  selectedRetry.current = toInvocationOptions(options);
1676
1714
  refetch();
1677
- }, [refetch]);
1715
+ queryClient.invalidateQueries({
1716
+ queryKey: capxulKeys.activitySummary(actor).slice(0, -1),
1717
+ predicate: (cached) => cached.queryKey.at(-1) === accountKey([], identity)[0]
1718
+ });
1719
+ }, [
1720
+ actor,
1721
+ identity,
1722
+ queryClient,
1723
+ refetch
1724
+ ]);
1678
1725
  return {
1679
1726
  actor,
1680
1727
  filters: {
@@ -1700,7 +1747,8 @@ function useActivity(input) {
1700
1747
  isLoading: query.isLoading,
1701
1748
  error: asCapxulError$1(query.error),
1702
1749
  retry,
1703
- observedAt: pages === void 0 ? null : pages[pages.length - 1]?.observedAt ?? null
1750
+ observedAt: pages === void 0 ? null : pages[pages.length - 1]?.observedAt ?? null,
1751
+ ...pages?.some((page) => page.readWarning === "indexer-unavailable") ? { readWarning: "indexer-unavailable" } : {}
1704
1752
  },
1705
1753
  loadMore: {
1706
1754
  hasMore: hasNextPage,
@@ -1762,11 +1810,12 @@ function DetailInstance({ actor, reference, children }) {
1762
1810
  }
1763
1811
  function Detail({ reference, children }) {
1764
1812
  const { actor } = useActivityContext();
1813
+ const identity = useCapxulIdentityOrNull();
1765
1814
  return /* @__PURE__ */ jsx(DetailInstance, {
1766
1815
  actor,
1767
1816
  reference,
1768
1817
  children
1769
- }, activityDetailKey(actor, reference));
1818
+ }, JSON.stringify(accountKey([activityDetailKey(actor, reference)], identity)));
1770
1819
  }
1771
1820
  function Export({ children }) {
1772
1821
  return /* @__PURE__ */ jsx(Fragment, { children: children(useActivityContext().csv) });
@@ -1789,7 +1838,7 @@ function useOrgMeReading(orgId) {
1789
1838
  const ready = client !== null && identity !== null && isClaimed$1(identity);
1790
1839
  const mayStillOpen = client === null || identity === null || isRestoring$1(identity);
1791
1840
  const query = useQuery({
1792
- queryKey: capxulKeys.orgMe(orgId),
1841
+ queryKey: capxulKeys.orgMe(orgId, actingAccount(identity)),
1793
1842
  queryFn: async () => {
1794
1843
  return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.org.me).org(orgId).me());
1795
1844
  },
@@ -2293,6 +2342,16 @@ function decidePhase(input) {
2293
2342
  if (input.orgLaneSettled && input.destination !== null) return "redirect";
2294
2343
  return "checking";
2295
2344
  }
2345
+ /**
2346
+ * Which probe produced the surfaced error — the SAME precedence `error` itself
2347
+ * is chosen by, written once so the code and its source can never disagree.
2348
+ */
2349
+ function probeOf(session, membership, lifecycle) {
2350
+ if (session !== null) return "session";
2351
+ if (membership !== null) return "membership";
2352
+ if (lifecycle !== null) return "lifecycle";
2353
+ return null;
2354
+ }
2296
2355
  /** The engine — all the logic. NOT exported from the package barrel. */
2297
2356
  function useDashboardAccess(scope) {
2298
2357
  const client = useCapxulClientOrNull();
@@ -2329,6 +2388,7 @@ function useDashboardAccess(scope) {
2329
2388
  lifecycle.refetch
2330
2389
  ]);
2331
2390
  const error = sessionError ?? membershipError ?? lifecycleError;
2391
+ const probe = probeOf(sessionError, membershipError, lifecycleError);
2332
2392
  const phase = decidePhase({
2333
2393
  error,
2334
2394
  settled: client !== null && identity !== null && !isRestoring$1(identity) && membershipsSettled && lifecycleSettled,
@@ -2339,11 +2399,13 @@ function useDashboardAccess(scope) {
2339
2399
  return useMemo(() => ({
2340
2400
  phase,
2341
2401
  error,
2402
+ probe,
2342
2403
  destination,
2343
2404
  retry
2344
2405
  }), [
2345
2406
  phase,
2346
2407
  error,
2408
+ probe,
2347
2409
  destination,
2348
2410
  retry
2349
2411
  ]);
@@ -2388,12 +2450,19 @@ function Checking({ children }) {
2388
2450
  }
2389
2451
  function DashboardError({ children }) {
2390
2452
  const state = usePart("error");
2391
- if (state === null || state.error === null) return null;
2453
+ if (state === null || state.error === null || state.probe === null) return null;
2392
2454
  return /* @__PURE__ */ jsx(Fragment, { children: children({
2393
2455
  error: state.error,
2456
+ probe: state.probe,
2394
2457
  retry: state.retry
2395
2458
  }) });
2396
2459
  }
2460
+ /**
2461
+ * Hands the destination and draws nothing. Reaching this part is a REQUEST to
2462
+ * navigate, never an arrival: the app may cancel or supersede it, so nothing
2463
+ * here — and nothing a consumer hangs off it — may claim a completed redirect
2464
+ * (#1963 R05-1). The destination page's own normalized pageview proves arrival.
2465
+ */
2397
2466
  function Redirect({ children }) {
2398
2467
  const state = usePart("redirect");
2399
2468
  if (state === null || state.destination === null) return null;
@@ -2470,8 +2539,9 @@ function toRecipientOption(entry) {
2470
2539
  */
2471
2540
  function useOrgRoster(orgId) {
2472
2541
  const client = useCapxulClientOrNull();
2542
+ const identity = useCapxulIdentityOrNull();
2473
2543
  const query = useQuery({
2474
- queryKey: capxulKeys.contactsList(orgId ?? "pending", false),
2544
+ queryKey: accountKey(capxulKeys.contactsList(orgId ?? "pending", false), identity),
2475
2545
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.addressBook.list, orgId).addressBook.list({ includeHidden: false })),
2476
2546
  enabled: client !== null && orgId !== void 0
2477
2547
  });
@@ -2492,16 +2562,18 @@ function useOrgRoster(orgId) {
2492
2562
  }
2493
2563
  function usePayrollGroups(orgId) {
2494
2564
  const client = useCapxulClientOrNull();
2565
+ const identity = useCapxulIdentityOrNull();
2495
2566
  return useQuery({
2496
- queryKey: capxulKeys.payrollGroups(orgId),
2567
+ queryKey: accountKey(capxulKeys.payrollGroups(orgId), identity),
2497
2568
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.groups.list, orgId).payroll.groups.list()),
2498
2569
  enabled: client !== null && orgId !== void 0
2499
2570
  });
2500
2571
  }
2501
2572
  function usePayrollRuns(orgId) {
2502
2573
  const client = useCapxulClientOrNull();
2574
+ const identity = useCapxulIdentityOrNull();
2503
2575
  return useQuery({
2504
- queryKey: capxulKeys.payrollRuns(orgId),
2576
+ queryKey: accountKey(capxulKeys.payrollRuns(orgId), identity),
2505
2577
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.runs, orgId).payroll.runs()),
2506
2578
  enabled: client !== null && orgId !== void 0
2507
2579
  });
@@ -2516,29 +2588,34 @@ function usePayrollRuns(orgId) {
2516
2588
  */
2517
2589
  function useOrgTerms(orgId) {
2518
2590
  const client = useCapxulClientOrNull();
2591
+ const identity = useCapxulIdentityOrNull();
2519
2592
  return useQuery({
2520
- queryKey: capxulKeys.payrollTerms(orgId),
2593
+ queryKey: accountKey(capxulKeys.payrollTerms(orgId), identity),
2521
2594
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.terms, orgId).payroll.terms()),
2522
2595
  enabled: client !== null && orgId !== void 0
2523
2596
  });
2524
2597
  }
2525
2598
  function useOrgTreasury(orgId) {
2526
2599
  const client = useCapxulClientOrNull();
2600
+ const identity = useCapxulIdentityOrNull();
2527
2601
  return useQuery({
2528
- queryKey: capxulKeys.orgTreasury(orgId),
2602
+ queryKey: accountKey(capxulKeys.orgTreasury(orgId), identity),
2529
2603
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.treasury, orgId).treasury()),
2530
2604
  enabled: client !== null && orgId !== void 0
2531
2605
  });
2532
2606
  }
2533
2607
  /**
2534
2608
  * The caller's own standing, read for its Budgets alone (ruling Q2 grades
2535
- * them). Keyed as `CapxulOrgMember` keys it, so a payroll screen inside a
2536
- * `.Can` wrapper reads `org(id).me()` once.
2609
+ * them). Keyed as `CapxulOrgMember` keys it — Organization AND acting account
2610
+ * (#2007 R19) — so a payroll screen inside a `.Can` wrapper still reads
2611
+ * `org(id).me()` once, and an account replacement is a miss for both of them
2612
+ * rather than the previous person's Budgets for both.
2537
2613
  */
2538
2614
  function useOrgMe(orgId) {
2539
2615
  const client = useCapxulClientOrNull();
2616
+ const identity = useCapxulIdentityOrNull();
2540
2617
  return useQuery({
2541
- queryKey: capxulKeys.orgMe(orgId),
2618
+ queryKey: capxulKeys.orgMe(orgId, actingAccount(identity)),
2542
2619
  queryFn: async () => unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.me, orgId).me()),
2543
2620
  enabled: client !== null && orgId !== void 0
2544
2621
  });
@@ -2557,6 +2634,14 @@ function scopedClient(client, method, orgId) {
2557
2634
  //#region src/headless/payroll/use-payroll.ts
2558
2635
  /** Money reads the same way everywhere on this screen: amount then code. */
2559
2636
  const GRAMMAR$1 = { grammar: "code" };
2637
+ /**
2638
+ * One captured snapshot, or nothing — never a fabricated empty options object,
2639
+ * and never a DOM event a screen wired straight to `onClick`.
2640
+ */
2641
+ function carry(options) {
2642
+ const attempt = toInvocationOptions(options);
2643
+ return attempt === void 0 ? {} : { options: attempt };
2644
+ }
2560
2645
  function toPayrollGroupRow(group) {
2561
2646
  const currency = new Set(group.members.map((member) => member.currency)).size === 1 ? group.members[0]?.currency : void 0;
2562
2647
  return {
@@ -2596,16 +2681,17 @@ function usePayroll(orgId) {
2596
2681
  const write = useMutation({
2597
2682
  mutationFn: async (command) => {
2598
2683
  const payroll = scopedClient(client, CAPXUL_OPERATIONS.org.payroll.groups[command.kind], orgId).payroll;
2684
+ const controls = toInvocationControls(command.options);
2599
2685
  if (command.kind === "remove") {
2600
- unwrapCapxulResult(await payroll.groups.remove(command.id));
2686
+ unwrapCapxulResult(await payroll.groups.remove(command.id, controls));
2601
2687
  return null;
2602
2688
  }
2603
- return unwrapCapxulResult(await payroll.groups.save(command.input));
2689
+ return unwrapCapxulResult(await payroll.groups.save(command.input, controls));
2604
2690
  },
2605
2691
  onSettled: invalidate
2606
2692
  });
2607
2693
  const mutateAsync = write.mutateAsync;
2608
- const save = useCallback(async (input) => {
2694
+ const save = useCallback(async (input, options) => {
2609
2695
  const refusal = invalidGroup(input);
2610
2696
  if (refusal !== null) return {
2611
2697
  ok: false,
@@ -2614,7 +2700,8 @@ function usePayroll(orgId) {
2614
2700
  try {
2615
2701
  const saved = await mutateAsync({
2616
2702
  kind: "save",
2617
- input
2703
+ input,
2704
+ ...carry(options)
2618
2705
  });
2619
2706
  return saved === null ? {
2620
2707
  ok: false,
@@ -2630,11 +2717,12 @@ function usePayroll(orgId) {
2630
2717
  };
2631
2718
  }
2632
2719
  }, [mutateAsync]);
2633
- const remove = useCallback(async (id) => {
2720
+ const remove = useCallback(async (id, options) => {
2634
2721
  try {
2635
2722
  await mutateAsync({
2636
2723
  kind: "remove",
2637
- id
2724
+ id,
2725
+ ...carry(options)
2638
2726
  });
2639
2727
  return {
2640
2728
  ok: true,
@@ -3152,11 +3240,12 @@ function usePayrollRun(input) {
3152
3240
  amountsParse: total !== null
3153
3241
  });
3154
3242
  const authorize = useMutation({
3155
- mutationFn: async (candidate) => {
3243
+ mutationFn: async ({ candidate, options }) => {
3156
3244
  if (candidate.scope !== currentScope.current) throw Errors.notAuthenticated();
3157
3245
  return executeRunDraft(candidate, async (persisted, onRequestKey, onResolved) => {
3158
3246
  if (candidate.scope === currentScope.current) setDraft(persisted);
3159
3247
  return unwrapCapxulResult(await scopedClient(client, CAPXUL_OPERATIONS.org.payroll.authorizeRun, orgId).payroll.authorizeRun(persisted.input, {
3248
+ ...toInvocationControls(options),
3160
3249
  onResolved,
3161
3250
  onRequestKey: (key) => {
3162
3251
  if (candidate.scope !== currentScope.current) throw Errors.notAuthenticated();
@@ -3165,14 +3254,15 @@ function usePayrollRun(input) {
3165
3254
  }));
3166
3255
  });
3167
3256
  },
3168
- onSettled: (_run, _error, candidate) => {
3257
+ onSettled: (_run, _error, { candidate }) => {
3169
3258
  queryClient.invalidateQueries({ queryKey: capxulKeys.payrollRuns(orgId) });
3170
3259
  if (candidate.scope === currentScope.current) restoreDraft(candidate.scope);
3171
3260
  }
3172
3261
  });
3173
3262
  const totalDisplay = total === null ? null : formatMoney(total, GRAMMAR);
3174
3263
  const authorizeMutate = authorize.mutate;
3175
- const submit = useCallback(() => {
3264
+ const submit = useCallback((options) => {
3265
+ const attempt = toInvocationOptions(options);
3176
3266
  const permissionId = budgets[0]?.id;
3177
3267
  if (blockedReason !== null || submitGate.current || draftBlocked || draftScope === null || assetMoney === null || selectedAsset === null) return;
3178
3268
  if (permissionId === void 0 || totalDisplay === null || parsedAmounts === null) return;
@@ -3214,7 +3304,10 @@ function usePayrollRun(input) {
3214
3304
  }
3215
3305
  };
3216
3306
  submitGate.current = true;
3217
- authorizeMutate(candidate, {
3307
+ authorizeMutate({
3308
+ candidate,
3309
+ ...attempt === void 0 ? {} : { options: attempt }
3310
+ }, {
3218
3311
  onSuccess: (run) => {
3219
3312
  if (candidate.scope === currentScope.current) onRun({
3220
3313
  id: run.id,
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DaT-AGx6.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DXmEHrnw.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.9",
3
+ "version": "4.20.0-beta.1",
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.9"
29
+ "@capxul/sdk": "4.20.0-beta.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -43,8 +43,8 @@
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/types": "0.3.0",
47
46
  "@capxul/errors": "0.3.0",
47
+ "@capxul/types": "0.3.0",
48
48
  "@capxul/typescript-config": "0.0.0"
49
49
  },
50
50
  "peerDependencies": {
@@ -1,11 +0,0 @@
1
- {
2
- "source": {
3
- "commit": "1c96a26356e8f36402e47eb4ac60bb89d6aeed7f",
4
- "tree": "375f49f76377eeec331fd44ce17238d4a6f02ad4",
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.9"
11
- }