@ic-reactor/core 1.2.2 → 1.3.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
@@ -19,7 +19,7 @@ yarn add @ic-reactor/core
19
19
  or you can use the UMD version:
20
20
 
21
21
  ```html
22
- <script src="https://github.com/B3Pay/ic-reactor/releases/download/v1.2.1/ic-reactor-core.min.js"></script>
22
+ <script src="https://github.com/B3Pay/ic-reactor/releases/download/v1.2.3/ic-reactor-core.min.js"></script>
23
23
  ```
24
24
 
25
25
  ### Using `createReactorCore`
@@ -42,7 +42,7 @@ const { queryCall, updateCall, getPrincipal, login } =
42
42
  })
43
43
  ```
44
44
 
45
- You can find All available methods are returned from the `createReactorCore` function here: [ReactorCore](https://b3pay.github.io/ic-reactor/interfaces/core.types.ReactorCore.html)
45
+ You can find All available methods are returned from the `createReactorCore` function [here](https://b3pay.github.io/ic-reactor/interfaces/core.types.CreateReactorCoreReturnType.html).
46
46
 
47
47
  ```typescript
48
48
  // later in your code
@@ -1,4 +1,4 @@
1
- import type { CanisterId, ActorMethodParameters, ActorMethodReturnType, ActorStore, ActorManagerParameters, FunctionName, VisitService, BaseActor, ActorMethodState } from "./types";
1
+ import type { CanisterId, ActorMethodParameters, ActorMethodReturnType, ActorStore, ActorManagerParameters, FunctionName, VisitService, BaseActor, ActorMethodState, MethodAttributes } from "./types";
2
2
  import { IDL } from "@dfinity/candid";
3
3
  import type { AgentManager } from "../agent";
4
4
  import type { UpdateAgentParameters } from "../../types";
