Skip to content

Commit 181fe25

Browse files
committed
docs: update structure explanation
1 parent 2e9a5a6 commit 181fe25

File tree

1 file changed

+312
-13
lines changed

1 file changed

+312
-13
lines changed

docs/src/content/docs/structure.md

Lines changed: 312 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,336 @@
22
title: Bindings Structure
33
prev: false
44
next: false
5+
head:
6+
- tag: style
7+
content: |
8+
.code-comparison {
9+
display: grid;
10+
grid-template-columns: 1fr 1fr;
11+
gap: 1rem;
12+
}
13+
14+
.code-comparison > div {
15+
margin: 0;
16+
overflow-x: hidden;
17+
}
18+
19+
@media (max-width: 768px) {
20+
.code-comparison {
21+
grid-template-columns: 1fr;
22+
}
23+
}
524
---
625

726
The tool writes the files in the specified output directory with the following structure. Assuming you have a `<service-name>.did` file, `<service-name>` is used for the generated files.
827

9-
> Note: Generated code references `@icp-sdk/core` (agents, candid, principals). Install it in your app if you plan to compile/run the generated code. See `https://js.icp.build/core`.
28+
> Note: The generated code imports elements from `@icp-sdk/core`. You must install it, see [js.icp.build/core](https://js.icp.build/core).
1029
11-
## `declarations/`
30+
## `<service-name>.ts`
1231

13-
This folder contains the actual Candid JS bindings. It generates the same bindings that the [`dfx generate`](https://internetcomputer.org/docs/building-apps/developer-tools/dfx/dfx-generate) command was generating.
32+
This file contains the TypeScript wrapper for the Candid JS bindings generated in [`declarations/<service-name>.did.js`](#declarationsservice-namedidjs). It offers a more idiomatic and type-safe TypeScript interface over the Candid JS bindings.
1433

15-
### `declarations/<service-name>.did.d.ts`
34+
Set the [`output.actor.disabled`](./core/api/type-aliases/GenerateOutputOptions.md#disabled) option to `true` to skip generating this file.
1635

17-
This file is used in TypeScript projects to type the Candid JS bindings generated in [`declarations/<service-name>.did.js`](#declarationsservice-namedidjs).
36+
The generated file exposes:
1837

19-
### `declarations/<service-name>.did.js`
38+
- The [types](#types), that is the TypeScript representation of the Candid types.
39+
- The [`<service-name>Interface` type](#service-nameinterface-type), that is the TypeScript interface for the service.
40+
- The [`<service-name>` class](#service-name-class), that is the TypeScript class for the service.
41+
- The [`createActor` function](#createactor-function), that creates a new instance of the actor.
2042

21-
This file contains the actual Candid JS bindings, that allow encoding and decoding JS objects to and from Candid.
43+
### Types
2244

23-
## `<service-name>.ts`
45+
This section contains the TypeScript representation of the Candid types. It contains all the types that are defined as Candid types in the `.did` file. To make the generated types more idiomatic, some types are transformed into more TypeScript-friendly types.
46+
47+
#### Options
48+
49+
Candid [options](https://github.com/dfinity/candid/blob/master/spec/Candid.md#options) are represented as a union of the inner option type and undefined:
50+
51+
<div class="code-comparison">
52+
53+
<div>
54+
55+
**Candid**
56+
57+
```
58+
type MyType = opt text;
59+
```
60+
61+
</div>
62+
63+
<div>
64+
65+
**TypeScript**
66+
67+
```typescript
68+
type MyType = string | undefined;
69+
```
70+
71+
</div>
72+
73+
</div>
74+
75+
#### Nested Options
76+
77+
Nested or recursive options are represented as union of the `Some` and `None` types:
78+
79+
<div class="code-comparison">
80+
81+
<div>
82+
83+
**Candid**
84+
85+
```
86+
type MyType = opt opt text;
87+
```
88+
89+
</div>
90+
91+
<div>
92+
93+
**TypeScript**
94+
95+
```typescript
96+
type MyType = Some<string> | None;
97+
```
98+
99+
</div>
100+
101+
</div>
102+
103+
Where `Some` and `None` are defined as:
104+
105+
```typescript
106+
interface Some<T> {
107+
__kind__: "Some";
108+
value: T;
109+
}
110+
interface None {
111+
__kind__: "None";
112+
}
113+
```
114+
115+
#### Record Fields with Options
116+
117+
Record fields that have an option type are optional fields in the TypeScript type:
118+
119+
<div class="code-comparison">
120+
121+
<div>
122+
123+
**Candid**
124+
125+
```
126+
type MyType = record {
127+
my_field : opt text;
128+
}
129+
```
130+
131+
</div>
132+
133+
<div>
134+
135+
**TypeScript**
136+
137+
```typescript
138+
type MyType = {
139+
my_field?: string;
140+
};
141+
```
142+
143+
</div>
144+
145+
</div>
146+
147+
#### Variants
148+
149+
Candid [variants](https://github.com/dfinity/candid/blob/master/spec/Candid.md#variants) without type parameters are represented as TypeScript enums:
150+
151+
<div class="code-comparison">
152+
153+
<div>
154+
155+
**Candid**
156+
157+
```
158+
type MyType = variant {
159+
A;
160+
B;
161+
}
162+
```
163+
164+
</div>
165+
166+
<div>
167+
168+
**TypeScript**
24169

25-
This file contains the TypeScript wrapper for the Candid JS bindings generated in [`declarations/<service-name>.did.js`](#declarationsservice-namedidjs). It offers a more idiomatic and type-safe TypeScript interface over the Candid JS bindings. Set the [`output.actor.disabled`](./core/api/type-aliases/GenerateOutputOptions.md#disabled) option to `true` to skip generating this file.
170+
```typescript
171+
enum MyType {
172+
A,
173+
B,
174+
}
175+
```
176+
177+
</div>
178+
179+
</div>
180+
181+
#### Variants with Types
182+
183+
Variants that contain types in their fields are represented as TypeScript unions:
184+
185+
<div class="code-comparison">
186+
187+
<div>
188+
189+
**Candid**
190+
191+
```
192+
type MyType = variant {
193+
A : text;
194+
B;
195+
C : record {
196+
my_field : text;
197+
};
198+
}
199+
```
200+
201+
</div>
202+
203+
<div>
204+
205+
**TypeScript**
206+
207+
```typescript
208+
type MyType =
209+
| { __kind__: "A"; A: string }
210+
| { __kind__: "B"; B: null }
211+
| { __kind__: "C"; C: { my_field: string } };
212+
```
213+
214+
</div>
215+
216+
</div>
217+
218+
### `<service-name>Interface` type
219+
220+
This type is the TypeScript interface for the service. It contains all the methods that are defined in the [Candid service](https://github.com/dfinity/candid/blob/master/spec/Candid.md#services) in the `.did` file.
221+
222+
For example, a Candid service will be represented as:
223+
224+
<div class="code-comparison">
225+
226+
<div>
227+
228+
**Candid**
229+
230+
```txt title="hello_world.did"
231+
service : () -> {
232+
greet : (name : text) -> text;
233+
};
234+
```
235+
236+
</div>
237+
238+
<div>
239+
240+
**TypeScript**
241+
242+
```typescript title="hello_world.ts"
243+
interface helloWorldInterface = {
244+
greet: (name: string) => string;
245+
};
246+
```
247+
248+
</div>
249+
250+
</div>
251+
252+
### `<service-name>` class
253+
254+
This class implements the [`<service-name>Interface` type](#service-nameinterface-type). It can be instantiated with the [`createActor` function](#createactor-function).
255+
256+
For example, a Candid service will be represented as:
257+
258+
<div class="code-comparison">
259+
260+
<div>
261+
262+
**Candid**
263+
264+
```txt title="hello_world.did"
265+
service : () -> {
266+
greet : (name : text) -> text;
267+
};
268+
```
269+
270+
</div>
271+
272+
<div>
273+
274+
**TypeScript**
275+
276+
```typescript title="hello_world.ts"
277+
class HelloWorld implements helloWorldInterface {
278+
constructor(
279+
private actor: ActorSubclass<_SERVICE>,
280+
) {}
281+
async greet(arg0: string): Promise<string> {
282+
const result = await this.actor.greet(arg0);
283+
return result;
284+
}
285+
}
286+
```
287+
288+
</div>
289+
290+
</div>
291+
292+
Where the `_SERVICE` type is imported from the [`declarations/<service-name>.did.d.ts`](#declarationsservice-namediddts) file and the [`ActorSubclass`](https://js.icp.build/core/latest/libs/agent/api/type-aliases/actorsubclass/) type is imported from the [`@icp-sdk/core/agent`](https://js.icp.build/core/latest/libs/agent/) module.
293+
294+
### `createActor` function
295+
296+
Creates an instance of the [`<service-name>` class](#service-name-class).
26297

27298
Here's an example of how to use the generated client:
28299

29-
```ts
30-
import { createActor } from './bindings/hello_world';
300+
```typescript
301+
import { createActor } from "./bindings/hello_world";
302+
303+
const actor = createActor("your-canister-id");
304+
const greeting = await actor.greet("World");
305+
```
306+
307+
The signature of the `createActor` function is:
308+
309+
```typescript
310+
interface CreateActorOptions {
311+
agent?: Agent;
312+
agentOptions?: HttpAgentOptions;
313+
actorOptions?: ActorConfig;
314+
}
31315

32-
const actor = createActor('your-canister-id');
33-
const greeting = await actor.greet('World');
316+
function createActor(canisterId: string, options: CreateActorOptions = {}): <service-name>Interface;
34317
```
35318

319+
If both the `agent` and `agentOptions` are provided, the `agentOptions` will be ignored and the `agent` will be used. Otherwise, a new [`HttpAgent`](https://js.icp.build/core/latest/libs/agent/api/classes/httpagent/) will be created using the `agentOptions` if provided.
320+
321+
If provided, the `actorOptions` will be passed to the [`Actor.createActor`](https://js.icp.build/core/latest/libs/agent/api/classes/actor/#createactor) function. Otherwise, the default options will be used.
322+
323+
## `declarations/`
324+
325+
This folder contains the actual Candid JS bindings. It generates the same bindings that the [`dfx generate`](https://internetcomputer.org/docs/building-apps/developer-tools/dfx/dfx-generate) command was generating.
326+
327+
### `declarations/<service-name>.did.d.ts`
328+
329+
This file is used in TypeScript projects to type the Candid JS bindings generated in [`declarations/<service-name>.did.js`](#declarationsservice-namedidjs).
330+
331+
### `declarations/<service-name>.did.js`
332+
333+
This file contains the actual Candid JS bindings, that allow encoding and decoding JS objects to and from Candid.
334+
36335
## Optional files
37336

38337
### `<service-name>.d.ts`

0 commit comments

Comments
 (0)