@capxul/sdk-react 4.2.0-rc.4 → 4.2.0-rc.6

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.
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "source": {
3
- "commit": "400e4b861e8c10091ad2d9e71fc0502fe222a801",
4
- "tree": "c3afb8bb5f3ce69ee8aa1e8fbe811fe213627887",
3
+ "commit": "8e8ae6c3c56c5d5260c469cf8e4e7bbe172a098f",
4
+ "tree": "6fcb3062a577d0af2b426b2e50ef92c0d9027701",
5
5
  "branch": "codex/programme-rc",
6
6
  "repository": "https://github.com/Xelmar-tech/infrastructure",
7
7
  "lockfileSha256": "5870f53b72706d103220c1bcf733cb4fb71196aea32a9cfbdc277d73cc959264"
8
8
  },
9
9
  "name": "@capxul/sdk-react",
10
- "version": "4.2.0-rc.4"
10
+ "version": "4.2.0-rc.6"
11
11
  }
@@ -519,13 +519,6 @@ function createAuth(client, clearAuthenticatedQueries) {
519
519
  const event = state.phase === "authenticated" && state.account.at === "claimed" ? { _tag: "RetryOrganization" } : { _tag: "RetryAccount" };
520
520
  const result = await runtime.send(event, invocation);
521
521
  return failure(result) ?? { ok: true };
522
- }),
523
- resumeSubmittedOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
524
- const prepared = await prepareOrganization(submission, invocation);
525
- return prepared.ok ? { ok: true } : {
526
- ok: false,
527
- reason: prepared.reason
528
- };
529
522
  })
530
523
  };
531
524
  }
@@ -576,12 +569,10 @@ function CapxulIdentityProvider({ client, children }) {
576
569
  await queryClient.cancelQueries({ queryKey: capxulKeys.root });
577
570
  await queryClient.resetQueries({ queryKey: capxulKeys.root });
578
571
  };
579
- const auth = createAuth(client, clearAuthenticatedQueries);
580
572
  return {
581
573
  runtime,
582
574
  send,
583
- auth,
584
- resumeSubmittedOrganization: auth.resumeSubmittedOrganization,
575
+ auth: createAuth(client, clearAuthenticatedQueries),
585
576
  addTransitionListener
586
577
  };
