@ic-reactor/core 2.0.1 → 3.0.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.
- package/dist/client.d.ts +161 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +499 -0
- package/dist/client.js.map +1 -0
- package/dist/display/helper.d.ts +10 -0
- package/dist/display/helper.d.ts.map +1 -0
- package/dist/display/helper.js +67 -0
- package/dist/display/helper.js.map +1 -0
- package/dist/display/index.d.ts +4 -0
- package/dist/display/index.d.ts.map +1 -0
- package/dist/display/index.js +4 -0
- package/dist/display/index.js.map +1 -0
- package/dist/display/types.d.ts +31 -0
- package/dist/display/types.d.ts.map +1 -0
- package/dist/display/types.js +2 -0
- package/dist/display/types.js.map +1 -0
- package/dist/display/visitor.d.ts +28 -0
- package/dist/display/visitor.d.ts.map +1 -0
- package/dist/display/visitor.js +318 -0
- package/dist/display/visitor.js.map +1 -0
- package/dist/display-reactor.d.ts +245 -0
- package/dist/display-reactor.d.ts.map +1 -0
- package/dist/display-reactor.js +331 -0
- package/dist/display-reactor.js.map +1 -0
- package/dist/errors/index.d.ts +118 -0
- package/dist/errors/index.d.ts.map +1 -0
- package/dist/errors/index.js +204 -0
- package/dist/errors/index.js.map +1 -0
- package/dist/index.d.ts +9 -8
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -47
- package/dist/index.js.map +1 -0
- package/dist/reactor.d.ts +133 -0
- package/dist/reactor.d.ts.map +1 -0
- package/dist/reactor.js +325 -0
- package/dist/reactor.js.map +1 -0
- package/dist/types/client.d.ts +89 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/client.js +2 -0
- package/dist/types/client.js.map +1 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/reactor.d.ts +117 -0
- package/dist/types/reactor.d.ts.map +1 -0
- package/dist/types/reactor.js +2 -0
- package/dist/types/reactor.js.map +1 -0
- package/dist/types/result.d.ts +48 -0
- package/dist/types/result.d.ts.map +1 -0
- package/dist/types/result.js +2 -0
- package/dist/types/result.js.map +1 -0
- package/dist/types/transform.d.ts +7 -0
- package/dist/types/transform.d.ts.map +1 -0
- package/dist/types/transform.js +2 -0
- package/dist/types/transform.js.map +1 -0
- package/dist/types/variant.d.ts +18 -0
- package/dist/types/variant.d.ts.map +1 -0
- package/dist/types/variant.js +2 -0
- package/dist/types/variant.js.map +1 -0
- package/dist/utils/agent.d.ts +30 -1
- package/dist/utils/agent.d.ts.map +1 -0
- package/dist/utils/agent.js +118 -16
- package/dist/utils/agent.js.map +1 -0
- package/dist/utils/candid.d.ts +39 -1
- package/dist/utils/candid.d.ts.map +1 -0
- package/dist/utils/candid.js +76 -16
- package/dist/utils/candid.js.map +1 -0
- package/dist/utils/constants.d.ts +3 -4
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +7 -11
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/helper.d.ts +16 -39
- package/dist/utils/helper.d.ts.map +1 -0
- package/dist/utils/helper.js +53 -155
- package/dist/utils/helper.js.map +1 -0
- package/dist/utils/index.d.ts +4 -5
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +5 -49
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/polling.d.ts +176 -0
- package/dist/utils/polling.d.ts.map +1 -0
- package/dist/utils/polling.js +170 -0
- package/dist/utils/polling.js.map +1 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +5 -0
- package/dist/version.js.map +1 -0
- package/package.json +65 -39
- package/LICENSE.md +0 -8
- package/README.md +0 -283
- package/dist/classes/actor/index.d.ts +0 -34
- package/dist/classes/actor/index.js +0 -245
- package/dist/classes/actor/types.d.ts +0 -113
- package/dist/classes/actor/types.js +0 -2
- package/dist/classes/adapter/index.d.ts +0 -19
- package/dist/classes/adapter/index.js +0 -140
- package/dist/classes/adapter/types.d.ts +0 -14
- package/dist/classes/adapter/types.js +0 -2
- package/dist/classes/agent/index.d.ts +0 -37
- package/dist/classes/agent/index.js +0 -221
- package/dist/classes/agent/types.d.ts +0 -87
- package/dist/classes/agent/types.js +0 -2
- package/dist/classes/index.d.ts +0 -3
- package/dist/classes/index.js +0 -19
- package/dist/classes/types.d.ts +0 -15
- package/dist/classes/types.js +0 -20
- package/dist/createActorManager.d.ts +0 -12
- package/dist/createActorManager.js +0 -17
- package/dist/createAgentManager.d.ts +0 -12
- package/dist/createAgentManager.js +0 -17
- package/dist/createCandidAdapter.d.ts +0 -11
- package/dist/createCandidAdapter.js +0 -16
- package/dist/createReactorCore.d.ts +0 -10
- package/dist/createReactorCore.js +0 -112
- package/dist/createReactorStore.d.ts +0 -11
- package/dist/createReactorStore.js +0 -31
- package/dist/types.d.ts +0 -96
- package/dist/types.js +0 -17
- package/dist/utils/hash.d.ts +0 -12
- package/dist/utils/hash.js +0 -70
- package/dist/utils/principal.d.ts +0 -1
- package/dist/utils/principal.js +0 -17
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { Reactor } from "./reactor";
|
|
2
|
+
import { ActorMethodParameters, ActorMethodReturnType, FunctionName, ReactorArgs, ReactorReturnOk, ActorMethodCodecs, ReactorParameters, BaseActor } from "./types/reactor";
|
|
3
|
+
import { ValidationIssue } from "./errors";
|
|
4
|
+
/**
|
|
5
|
+
* Validation result returned by a validator function.
|
|
6
|
+
* Either success (true) or failure with issues.
|
|
7
|
+
*/
|
|
8
|
+
export type ValidationResult = {
|
|
9
|
+
success: true;
|
|
10
|
+
} | {
|
|
11
|
+
success: false;
|
|
12
|
+
issues: ValidationIssue[];
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A validator function that validates method arguments.
|
|
16
|
+
* Receives display types (strings for Principal, bigint, etc.).
|
|
17
|
+
*
|
|
18
|
+
* @param args - The display-type arguments to validate
|
|
19
|
+
* @returns ValidationResult indicating success or failure with issues
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```typescript
|
|
23
|
+
* // Validator receives display types
|
|
24
|
+
* reactor.registerValidator("transfer", ([input]) => {
|
|
25
|
+
* const issues = []
|
|
26
|
+
*
|
|
27
|
+
* // input.to is string (not Principal)
|
|
28
|
+
* if (!input.to) {
|
|
29
|
+
* issues.push({ path: ["to"], message: "Recipient is required" })
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* // input.amount is string (not bigint)
|
|
33
|
+
* if (!/^\d+$/.test(input.amount)) {
|
|
34
|
+
* issues.push({ path: ["amount"], message: "Must be a valid number" })
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* return issues.length > 0 ? { success: false, issues } : { success: true }
|
|
38
|
+
* })
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export type Validator<Args = unknown[]> = (args: Args) => ValidationResult | Promise<ValidationResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Validator that receives display types for a specific method.
|
|
44
|
+
*/
|
|
45
|
+
export type DisplayValidator<A, M extends FunctionName<A>> = Validator<ReactorArgs<A, M, "display">>;
|
|
46
|
+
export type DisplayReactorParameters<A = BaseActor> = ReactorParameters<A> & {
|
|
47
|
+
/**
|
|
48
|
+
* Optional initial validators to register.
|
|
49
|
+
* Validators receive display types (strings for Principal, bigint, etc.)
|
|
50
|
+
*/
|
|
51
|
+
validators?: Partial<{
|
|
52
|
+
[M in FunctionName<A>]: DisplayValidator<A, M>;
|
|
53
|
+
}>;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* DisplayReactor provides automatic type transformations between Candid and
|
|
57
|
+
* display-friendly types, plus optional argument validation.
|
|
58
|
+
*
|
|
59
|
+
* ### Type Transformations
|
|
60
|
+
* - `bigint` → `string` (for JSON/UI display)
|
|
61
|
+
* - `Principal` → `string` (text representation)
|
|
62
|
+
* - `[T] | []` → `T | null` (optional unwrapping)
|
|
63
|
+
* - Small blobs → hex strings
|
|
64
|
+
*
|
|
65
|
+
* ### Validation (Optional)
|
|
66
|
+
* Register validators to check arguments before canister calls.
|
|
67
|
+
* Validators receive **display types** (strings), making them perfect for
|
|
68
|
+
* form validation.
|
|
69
|
+
*
|
|
70
|
+
* @typeParam A - The actor service type
|
|
71
|
+
*
|
|
72
|
+
* @example
|
|
73
|
+
* ```typescript
|
|
74
|
+
* import { DisplayReactor } from "@ic-reactor/core"
|
|
75
|
+
*
|
|
76
|
+
* const reactor = new DisplayReactor<_SERVICE>({
|
|
77
|
+
* clientManager,
|
|
78
|
+
* canisterId: "...",
|
|
79
|
+
* idlFactory,
|
|
80
|
+
* })
|
|
81
|
+
*
|
|
82
|
+
* // Optional: Add validation
|
|
83
|
+
* reactor.registerValidator("transfer", ([input]) => {
|
|
84
|
+
* if (!input.to) {
|
|
85
|
+
* return {
|
|
86
|
+
* success: false,
|
|
87
|
+
* issues: [{ path: ["to"], message: "Recipient is required" }]
|
|
88
|
+
* }
|
|
89
|
+
* }
|
|
90
|
+
* return { success: true }
|
|
91
|
+
* })
|
|
92
|
+
*
|
|
93
|
+
* // Call with display types
|
|
94
|
+
* await reactor.callMethod({
|
|
95
|
+
* functionName: "transfer",
|
|
96
|
+
* args: [{ to: "aaaaa-aa", amount: "100" }], // strings!
|
|
97
|
+
* })
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare class DisplayReactor<A = BaseActor> extends Reactor<A, "display"> {
|
|
101
|
+
readonly transform = "display";
|
|
102
|
+
private codecs;
|
|
103
|
+
private validators;
|
|
104
|
+
constructor(config: DisplayReactorParameters<A>);
|
|
105
|
+
/**
|
|
106
|
+
* Initialize codecs from IDL factory for automatic type transformations
|
|
107
|
+
*/
|
|
108
|
+
private initializeCodecs;
|
|
109
|
+
/**
|
|
110
|
+
* Get a codec for a specific method.
|
|
111
|
+
* Returns the args and result codecs for bidirectional transformation.
|
|
112
|
+
* @param methodName - The name of the method
|
|
113
|
+
* @returns Object with args and result codecs, or null if not found
|
|
114
|
+
*/
|
|
115
|
+
getCodec<M extends FunctionName<A>>(methodName: M): ActorMethodCodecs<A, M> | null;
|
|
116
|
+
/**
|
|
117
|
+
* Register a validator for a specific method.
|
|
118
|
+
* Validators receive display types (strings for Principal/bigint).
|
|
119
|
+
*
|
|
120
|
+
* @param methodName - The name of the method to validate
|
|
121
|
+
* @param validator - The validator function receiving display types
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* ```typescript
|
|
125
|
+
* // input.to is string, input.amount is string
|
|
126
|
+
* reactor.registerValidator("transfer", ([input]) => {
|
|
127
|
+
* if (!/^\d+$/.test(input.amount)) {
|
|
128
|
+
* return {
|
|
129
|
+
* success: false,
|
|
130
|
+
* issues: [{ path: ["amount"], message: "Must be a valid number" }]
|
|
131
|
+
* }
|
|
132
|
+
* }
|
|
133
|
+
* return { success: true }
|
|
134
|
+
* })
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
registerValidator<M extends FunctionName<A>>(methodName: M, validator: DisplayValidator<A, M>): void;
|
|
138
|
+
/**
|
|
139
|
+
* Unregister a validator for a specific method.
|
|
140
|
+
*/
|
|
141
|
+
unregisterValidator<M extends FunctionName<A>>(methodName: M): void;
|
|
142
|
+
/**
|
|
143
|
+
* Check if a method has a registered validator.
|
|
144
|
+
*/
|
|
145
|
+
hasValidator<M extends FunctionName<A>>(methodName: M): boolean;
|
|
146
|
+
/**
|
|
147
|
+
* Validate arguments without calling the canister.
|
|
148
|
+
* Arguments are in display format (strings for Principal/bigint).
|
|
149
|
+
* Useful for form validation before submission.
|
|
150
|
+
*
|
|
151
|
+
* @param methodName - The name of the method
|
|
152
|
+
* @param args - The display-type arguments to validate
|
|
153
|
+
* @returns ValidationResult indicating success or failure
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* // Validate form data before submission
|
|
158
|
+
* const result = await reactor.validate("transfer", [{
|
|
159
|
+
* to: formData.recipient, // string
|
|
160
|
+
* amount: formData.amount, // string
|
|
161
|
+
* }])
|
|
162
|
+
*
|
|
163
|
+
* if (!result.success) {
|
|
164
|
+
* result.issues.forEach(issue => {
|
|
165
|
+
* form.setError(issue.path[0], issue.message)
|
|
166
|
+
* })
|
|
167
|
+
* }
|
|
168
|
+
* ```
|
|
169
|
+
*/
|
|
170
|
+
validate<M extends FunctionName<A>>(methodName: M, args: ReactorArgs<A, M, "display">): Promise<ValidationResult>;
|
|
171
|
+
/**
|
|
172
|
+
* Call a method with async validation support.
|
|
173
|
+
* Use this instead of callMethod() when you have async validators.
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // Async validator (e.g., check if address is blocked)
|
|
178
|
+
* reactor.registerValidator("transfer", async ([input]) => {
|
|
179
|
+
* const isBlocked = await checkBlocklist(input.to)
|
|
180
|
+
* if (isBlocked) {
|
|
181
|
+
* return {
|
|
182
|
+
* success: false,
|
|
183
|
+
* issues: [{ path: ["to"], message: "Address is blocked" }]
|
|
184
|
+
* }
|
|
185
|
+
* }
|
|
186
|
+
* return { success: true }
|
|
187
|
+
* })
|
|
188
|
+
*
|
|
189
|
+
* await reactor.callMethodWithValidation({
|
|
190
|
+
* functionName: "transfer",
|
|
191
|
+
* args: [{ to: "...", amount: "100" }],
|
|
192
|
+
* })
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
callMethodWithValidation<M extends FunctionName<A>>(params: {
|
|
196
|
+
functionName: M;
|
|
197
|
+
args?: ReactorArgs<A, M, "display">;
|
|
198
|
+
callConfig?: Parameters<Reactor<A, "display">["callMethod"]>[0]["callConfig"];
|
|
199
|
+
}): Promise<ReactorReturnOk<A, M, "display">>;
|
|
200
|
+
/**
|
|
201
|
+
* Transform arguments before calling the actor method.
|
|
202
|
+
* 1. Validates display-type args (if validator registered)
|
|
203
|
+
* 2. Converts Display → Candid
|
|
204
|
+
*/
|
|
205
|
+
protected transformArgs<M extends FunctionName<A>>(methodName: M, args?: ReactorArgs<A, M, "display">): ActorMethodParameters<A[M]>;
|
|
206
|
+
/**
|
|
207
|
+
* Transform the result after calling the actor method.
|
|
208
|
+
* Always extracts the Ok value from Result types (throws CanisterError on Err).
|
|
209
|
+
* Also converts Candid → Display format.
|
|
210
|
+
*/
|
|
211
|
+
protected transformResult<M extends FunctionName<A>>(methodName: M, result: ActorMethodReturnType<A[M]>): ReactorReturnOk<A, M, "display">;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Create a validator from a Zod schema.
|
|
215
|
+
* This is a utility function to easily integrate Zod schemas as validators.
|
|
216
|
+
*
|
|
217
|
+
* @param schema - A Zod schema to validate against
|
|
218
|
+
* @returns A Validator function compatible with DisplayReactor
|
|
219
|
+
*
|
|
220
|
+
* @example
|
|
221
|
+
* ```typescript
|
|
222
|
+
* import { z } from "zod"
|
|
223
|
+
* import { fromZodSchema } from "@ic-reactor/core"
|
|
224
|
+
*
|
|
225
|
+
* const transferSchema = z.object({
|
|
226
|
+
* to: z.string().min(1, "Recipient is required"),
|
|
227
|
+
* amount: z.string().regex(/^\d+$/, "Must be a valid number"),
|
|
228
|
+
* })
|
|
229
|
+
*
|
|
230
|
+
* reactor.registerValidator("transfer", fromZodSchema(transferSchema))
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export declare function fromZodSchema<T>(schema: {
|
|
234
|
+
safeParse: (data: unknown) => {
|
|
235
|
+
success: boolean;
|
|
236
|
+
error?: {
|
|
237
|
+
issues: Array<{
|
|
238
|
+
path: (string | number)[];
|
|
239
|
+
message: string;
|
|
240
|
+
code?: string;
|
|
241
|
+
}>;
|
|
242
|
+
};
|
|
243
|
+
};
|
|
244
|
+
}): Validator<T[]>;
|
|
245
|
+
//# sourceMappingURL=display-reactor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-reactor.d.ts","sourceRoot":"","sources":["../src/display-reactor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { Reactor } from "./reactor";
|
|
2
|
+
import { didToDisplayCodec, transformArgsWithCodec, transformResultWithCodec, didTypeFromArray, } from "./display";
|
|
3
|
+
import { extractOkResult } from "./utils/helper";
|
|
4
|
+
import { ValidationError } from "./errors";
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// DisplayReactor
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* DisplayReactor provides automatic type transformations between Candid and
|
|
10
|
+
* display-friendly types, plus optional argument validation.
|
|
11
|
+
*
|
|
12
|
+
* ### Type Transformations
|
|
13
|
+
* - `bigint` → `string` (for JSON/UI display)
|
|
14
|
+
* - `Principal` → `string` (text representation)
|
|
15
|
+
* - `[T] | []` → `T | null` (optional unwrapping)
|
|
16
|
+
* - Small blobs → hex strings
|
|
17
|
+
*
|
|
18
|
+
* ### Validation (Optional)
|
|
19
|
+
* Register validators to check arguments before canister calls.
|
|
20
|
+
* Validators receive **display types** (strings), making them perfect for
|
|
21
|
+
* form validation.
|
|
22
|
+
*
|
|
23
|
+
* @typeParam A - The actor service type
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* ```typescript
|
|
27
|
+
* import { DisplayReactor } from "@ic-reactor/core"
|
|
28
|
+
*
|
|
29
|
+
* const reactor = new DisplayReactor<_SERVICE>({
|
|
30
|
+
* clientManager,
|
|
31
|
+
* canisterId: "...",
|
|
32
|
+
* idlFactory,
|
|
33
|
+
* })
|
|
34
|
+
*
|
|
35
|
+
* // Optional: Add validation
|
|
36
|
+
* reactor.registerValidator("transfer", ([input]) => {
|
|
37
|
+
* if (!input.to) {
|
|
38
|
+
* return {
|
|
39
|
+
* success: false,
|
|
40
|
+
* issues: [{ path: ["to"], message: "Recipient is required" }]
|
|
41
|
+
* }
|
|
42
|
+
* }
|
|
43
|
+
* return { success: true }
|
|
44
|
+
* })
|
|
45
|
+
*
|
|
46
|
+
* // Call with display types
|
|
47
|
+
* await reactor.callMethod({
|
|
48
|
+
* functionName: "transfer",
|
|
49
|
+
* args: [{ to: "aaaaa-aa", amount: "100" }], // strings!
|
|
50
|
+
* })
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
export class DisplayReactor extends Reactor {
|
|
54
|
+
constructor(config) {
|
|
55
|
+
super(config);
|
|
56
|
+
Object.defineProperty(this, "transform", {
|
|
57
|
+
enumerable: true,
|
|
58
|
+
configurable: true,
|
|
59
|
+
writable: true,
|
|
60
|
+
value: "display"
|
|
61
|
+
});
|
|
62
|
+
Object.defineProperty(this, "codecs", {
|
|
63
|
+
enumerable: true,
|
|
64
|
+
configurable: true,
|
|
65
|
+
writable: true,
|
|
66
|
+
value: new Map()
|
|
67
|
+
});
|
|
68
|
+
Object.defineProperty(this, "validators", {
|
|
69
|
+
enumerable: true,
|
|
70
|
+
configurable: true,
|
|
71
|
+
writable: true,
|
|
72
|
+
value: new Map()
|
|
73
|
+
});
|
|
74
|
+
this.initializeCodecs();
|
|
75
|
+
// Register initial validators if provided
|
|
76
|
+
if (config.validators) {
|
|
77
|
+
for (const [methodName, validator] of Object.entries(config.validators)) {
|
|
78
|
+
if (validator) {
|
|
79
|
+
this.validators.set(methodName, validator);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Initialize codecs from IDL factory for automatic type transformations
|
|
86
|
+
*/
|
|
87
|
+
initializeCodecs() {
|
|
88
|
+
try {
|
|
89
|
+
const fields = this.getServiceInterface()?._fields;
|
|
90
|
+
if (!fields) {
|
|
91
|
+
throw new Error("No fields found");
|
|
92
|
+
}
|
|
93
|
+
for (const [methodName, funcType] of fields) {
|
|
94
|
+
// Generate args codec
|
|
95
|
+
const argsIdlType = didTypeFromArray(funcType.argTypes);
|
|
96
|
+
// Generate result codec
|
|
97
|
+
const retIdlType = didTypeFromArray(funcType.retTypes);
|
|
98
|
+
// Set codec in map
|
|
99
|
+
this.codecs.set(methodName, {
|
|
100
|
+
args: didToDisplayCodec(argsIdlType),
|
|
101
|
+
result: didToDisplayCodec(retIdlType),
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error("Failed to initialize codecs:", error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Codec Methods
|
|
111
|
+
// ============================================================================
|
|
112
|
+
/**
|
|
113
|
+
* Get a codec for a specific method.
|
|
114
|
+
* Returns the args and result codecs for bidirectional transformation.
|
|
115
|
+
* @param methodName - The name of the method
|
|
116
|
+
* @returns Object with args and result codecs, or null if not found
|
|
117
|
+
*/
|
|
118
|
+
getCodec(methodName) {
|
|
119
|
+
const cached = this.codecs.get(methodName);
|
|
120
|
+
if (cached) {
|
|
121
|
+
return cached;
|
|
122
|
+
}
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Validation Methods
|
|
127
|
+
// ============================================================================
|
|
128
|
+
/**
|
|
129
|
+
* Register a validator for a specific method.
|
|
130
|
+
* Validators receive display types (strings for Principal/bigint).
|
|
131
|
+
*
|
|
132
|
+
* @param methodName - The name of the method to validate
|
|
133
|
+
* @param validator - The validator function receiving display types
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // input.to is string, input.amount is string
|
|
138
|
+
* reactor.registerValidator("transfer", ([input]) => {
|
|
139
|
+
* if (!/^\d+$/.test(input.amount)) {
|
|
140
|
+
* return {
|
|
141
|
+
* success: false,
|
|
142
|
+
* issues: [{ path: ["amount"], message: "Must be a valid number" }]
|
|
143
|
+
* }
|
|
144
|
+
* }
|
|
145
|
+
* return { success: true }
|
|
146
|
+
* })
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
registerValidator(methodName, validator) {
|
|
150
|
+
this.validators.set(methodName, validator);
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Unregister a validator for a specific method.
|
|
154
|
+
*/
|
|
155
|
+
unregisterValidator(methodName) {
|
|
156
|
+
this.validators.delete(methodName);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Check if a method has a registered validator.
|
|
160
|
+
*/
|
|
161
|
+
hasValidator(methodName) {
|
|
162
|
+
return this.validators.has(methodName);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Validate arguments without calling the canister.
|
|
166
|
+
* Arguments are in display format (strings for Principal/bigint).
|
|
167
|
+
* Useful for form validation before submission.
|
|
168
|
+
*
|
|
169
|
+
* @param methodName - The name of the method
|
|
170
|
+
* @param args - The display-type arguments to validate
|
|
171
|
+
* @returns ValidationResult indicating success or failure
|
|
172
|
+
*
|
|
173
|
+
* @example
|
|
174
|
+
* ```typescript
|
|
175
|
+
* // Validate form data before submission
|
|
176
|
+
* const result = await reactor.validate("transfer", [{
|
|
177
|
+
* to: formData.recipient, // string
|
|
178
|
+
* amount: formData.amount, // string
|
|
179
|
+
* }])
|
|
180
|
+
*
|
|
181
|
+
* if (!result.success) {
|
|
182
|
+
* result.issues.forEach(issue => {
|
|
183
|
+
* form.setError(issue.path[0], issue.message)
|
|
184
|
+
* })
|
|
185
|
+
* }
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
async validate(methodName, args) {
|
|
189
|
+
const validator = this.validators.get(methodName);
|
|
190
|
+
if (!validator) {
|
|
191
|
+
return { success: true };
|
|
192
|
+
}
|
|
193
|
+
return validator(args);
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Call a method with async validation support.
|
|
197
|
+
* Use this instead of callMethod() when you have async validators.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* // Async validator (e.g., check if address is blocked)
|
|
202
|
+
* reactor.registerValidator("transfer", async ([input]) => {
|
|
203
|
+
* const isBlocked = await checkBlocklist(input.to)
|
|
204
|
+
* if (isBlocked) {
|
|
205
|
+
* return {
|
|
206
|
+
* success: false,
|
|
207
|
+
* issues: [{ path: ["to"], message: "Address is blocked" }]
|
|
208
|
+
* }
|
|
209
|
+
* }
|
|
210
|
+
* return { success: true }
|
|
211
|
+
* })
|
|
212
|
+
*
|
|
213
|
+
* await reactor.callMethodWithValidation({
|
|
214
|
+
* functionName: "transfer",
|
|
215
|
+
* args: [{ to: "...", amount: "100" }],
|
|
216
|
+
* })
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
async callMethodWithValidation(params) {
|
|
220
|
+
// Run async validation first (on display types)
|
|
221
|
+
if (params.args) {
|
|
222
|
+
const result = await this.validate(params.functionName, params.args);
|
|
223
|
+
if (!result.success) {
|
|
224
|
+
throw new ValidationError(String(params.functionName), result.issues);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// Skip synchronous validation in transformArgs by temporarily removing validator
|
|
228
|
+
const validator = this.validators.get(params.functionName);
|
|
229
|
+
if (validator) {
|
|
230
|
+
this.validators.delete(params.functionName);
|
|
231
|
+
}
|
|
232
|
+
try {
|
|
233
|
+
return await this.callMethod(params);
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
// Restore validator
|
|
237
|
+
if (validator) {
|
|
238
|
+
this.validators.set(params.functionName, validator);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
// ============================================================================
|
|
243
|
+
// Transform Methods
|
|
244
|
+
// ============================================================================
|
|
245
|
+
/**
|
|
246
|
+
* Transform arguments before calling the actor method.
|
|
247
|
+
* 1. Validates display-type args (if validator registered)
|
|
248
|
+
* 2. Converts Display → Candid
|
|
249
|
+
*/
|
|
250
|
+
transformArgs(methodName, args) {
|
|
251
|
+
// 1. Validate FIRST (on display types)
|
|
252
|
+
const validator = this.validators.get(methodName);
|
|
253
|
+
if (validator && args) {
|
|
254
|
+
const result = validator(args);
|
|
255
|
+
// Handle Promise (async validator)
|
|
256
|
+
if (result &&
|
|
257
|
+
typeof result.then === "function") {
|
|
258
|
+
throw new Error(`Async validators are not supported in callMethod(). ` +
|
|
259
|
+
`Use reactor.callMethodWithValidation() for async validation.`);
|
|
260
|
+
}
|
|
261
|
+
const syncResult = result;
|
|
262
|
+
if (!syncResult.success) {
|
|
263
|
+
throw new ValidationError(String(methodName), syncResult.issues);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// 2. THEN transform: Display → Candid
|
|
267
|
+
if (this.codecs.has(methodName)) {
|
|
268
|
+
const codec = this.codecs.get(methodName);
|
|
269
|
+
return transformArgsWithCodec(codec.args, args);
|
|
270
|
+
}
|
|
271
|
+
if (!args) {
|
|
272
|
+
return [];
|
|
273
|
+
}
|
|
274
|
+
return args;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Transform the result after calling the actor method.
|
|
278
|
+
* Always extracts the Ok value from Result types (throws CanisterError on Err).
|
|
279
|
+
* Also converts Candid → Display format.
|
|
280
|
+
*/
|
|
281
|
+
transformResult(methodName, result) {
|
|
282
|
+
let transformedResult = result;
|
|
283
|
+
// 1. Apply display transformation to the FULL result
|
|
284
|
+
if (this.codecs.has(methodName)) {
|
|
285
|
+
const codec = this.codecs.get(methodName);
|
|
286
|
+
transformedResult = transformResultWithCodec(codec.result, result);
|
|
287
|
+
}
|
|
288
|
+
// 2. Extract Ok value from the TRANSFORMED (or raw) result
|
|
289
|
+
// This handles { ok: T } / { err: E } from Motoko/Rust canisters
|
|
290
|
+
return extractOkResult(transformedResult);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
// ============================================================================
|
|
294
|
+
// Zod Integration Helper
|
|
295
|
+
// ============================================================================
|
|
296
|
+
/**
|
|
297
|
+
* Create a validator from a Zod schema.
|
|
298
|
+
* This is a utility function to easily integrate Zod schemas as validators.
|
|
299
|
+
*
|
|
300
|
+
* @param schema - A Zod schema to validate against
|
|
301
|
+
* @returns A Validator function compatible with DisplayReactor
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```typescript
|
|
305
|
+
* import { z } from "zod"
|
|
306
|
+
* import { fromZodSchema } from "@ic-reactor/core"
|
|
307
|
+
*
|
|
308
|
+
* const transferSchema = z.object({
|
|
309
|
+
* to: z.string().min(1, "Recipient is required"),
|
|
310
|
+
* amount: z.string().regex(/^\d+$/, "Must be a valid number"),
|
|
311
|
+
* })
|
|
312
|
+
*
|
|
313
|
+
* reactor.registerValidator("transfer", fromZodSchema(transferSchema))
|
|
314
|
+
* ```
|
|
315
|
+
*/
|
|
316
|
+
export function fromZodSchema(schema) {
|
|
317
|
+
return (args) => {
|
|
318
|
+
// Validate the first argument (common IC pattern)
|
|
319
|
+
const result = schema.safeParse(args[0]);
|
|
320
|
+
if (result.success) {
|
|
321
|
+
return { success: true };
|
|
322
|
+
}
|
|
323
|
+
const issues = result.error.issues.map((issue) => ({
|
|
324
|
+
path: issue.path,
|
|
325
|
+
message: issue.message,
|
|
326
|
+
code: issue.code,
|
|
327
|
+
}));
|
|
328
|
+
return { success: false, issues };
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
//# sourceMappingURL=display-reactor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"display-reactor.js","sourceRoot":"","sources":["../src/display-reactor.ts"],"names":[],"mappings":"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"}
|