@terminal3/t3n-sdk 0.8.0 → 0.11.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.
@@ -16,7 +16,28 @@ export declare class T3nClient {
16
16
  private readonly logger;
17
17
  private readonly encryption;
18
18
  private status;
19
+ /**
20
+ * In-flight WASM state-machine bytes. Holds the opaque state
21
+ * returned by `flow[method].next()` between iterations of
22
+ * `runFlow`. Always cleared at the top of `runFlow` and again
23
+ * once `tryFinalize` has extracted the terminal payload — so
24
+ * outside of an active loop these slots are always `null`.
25
+ */
19
26
  private wasmState;
27
+ /**
28
+ * Terminal payloads produced by `flow[method].finish()`:
29
+ * - `handshake` → serialized session blob, used by
30
+ * `getSessionState()` for subsequent `session.encrypt` calls.
31
+ * - `auth` → serialized DID; the public `authenticate()` decodes
32
+ * it into `this.did` and the slot is otherwise unused.
33
+ * - `execute` → unused (executes return immediately to the caller).
34
+ *
35
+ * Stored in a dedicated field instead of reusing `wasmState`
36
+ * because the two meanings — "in-flight state machine" vs
37
+ * "finalized payload" — are semantically different and merging
38
+ * them invites the bug-class Devin flagged in PR #1140.
39
+ */
40
+ private finalizedPayload;
20
41
  private did;
21
42
  private handshakeResult;
22
43
  constructor(config: T3nClientConfig);
@@ -57,11 +78,38 @@ export declare class T3nClient {
57
78
  getLastResponseHeaders(): Record<string, string>;
58
79
  isAuthenticated(): boolean;
59
80
  /**
60
- * Run a WASM state machine flow to completion
81
+ * Run a WASM state machine flow to completion.
82
+ *
83
+ * Clears both `wasmState[method]` and `finalizedPayload[method]`
84
+ * at entry so a flow that previously threw partway (e.g. an RPC
85
+ * error) starts from a clean slate on retry. Without the reset,
86
+ * stale state from the failed attempt leaks into the new flow
87
+ * and `tryFinalize` may either spuriously succeed or run `next()`
88
+ * against a state that no longer matches the action we're sending.
89
+ *
90
+ * The `tryFinalize`-then-`next` order is load-bearing: the loop's
91
+ * exit condition fires *after* the previous iteration's
92
+ * `handleWasmRequest` has flushed the outbound peer reply, so
93
+ * every state-machine emission reaches the wire before we extract
94
+ * the final payload.
61
95
  */
62
96
  private runFlow;
63
97
  /**
64
- * Try to finalize the current flow
98
+ * Try to finalize the current flow. Returns the finish() payload
99
+ * (a serialized Session for handshake, a serialized DID for auth)
100
+ * or `null` if the state machine has not reached its terminal phase
101
+ * yet.
102
+ *
103
+ * The "not yet finalized" case is the loop's signal to keep
104
+ * iterating, not a real error. Any *other* failure must propagate
105
+ * so callers see real WASM errors instead of silent retries that
106
+ * spin forever.
107
+ *
108
+ * The terminal payload is stored in `finalizedPayload[method]`
109
+ * (a separate field from `wasmState[method]`) so the in-flight
110
+ * state-machine bytes and the finalized session/DID bytes never
111
+ * occupy the same slot. `getSessionState()` reads from
112
+ * `finalizedPayload.handshake`.
65
113
  */
66
114
  private tryFinalize;
67
115
  /**
@@ -82,7 +130,9 @@ export declare class T3nClient {
82
130
  */
83
131
  private sendRpcRequest;
84
132
  /**
85
- * Get the current session state for encryption
133
+ * Get the finalized session blob (for `session.encrypt` calls).
134
+ * Populated by `tryFinalize` once the handshake state machine
135
+ * reaches its terminal phase.
86
136
  */
87
137
  private getSessionState;
88
138
  }
@@ -26,7 +26,9 @@ export interface ClientHandshake {
26
26
  * Attempt to finalize handshake
27
27
  * @param state - Current handshake state
28
28
  * @returns Promise with session bytes if successful
29
- * @throws Error if handshake not ready to finalize
29
+ * @throws Error containing "not yet finalized" if the state machine
30
+ * has not reached its terminal phase. The SDK runtime treats
31
+ * this as the loop's "keep going" signal, not a real error.
30
32
  */
31
33
  finish(state: Uint8Array): Promise<Uint8Array>;
32
34
  }
@@ -45,7 +47,9 @@ export interface ClientAuth {
45
47
  * Attempt to finalize authentication
46
48
  * @param state - Current auth state
47
49
  * @returns Promise with DID bytes if successful
48
- * @throws Error if authentication not ready to finalize
50
+ * @throws Error containing "not yet finalized" if the state machine
51
+ * has not reached its terminal phase. The SDK runtime treats
52
+ * this as the loop's "keep going" signal, not a real error.
49
53
  */
50
54
  finish(state: Uint8Array): Promise<Uint8Array>;
51
55
  }
@@ -64,7 +68,9 @@ export interface ClientExecute {
64
68
  * Attempt to finalize authentication
65
69
  * @param state - Current auth state
66
70
  * @returns Promise with DID bytes if successful
67
- * @throws Error if authentication not ready to finalize
71
+ * @throws Error containing "not yet finalized" if the state machine
72
+ * has not reached its terminal phase. The SDK runtime treats
73
+ * this as the loop's "keep going" signal, not a real error.
68
74
  */
69
75
  finish(state: Uint8Array): Promise<Uint8Array>;
70
76
  }
@@ -94,7 +100,7 @@ export interface SessionCrypto {
94
100
  * authentication flows, and cryptographic operations are handled in WASM.
95
101
  */
96
102
  export interface WasmComponent {
97
- /** Client handshake operations */
103
+ /** Client-side state machines exported by the WASM component. */
98
104
  flow: {
99
105
  handshake: ClientHandshake;
100
106
  auth: ClientAuth;
@@ -6,8 +6,6 @@ export type * as WasiIoError029 from './interfaces/wasi-io-error.js'; // import
6
6
  export type * as WasiIoStreams029 from './interfaces/wasi-io-streams.js'; // import wasi:io/streams@0.2.9
7
7
  export type * as WasiRandomRandom029 from './interfaces/wasi-random-random.js'; // import wasi:random/random@0.2.9
8
8
  export * as clientAuth from './interfaces/component-session-client-auth.js'; // export component:session/client-auth@0.1.0
9
- export * as serverAuth from './interfaces/component-session-server-auth.js'; // export component:session/server-auth@0.1.0
10
9
  export * as clientHandshake from './interfaces/component-session-client-handshake.js'; // export component:session/client-handshake@0.1.0
11
- export * as serverHandshake from './interfaces/component-session-server-handshake.js'; // export component:session/server-handshake@0.1.0
12
10
  export * as session from './interfaces/component-session-session.js'; // export component:session/session@0.1.0
13
11
  export * as cookie from './interfaces/component-session-cookie.js'; // export component:session/cookie@0.1.0