587
578
  }, [
@@ -619,9 +610,6 @@ function useCapxulSend() {
619
610
  function useCapxulAuth() {
620
611
  return useIdentityContext().auth;
621
612
  }
622
- function useResumeSubmittedOrganization() {
623
- return useIdentityContext().resumeSubmittedOrganization;
624
- }
625
613
  function useCapxulDestination() {
626
614
  const state = useCapxulIdentity();
627
615
  const next = resolveIdentityDestination(state);
@@ -832,29 +820,24 @@ function CapxulAuthenticationController({ slots }) {
832
820
  function ready(destination) {
833
821
  return destination?.to === "dashboardPersonal" || destination?.to === "dashboardOrganization";
834
822
  }
823
+ /**
824
+ * The pre-attach window: a claimed identity holding no Organization while the
825
+ * SDK asks the backend whether one is pending. The controller reports progress
826
+ * only when no form step is left to render. An app that still holds an
827
+ * Organization profile and has not submitted through this mount is entering
828
+ * the form, not resuming it — a member who starts an Organization from the
829
+ * dashboard is claimed with a complete Profile before they ever see the form,
830
+ * so reporting progress on the claim alone would hide the form for good.
831
+ */
832
+ const ATTACHING = {
833
+ at: "loading",
834
+ orgId: null
835
+ };
835
836
  function CapxulOnboardingController(props) {
836
837
  const state = useCapxulIdentity();
837
838
  const destination = useCapxulDestination();
838
839
  const auth = useCapxulAuth();
839
- const resumeSubmittedOrganization = useResumeSubmittedOrganization();
840
- const resumedSubmission = useRef(null);
841
- const [failedRecovery, setFailedRecovery] = useState(null);
842
- const submission = props.submittedOrganization;
843
- const accountAt = state.phase === "authenticated" ? state.account.at : null;
844
- useEffect(() => {
845
- if (props.intent !== "organization" || submission === null || props.recoveryOptions === void 0 || accountAt !== "unknown" && accountAt !== "counterfactual" || resumedSubmission.current === submission) return;
846
- resumedSubmission.current = submission;
847
- setFailedRecovery(null);
848
- resumeSubmittedOrganization(submission, props.recoveryOptions()).then((result) => {
849
- if (!result.ok) setFailedRecovery(submission);
850
- });
851
- }, [
852
- accountAt,
853
- props.intent,
854
- props.recoveryOptions,
855
- resumeSubmittedOrganization,
856
- submission
857
- ]);
840
+ const submitted = useRef(false);
858
841
  if (state.phase !== "authenticated") return null;
859
842
  const { slots, navigation } = props;
860
843
  if (props.intent === null) return slots.intent({
@@ -868,37 +851,35 @@ function CapxulOnboardingController(props) {
868
851
  completePersonal: auth.completePersonal,
869
852
  cancel: navigation.profileCancel
870
853
  });
871
- if (props.intent === "organization" && props.organizationProfile === null && submission === null) return slots.profile({
872
- intent: "organization",
873
- state,
874
- continueOrganization: props.onOrganizationProfile,
875
- cancel: navigation.profileCancel
876
- });
877
- if (props.intent === "organization" && props.organizationProfile !== null && submission === null) return organizationForm(props, state, auth, null);
878
- if (submission !== null && failedRecovery === submission && state.account.at !== "claimed") return organizationForm(props, state, auth, submission);
879
- if (submission !== null && state.account.at !== "claimed") {
880
- if (state.account.at === "failed") {
881
- const retry = state.account.retryable ? (options) => auth.createOrganization(submission, options) : void 0;
882
- return slots.accountFailure({
883
- state,
884
- account: state.account,
885
- ...retry === void 0 ? {} : { retry }
886
- });
887
- }
854
+ if (props.intent === "organization" && submitted.current && state.account.at !== "claimed") {
855
+ if (state.account.at === "failed") return slots.accountFailure({
856
+ state,
857
+ account: state.account,
858
+ ...state.account.retryable ? { retry: auth.retry } : {}
859
+ });
888
860
  return slots.accountProgress({
889
861
  state,
890
862
  account: state.account
891
863
  });
892
864
  }
893
- if (submission !== null && state.account.at === "claimed") {
865
+ if (props.intent === "organization" && !state.profileComplete) return props.organizationProfile === null ? slots.profile({
866
+ intent: "organization",
867
+ state,
868
+ continueOrganization: props.onOrganizationProfile,
869
+ cancel: navigation.profileCancel
870
+ }) : organizationForm(props, state, auth, submitted);
871
+ if (props.intent === "organization" && state.account.at === "claimed") {
894
872
  const org = state.account.org;
895
- if (org === null) return organizationForm(props, state, auth, submission);
873
+ if (org === null) return props.organizationProfile === null || submitted.current ? slots.organizationProgress({
874
+ state,
875
+ org: ATTACHING
876
+ }) : organizationForm(props, state, auth, submitted);
896
877
  if (org.at === "failed") {
897
- const retry = org.retryable ? org.orgId === null ? (options) => auth.createOrganization(submission, options) : auth.retry : void 0;
878
+ const retryable = org.retryable && org.orgId !== null;
898
879
  return slots.organizationFailure({
899
880
  state,
900
881
  org,
901
- ...retry === void 0 ? {} : { retry }
882
+ ...retryable ? { retry: auth.retry } : {}
902
883
  });
903
884
  }
904
885
  if (org.at !== "ready") return slots.organizationProgress({
@@ -921,26 +902,20 @@ function CapxulOnboardingController(props) {
921
902
  }) : null;
922
903
  }
923
904
  function organizationForm(props, state, auth, submitted) {
924
- const profileDetails = submitted?.profileDetails ?? props.organizationProfile;
905
+ const profileDetails = props.organizationProfile;
925
906
  if (profileDetails === null) return null;
926
907
  return props.slots.organization({
927
908
  state,
928
909
  profileDetails,
929
- submitted,
930
- pinnedHandle: submitted?.organization.handle ?? null,
931
910
  submit: (organization, options) => {
932
- if (submitted !== null) return auth.createOrganization(submitted, options);
933
- const normalized = normalizeOrganization(organization);
934
- if (normalized === null) return auth.createOrganization({
911
+ submitted.current = true;
912
+ return auth.createOrganization({
935
913
  profileDetails,
936
914
  organization
937
- }, options);
938
- const next = {
939
- profileDetails,
940
- organization: normalized
941
- };
942
- props.onSubmittedOrganization(next);
943
- return auth.createOrganization(next, options);
915
+ }, options).then((result) => {
916
+ if (!result.ok) submitted.current = false;
917
+ return result;
918
+ });
944
919
  },
945
920
  back: () => {
946
921
  props.onOrganizationProfile(null);
@@ -106,11 +106,23 @@ type AccountProgress = Exclude<Readiness, {
106
106
  type AccountFailure = Extract<Readiness, {
107
107
  at: "failed";
108
108
  }>;
109
+ /**
110
+ * The Organization lane while it still owes an answer. `loading` widens the
111
+ * lane's `orgId` to `string | null`: after a reload the SDK asks the backend
112
+ * whether a setup is pending, and until that read lands the claimed identity
113
+ * holds no Organization id at all. The identity model keeps its own `loading`
114
+ * id non-null — only this slot type carries the pre-attach window.
115
+ */
109
116
  type OrgProgress = Exclude<OrgLane, {
110
117
  at: "failed";
111
118
  } | {
112
119
  at: "ready";
113
- }>;
120
+ } | {
121
+ at: "loading";
122
+ }> | {
123
+ readonly at: "loading";
124
+ readonly orgId: string | null;
125
+ };
114
126
  type OrgFailure = Extract<OrgLane, {
115
127
  at: "failed";
116
128
  }>;
@@ -157,11 +169,8 @@ type ProfileSlotProps = {
157
169
  interface OnboardingControllerProps {
158
170
  readonly intent: "personal" | "organization" | null;
159
171
  readonly organizationProfile: ProfileDetails | null;
160
- readonly submittedOrganization: CreateOrganizationSubmission | null;
161
- readonly recoveryOptions?: () => InvocationOptions;
162
172
  readonly onIntent: (intent: "personal" | "organization") => void;
163
173
  readonly onOrganizationProfile: (profile: ProfileDetails | null) => void;
164
- readonly onSubmittedOrganization: (submission: CreateOrganizationSubmission | null) => void;
165
174
  readonly navigation: {
166
175
  readonly selectorBack: NavigationAction;
167
176
  readonly profileCancel: NavigationAction;
@@ -178,8 +187,6 @@ interface OnboardingControllerProps {
178
187
  readonly organization: Slot<{
179
188
  state: AuthenticatedState;
180
189
  profileDetails: ProfileDetails;
181
- submitted: CreateOrganizationSubmission | null;
182
- pinnedHandle: string | null;
183
190
  submit: (organization: OrganizationDetails, options: InvocationOptions) => ReturnType<CapxulAuth["createOrganization"]>;
184
191
  back: NavigationAction;
185
192
  cancel: NavigationAction;
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-BWmKRFy6.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-COGAAS-c.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";
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 { 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-BzB9gZ6P.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";
@@ -1,4 +1,4 @@
1
- import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-BWmKRFy6.mjs";
1
+ import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-COGAAS-c.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-DaT-AGx6.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-BzB9gZ6P.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.4",
3
+ "version": "4.2.0-rc.6",
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.4"
29
+ "@capxul/sdk": "4.2.0-rc.6"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -43,9 +43,9 @@
43
43
  "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
44
44
  "vite-plus": "0.3.0",
45
45
  "vitest": "4.1.11",
46
- "@capxul/typescript-config": "0.0.0",
46
+ "@capxul/errors": "0.3.0",
47
47
  "@capxul/types": "0.3.0",
48
- "@capxul/errors": "0.3.0"
48
+ "@capxul/typescript-config": "0.0.0"
49
49
  },
50
50
  "peerDependencies": {
51
51
  "@tanstack/react-query": "^5.66.9",