@capxul/sdk-react 4.20.0-beta.23 → 4.20.0-beta.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import { ReactNode } from "react";
2
- import { CapxulClient, CapxulError, CapxulErrorCode, IdentityDestination, IdentityEvent, IdentityProfileDetails, IdentityState, IdentityTransition, OrgLane, Readiness, StateLabel } from "@capxul/sdk";
3
- //#region src/identity.d.ts
2
+ import { CapxulClient, CapxulError, CapxulErrorCode, IdentityDestination, IdentityEvent, IdentityProfileDetails, IdentityState, IdentityTransition, OrgLane, Readiness } from "@capxul/sdk";
3
+ //#region src/platform/identity-contract.d.ts
4
4
  type Destination = IdentityDestination;
5
5
  interface InvocationOptions {
6
6
  readonly correlationId?: string;
@@ -36,9 +36,11 @@ interface CreateOrganizationSubmission {
36
36
  readonly profileDetails: ProfileDetails;
37
37
  readonly organization: OrganizationDetails;
38
38
  }
39
+ /** A refused facade call: its code, and the whole error when one was raised. */
39
40
  type FacadeFailure = {
40
41
  readonly ok: false;
41
42
  readonly reason: CapxulErrorCode;
43
+ readonly error?: CapxulError;
42
44
  };
43
45
  type CreateOrganizationFailure = FacadeFailure & {
44
46
  readonly error: CapxulError;
@@ -65,14 +67,8 @@ interface CapxulAuth {
65
67
  readonly retry: (options?: InvocationOptions) => Promise<EmptyResult>;
66
68
  }
67
69
  type TransitionListener = (record: IdentityTransition, state: IdentityState) => void;
68
- declare function useCapxulIdentity(): IdentityState;
69
- declare function useCapxulSend(): CapxulSend;
70
- declare function useCapxulAuth(): CapxulAuth;
71
- declare function useCapxulDestination(): Destination | null;
72
- declare function useCapxulTransitions(listener: TransitionListener): void;
73
- declare const entered: (record: IdentityTransition, target: StateLabel) => boolean;
74
70
  //#endregion
75
- //#region src/controllers.d.ts
71
+ //#region src/access/controllers.d.ts
76
72
  type Slot<P> = (props: P) => ReactNode;
77
73
  type ActionResult = {
78
74
  readonly ok: true;
@@ -148,6 +144,8 @@ type ProfileSlotProps = {
148
144
  readonly continueOrganization: (profile: ProfileDetails) => void;
149
145
  readonly cancel: NavigationAction;
150
146
  };
147
+ //#endregion
148
+ //#region src/access/onboarding-controller.d.ts
151
149
  interface OnboardingControllerProps {
152
150
  readonly intent: "personal" | "organization" | null;
153
151
  readonly organizationProfile: ProfileDetails | null;
@@ -202,6 +200,6 @@ interface OnboardingControllerProps {
202
200
  }>;
203
201
  };
204
202
  }
205
- declare function CapxulOnboardingController(props: OnboardingControllerProps): ReactNode;
203
+ declare function CapxulOnboardingController(props: OnboardingControllerProps): import("react").ReactNode;
206
204
  //#endregion
207
- export { entered as A, CreateOrganizationFailure as C, OrganizationDetails as D, InvocationOptions as E, useCapxulTransitions as F, useCapxulDestination as M, useCapxulIdentity as N, ProfileDetails as O, useCapxulSend as P, CapxulSend as S, Destination as T, ReadyDestination as _, AuthenticationSlots as a, Slot as b, ControllerAction as c, OnboardingControllerProps as d, OrgFailure as f, ProfileSlotProps as g, PendingAuthState as h, AuthenticatedState as i, useCapxulAuth as j, SendResult as k, FaultedState as l, OtpPendingState as m, AccountProgress as n, CapxulAuthenticationController as o, OrgProgress as p, ActionResult as r, CapxulOnboardingController as s, AccountFailure as t, NavigationAction as u, RetryAction as v, CreateOrganizationSubmission as w, CapxulAuth as x, SignedOutState as y };
205
+ export { TransitionListener as A, CreateOrganizationFailure as C, OrganizationDetails as D, InvocationOptions as E, ProfileDetails as O, CapxulSend as S, Destination as T, ReadyDestination as _, ActionResult as a, Slot as b, CapxulAuthenticationController as c, NavigationAction as d, OrgFailure as f, ProfileSlotProps as g, PendingAuthState as h, AccountProgress as i, SendResult as k, ControllerAction as l, OtpPendingState as m, OnboardingControllerProps as n, AuthenticatedState as o, OrgProgress as p, AccountFailure as r, AuthenticationSlots as s, CapxulOnboardingController as t, FaultedState as u, RetryAction as v, CreateOrganizationSubmission as w, CapxulAuth as x, SignedOutState as y };
@@ -1,8 +1,8 @@
1
1
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
2
2
  import { QueryClient, QueryClientProvider, useQueryClient } from "@tanstack/react-query";
3
- import { CapxulError, createCapxulClient, isCapxulError, resolveIdentityDestination, toCountryCode, toHandle } from "@capxul/sdk";
3
+ import { CapxulError, createCapxulClient, isCapxulError, resolveIdentityDestination, toCountryCode, toHandle, toOrgId } from "@capxul/sdk";
4
4
  import { jsx } from "react/jsx-runtime";
5
- //#region src/internal/capxul-bootstrap-context.tsx
5
+ //#region src/platform/bootstrap-context.tsx
6
6
  const CapxulBootstrapContext = createContext(null);
7
7
  function CapxulBootstrapProvider({ value, children }) {
8
8
  return /* @__PURE__ */ jsx(CapxulBootstrapContext.Provider, {
@@ -16,7 +16,7 @@ function useCapxul() {
16
16
  return state;
17
17
  }
18
18
  //#endregion
19
- //#region src/internal/capxul-client-context.tsx
19
+ //#region src/platform/client-context.tsx
20
20
  const MISSING_CAPXUL_CLIENT_PROVIDER = Symbol("MISSING_CAPXUL_CLIENT_PROVIDER");
21
21
  const CapxulClientContext = createContext(MISSING_CAPXUL_CLIENT_PROVIDER);
22
22
  function CapxulClientProvider({ client, children }) {
@@ -36,7 +36,14 @@ function useCapxulClientOrNull() {
36
36
  return client;
37
37
  }
38
38
  //#endregion
39
- //#region src/internal/reactivity-keys.ts
39
+ //#region src/platform/query-keys.ts
40
+ /**
41
+ * An Organization id a consumer passed as a plain string (often a URL
42
+ * parameter), as a key segment. An absent or empty id names no Organization.
43
+ */
44
+ function orgKeySegment(orgId) {
45
+ return orgId === void 0 || orgId === "" ? void 0 : toOrgId(orgId);
46
+ }
40
47
  /**
41
48
  * The account a read is answered FOR, as a key segment (#2007 R19).
42
49
  *
@@ -144,7 +151,7 @@ const capxulKeys = {
144
151
  "terms"
145
152
  ],
146
153
  activity: ["capxul", "activity"],
147
- activityDetail: (reference, actor = void 0) => [
154
+ activityDetail: (reference, actor) => [
148
155
  "capxul",
149
156
  "activity",
150
157
  actor ?? "self",
@@ -170,7 +177,7 @@ const capxulKeys = {
170
177
  ]
171
178
  };
172
179
  //#endregion
173
- //#region src/internal/invocation-controls.ts
180
+ //#region src/platform/invocation-controls.ts
174
181
  /**
175
182
  * Keep only the five public option fields, and only when they hold the right
176
183
  * kind of value. A named action verb takes its attempt as an optional FIRST
@@ -209,71 +216,23 @@ function toInvocationControls(options) {
209
216
  };
210
217
  }
211
218
  //#endregion
212
- //#region src/identity.tsx
213
- const MISSING_IDENTITY_PROVIDER = Symbol("MISSING_IDENTITY_PROVIDER");
214
- const IdentityContext = createContext(MISSING_IDENTITY_PROVIDER);
219
+ //#region src/platform/identity-lanes.ts
215
220
  const failure = (result) => result.ok ? null : {
216
221
  ok: false,
217
222
  reason: result.refused
218
223
  };
219
- async function guarded(runtime, verb, options, run) {
220
- const invocation = toInvocationControls(options);
221
- try {
222
- return await (runtime.runFacade?.(verb, invocation, run) ?? run(invocation));
223
- } catch {
224
- return {
225
- ok: false,
226
- reason: "UNKNOWN"
227
- };
228
- }
229
- }
230
- function organizationFailure(reason, state) {
231
- const stateFailure = state.phase === "faulted" ? state.failure : state.phase === "authenticated" && state.account.at === "failed" ? state.account.failure : state.phase === "authenticated" && state.account.at === "claimed" ? state.account.org?.failure : void 0;
232
- if (stateFailure?.code === reason) return {
233
- ok: false,
234
- reason,
235
- error: stateFailure.error ?? new CapxulError(stateFailure.code === "WORK_DIED" ? "UNKNOWN" : stateFailure.code, stateFailure.message, {
236
- ...stateFailure.mode === void 0 ? {} : { details: { failure_mode: stateFailure.mode } },
237
- layer: "identity"
238
- })
239
- };
240
- return {
241
- ok: false,
242
- reason,
243
- error: new CapxulError(reason === "WORK_DIED" ? "UNKNOWN" : reason, reason === "INVALID_INPUT" ? "Organization details are invalid." : "Organization creation failed.", { layer: "identity" })
244
- };
245
- }
246
- function normalizeOrganization(organization) {
247
- const name = typeof organization.name === "string" ? organization.name.trim() : "";
248
- const handle = typeof organization.handle === "string" ? organization.handle.trim().toLowerCase() : "";
249
- if (name.length === 0) return null;
250
- if (organization.bio !== void 0 && typeof organization.bio !== "string") return null;
251
- if (organization.size !== void 0 && typeof organization.size !== "string") return null;
252
- if (organization.logoStorageId !== void 0 && (typeof organization.logoStorageId !== "string" || organization.logoStorageId.length === 0)) return null;
253
- try {
254
- return {
255
- name,
256
- handle: toHandle(handle),
257
- country: toCountryCode(organization.country),
258
- ...organization.bio === void 0 ? {} : { bio: organization.bio },
259
- ...organization.size === void 0 ? {} : { size: organization.size },
260
- ...organization.logoStorageId === void 0 ? {} : { logoStorageId: organization.logoStorageId }
261
- };
262
- } catch {
263
- return null;
264
- }
265
- }
266
- /** The Organization id when its lane is already running or finished, else null. */
267
- const runningOrganization = (state) => {
268
- if (state.phase !== "authenticated" || state.account.at !== "claimed") return null;
269
- return state.account.org?.orgId ?? null;
270
- };
271
224
  /** A superseded session read waits at most this long for the winning read. */
272
225
  const SESSION_SETTLE_LIMIT_MS = 3e4;
273
226
  const accountInFlight = (state) => state.phase === "authenticated" && (state.account.at === "deriving" || state.account.at === "claiming");
274
- function createAuth(client, clearAuthenticatedQueries) {
275
- const runtime = client._internal.identity;
276
- const settledSession = (invocation) => new Promise((resolve) => {
227
+ /**
228
+ * The session slot keeps the latest ReadSession only: a second reader
229
+ * interrupts the first and the machine refuses the first with SUPERSEDED.
230
+ * Two onboarding callers read at once after a reload (the controller's
231
+ * resume and the recovery submit), so the loser must wait for the winner's
232
+ * read to land and then continue on the shared state, not fail.
233
+ */
234
+ function settledSession(runtime, invocation) {
235
+ return new Promise((resolve) => {
277
236
  let done = false;
278
237
  let stop = null;
279
238
  let timer = null;
@@ -309,20 +268,29 @@ function createAuth(client, clearAuthenticatedQueries) {
309
268
  stop = unsubscribe;
310
269
  timer = setTimeout(() => finish({
311
270
  ok: false,
312
- reason: "UNKNOWN"
271
+ reason: "UNKNOWN",
272
+ error: new CapxulError("UNKNOWN", "The session did not settle in time.", {
273
+ mode: "timeout",
274
+ layer: "identity",
275
+ details: { limitMs: SESSION_SETTLE_LIMIT_MS }
276
+ })
313
277
  }), SESSION_SETTLE_LIMIT_MS);
314
278
  });
315
- const read = async (invocation) => {
316
- const result = await runtime.send({ _tag: "ReadSession" }, invocation);
317
- const refused = failure(result);
318
- if (refused === null) return { ok: true };
319
- return refused.reason === "SUPERSEDED" ? settledSession(invocation) : refused;
320
- };
321
- const ensureAccount = async (invocation) => {
322
- const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
323
- return failure(result) ?? { ok: true };
324
- };
325
- const settledAccount = (invocation) => new Promise((resolve) => {
279
+ }
280
+ /** Read the session; a superseded read waits for the winning one. */
281
+ async function readSession(runtime, invocation) {
282
+ const result = await runtime.send({ _tag: "ReadSession" }, invocation);
283
+ const refused = failure(result);
284
+ if (refused === null) return { ok: true };
285
+ return refused.reason === "SUPERSEDED" ? settledSession(runtime, invocation) : refused;
286
+ }
287
+ /**
288
+ * The account lane accepts no account event while a derivation or claim is
289
+ * landing. A person who submits the Organization before their own Safe claim
290
+ * settles must wait for it, not be refused with WRONG_STATE.
291
+ */
292
+ function settledAccount(runtime, invocation) {
293
+ return new Promise((resolve) => {
326
294
  let done = false;
327
295
  let stop = null;
328
296
  const onAbort = () => finish({
@@ -351,44 +319,110 @@ function createAuth(client, clearAuthenticatedQueries) {
351
319
  stop = unsubscribe;
352
320
  if (!accountInFlight(runtime.snapshot())) finish({ ok: true });
353
321
  });
354
- const reachClaimed = async (invocation) => {
355
- let state = runtime.snapshot();
356
- if (accountInFlight(state)) {
357
- const settled = await settledAccount(invocation);
358
- if (!settled.ok) return settled;
359
- state = runtime.snapshot();
360
- }
361
- if (state.phase !== "authenticated" || state.account.at === "unknown") {
362
- const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
363
- const refused = failure(result);
364
- if (refused !== null) return refused;
365
- state = result.state;
366
- }
322
+ }
323
+ /** Drive the person's own Account to claimed, waiting out a landing derivation or claim. */
324
+ async function reachClaimed(runtime, invocation) {
325
+ let state = runtime.snapshot();
326
+ if (accountInFlight(state)) {
327
+ const settled = await settledAccount(runtime, invocation);
328
+ if (!settled.ok) return settled;
329
+ state = runtime.snapshot();
330
+ }
331
+ if (state.phase !== "authenticated" || state.account.at === "unknown") {
332
+ const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
333
+ const refused = failure(result);
334
+ if (refused !== null) return refused;
335
+ state = result.state;
336
+ }
337
+ if (state.phase !== "authenticated") return {
338
+ ok: false,
339
+ reason: "WRONG_STATE"
340
+ };
341
+ if (state.account.at === "claimed") return { ok: true };
342
+ if (accountInFlight(state)) {
343
+ const settled = await settledAccount(runtime, invocation);
344
+ if (!settled.ok) return settled;
345
+ state = runtime.snapshot();
367
346
  if (state.phase !== "authenticated") return {
368
347
  ok: false,
369
348
  reason: "WRONG_STATE"
370
349
  };
371
350
  if (state.account.at === "claimed") return { ok: true };
372
- if (accountInFlight(state)) {
373
- const settled = await settledAccount(invocation);
374
- if (!settled.ok) return settled;
375
- state = runtime.snapshot();
376
- if (state.phase !== "authenticated") return {
377
- ok: false,
378
- reason: "WRONG_STATE"
379
- };
380
- if (state.account.at === "claimed") return { ok: true };
381
- }
382
- const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
383
- const result = await runtime.send(event, invocation);
384
- const refused = failure(result);
385
- if (refused !== null) return refused;
386
- const next = result.state;
387
- return next.phase === "authenticated" && next.account.at === "claimed" ? { ok: true } : {
351
+ }
352
+ const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
353
+ const result = await runtime.send(event, invocation);
354
+ const refused = failure(result);
355
+ if (refused !== null) return refused;
356
+ const next = result.state;
357
+ return next.phase === "authenticated" && next.account.at === "claimed" ? { ok: true } : {
358
+ ok: false,
359
+ reason: "WRONG_STATE"
360
+ };
361
+ }
362
+ //#endregion
363
+ //#region src/platform/organization-submission.ts
364
+ function organizationFailure(reason, state) {
365
+ const stateFailure = state.phase === "faulted" ? state.failure : state.phase === "authenticated" && state.account.at === "failed" ? state.account.failure : state.phase === "authenticated" && state.account.at === "claimed" ? state.account.org?.failure : void 0;
366
+ if (stateFailure?.code === reason) return {
367
+ ok: false,
368
+ reason,
369
+ error: stateFailure.error ?? new CapxulError(stateFailure.code === "WORK_DIED" ? "UNKNOWN" : stateFailure.code, stateFailure.message, {
370
+ ...stateFailure.mode === void 0 ? {} : { details: { failure_mode: stateFailure.mode } },
371
+ layer: "identity"
372
+ })
373
+ };
374
+ return {
375
+ ok: false,
376
+ reason,
377
+ error: new CapxulError(reason === "WORK_DIED" ? "UNKNOWN" : reason, reason === "INVALID_INPUT" ? "Organization details are invalid." : "Organization creation failed.", { layer: "identity" })
378
+ };
379
+ }
380
+ function normalizeOrganization(organization) {
381
+ const name = typeof organization.name === "string" ? organization.name.trim() : "";
382
+ const handle = typeof organization.handle === "string" ? organization.handle.trim().toLowerCase() : "";
383
+ if (name.length === 0) return null;
384
+ if (organization.bio !== void 0 && typeof organization.bio !== "string") return null;
385
+ if (organization.size !== void 0 && typeof organization.size !== "string") return null;
386
+ if (organization.logoStorageId !== void 0 && (typeof organization.logoStorageId !== "string" || organization.logoStorageId.length === 0)) return null;
387
+ try {
388
+ return {
389
+ name,
390
+ handle: toHandle(handle),
391
+ country: toCountryCode(organization.country),
392
+ ...organization.bio === void 0 ? {} : { bio: organization.bio },
393
+ ...organization.size === void 0 ? {} : { size: organization.size },
394
+ ...organization.logoStorageId === void 0 ? {} : { logoStorageId: organization.logoStorageId }
395
+ };
396
+ } catch {
397
+ return null;
398
+ }
399
+ }
400
+ /** The Organization id when its lane is already running or finished, else null. */
401
+ const runningOrganization = (state) => {
402
+ if (state.phase !== "authenticated" || state.account.at !== "claimed") return null;
403
+ return state.account.org?.orgId ?? null;
404
+ };
405
+ //#endregion
406
+ //#region src/platform/identity-auth.ts
407
+ async function guarded(runtime, verb, options, run) {
408
+ const invocation = toInvocationControls(options);
409
+ try {
410
+ return await (runtime.runFacade?.(verb, invocation, run) ?? run(invocation));
411
+ } catch (cause) {
412
+ const error = isCapxulError(cause) ? cause : new CapxulError("UNKNOWN", "The identity request failed unexpectedly.", {
413
+ cause,
414
+ layer: "identity"
415
+ });
416
+ return {
388
417
  ok: false,
389
- reason: "WRONG_STATE"
418
+ reason: error.code,
419
+ error
390
420
  };
391
- };
421
+ }
422
+ }
423
+ /** The auth verbs behind `useCapxulAuth`, each run as one guarded facade call. */
424
+ function createAuth(client, clearAuthenticatedQueries) {
425
+ const runtime = client._internal.identity;
392
426
  const completeProfile = async (profile, invocation) => {
393
427
  const result = await runtime.completeProfile(profile, invocation);
394
428
  return result.ok ? { ok: true } : result;
@@ -399,14 +433,14 @@ function createAuth(client, clearAuthenticatedQueries) {
399
433
  ok: false,
400
434
  reason: "INVALID_INPUT"
401
435
  };
402
- const refreshed = await read(invocation);
436
+ const refreshed = await readSession(runtime, invocation);
403
437
  if (!refreshed.ok) return refreshed;
404
438
  const current = runtime.snapshot();
405
439
  if (current.phase !== "authenticated" || !current.profileComplete) {
406
440
  const completed = await runtime.completeProfile(submission.profileDetails, invocation);
407
441
  if (!completed.ok) return completed;
408
442
  }
409
- const claimed = await reachClaimed(invocation);
443
+ const claimed = await reachClaimed(runtime, invocation);
410
444
  return claimed.ok ? {
411
445
  ok: true,
412
446
  organization
@@ -476,9 +510,9 @@ function createAuth(client, clearAuthenticatedQueries) {
476
510
  ok: false,
477
511
  reason: completed.reason
478
512
  };
479
- const refreshed = await read(invocation);
513
+ const refreshed = await readSession(runtime, invocation);
480
514
  if (!refreshed.ok) return refreshed;
481
- return ensureAccount(invocation);
515
+ return failure(await runtime.send({ _tag: "EnsureAccount" }, invocation)) ?? { ok: true };
482
516
  }),
483
517
  createOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
484
518
  const current = runtime.snapshot();
@@ -526,7 +560,7 @@ function createAuth(client, clearAuthenticatedQueries) {
526
560
  const state = runtime.snapshot();
527
561
  const orgId = runningOrganization(state);
528
562
  if (orgId !== null) {
529
- const scoped = client.org(orgId);
563
+ const scoped = client.org(toOrgId(orgId));
530
564
  const current = await scoped.setup.get(invocation);
531
565
  if (!current.ok) return {
532
566
  ok: false,
@@ -550,6 +584,10 @@ function createAuth(client, clearAuthenticatedQueries) {
550
584
  })
551
585
  };
552
586
  }
587
+ //#endregion
588
+ //#region src/platform/identity.tsx
589
+ const MISSING_IDENTITY_PROVIDER = Symbol("MISSING_IDENTITY_PROVIDER");
590
+ const IdentityContext = createContext(MISSING_IDENTITY_PROVIDER);
553
591
  function CapxulIdentityProvider({ client, children }) {
554
592
  const queryClient = useQueryClient();
555
593
  const runtime = client?._internal.identity ?? null;
@@ -667,7 +705,7 @@ function useCapxulTransitions(listener) {
667
705
  }
668
706
  const entered = (record, target) => record.outcome === "applied" && record.from !== target && record.to === target;
669
707
  //#endregion
670
- //#region src/provider.tsx
708
+ //#region src/platform/provider.tsx
671
709
  /**
672
710
  * Transient failure codes worth a retry — network blips, rate limits, and
673
711
  * upstream provider/unknown hiccups that a later attempt may clear. Everything
@@ -819,7 +857,80 @@ function CapxulProvider(props) {
819
857
  });
820
858
  }
821
859
  //#endregion
822
- //#region src/controllers.tsx
860
+ //#region ../protocol/src/errors/failure-modes.ts
861
+ /**
862
+ * Why an operation failed — the one flat vocabulary. The first four are the
863
+ * auth/provider diagnoses that predate this file. The rest name the chain
864
+ * path. `FailureMode` is derived from this list so a runtime membership check
865
+ * (the SDK's `$exception` projection, the observability schema) and the type
866
+ * can never drift apart.
867
+ */
868
+ const FAILURE_MODES = [
869
+ "auth-origin-mismatch",
870
+ "stale-openfort-cache",
871
+ "app-env-allowlist",
872
+ "no-secure-context",
873
+ "signer-not-ready",
874
+ "rate-limited",
875
+ "timeout",
876
+ "upstream-down",
877
+ "revert",
878
+ "insufficient-balance",
879
+ "insufficient-allowance",
880
+ "rejected",
881
+ "unauthorized",
882
+ "forbidden",
883
+ "bad-request",
884
+ "method-unsupported",
885
+ "unknown"
886
+ ];
887
+ function isFailureMode(value) {
888
+ return typeof value === "string" && FAILURE_MODES.includes(value);
889
+ }
890
+ //#endregion
891
+ //#region ../protocol/src/errors/model.ts
892
+ /**
893
+ * `Code` narrows to the literal a factory passes, so `Errors.invalidInput(...)`
894
+ * is a `CapxulError<"INVALID_INPUT">`. An operation's error channel is then the
895
+ * union of the codes it can actually produce.
896
+ */
897
+ var CapxulError$1 = class extends Error {
898
+ code;
899
+ details;
900
+ correlationId;
901
+ layer;
902
+ /** The one-word cause (`FailureMode`). `chain.mode` when a chain cause is set. */
903
+ mode;
904
+ /** The structured chain-path cause. Never rewritten by a later layer. */
905
+ chain;
906
+ constructor(code, message, options = {}) {
907
+ super(message, "cause" in options ? { cause: options.cause } : void 0);
908
+ this.name = "CapxulError";
909
+ this.code = code;
910
+ if (options.details !== void 0) this.details = options.details;
911
+ if (options.correlationId !== void 0) this.correlationId = options.correlationId;
912
+ if (options.layer !== void 0) this.layer = options.layer;
913
+ const legacy = options.details?.failure_mode;
914
+ const mode = options.chain?.mode ?? (isFailureMode(options.mode) ? options.mode : void 0) ?? (isFailureMode(legacy) ? legacy : void 0);
915
+ if (mode !== void 0) this.mode = mode;
916
+ if (options.chain !== void 0) this.chain = options.chain;
917
+ }
918
+ };
919
+ //#endregion
920
+ //#region ../protocol/src/primitives/absurd.ts
921
+ /**
922
+ * The default branch of an exhaustive switch: `default: return absurd(value)`.
923
+ * The compiler proves it unreachable; if a value the types rule out arrives at
924
+ * run time anyway, it fails as a named defect instead of falling through.
925
+ */
926
+ function absurd(value) {
927
+ throw new CapxulError$1("UNKNOWN", "An exhaustive switch received a value its type rules out.", { details: {
928
+ defect: "unreachable_case",
929
+ value: String(value)
930
+ } });
931
+ }
932
+ //#endregion
933
+ //#region src/access/controllers.tsx
823
934
  const action = async (send, event) => {
824
935
  const result = await send(event);
825
936
  return result.ok ? { ok: true } : {
@@ -858,11 +969,14 @@ function CapxulAuthenticationController({ slots }) {
858
969
  state,
859
970
  destination
860
971
  });
972
+ default: return absurd(state);
861
973
  }
862
974
  }
863
975
  function ready(destination) {
864
976
  return destination?.to === "dashboardPersonal" || destination?.to === "dashboardOrganization";
865
977
  }
978
+ //#endregion
979
+ //#region src/access/onboarding-controller.tsx
866
980
  function CapxulOnboardingController(props) {
867
981
  const state = useCapxulIdentity();
868
982
  const destination = useCapxulDestination();
@@ -981,4 +1095,4 @@ function organizationForm(props, state, auth, submitted) {
981
1095
  });
982
1096
  }
983
1097
  //#endregion
984
- 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 };
1098
+ export { orgKeySegment as _, entered as a, useCapxulIdentity as c, useCapxulTransitions as d, toInvocationControls as f, capxulKeys as g, actingAccount as h, CapxulProvider as i, useCapxulIdentityOrNull as l, accountKey as m, CapxulAuthenticationController as n, useCapxulAuth as o, toInvocationOptions as p, absurd as r, useCapxulDestination as s, CapxulOnboardingController as t, useCapxulSend as u, useCapxulClientOrNull as v, useCapxul as y };
@@ -1,12 +1,12 @@
1
- import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-BMAU2kKH.mjs";
1
+ import { n as OnboardingControllerProps, s as AuthenticationSlots } from "../onboarding-controller-DrJiYWfY.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";
5
5
  //#region src/testing/index.d.ts
6
- interface CreateCapxulReactTestHarnessOptions extends CreateCapxulTestClientOptions {
6
+ export interface CreateCapxulReactTestHarnessOptions extends CreateCapxulTestClientOptions {
7
7
  readonly testing?: CapxulTestClient;
8
8
  }
9
- interface CapxulReactTestHarness {
9
+ export interface CapxulReactTestHarness {
10
10
  readonly testing: CapxulTestClient;
11
11
  readonly client: CapxulTestClient["client"];
12
12
  readonly provider: (children: ReactNode) => React.JSX.Element;
@@ -14,6 +14,6 @@ interface CapxulReactTestHarness {
14
14
  readonly onboarding: (props: OnboardingControllerProps) => React.JSX.Element;
15
15
  }
16
16
  /** Build renderer-neutral React test elements over the real SDK testing client. */
17
- declare function createCapxulReactTestHarness(options?: CreateCapxulReactTestHarnessOptions): CapxulReactTestHarness;
17
+ export declare function createCapxulReactTestHarness(options?: CreateCapxulReactTestHarnessOptions): CapxulReactTestHarness;
18
18
  //#endregion
19
- export { CapxulReactTestHarness, type CapxulTestClient, type CapxulTestClock, type CapxulTestObservation, CreateCapxulReactTestHarnessOptions, type CreateCapxulTestClientOptions, type SeedTestIdentityInput, createCapxulReactTestHarness, createCapxulTestClient };
19
+ export { type CapxulTestClient, type CapxulTestClock, type CapxulTestObservation, type CreateCapxulTestClientOptions, type SeedTestIdentityInput, createCapxulTestClient };
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-BV3e8WD3.mjs";
1
+ import { i as CapxulProvider, n as CapxulAuthenticationController, t as CapxulOnboardingController } from "../onboarding-controller-ZlvveARR.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.20.0-beta.23",
3
+ "version": "4.20.0-beta.26",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
@@ -12,6 +12,36 @@
12
12
  "README.md"
13
13
  ],
14
14
  "type": "module",
15
+ "imports": {
16
+ "#access": "./src/access/index.ts",
17
+ "#access/client-connection": "./src/access/client-connection.tsx",
18
+ "#access/controllers": "./src/access/controllers.tsx",
19
+ "#access/dashboard-access": "./src/access/dashboard-access.tsx",
20
+ "#access/onboarding-controller": "./src/access/onboarding-controller.tsx",
21
+ "#accounts": "./src/accounts/index.ts",
22
+ "#activity": "./src/activity/index.ts",
23
+ "#activity/activity": "./src/activity/activity.tsx",
24
+ "#media": "./src/media/index.ts",
25
+ "#organizations": "./src/organizations/index.ts",
26
+ "#organizations/org-member": "./src/organizations/org-member.tsx",
27
+ "#package.json": "./package.json",
28
+ "#parties": "./src/parties/index.ts",
29
+ "#parties/contacts": "./src/parties/contacts.tsx",
30
+ "#payments": "./src/payments/index.ts",
31
+ "#payments/send-money": "./src/payments/send-money.tsx",
32
+ "#payroll": "./src/payroll/index.ts",
33
+ "#payroll/payroll": "./src/payroll/payroll.tsx",
34
+ "#payroll/payroll-run": "./src/payroll/payroll-run.tsx",
35
+ "#permissions": "./src/permissions/index.ts",
36
+ "#platform/bootstrap-context": "./src/platform/bootstrap-context.tsx",
37
+ "#platform/client-context": "./src/platform/client-context.tsx",
38
+ "#platform/identity": "./src/platform/identity.tsx",
39
+ "#platform/provider": "./src/platform/provider.tsx",
40
+ "#platform/tests/render-hook-with-capxul": "./src/platform/tests/render-hook-with-capxul.tsx",
41
+ "#profiles": "./src/profiles/index.ts",
42
+ "#testing": "./src/testing/index.tsx",
43
+ "#*": "./src/*.ts"
44
+ },
15
45
  "exports": {
16
46
  ".": {
17
47
  "types": "./dist/index.d.mts",
@@ -26,26 +56,26 @@
26
56
  "access": "public"
27
57
  },
28
58
  "dependencies": {
29
- "@capxul/sdk": "4.20.0-beta.23"
59
+ "@capxul/sdk": "4.20.0-beta.26"
30
60
  },
31
61
  "devDependencies": {
32
62
  "@tanstack/react-query": "^5.66.9",
33
63
  "@testing-library/react": "^16.3.2",
64
+ "@total-typescript/shoehorn": "0.1.2",
34
65
  "@types/jsdom": "^28.0.3",
35
66
  "@types/react": "^19.2.15",
36
67
  "@typescript/native": "npm:typescript@7.0.2",
37
- "@vitest/coverage-v8": "4.1.11",
68
+ "@vitest/coverage-v8": "5.0.1",
38
69
  "ink": "^7.0.3",
39
70
  "ink-testing-library": "^4.0.0",
40
71
  "jsdom": "^29.1.1",
41
72
  "react": "^19.2.6",
42
73
  "react-dom": "^19.2.6",
43
- "vite": "npm:@voidzero-dev/vite-plus-core@0.3.0",
44
- "vite-plus": "0.3.0",
45
- "vitest": "4.1.11",
46
- "@capxul/config": "0.4.0-beta.1",
47
- "@capxul/errors": "0.3.0",
48
- "@capxul/types": "0.3.0",
74
+ "typescript": "npm:@typescript/typescript6@6.0.2",
75
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.0.0",
76
+ "vite-plus": "1.0.0",
77
+ "vitest": "5.0.1",
78
+ "@capxul/protocol": "0.2.0-beta.0",
49
79
  "@capxul/typescript-config": "0.0.0"
50
80
  },
51
81
  "peerDependencies": {
@@ -57,7 +87,7 @@
57
87
  },
58
88
  "scripts": {
59
89
  "check-types": "vp exec ../../node_modules/@typescript/native/bin/tsc -p tsconfig.json --noEmit",
60
- "lint": "vp lint -c ../../.oxlintrc.json . --deny-warnings",
90
+ "lint": "vp lint -c ../../.oxlintrc.json .",
61
91
  "build": "vp pack",
62
92
  "_vp-tasks-allowed": "vp-allowed: `test` + `test:coverage` are vp tasks in vite.config.ts so vitest self-writes don't bust cache (#205)."
63
93
  }