Skip to content

Commit

Permalink
docs: add docs explaining the type shims that workaround issues with …
Browse files Browse the repository at this point in the history
…candid/dfx generated types
  • Loading branch information
nathanosdev committed Jan 24, 2024
1 parent 74824d0 commit 42a0dbd
Showing 1 changed file with 107 additions and 2 deletions.
109 changes: 107 additions & 2 deletions packages/pic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ npm i -D @dfinity/{agent,candid,identity,principal}

## Usage

The easist way to use PocketIC is to use `setupCanister` convenience method:
The easiest way to use PocketIC is to use `setupCanister` convenience method:

```ts
import { PocketIc } from '@hadronous/pic';
Expand Down Expand Up @@ -69,9 +69,114 @@ PicJS leverages a [`postinstall`](https://docs.npmjs.com/cli/v9/using-npm/script
}
```

## Canister Declarations

The DFX auto-generated bindings for canisters have some issues that make the developer experience with PicJS less than ideal. There are four files generated by DFX for a canister. To use a `counter` canister as an example:

- `counter.did.js` - Exports the canister's Candid as a JavaScript object. The `idlFactory` and `init` exports in this file are not included in the `counter.did.d.ts` file.

```js
export const idlFactory = ({ IDL }) => {
const Counter = IDL.Service({
// redacted...
});
return Counter;
};

export const init = ({ IDL }) => {
return [IDL.Nat];
};
```

- `counter.did.d.ts` - Exports the canister's Candid as a TypeScript interface. This file is missing the `idlFactory` and `init` exports that are present in the `counter.did.js` file.

```ts
import type { Principal } from '@dfinity/principal';
import type { ActorMethod } from '@dfinity/agent';

export interface Counter {
// redacted...
}

export interface _SERVICE extends Counter {}
```

- `index.d.ts` - Exports TypeScript interfaces for actor creation utilities. This file re-exports the `idlFactory`, but not the `init` declarations from `clock.did.ts`.

```ts
import type {
ActorSubclass,
HttpAgentOptions,
ActorConfig,
Agent,
} from '@dfinity/agent';
import type { Principal } from '@dfinity/principal';
import type { IDL } from '@dfinity/candid';

import { _SERVICE } from './counter.did';

export declare const idlFactory: IDL.InterfaceFactory;
export declare const canisterId: string;

export declare interface CreateActorOptions {
// redacted...
}

export declare const createActor: (
canisterId: string | Principal,
options?: CreateActorOptions,
) => ActorSubclass<_SERVICE>;

export declare const counter: ActorSubclass<_SERVICE>;
```

- `index.js` - Exports TypeScript interfaces for actor creation utilities. This file re-exports the `idlFactory`, but not the `init` declarations from `clock.did.js` and also exports an auto-created canister actor which will throw exceptions outside of the browser due to `window.location` missing.

```js
import { Actor, HttpAgent } from '@dfinity/agent';

import { idlFactory } from './counter.did.js';
export { idlFactory } from './counter.did.js';

export const canisterId =
process.env.CANISTER_ID_COUNTER || process.env.COUNTER_CANISTER_ID;

export const createActor = (canisterId, options = {}) => {
// redacted...
};

export const counter = createActor(canisterId);
```

To summarize the problems:

- `index.js` and `index.d.ts` are missing the `init` export and also export an auto-created actor that breaks outside of the browser.
- `counter.did.js` and `counter.did.d.ts` are missing the `init` and `idlFactory` exports.

Fixes for these issues are already merged into Candid, but they need to be released and included in DFX before we can leverage them. To work around these issues for now, we can add two new files to export the missing items:

- `index.js`

```js
export { idlFactory, init } from '../../declarations/counter.did';
```

- `index.d.ts`

```ts
import { IDL } from '@dfinity/candid';
import { Actor } from '@hadronous/pic';
import { _SERVICE } from '../../declarations/counter.did';

export declare const idlFactory: IDL.InterfaceFactory;
export declare const init: ({ IDL }: { IDL: IDL }) => IDL.Type[];
```

Examples of this fix can be found for each of the examples in the [examples](#examples) section.

## API Docs

More detailed documentation is available in the [API docs](https://hadronous.github.io/pic-js/). The best place to start is with the [PocketIc](https://hadronous.github.io/pic-js/classes/PocketIc.html) class and then move onto the [Actor](https://hadronous.github.io/pic-js/interfaces/Actor.html) class.
More detailed documentation is available in the [API docs](https://hadronous.github.io/pic-js/). The best place to start is with the [PocketIc](https://hadronous.github.io/pic-js/classes/PocketIc.html) class and then move on to the [Actor](https://hadronous.github.io/pic-js/interfaces/Actor.html) class.

## Examples

Expand Down

0 comments on commit 42a0dbd

Please sign in to comment.