@@ -8,10 +8,10 @@ export declare class ActorManager<A = BaseActor> {
8
8
  private _agentManager;
9
9
  private _unsubscribeAgent;
10
10
  private _subscribers;
11
- methods: Array<FunctionName<A>>;
12
11
  canisterId: CanisterId;
13
12
  actorStore: ActorStore<A>;
14
13
  visitFunction: VisitService<A>;
14
+ methodAttributes: MethodAttributes<A>;
15
15
  private initialState;
16
16
  private updateState;
17
17
  updateMethodState: (method: FunctionName<A>, hash: string, newState: Partial<{
@@ -21,9 +21,9 @@ export declare class ActorManager<A = BaseActor> {
21
21
  }>) => void;
22
22
  constructor(actorConfig: ActorManagerParameters);
23
23
  initialize: (options?: UpdateAgentParameters) => Promise<void>;
24
- extractMethodNames: () => Array<FunctionName<A>>;
25
- extractService: () => VisitService<A>;
26
24
  extractInterface: () => IDL.ServiceClass;
25
+ extractMethodAttributes: () => MethodAttributes<A>;
26
+ extractVisitor: () => VisitService<A>;
27
27
  private initializeActor;
28
28
  callMethod: <M extends FunctionName<A>>(functionName: M, ...args: ActorMethodParameters<A[M]>) => Promise<ActorMethodReturnType<A[M]>>;
29
29
  get agentManager(): AgentManager;
@@ -13,11 +13,11 @@ exports.ActorManager = void 0;
13
13
  /* eslint-disable no-console */
14
14
  const agent_1 = require("@dfinity/agent");
15
15
  const helper_1 = require("../../utils/helper");
16
+ const candid_1 = require("@dfinity/candid");
16
17
  class ActorManager {
17
18
  constructor(actorConfig) {
18
19
  this._actor = null;
19
20
  this._subscribers = [];
20
- this.methods = [];
21
21
  this.initialState = {
22
22
  methodState: {},
23
23
  initializing: false,
@@ -38,11 +38,31 @@ class ActorManager {
38
38
  this.initialize = (options) => __awaiter(this, void 0, void 0, function* () {
39
39
  yield this._agentManager.updateAgent(options);
40
40
  });
41
- this.extractMethodNames = () => {
41
+ this.extractInterface = () => {
42
+ return this._idlFactory({ IDL: candid_1.IDL });
43
+ };
44
+ this.extractMethodAttributes = () => {
42
45
  const iface = this.extractInterface();
43
- return iface._fields.map((service) => service[0]);
46
+ const methodAttributesArray = iface._fields.map(([name, func]) => ({
47
+ name: name,
48
+ attributes: {
49
+ numberOfArgs: func.argTypes.length,
50
+ type: ((0, helper_1.isQuery)(func) ? "query" : "update"),
51
+ validate: (arg) => func.argTypes.some((t, i) => t.covariant(arg[i])),
52
+ },
53
+ }));
54
+ methodAttributesArray.sort((a, b) => {
55
+ if (a.attributes.type === b.attributes.type) {
56
+ return a.attributes.numberOfArgs - b.attributes.numberOfArgs;
57
+ }
58
+ return a.attributes.type === "query" ? -1 : 1;
59
+ });
60
+ return methodAttributesArray.reduce((acc, { name, attributes }) => {
61
+ acc[name] = attributes;
62
+ return acc;
63
+ }, {});
44
64
  };
45
- this.extractService = () => {
65
+ this.extractVisitor = () => {
46
66
  const iface = this.extractInterface();
47
67
  return iface._fields.reduce((acc, service) => {
48
68
  const functionName = service[0];
@@ -54,12 +74,6 @@ class ActorManager {
54
74
  return acc;
55
75
  }, {});
56
76
  };
57
- this.extractInterface = () => {
58
- if (this._actor === null) {
59
- throw new Error("For extracting interface, actor must be initialized");
60
- }
61
- return agent_1.Actor.interfaceOf(this._actor);
62
- };
63
77
  this.initializeActor = (agent) => {
64
78
  console.info(`Initializing actor ${this.canisterId} on ${agent.isLocal() ? "local" : "ic"} network`);
65
79
  const { _idlFactory, canisterId } = this;
@@ -79,7 +93,6 @@ class ActorManager {
79
93
  if (!this._actor) {
80
94
  throw new Error("Failed to initialize actor");
81
95
  }
82
- this.methods = this.extractMethodNames();
83
96
  this.updateState({
84
97
  initializing: false,
85
98
  initialized: true,
@@ -125,9 +138,16 @@ class ActorManager {
125
138
  if (!canisterId) {
126
139
  throw new Error("CanisterId is required!");
127
140
  }
128
- this._agentManager = agentManager;
129
141
  this.canisterId = canisterId;
142
+ if (!idlFactory) {
143
+ throw new Error("IDL factory is required!");
144
+ }
130
145
  this._idlFactory = idlFactory;
146
+ this.methodAttributes = this.extractMethodAttributes();
147
+ if (!agentManager) {
148
+ throw new Error("Agent manager is required!");
149
+ }
150
+ this._agentManager = agentManager;
131
151
  // Initialize stores
132
152
  this.actorStore = (0, helper_1.createStoreWithOptionalDevtools)(this.initialState, {
133
153
  withDevtools,
@@ -136,7 +156,7 @@ class ActorManager {
136
156
  });
137
157
  this._unsubscribeAgent = this._agentManager.subscribeAgent(this.initializeActor, initializeOnCreate);
138
158
  if (withVisitor) {
139
- this.visitFunction = this.extractService();
159
+ this.visitFunction = this.extractVisitor();
140
160
  }
141
161
  else {
142
162
  this.visitFunction = emptyVisitor;
@@ -44,3 +44,8 @@ export type ActorState<A = BaseActor> = {
44
44
  };
45
45
  export type ActorStore<A = BaseActor> = StoreApiWithDevtools<ActorState<A>>;
46
46
  export type CallActorMethod<A = BaseActor> = <M extends FunctionName<A> = FunctionName<A>>(functionName: M, ...args: ActorMethodParameters<A[M]>) => Promise<ActorMethodReturnType<A[M]>>;
47
+ export type MethodAttributes<A = BaseActor> = Record<FunctionName<A>, {
48
+ type: FunctionType;
49
+ numberOfArgs: number;
50
+ validate: (arg: never) => boolean;
51
+ }>;
@@ -8,7 +8,6 @@ export declare class AgentManager {
8
8
  private _subscribers;
9
9
  agentStore: AgentStore;
10
10
  authStore: AuthStore;
11
- isLocalEnv: boolean;
12
11
  private initialAgentState;
13
12
  private initialAuthState;
14
13
  private updateAgentState;
@@ -25,6 +24,7 @@ export declare class AgentManager {
25
24
  returnTo?: string;
26
25
  }) => Promise<void>;
27
26
  getAgent: () => HttpAgent;
27
+ getIsLocal: () => boolean;
28
28
  getAgentState: AgentStore["getState"];
29
29
  subscribeAgentState: AgentStore["subscribe"];
30
30
  getAuthState: AuthStore["getState"];
@@ -48,12 +48,13 @@ class AgentManager {
48
48
  this.authStore.setState((state) => (Object.assign(Object.assign({}, state), newState)), false, action);
49
49
  };
50
50
  this.initializeAgent = () => __awaiter(this, void 0, void 0, function* () {
51
+ const isLocalEnv = this.getIsLocal();
51
52
  this.updateAgentState({
52
53
  initializing: true,
53
54
  error: undefined,
54
- network: this.isLocalEnv ? "local" : "ic",
55
+ network: isLocalEnv ? "local" : "ic",
55
56
  }, "initializing");
56
- if (this.isLocalEnv) {
57
+ if (isLocalEnv) {
57
58
  try {
58
59
  yield this._agent.fetchRootKey();
59
60
  }
@@ -83,7 +84,6 @@ class AgentManager {
83
84
  }
84
85
  else if (options) {
85
86
  this._agent = new agent_1.HttpAgent(options);
86
- this.isLocalEnv = this._agent.isLocal();
87
87
  yield this.initializeAgent();
88
88
  }
89
89
  yield this.notifySubscribers();
@@ -116,7 +116,7 @@ class AgentManager {
116
116
  if (!this._auth) {
117
117
  throw new Error("Auth client not initialized");
118
118
  }
119
- yield this._auth.login(Object.assign(Object.assign({ identityProvider: this.isLocalEnv
119
+ yield this._auth.login(Object.assign(Object.assign({ identityProvider: this.getIsLocal()
120
120
  ? constants_1.LOCAL_INTERNET_IDENTITY_PROVIDER
121
121
  : constants_1.IC_INTERNET_IDENTITY_PROVIDER }, options), { onSuccess: () => __awaiter(this, void 0, void 0, function* () {
122
122
  var _b;
@@ -135,6 +135,9 @@ class AgentManager {
135
135
  this.getAgent = () => {
136
136
  return this._agent;
137
137
  };
138
+ this.getIsLocal = () => {
139
+ return this._agent.isLocal();
140
+ };
138
141
  this.getAgentState = () => {
139
142
  return this.agentStore.getState();
140
143
  };
@@ -177,7 +180,6 @@ class AgentManager {
177
180
  store: "auth",
178
181
  });
179
182
  this._agent = new agent_1.HttpAgent(Object.assign(Object.assign({}, agentOptions), { host }));
180
- this.isLocalEnv = this._agent.isLocal();
181
183
  this.initializeAgent();
182
184
  }
183
185
  }
@@ -7,6 +7,6 @@ import { ActorManagerParameters, BaseActor } from "./types";
7
7
  * It also provides a way to interact with the actor's state.
8
8
  *
9
9
  * @category Main
10
- * @includeExample ./packages/core/README.md:262-277
10
+ * @includeExample ./packages/core/README.md:268-283
11
11
  */
12
12
  export declare const createActorManager: <A = BaseActor>(config: ActorManagerParameters) => ActorManager<A>;
@@ -9,7 +9,7 @@ const actor_1 = require("./classes/actor");
9
9
  * It also provides a way to interact with the actor's state.
10
10
  *
11
11
  * @category Main
12
- * @includeExample ./packages/core/README.md:262-277
12
+ * @includeExample ./packages/core/README.md:268-283
13
13
  */
14
14
  const createActorManager = (config) => {
15
15
  return new actor_1.ActorManager(config);
@@ -7,6 +7,6 @@ import { AgentManagerParameters } from "./types";
7
7
  * login and logout to the internet identity.
8
8
  *
9
9
  * @category Main
10
- * @includeExample ./packages/core/README.md:226-254
10
+ * @includeExample ./packages/core/README.md:232-260
11
11
  */
12
12
  export declare const createAgentManager: (config?: AgentManagerParameters) => AgentManager;
@@ -9,7 +9,7 @@ const agent_1 = require("./classes/agent");
9
9
  * login and logout to the internet identity.
10
10
  *
11
11
  * @category Main
12
- * @includeExample ./packages/core/README.md:226-254
12
+ * @includeExample ./packages/core/README.md:232-260
13
13
  */
14
14
  const createAgentManager = (config) => {
15
15
  return new agent_1.AgentManager(config);
@@ -6,6 +6,6 @@ import { CandidAdapterParameters } from "./types";
6
6
  * If both methods fail, it throws an error.
7
7
  *
8
8
  * @category Main
9
- * @includeExample ./packages/core/README.md:145-186
9
+ * @includeExample ./packages/core/README.md:151-192
10
10
  */
11
11
  export declare const createCandidAdapter: (config: CandidAdapterParameters) => CandidAdapter;
@@ -8,7 +8,7 @@ const candid_1 = require("./classes/candid");
8
8
  * If both methods fail, it throws an error.
9
9
  *
10
10
  * @category Main
11
- * @includeExample ./packages/core/README.md:145-186
11
+ * @includeExample ./packages/core/README.md:151-192
12
12
  */
13
13
  const createCandidAdapter = (config) => {
14
14
  return new candid_1.CandidAdapter(config);
@@ -5,6 +5,6 @@ import type { BaseActor, CreateReactorCoreParameters, CreateReactorCoreReturnTyp
5
5
  * Its create a new agent manager if not provided.
6
6
  *
7
7
  * @category Main
8
- * @includeExample ./packages/core/README.md:26-80
8
+ * @includeExample ./packages/core/README.md:32-86
9
9
  */
10
10
  export declare const createReactorCore: <A = BaseActor>(config: CreateReactorCoreParameters) => CreateReactorCoreReturnType<A>;
@@ -29,7 +29,7 @@ const createReactorStore_1 = require("./createReactorStore");
29
29
  * Its create a new agent manager if not provided.
30
30
  *
31
31
  * @category Main
32
- * @includeExample ./packages/core/README.md:26-80
32
+ * @includeExample ./packages/core/README.md:32-86
33
33
  */
34
34
  const createReactorCore = (config) => {
35
35
  const _a = (0, createReactorStore_1.createReactorStore)(config), { subscribeActorState, updateMethodState, callMethod, getState, agentManager } = _a, rest = __rest(_a, ["subscribeActorState", "updateMethodState", "callMethod", "getState", "agentManager"]);
@@ -6,6 +6,6 @@ import type { BaseActor, CreateReactorStoreParameters } from "./types";
6
6
  * It also creates a new actor manager with the given options.
7
7
  *
8
8
  * @category Main
9
- * @includeExample ./packages/core/README.md:194-220
9
+ * @includeExample ./packages/core/README.md:200-226
10
10
  */
11
11
  export declare const createReactorStore: <A = BaseActor>(config: CreateReactorStoreParameters) => ActorManager<A>;
@@ -21,7 +21,7 @@ const createAgentManager_1 = require("./createAgentManager");
21
21
  * It also creates a new actor manager with the given options.
22
22
  *
23
23
  * @category Main
24
- * @includeExample ./packages/core/README.md:194-220
24
+ * @includeExample ./packages/core/README.md:200-226
25
25
  */
26
26
  const createReactorStore = (config) => {
27
27
  const withLocalEnv = config.withProcessEnv
@@ -1,11 +1,12 @@
1
1
  import { DevtoolsOptions } from "zustand/middleware";
2
- import type { BaseActor } from "../types";
2
+ import type { BaseActor, IDL } from "../types";
3
3
  export declare function createStoreWithOptionalDevtools<T>(initialState: T, config: DevtoolsOptions): Omit<import("zustand/vanilla").StoreApi<T>, "setState"> & {
4
4
  setState<A extends string | {
5
5
  type: string;
6
6
  }>(partial: T | Partial<T> | ((state: T) => T | Partial<T>), replace?: boolean | undefined, action?: A | undefined): void;
7
7
  };
8
8
  export declare const isInLocalOrDevelopment: () => boolean;
9
+ export declare function isQuery(func: IDL.FuncClass): boolean;
9
10
  export declare const jsonToString: (json: unknown, space?: number) => string;
10
11
  export declare const generateRequestHash: (args?: unknown[]) => `0x${string}`;
11
12
  export declare const generateHash: (field?: unknown) => `0x${string}`;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.stringToHash = exports.generateActorHash = exports.generateHash = exports.generateRequestHash = exports.jsonToString = exports.isInLocalOrDevelopment = exports.createStoreWithOptionalDevtools = void 0;
3
+ exports.stringToHash = exports.generateActorHash = exports.generateHash = exports.generateRequestHash = exports.jsonToString = exports.isQuery = exports.isInLocalOrDevelopment = exports.createStoreWithOptionalDevtools = void 0;
4
4
  const agent_1 = require("@dfinity/agent");
5
5
  const middleware_1 = require("zustand/middleware");
6
6
  const vanilla_1 = require("zustand/vanilla");
@@ -21,6 +21,11 @@ const isInLocalOrDevelopment = () => {
21
21
  process.env.NODE_ENV === "development"));
22
22
  };
23
23
  exports.isInLocalOrDevelopment = isInLocalOrDevelopment;
24
+ function isQuery(func) {
25
+ return (func.annotations.includes("query") ||
26
+ func.annotations.includes("composite_query"));
27
+ }
28
+ exports.isQuery = isQuery;
24
29
  const jsonToString = (json, space = 2) => {
25
30
  return JSON.stringify(json, (_, value) => (typeof value === "bigint" ? `BigInt(${value})` : value), space);
26
31
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ic-reactor/core",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "A library for intracting with the Internet Computer canisters",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -52,5 +52,5 @@
52
52
  "engines": {
53
53
  "node": ">=10"
54
54
  },
55
- "gitHead": "9d79b40cd3306d2f363ac7ab3a6b9815300648d6"
55
+ "gitHead": "25043c2d1a78b97e327995abaf13835ac511e5d6"
56
56
  }