@usearete/react 0.24.0 → 0.25.0

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
@@ -10,7 +10,7 @@ Built on top of [`@usearete/sdk`](https://www.npmjs.com/package/@usearete/sdk),
10
10
  npm install @usearete/react @usearete/sdk zod
11
11
  ```
12
12
 
13
- `@usearete/react` installs `zustand` as a normal dependency, so do not install it separately. React remains an application dependency. Generated consumers install the core SDK and Zod because generated stack files import their types and schemas directly.
13
+ `@usearete/react` installs `zustand` as a normal dependency, so do not install it separately. React and `@usearete/sdk` are peer dependencies: the application owns exactly one copy of the core SDK, on the same release as `@usearete/react`, so error and outcome checks see one set of classes. Generated consumers install the core SDK and Zod because generated stack files import their types and schemas directly.
14
14
 
15
15
  ### Hooks linting
16
16
 
@@ -126,7 +126,7 @@ Supported props:
126
126
  - `auth`
127
127
  - `fetch`
128
128
  - `validateFrames` — set `false` to suppress rejected-frame warnings; generated schemas still normalize and validate entities
129
- - `onFrameValidationError` — structured callback for generated-schema rejections
129
+ - `onFrameValidationError` — structured callback for frames that were not stored: schema rejections (`reason: 'schema'`) and patches for keys the client holds no entity for (`reason: 'unknown-key'`)
130
130
  - `reconnectIntervals`
131
131
  - `maxReconnectAttempts`
132
132
  - `maxEntriesPerView`
@@ -357,7 +357,7 @@ deploy.submit(args, { reconcile: { timeoutMs: 10_000 } });
357
357
  deploy.submit(args, { reconcile: async (context) => { /* ... */ } });
358
358
  ```
359
359
 
360
- The mutation `phase` field is the discriminated status to branch on for busy labels (`'preparing'`, `'awaiting-wallet'`, `'submitted'`, `'confirmed'`, `'reconciling'`, `'reconciled'`, plus the failure outcomes); `status` remains `'pending'` until the mutation settles. Generated operation hooks publish each completed receipt and signature during `submitted`, before the final operation receipt resolves. `onConfirmed` runs immediately after chain confirmation; `onSuccess` runs only after successful reconciliation (or immediately when reconciliation is disabled/skipped). Reconciliation failure, including a refreshed snapshot timeout, is exposed through `reconciliationError`, does not call `onSuccess`, and does not reject the confirmed `submit()` result. The confirmed transaction remains landed. `retryReconciliation()` repeats only post-confirmation watermark/refresh work using the saved receipts and targets; it never rebuilds, signs, or submits. Convenience booleans (`isPreparing`, `isAwaitingWallet`, `isReconciling`, `canRetryReconciliation`) remain available.
360
+ The mutation `phase` field is the discriminated status to branch on. Its values are exactly `'idle'`, `'preparing'`, `'awaiting-wallet'`, `'submitted'`, `'confirmed'`, `'reconciling'`, `'reconciled'`, `'confirmed-unreconciled'`, `'not-submitted'`, `'submitted-unknown'` and `'chain-failed'`. There is no `'submitting'` or `'confirming'` phase: `'awaiting-wallet'` covers signing, sending and confirming, because the wallet adapter does all three in one call. `status` remains `'pending'` until the mutation settles. Generated operation hooks publish each completed receipt and signature during `submitted`, before the final operation receipt resolves. `onConfirmed` runs immediately after chain confirmation; `onSuccess` runs only after successful reconciliation (or immediately when reconciliation is disabled/skipped). Reconciliation failure, including a refreshed snapshot timeout, is exposed through `reconciliationError`, does not call `onSuccess`, and does not reject the confirmed `submit()` result. The confirmed transaction remains landed. `retryReconciliation()` repeats only post-confirmation watermark/refresh work using the saved receipts and targets; it never rebuilds, signs, or submits. Convenience booleans (`isPreparing`, `isAwaitingWallet`, `isReconciling`, `canRetryReconciliation`) remain available.
361
361
 
362
362
  ## Migration notes (0.3 → next)
363
363
 
@@ -380,6 +380,22 @@ The mutation `phase` field is the discriminated status to branch on for busy lab
380
380
  - Stack reads expose imperative calls and hooks together under `arete.read.<name>`; `arete.reads` remains a deprecated alias.
381
381
  - Repeated `useArete` calls now share a provider-managed client when stack and option identities match; remove component-local connection ownership workarounds.
382
382
 
383
+ ## Testing
384
+
385
+ `@usearete/react/testing` re-exports every `@usearete/sdk/testing` helper and adds:
386
+
387
+ - `createAreteTestConfig(harness, props?)` — `<AreteProvider>` props that connect every client to a `createWebSocketHarness()` server, with no reconnects or batching delay.
388
+ - `createMutationResultFixture(phase, overrides?)` — a complete, consistent `useMutation()` result for any of the `MUTATION_PHASES`, for rendering phase-specific UI without a wallet.
389
+
390
+ ```tsx
391
+ import { createAreteTestConfig, createWebSocketHarness } from '@usearete/react/testing';
392
+
393
+ const ws = createWebSocketHarness();
394
+ render(<AreteProvider {...createAreteTestConfig(ws)}><Dashboard /></AreteProvider>);
395
+ const subscription = await ws.waitForSubscription('OreRound/latest'); // flush renders between polls
396
+ ws.serve(subscription, [{ key: '1', data: round }]);
397
+ ```
398
+
383
399
  ## Low-Level Hooks
384
400
 
385
401
  The React SDK also exports:
package/dist/index.d.ts CHANGED
@@ -56,7 +56,11 @@ interface AreteConfig {
56
56
  flushIntervalMs?: number;
57
57
  fetch?: ConnectOptions['fetch'];
58
58
  validateFrames?: boolean;
59
- /** Receives structured details when a generated schema rejects a frame. */
59
+ /**
60
+ * Receives structured details when a frame is not stored: a generated schema
61
+ * rejected it (`reason: 'schema'`), or it was a patch for a key the client
62
+ * holds no entity for (`reason: 'unknown-key'`).
63
+ */
60
64
  onFrameValidationError?: ConnectOptions['onFrameValidationError'];
61
65
  /** Authentication configuration */
62
66
  auth?: AuthConfig;
@@ -0,0 +1,165 @@
1
+ 'use strict';
2
+
3
+ var testing = require('@usearete/sdk/testing');
4
+
5
+ /** Every value `useMutation().phase` can take, in lifecycle order. */
6
+ const MUTATION_PHASES = [
7
+ 'idle',
8
+ 'preparing',
9
+ 'awaiting-wallet',
10
+ 'submitted',
11
+ 'confirmed',
12
+ 'reconciling',
13
+ 'reconciled',
14
+ 'confirmed-unreconciled',
15
+ 'not-submitted',
16
+ 'submitted-unknown',
17
+ 'chain-failed',
18
+ ];
19
+ const LANDED_PHASES = new Set([
20
+ 'submitted',
21
+ 'confirmed',
22
+ 'reconciling',
23
+ 'reconciled',
24
+ 'confirmed-unreconciled',
25
+ ]);
26
+ function failureFor(phase) {
27
+ const outcomes = testing.createTransactionOutcomeFixtures();
28
+ switch (phase) {
29
+ case 'not-submitted':
30
+ return outcomes['not-submitted:wallet'];
31
+ case 'submitted-unknown':
32
+ return outcomes['submitted-unknown:send'];
33
+ case 'chain-failed':
34
+ return outcomes['chain-failed:chain'];
35
+ default:
36
+ return null;
37
+ }
38
+ }
39
+ function statusFor(phase) {
40
+ if (phase === 'idle')
41
+ return 'idle';
42
+ if (phase === 'reconciled' || phase === 'confirmed-unreconciled')
43
+ return 'success';
44
+ if (failureFor(phase))
45
+ return 'error';
46
+ return 'pending';
47
+ }
48
+ function displayErrorFor(failure) {
49
+ if (!failure)
50
+ return null;
51
+ if (failure.status === 'chain-failed' && failure.programError) {
52
+ return `${failure.programError.name}: ${failure.programError.message}`;
53
+ }
54
+ return failure.cause instanceof Error ? failure.cause.message : 'Transaction failed';
55
+ }
56
+ /**
57
+ * A complete, internally consistent `useMutation()` result for one phase, as
58
+ * the hook reports it: status, receipts, signatures, outcome, failure, display
59
+ * error and the derived `is*` flags all agree. Use it to render and test UI
60
+ * for every phase without a wallet or a chain. `overrides` replace any field.
61
+ *
62
+ * `submit`/`mutateAsync` resolve with the fixture result on landed phases and
63
+ * reject with the phase's failure otherwise; `mutate`, `reset` and
64
+ * `retryReconciliation` do nothing.
65
+ */
66
+ function createMutationResultFixture(phase, overrides = {}) {
67
+ const failure = failureFor(phase);
68
+ const landed = LANDED_PHASES.has(phase);
69
+ const receipt = {
70
+ transactionIndex: 0,
71
+ transactionName: 'fixture',
72
+ signature: testing.FIXTURE_SIGNATURE,
73
+ slot: testing.FIXTURE_SLOT,
74
+ };
75
+ const completedReceipts = landed ? [receipt] : [];
76
+ const signatures = landed || (failure && 'signature' in failure && failure.signature)
77
+ ? [testing.FIXTURE_SIGNATURE]
78
+ : [];
79
+ const outcome = failure
80
+ ?? (landed && phase !== 'submitted'
81
+ ? { status: 'confirmed', phase: 'confirmation', signature: testing.FIXTURE_SIGNATURE, slot: testing.FIXTURE_SLOT }
82
+ : null);
83
+ const result = (landed && phase !== 'submitted'
84
+ ? { signature: testing.FIXTURE_SIGNATURE, slot: testing.FIXTURE_SLOT, transaction: receipt }
85
+ : undefined);
86
+ const displayError = displayErrorFor(failure);
87
+ const reconciliationError = phase === 'confirmed-unreconciled'
88
+ ? new Error('Fixture: the stream did not reach the confirmed slot in time')
89
+ : null;
90
+ const status = statusFor(phase);
91
+ const settle = async () => {
92
+ if (failure)
93
+ throw testing.transactionFailureError(failure);
94
+ return result;
95
+ };
96
+ return {
97
+ mutate: () => undefined,
98
+ mutateAsync: settle,
99
+ submit: settle,
100
+ status,
101
+ phase,
102
+ latestEvent: phase === 'idle'
103
+ ? null
104
+ : {
105
+ phase,
106
+ prepared: null,
107
+ ...(result !== undefined ? { result } : {}),
108
+ ...(failure ? { failure } : {}),
109
+ },
110
+ error: displayError,
111
+ displayError,
112
+ failure,
113
+ outcome,
114
+ prepared: null,
115
+ data: result,
116
+ result,
117
+ signatures,
118
+ signature: signatures.length === 1 ? signatures[0] : null,
119
+ completedReceipts,
120
+ callbackError: null,
121
+ callbackErrors: [],
122
+ reconciliationError,
123
+ isLoading: status === 'pending',
124
+ isConfirmed: outcome?.status === 'confirmed',
125
+ isSubmittedUnknown: failure?.status === 'submitted-unknown',
126
+ isPreparing: phase === 'preparing',
127
+ isAwaitingWallet: phase === 'awaiting-wallet',
128
+ isReconciling: phase === 'reconciling',
129
+ canRetryReconciliation: phase === 'confirmed-unreconciled',
130
+ retryReconciliation: async () => undefined,
131
+ reset: () => undefined,
132
+ ...overrides,
133
+ };
134
+ }
135
+ /**
136
+ * `<AreteProvider>` props that connect every client to a
137
+ * {@link WebSocketHarness} instead of the network: no reconnects, no
138
+ * batching delay, so frames a test sends are visible on the next render.
139
+ *
140
+ * ```tsx
141
+ * const ws = createWebSocketHarness();
142
+ * render(<AreteProvider {...createAreteTestConfig(ws, { wallet })}><App /></AreteProvider>);
143
+ * const subscription = await ws.waitForSubscription('OreRound/latest');
144
+ * ws.serve(subscription, [{ key: '1', data: round }]);
145
+ * ```
146
+ */
147
+ function createAreteTestConfig(harness, overrides = {}) {
148
+ return {
149
+ autoReconnect: false,
150
+ flushIntervalMs: 0,
151
+ ...overrides,
152
+ auth: { ...overrides.auth, websocketFactory: harness.websocketFactory },
153
+ };
154
+ }
155
+
156
+ exports.MUTATION_PHASES = MUTATION_PHASES;
157
+ exports.createAreteTestConfig = createAreteTestConfig;
158
+ exports.createMutationResultFixture = createMutationResultFixture;
159
+ Object.keys(testing).forEach(function (k) {
160
+ if (k !== 'default' && !Object.prototype.hasOwnProperty.call(exports, k)) Object.defineProperty(exports, k, {
161
+ enumerable: true,
162
+ get: function () { return testing[k]; }
163
+ });
164
+ });
165
+ //# sourceMappingURL=testing.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.cjs","sources":["../src/testing.ts"],"sourcesContent":[null],"names":["createTransactionOutcomeFixtures","FIXTURE_SIGNATURE","FIXTURE_SLOT","transactionFailureError"],"mappings":"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"}
@@ -0,0 +1,198 @@
1
+ import { PreparedOperation, TransactionFailureOutcome, TransactionOutcome, OperationTransactionReceipt, OperationExecutionEvent, OperationExecutionSuccessEvent, StackDefinition, WalletAdapter, ConnectOptions, AuthConfig, ProgramSdkDefinition } from '@usearete/sdk';
2
+ import { WebSocketHarness } from '@usearete/sdk/testing';
3
+ export * from '@usearete/sdk/testing';
4
+
5
+ type MutationStatus = 'idle' | 'pending' | 'success' | 'error';
6
+ type MutationPhase = 'idle' | 'preparing' | 'awaiting-wallet' | 'submitted' | 'confirmed' | 'reconciling' | 'reconciled' | 'confirmed-unreconciled' | 'not-submitted' | 'submitted-unknown' | 'chain-failed';
7
+ interface MutationLifecycleEvent<TResult = unknown, TPrepared extends PreparedOperation = PreparedOperation> {
8
+ readonly phase: MutationPhase;
9
+ readonly prepared: TPrepared | null;
10
+ readonly result?: TResult;
11
+ readonly failure?: TransactionFailureOutcome;
12
+ readonly error?: Error;
13
+ readonly transactionEvent?: OperationExecutionEvent<TPrepared> | OperationExecutionSuccessEvent<TPrepared>;
14
+ }
15
+ interface MutationReconciliationContext<TResult = unknown, TPrepared extends PreparedOperation = PreparedOperation> {
16
+ readonly result: TResult;
17
+ readonly prepared: TPrepared | null;
18
+ readonly signatures: readonly string[];
19
+ readonly completedReceipts: readonly OperationTransactionReceipt[];
20
+ readonly signal: AbortSignal;
21
+ }
22
+ type MutationReconcileFn<TResult = unknown, TPrepared extends PreparedOperation = PreparedOperation> = (context: MutationReconciliationContext<TResult, TPrepared>) => unknown | Promise<unknown>;
23
+ /**
24
+ * Anything that can be refreshed after a mutation reconciles: a plain
25
+ * callback, or any hook result carrying a `refresh` method (view hooks from
26
+ * `arete.views.*` and read hooks from `arete.read.*`), so callers can write
27
+ * `reconcile: { refresh: [board, round, quoteRead] }` without extracting
28
+ * `.refresh` functions by hand.
29
+ */
30
+ type ReconciliationRefreshTarget = (() => unknown | Promise<unknown>) | {
31
+ readonly refresh: () => unknown | Promise<unknown>;
32
+ };
33
+ /**
34
+ * Shorthand overrides for the default reconciliation injected into generated
35
+ * program hooks. Only valid when the hook-level default is a marked default
36
+ * reconciliation (see `createProcessedSlotReconciliation`).
37
+ */
38
+ interface MutationReconcileOverrides {
39
+ readonly refresh?: ReconciliationRefreshTarget | readonly ReconciliationRefreshTarget[];
40
+ readonly timeoutMs?: number;
41
+ }
42
+ type UseMutationOptions<TOptions extends object = Record<string, unknown>, TResult = unknown, TPrepared extends PreparedOperation = PreparedOperation> = TOptions & {
43
+ onConfirmed?: (result: TResult) => void | Promise<void>;
44
+ onSuccess?: (result: TResult) => void | Promise<void>;
45
+ onError?: (error: Error) => void | Promise<void>;
46
+ reconcile?: false | MutationReconcileFn<TResult, TPrepared> | MutationReconcileOverrides;
47
+ };
48
+ /**
49
+ * Result of {@link useInstructionMutation}.
50
+ *
51
+ * `phase` is the primary, discriminated status: it walks
52
+ * 'preparing' → 'awaiting-wallet' → 'submitted' → 'confirmed' →
53
+ * 'reconciling' → 'reconciled' on the happy path, and lands on
54
+ * 'confirmed-unreconciled', 'not-submitted', 'submitted-unknown', or
55
+ * 'chain-failed' otherwise. UIs should branch on `phase` for busy labels and
56
+ * on {@link UseMutationResult.displayError} /
57
+ * {@link UseMutationResult.reconciliationError} for messages.
58
+ *
59
+ * `failure` and `outcome` describe chain execution only; callback and
60
+ * reconciliation failures never replace a confirmed outcome.
61
+ */
62
+ interface UseMutationResult<TParams = Record<string, unknown>, TResult = unknown, TOptions extends object = Record<string, unknown>, TPrepared extends PreparedOperation = PreparedOperation> {
63
+ /** Event-handler form. Errors are recorded in mutation state and do not escape. */
64
+ mutate: (args: TParams, options?: Partial<UseMutationOptions<TOptions, TResult, TPrepared>>) => void;
65
+ /** Rejecting form for imperative composition. Equivalent to submit(). */
66
+ mutateAsync: (args: TParams, options?: Partial<UseMutationOptions<TOptions, TResult, TPrepared>>) => Promise<TResult>;
67
+ submit: (args: TParams, options?: Partial<UseMutationOptions<TOptions, TResult, TPrepared>>) => Promise<TResult>;
68
+ status: MutationStatus;
69
+ phase: MutationPhase;
70
+ latestEvent: MutationLifecycleEvent<TResult, TPrepared> | null;
71
+ error: string | null;
72
+ displayError: string | null;
73
+ failure: TransactionFailureOutcome | null;
74
+ outcome: TransactionOutcome | null;
75
+ prepared: TPrepared | null;
76
+ data: TResult | undefined;
77
+ result: TResult | undefined;
78
+ signatures: string[];
79
+ signature: string | null;
80
+ completedReceipts: OperationTransactionReceipt[];
81
+ callbackError: Error | null;
82
+ callbackErrors: Error[];
83
+ reconciliationError: Error | null;
84
+ isLoading: boolean;
85
+ isConfirmed: boolean;
86
+ isSubmittedUnknown: boolean;
87
+ isPreparing: boolean;
88
+ isAwaitingWallet: boolean;
89
+ isReconciling: boolean;
90
+ canRetryReconciliation: boolean;
91
+ /** Retry only post-confirmation stream reconciliation; never resubmits. */
92
+ retryReconciliation: () => Promise<void>;
93
+ reset: () => void;
94
+ }
95
+
96
+ type ProgramMap = Record<string, ProgramSdkDefinition>;
97
+ /**
98
+ * Global configuration for AreteProvider.
99
+ *
100
+ * Note: WebSocket URL is usually embedded in the stack definition
101
+ * (`stack.endpoints.ws` / `stack.endpoints.http`). Override it for the whole
102
+ * app via `stackOptions`, or per-hook via `useArete(stack, { url, httpUrl })`.
103
+ */
104
+ interface AreteConfig {
105
+ /**
106
+ * Default stack for the app. When set, components can call `useArete()`
107
+ * with no arguments; passing a stack explicitly always wins. Register the
108
+ * stack's type once for full inference on argument-less calls:
109
+ *
110
+ * ```ts
111
+ * declare module '@usearete/react' {
112
+ * interface AreteDefaultStackRegistry { defaultStack: OreStreamStack }
113
+ * }
114
+ * ```
115
+ */
116
+ stack?: StackDefinition;
117
+ /**
118
+ * Default lookup options for the provider stack. They also apply when that
119
+ * same stack is passed explicitly to `useArete(stack)` without options.
120
+ */
121
+ stackOptions?: ClientLookupOptions;
122
+ /**
123
+ * Connect immediately when the client is created (defaults to true).
124
+ * Provider connection settings are applied when a shared client is created;
125
+ * changing them does not mutate an existing client. Call retry() to replace
126
+ * that client with the latest settings. Wallet is the reactive exception.
127
+ */
128
+ autoConnect?: boolean;
129
+ /** Reconnect automatically after an established connection is lost (defaults to true). */
130
+ autoReconnect?: boolean;
131
+ wallet?: WalletAdapter;
132
+ reconnectIntervals?: number[];
133
+ maxReconnectAttempts?: number;
134
+ maxEntriesPerView?: number | null;
135
+ flushIntervalMs?: number;
136
+ fetch?: ConnectOptions['fetch'];
137
+ validateFrames?: boolean;
138
+ /**
139
+ * Receives structured details when a frame is not stored: a generated schema
140
+ * rejected it (`reason: 'schema'`), or it was a patch for a key the client
141
+ * holds no entity for (`reason: 'unknown-key'`).
142
+ */
143
+ onFrameValidationError?: ConnectOptions['onFrameValidationError'];
144
+ /** Authentication configuration */
145
+ auth?: AuthConfig;
146
+ }
147
+ /**
148
+ * Client lookup/connect options for React hooks.
149
+ */
150
+ interface ClientLookupOptions<TPrograms extends ProgramMap | undefined = undefined> {
151
+ /** Override the stack's embedded WebSocket URL (useful for local development) */
152
+ url?: string;
153
+ /** Override the stack's embedded HTTP read URL (useful for local development) */
154
+ httpUrl?: string;
155
+ /** Override the stack transport. HTTP mode disables streaming view subscriptions. */
156
+ transport?: ConnectOptions<TPrograms>['transport'];
157
+ /** Override the transaction transport independently from the stack HTTP endpoint. */
158
+ transactions?: ConnectOptions<TPrograms>['transactions'];
159
+ /** Override the chain transport independently from the stack HTTP endpoint. */
160
+ chain?: ConnectOptions<TPrograms>['chain'];
161
+ /** Attach additional program SDKs to the connected client. */
162
+ programs?: TPrograms;
163
+ }
164
+
165
+ /**
166
+ * `@usearete/react/testing`: supported helpers for testing React components
167
+ * built on `@usearete/react`. It re-exports every `@usearete/sdk/testing`
168
+ * helper and adds React-specific fixtures.
169
+ */
170
+
171
+ /** Every value `useMutation().phase` can take, in lifecycle order. */
172
+ declare const MUTATION_PHASES: readonly ["idle", "preparing", "awaiting-wallet", "submitted", "confirmed", "reconciling", "reconciled", "confirmed-unreconciled", "not-submitted", "submitted-unknown", "chain-failed"];
173
+ /**
174
+ * A complete, internally consistent `useMutation()` result for one phase, as
175
+ * the hook reports it: status, receipts, signatures, outcome, failure, display
176
+ * error and the derived `is*` flags all agree. Use it to render and test UI
177
+ * for every phase without a wallet or a chain. `overrides` replace any field.
178
+ *
179
+ * `submit`/`mutateAsync` resolve with the fixture result on landed phases and
180
+ * reject with the phase's failure otherwise; `mutate`, `reset` and
181
+ * `retryReconciliation` do nothing.
182
+ */
183
+ declare function createMutationResultFixture<TParams = Record<string, unknown>, TResult = unknown, TOptions extends object = Record<string, unknown>, TPrepared extends PreparedOperation = PreparedOperation>(phase: MutationPhase, overrides?: Partial<UseMutationResult<TParams, TResult, TOptions, TPrepared>>): UseMutationResult<TParams, TResult, TOptions, TPrepared>;
184
+ /**
185
+ * `<AreteProvider>` props that connect every client to a
186
+ * {@link WebSocketHarness} instead of the network: no reconnects, no
187
+ * batching delay, so frames a test sends are visible on the next render.
188
+ *
189
+ * ```tsx
190
+ * const ws = createWebSocketHarness();
191
+ * render(<AreteProvider {...createAreteTestConfig(ws, { wallet })}><App /></AreteProvider>);
192
+ * const subscription = await ws.waitForSubscription('OreRound/latest');
193
+ * ws.serve(subscription, [{ key: '1', data: round }]);
194
+ * ```
195
+ */
196
+ declare function createAreteTestConfig(harness: Pick<WebSocketHarness, 'websocketFactory'>, overrides?: AreteConfig): AreteConfig;
197
+
198
+ export { MUTATION_PHASES, createAreteTestConfig, createMutationResultFixture };
@@ -0,0 +1,156 @@
1
+ import { FIXTURE_SIGNATURE, FIXTURE_SLOT, createTransactionOutcomeFixtures, transactionFailureError } from '@usearete/sdk/testing';
2
+ export * from '@usearete/sdk/testing';
3
+
4
+ /** Every value `useMutation().phase` can take, in lifecycle order. */
5
+ const MUTATION_PHASES = [
6
+ 'idle',
7
+ 'preparing',
8
+ 'awaiting-wallet',
9
+ 'submitted',
10
+ 'confirmed',
11
+ 'reconciling',
12
+ 'reconciled',
13
+ 'confirmed-unreconciled',
14
+ 'not-submitted',
15
+ 'submitted-unknown',
16
+ 'chain-failed',
17
+ ];
18
+ const LANDED_PHASES = new Set([
19
+ 'submitted',
20
+ 'confirmed',
21
+ 'reconciling',
22
+ 'reconciled',
23
+ 'confirmed-unreconciled',
24
+ ]);
25
+ function failureFor(phase) {
26
+ const outcomes = createTransactionOutcomeFixtures();
27
+ switch (phase) {
28
+ case 'not-submitted':
29
+ return outcomes['not-submitted:wallet'];
30
+ case 'submitted-unknown':
31
+ return outcomes['submitted-unknown:send'];
32
+ case 'chain-failed':
33
+ return outcomes['chain-failed:chain'];
34
+ default:
35
+ return null;
36
+ }
37
+ }
38
+ function statusFor(phase) {
39
+ if (phase === 'idle')
40
+ return 'idle';
41
+ if (phase === 'reconciled' || phase === 'confirmed-unreconciled')
42
+ return 'success';
43
+ if (failureFor(phase))
44
+ return 'error';
45
+ return 'pending';
46
+ }
47
+ function displayErrorFor(failure) {
48
+ if (!failure)
49
+ return null;
50
+ if (failure.status === 'chain-failed' && failure.programError) {
51
+ return `${failure.programError.name}: ${failure.programError.message}`;
52
+ }
53
+ return failure.cause instanceof Error ? failure.cause.message : 'Transaction failed';
54
+ }
55
+ /**
56
+ * A complete, internally consistent `useMutation()` result for one phase, as
57
+ * the hook reports it: status, receipts, signatures, outcome, failure, display
58
+ * error and the derived `is*` flags all agree. Use it to render and test UI
59
+ * for every phase without a wallet or a chain. `overrides` replace any field.
60
+ *
61
+ * `submit`/`mutateAsync` resolve with the fixture result on landed phases and
62
+ * reject with the phase's failure otherwise; `mutate`, `reset` and
63
+ * `retryReconciliation` do nothing.
64
+ */
65
+ function createMutationResultFixture(phase, overrides = {}) {
66
+ const failure = failureFor(phase);
67
+ const landed = LANDED_PHASES.has(phase);
68
+ const receipt = {
69
+ transactionIndex: 0,
70
+ transactionName: 'fixture',
71
+ signature: FIXTURE_SIGNATURE,
72
+ slot: FIXTURE_SLOT,
73
+ };
74
+ const completedReceipts = landed ? [receipt] : [];
75
+ const signatures = landed || (failure && 'signature' in failure && failure.signature)
76
+ ? [FIXTURE_SIGNATURE]
77
+ : [];
78
+ const outcome = failure
79
+ ?? (landed && phase !== 'submitted'
80
+ ? { status: 'confirmed', phase: 'confirmation', signature: FIXTURE_SIGNATURE, slot: FIXTURE_SLOT }
81
+ : null);
82
+ const result = (landed && phase !== 'submitted'
83
+ ? { signature: FIXTURE_SIGNATURE, slot: FIXTURE_SLOT, transaction: receipt }
84
+ : undefined);
85
+ const displayError = displayErrorFor(failure);
86
+ const reconciliationError = phase === 'confirmed-unreconciled'
87
+ ? new Error('Fixture: the stream did not reach the confirmed slot in time')
88
+ : null;
89
+ const status = statusFor(phase);
90
+ const settle = async () => {
91
+ if (failure)
92
+ throw transactionFailureError(failure);
93
+ return result;
94
+ };
95
+ return {
96
+ mutate: () => undefined,
97
+ mutateAsync: settle,
98
+ submit: settle,
99
+ status,
100
+ phase,
101
+ latestEvent: phase === 'idle'
102
+ ? null
103
+ : {
104
+ phase,
105
+ prepared: null,
106
+ ...(result !== undefined ? { result } : {}),
107
+ ...(failure ? { failure } : {}),
108
+ },
109
+ error: displayError,
110
+ displayError,
111
+ failure,
112
+ outcome,
113
+ prepared: null,
114
+ data: result,
115
+ result,
116
+ signatures,
117
+ signature: signatures.length === 1 ? signatures[0] : null,
118
+ completedReceipts,
119
+ callbackError: null,
120
+ callbackErrors: [],
121
+ reconciliationError,
122
+ isLoading: status === 'pending',
123
+ isConfirmed: outcome?.status === 'confirmed',
124
+ isSubmittedUnknown: failure?.status === 'submitted-unknown',
125
+ isPreparing: phase === 'preparing',
126
+ isAwaitingWallet: phase === 'awaiting-wallet',
127
+ isReconciling: phase === 'reconciling',
128
+ canRetryReconciliation: phase === 'confirmed-unreconciled',
129
+ retryReconciliation: async () => undefined,
130
+ reset: () => undefined,
131
+ ...overrides,
132
+ };
133
+ }
134
+ /**
135
+ * `<AreteProvider>` props that connect every client to a
136
+ * {@link WebSocketHarness} instead of the network: no reconnects, no
137
+ * batching delay, so frames a test sends are visible on the next render.
138
+ *
139
+ * ```tsx
140
+ * const ws = createWebSocketHarness();
141
+ * render(<AreteProvider {...createAreteTestConfig(ws, { wallet })}><App /></AreteProvider>);
142
+ * const subscription = await ws.waitForSubscription('OreRound/latest');
143
+ * ws.serve(subscription, [{ key: '1', data: round }]);
144
+ * ```
145
+ */
146
+ function createAreteTestConfig(harness, overrides = {}) {
147
+ return {
148
+ autoReconnect: false,
149
+ flushIntervalMs: 0,
150
+ ...overrides,
151
+ auth: { ...overrides.auth, websocketFactory: harness.websocketFactory },
152
+ };
153
+ }
154
+
155
+ export { MUTATION_PHASES, createAreteTestConfig, createMutationResultFixture };
156
+ //# sourceMappingURL=testing.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testing.esm.js","sources":["../src/testing.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,11 +1,33 @@
1
1
  {
2
2
  "name": "@usearete/react",
3
- "version": "0.24.0",
3
+ "version": "0.25.0",
4
4
  "type": "module",
5
5
  "description": "React SDK for the Arete Solana developer platform",
6
6
  "main": "dist/index.cjs",
7
7
  "module": "dist/index.esm.js",
8
8
  "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.esm.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./testing": {
16
+ "types": "./dist/testing.d.ts",
17
+ "import": "./dist/testing.esm.js",
18
+ "require": "./dist/testing.cjs"
19
+ },
20
+ "./eslint-plugin.cjs": "./eslint-plugin.cjs",
21
+ "./eslint-rules/*": "./eslint-rules/*",
22
+ "./package.json": "./package.json"
23
+ },
24
+ "typesVersions": {
25
+ "*": {
26
+ "testing": [
27
+ "./dist/testing.d.ts"
28
+ ]
29
+ }
30
+ },
9
31
  "repository": {
10
32
  "type": "git",
11
33
  "url": "git+https://github.com/AreteA4/arete.git",
@@ -39,10 +61,10 @@
39
61
  "node": ">=16.0.0"
40
62
  },
41
63
  "peerDependencies": {
64
+ "@usearete/sdk": "^0.25.0",
42
65
  "react": "^18.0.0 || ^19.0.0"
43
66
  },
44
67
  "dependencies": {
45
- "@usearete/sdk": "^0.24.0",
46
68
  "zustand": "^4.0.0 || ^5.0.0"
47
69
  },
48
70
  "devDependencies": {
@@ -54,6 +76,7 @@
54
76
  "@types/react-test-renderer": "^19.1.0",
55
77
  "@typescript-eslint/eslint-plugin": "^6.21.0",
56
78
  "@typescript-eslint/parser": "^6.21.0",
79
+ "@usearete/sdk": "^0.25.0",
57
80
  "eslint": "^8.0.0",
58
81
  "eslint-plugin-react-hooks": "^5.2.0",
59
82
  "jest": "^29.0.0",