@ic-reactor/react 1.0.3 → 1.0.4

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.
@@ -1,4 +1,21 @@
1
1
  import type { ActorHooks } from "../types";
2
2
  import type { BaseActor } from "@ic-reactor/core/dist/types";
3
3
  import { ActorManager } from "@ic-reactor/core";
4
+ /**
5
+ * Provides a set of React hooks designed for interacting with actors in an Internet Computer (IC) project using the React framework and Zustand for state management.
6
+ *
7
+ * @param actorManager An instance of ActorManager containing methods and properties to manage actors, including the actorStore, canisterId, visitFunction, callMethod, and initialize function.
8
+ * @returns An object containing several hooks and utility functions for interacting with actors, managing state, and invoking actor methods.
9
+ *
10
+ * Hooks included:
11
+ * - initialize: Function to initialize actor management.
12
+ * - useActorState: Hook for accessing the actor's state including the canister ID.
13
+ * - useVisitMethod: Hook for memoizing a method visit service for a given actor method name.
14
+ * - useReactorCall: Hook for making calls to actor methods with support for loading states, errors, and custom event handlers.
15
+ * - useQueryCall: Hook specifically designed for query calls to actors with features such as automatic refetching on mount and at specified intervals.
16
+ * - useUpdateCall: Alias for useReactorCall, tailored for update calls to actors.
17
+ * - useMethodCall: Combines useVisitMethod and useReactorCall for a streamlined experience when calling actor methods, including visitation and state management.
18
+ *
19
+ * Each hook is designed to simplify the process of interacting with actors in IC projects by abstracting away the complexity of state management, error handling, and method invocation.
20
+ */
4
21
  export declare const getActorHooks: <A = BaseActor>(actorManager: ActorManager<A>) => ActorHooks<A>;
@@ -28,6 +28,23 @@ const DEFAULT_STATE = {
28
28
  error: undefined,
29
29
  loading: false,
30
30
  };
31
+ /**
32
+ * Provides a set of React hooks designed for interacting with actors in an Internet Computer (IC) project using the React framework and Zustand for state management.
33
+ *
34
+ * @param actorManager An instance of ActorManager containing methods and properties to manage actors, including the actorStore, canisterId, visitFunction, callMethod, and initialize function.
35
+ * @returns An object containing several hooks and utility functions for interacting with actors, managing state, and invoking actor methods.
36
+ *
37
+ * Hooks included:
38
+ * - initialize: Function to initialize actor management.
39
+ * - useActorState: Hook for accessing the actor's state including the canister ID.
40
+ * - useVisitMethod: Hook for memoizing a method visit service for a given actor method name.
41
+ * - useReactorCall: Hook for making calls to actor methods with support for loading states, errors, and custom event handlers.
42
+ * - useQueryCall: Hook specifically designed for query calls to actors with features such as automatic refetching on mount and at specified intervals.
43
+ * - useUpdateCall: Alias for useReactorCall, tailored for update calls to actors.
44
+ * - useMethodCall: Combines useVisitMethod and useReactorCall for a streamlined experience when calling actor methods, including visitation and state management.
45
+ *
46
+ * Each hook is designed to simplify the process of interacting with actors in IC projects by abstracting away the complexity of state management, error handling, and method invocation.
47
+ */
31
48
  const getActorHooks = (actorManager) => {
32
49
  const { actorStore, canisterId, visitFunction, callMethod, initialize } = actorManager;
33
50
  const useActorState = () => (Object.assign(Object.assign({}, (0, zustand_1.useStore)(actorStore)), { canisterId }));
@@ -59,7 +76,7 @@ const getActorHooks = (actorManager) => {
59
76
  if (throwOnError)
60
77
  throw error;
61
78
  }
62
- }), [args, functionName, events, callMethod]);
79
+ }), [args, functionName, events]);
63
80
  return Object.assign({ call, reset }, state);
64
81
  };
65
82
  const useQueryCall = (_a) => {
@@ -67,14 +84,14 @@ const getActorHooks = (actorManager) => {
67
84
  const _b = useReactorCall(rest), { call } = _b, state = __rest(_b, ["call"]);
68
85
  const intervalId = (0, react_1.useRef)();
69
86
  (0, react_1.useEffect)(() => {
70
- if (refetchInterval)
87
+ if (refetchInterval) {
71
88
  intervalId.current = setInterval(call, refetchInterval);
72
- return () => clearInterval(intervalId.current);
73
- }, [refetchInterval, call]);
74
- (0, react_1.useLayoutEffect)(() => {
75
- if (refetchOnMount)
89
+ }
90
+ if (refetchOnMount) {
76
91
  call();
77
- }, [call, refetchOnMount]);
92
+ }
93
+ return () => clearInterval(intervalId.current);
94
+ }, [refetchInterval, refetchOnMount]);
78
95
  return Object.assign({ call }, state);
79
96
  };
80
97
  const useUpdateCall = useReactorCall;
@@ -1,6 +1,3 @@
1
1
  import type { AgentManager } from "@ic-reactor/core/dist/agent";
2
- import type { HttpAgent } from "@ic-reactor/core/dist/types";
3
- export declare const getAgentHooks: (agentManager: AgentManager) => {
4
- useAgent: () => HttpAgent | undefined;
5
- useAgentState: () => import("@ic-reactor/core/dist/types").AgentState;
6
- };
2
+ import type { AgentHooks } from "./types";
3
+ export declare const getAgentHooks: (agentManager: AgentManager) => AgentHooks;
@@ -1,7 +1,3 @@
1
1
  import type { AgentManager } from "@ic-reactor/core/dist/agent";
2
- import type { UseAuthClientArgs, UseAuthClientReturn } from "../types";
3
- export declare const getAuthHooks: (agentManager: AgentManager) => {
4
- useUserPrincipal: () => import("@dfinity/principal").Principal | undefined;
5
- useAuthState: () => import("@ic-reactor/core/dist/agent/types").AuthState;
6
- useAuthClient: (events?: UseAuthClientArgs) => UseAuthClientReturn;
7
- };
2
+ import type { AuthHooks } from "../types";
3
+ export declare const getAuthHooks: (agentManager: AgentManager) => AuthHooks;
@@ -1,10 +1,23 @@
1
1
  /// <reference types="react" />
2
2
  import type { AuthClientLoginOptions } from "@dfinity/auth-client";
3
- import type { getAgentHooks } from "./agent";
4
- import type { getAuthHooks } from "./auth";
5
- import type { ActorState, CanisterId, ActorMethodArgs, ActorMethodReturnType, Identity, Principal, FunctionName, VisitService, AuthClient } from "@ic-reactor/core/dist/types";
6
- export type AgentHooks = ReturnType<typeof getAgentHooks>;
7
- export type AuthHooks = ReturnType<typeof getAuthHooks>;
3
+ import type { ActorState, CanisterId, ActorMethodArgs, ActorMethodReturnType, Identity, Principal, FunctionName, VisitService, AuthClient, AuthState, HttpAgent, AgentState } from "@ic-reactor/core/dist/types";
4
+ export interface AgentHooks {
5
+ useAgent: () => HttpAgent | undefined;
6
+ useAgentState: () => AgentState;
7
+ }
8
+ export interface AuthHooks {
9
+ useUserPrincipal: () => Principal | undefined;
10
+ useAuthState: () => AuthState;
11
+ useAuthClient: (events?: UseAuthClientArgs) => UseAuthClientReturn;
12
+ }
13
+ export interface ActorHooks<A> {
14
+ initialize: () => Promise<void>;
15
+ useActorState: () => UseActorState;
16
+ useQueryCall: UseQueryCall<A>;
17
+ useUpdateCall: UseUpdateCall<A>;
18
+ useMethodCall: UseMethodCall<A>;
19
+ useVisitMethod: <M extends FunctionName<A>>(functionName: M) => VisitService<A>[M];
20
+ }
8
21
  export interface UseAuthClientArgs {
9
22
  onAuthentication?: (promise: () => Promise<Identity>) => void;
10
23
  onAuthenticationSuccess?: (identity: Identity) => void;
@@ -71,11 +84,3 @@ export type UseMethodCallArg<A, M extends FunctionName<A>> = ReactorCallArgs<A,
71
84
  export interface UseActorState extends Omit<ActorState, "methodState"> {
72
85
  canisterId: CanisterId;
73
86
  }
74
- export interface ActorHooks<A> {
75
- initialize: () => Promise<void>;
76
- useActorState: () => UseActorState;
77
- useQueryCall: UseQueryCall<A>;
78
- useUpdateCall: UseUpdateCall<A>;
79
- useMethodCall: UseMethodCall<A>;
80
- useVisitMethod: <M extends FunctionName<A>>(functionName: M) => VisitService<A>[M];
81
- }
@@ -1,2 +1 @@
1
1
  export * from "./useReactor";
2
- export * from "./useCandid";
@@ -15,4 +15,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./useReactor"), exports);
18
- __exportStar(require("./useCandid"), exports);
@@ -0,0 +1,19 @@
1
+ import { IDL } from "@dfinity/candid";
2
+ import { ActorManagerOptions, BaseActor } from "@ic-reactor/core/dist/types";
3
+ import { ActorHooks, AgentContextType } from "../types";
4
+ export interface UseReactorOptions extends Omit<ActorManagerOptions, "idlFactory" | "agentManager" | "canisterId"> {
5
+ canisterId: string;
6
+ idlFactory?: IDL.InterfaceFactory;
7
+ agentContext?: AgentContextType;
8
+ didjsCanisterId?: string;
9
+ }
10
+ export interface UseReactorState {
11
+ idlFactory?: IDL.InterfaceFactory;
12
+ fetching: boolean;
13
+ fetchError: string | null;
14
+ }
15
+ export interface UseReactorReturn<A = BaseActor> {
16
+ hooks: ActorHooks<A> | null;
17
+ fetching: boolean;
18
+ fetchError: string | null;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,19 +1,41 @@
1
- import { IDL } from "@dfinity/candid";
2
- import { ActorManagerOptions, BaseActor } from "@ic-reactor/core/dist/types";
3
- import { AgentContextType } from "../types";
4
- interface DynamicActorArgs extends Omit<ActorManagerOptions, "idlFactory" | "agentManager" | "canisterId"> {
5
- canisterId: string;
6
- idlFactory?: IDL.InterfaceFactory;
7
- agentContext?: AgentContextType;
8
- didjsCanisterId?: string;
9
- }
1
+ import { BaseActor } from "../types";
2
+ import { UseReactorOptions, UseReactorReturn } from "./types";
10
3
  /**
11
- * A hook to create an actor manager and fetch the actor's candid interface.
4
+ * A comprehensive hook that manages both the fetching of Candid interfaces
5
+ * and the initialization of actor stores for Internet Computer (IC) canisters.
6
+ * It simplifies the process of interacting with canisters by encapsulating
7
+ * the logic for Candid retrieval and actor store management.
8
+ *
9
+ * @example
10
+ * ```tsx
11
+ * import React from 'react';
12
+ * import { useReactor } from '@ic-reactor/react';
13
+ * import { IDL } from '@dfinity/candid';
14
+ *
15
+ * const App = () => {
16
+ * const { actorManager, fetchCandid, candid, fetching, fetchError } = useReactor({
17
+ * canisterId: 'ryjl3-tyaaa-aaaaa-aaaba-cai',
18
+ * });
19
+ *
20
+ * return (
21
+ * <div>
22
+ * <h2>IC Canister Interaction</h2>
23
+ * {fetching && <p>Loading Candid interface...</p>}
24
+ * {fetchError && <p>Error: {fetchError}</p>}
25
+ * {candid.idlFactory && (
26
+ * <div>
27
+ * <p>Candid interface fetched successfully.</p>
28
+ * <pre>{JSON.stringify(candid.idlFactory({ IDL }), null, 2)}</pre>
29
+ * </div>
30
+ * )}
31
+ * <button onClick={fetchCandid} disabled={fetching}>
32
+ * {fetching ? 'Fetching...' : 'Fetch Candid'}
33
+ * </button>
34
+ * </div>
35
+ * );
36
+ * };
37
+ *
38
+ * export default App;
39
+ * ```
12
40
  */
13
- export declare const useReactor: <A = BaseActor>({ canisterId, agentContext, idlFactory: maybeIdlFactory, didjsCanisterId, ...config }: DynamicActorArgs) => {
14
- fetchCandid: () => Promise<import("@ic-reactor/core/dist/types").CandidDefenition | undefined>;
15
- fetching: boolean;
16
- fetchError: string | null;
17
- actorManager: import("@ic-reactor/core").ActorManager<A> | null;
18
- };
19
- export {};
41
+ export declare const useReactor: <A = BaseActor>({ canisterId, agentContext, idlFactory: maybeIdlFactory, didjsCanisterId, ...config }: UseReactorOptions) => UseReactorReturn<A>;
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __rest = (this && this.__rest) || function (s, e) {
3
12
  var t = {};
4
13
  for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
@@ -15,32 +24,98 @@ exports.useReactor = void 0;
15
24
  const core_1 = require("@ic-reactor/core");
16
25
  const react_1 = require("react");
17
26
  const agent_1 = require("../provider/agent");
18
- const useCandid_1 = require("./useCandid");
27
+ const helpers_1 = require("../helpers");
19
28
  /**
20
- * A hook to create an actor manager and fetch the actor's candid interface.
29
+ * A comprehensive hook that manages both the fetching of Candid interfaces
30
+ * and the initialization of actor stores for Internet Computer (IC) canisters.
31
+ * It simplifies the process of interacting with canisters by encapsulating
32
+ * the logic for Candid retrieval and actor store management.
33
+ *
34
+ * @example
35
+ * ```tsx
36
+ * import React from 'react';
37
+ * import { useReactor } from '@ic-reactor/react';
38
+ * import { IDL } from '@dfinity/candid';
39
+ *
40
+ * const App = () => {
41
+ * const { actorManager, fetchCandid, candid, fetching, fetchError } = useReactor({
42
+ * canisterId: 'ryjl3-tyaaa-aaaaa-aaaba-cai',
43
+ * });
44
+ *
45
+ * return (
46
+ * <div>
47
+ * <h2>IC Canister Interaction</h2>
48
+ * {fetching && <p>Loading Candid interface...</p>}
49
+ * {fetchError && <p>Error: {fetchError}</p>}
50
+ * {candid.idlFactory && (
51
+ * <div>
52
+ * <p>Candid interface fetched successfully.</p>
53
+ * <pre>{JSON.stringify(candid.idlFactory({ IDL }), null, 2)}</pre>
54
+ * </div>
55
+ * )}
56
+ * <button onClick={fetchCandid} disabled={fetching}>
57
+ * {fetching ? 'Fetching...' : 'Fetch Candid'}
58
+ * </button>
59
+ * </div>
60
+ * );
61
+ * };
62
+ *
63
+ * export default App;
64
+ * ```
21
65
  */
22
66
  const useReactor = (_a) => {
23
67
  var { canisterId, agentContext, idlFactory: maybeIdlFactory, didjsCanisterId } = _a, config = __rest(_a, ["canisterId", "agentContext", "idlFactory", "didjsCanisterId"]);
24
- const agentManager = (0, agent_1.useAgentManager)(agentContext);
25
- const _b = (0, useCandid_1.useCandid)({
26
- canisterId,
27
- didjsCanisterId,
68
+ const [{ idlFactory, fetching, fetchError }, setState] = (0, react_1.useState)({
28
69
  idlFactory: maybeIdlFactory,
29
- }), { candid: { idlFactory } } = _b, rest = __rest(_b, ["candid"]);
30
- const actorManager = (0, react_1.useMemo)(() => {
31
- if (!idlFactory) {
32
- return null;
33
- }
34
- else {
35
- const manager = (0, core_1.createReactorStore)({
70
+ fetching: false,
71
+ fetchError: null,
72
+ });
73
+ const agentManager = (0, agent_1.useAgentManager)(agentContext);
74
+ const fetchCandid = (0, react_1.useCallback)(() => __awaiter(void 0, void 0, void 0, function* () {
75
+ if (!canisterId)
76
+ return;
77
+ setState({
78
+ idlFactory: undefined,
79
+ fetching: true,
80
+ fetchError: null,
81
+ });
82
+ try {
83
+ const candidManager = (0, core_1.createCandidAdapter)({
36
84
  agentManager,
85
+ didjsCanisterId,
86
+ });
87
+ const { idlFactory } = yield candidManager.getCandidDefinition(canisterId);
88
+ setState({
37
89
  idlFactory,
38
- canisterId,
39
- withDevtools: config.withDevtools,
90
+ fetching: false,
91
+ fetchError: null,
92
+ });
93
+ return idlFactory;
94
+ }
95
+ catch (err) {
96
+ // eslint-disable-next-line no-console
97
+ console.error(err);
98
+ setState({
99
+ idlFactory: undefined,
100
+ fetchError: `Error fetching canister ${canisterId}`,
101
+ fetching: false,
40
102
  });
41
- return manager;
42
103
  }
104
+ }), [canisterId, didjsCanisterId, agentManager]);
105
+ // Automatically fetch Candid if not already fetched or provided.
106
+ (0, react_1.useEffect)(() => {
107
+ if (!fetching && !idlFactory) {
108
+ fetchCandid();
109
+ }
110
+ }, [fetchCandid]);
111
+ const hooks = (0, react_1.useMemo)(() => {
112
+ if (!idlFactory)
113
+ return null;
114
+ const actorManager = (0, core_1.createActorManager)(Object.assign({ agentManager,
115
+ idlFactory,
116
+ canisterId }, config));
117
+ return (0, helpers_1.getActorHooks)(actorManager);
43
118
  }, [idlFactory]);
44
- return Object.assign({ actorManager }, rest);
119
+ return { hooks, fetching, fetchError };
45
120
  };
46
121
  exports.useReactor = useReactor;
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { BaseActor, FunctionName, UseMethodCallArg, UseQueryCallArgs, UseUpdateCallArgs } from "../../types";
3
+ import { CreateActorOptions, ActorContextType, ActorProviderProps } from "./types";
4
+ export declare function createReactorContext<A = BaseActor>({ canisterId: defaultCanisterId, ...defaultConfig }?: Partial<CreateActorOptions>): {
5
+ useActorState: () => import("../../types").UseActorState;
6
+ useQueryCall: <M extends FunctionName<A>>(args: UseQueryCallArgs<A, M>) => import("../../types").ReactorCallReturn<A, M>;
7
+ useUpdateCall: <M_1 extends FunctionName<A>>(args: UseUpdateCallArgs<A, M_1>) => import("../../types").ReactorCallReturn<A, M_1>;
8
+ useMethodCall: <M_2 extends FunctionName<A>>(args: UseMethodCallArg<A, M_2>) => import("../../types").UseMethodCallReturn<A, M_2>;
9
+ useVisitMethod: (functionName: FunctionName<A>) => import("@ic-reactor/core/dist/actor/types").VisitService<A>[FunctionName<A>];
10
+ initialize: () => Promise<void>;
11
+ ActorProvider: React.FC<ActorProviderProps>;
12
+ };
13
+ export declare function extractActorHooks<A = BaseActor>(ActorContext: React.Context<ActorContextType<A> | null>): {
14
+ useActorState: () => import("../../types").UseActorState;
15
+ useQueryCall: <M extends FunctionName<A>>(args: UseQueryCallArgs<A, M>) => import("../../types").ReactorCallReturn<A, M>;
16
+ useUpdateCall: <M_1 extends FunctionName<A>>(args: UseUpdateCallArgs<A, M_1>) => import("../../types").ReactorCallReturn<A, M_1>;
17
+ useMethodCall: <M_2 extends FunctionName<A>>(args: UseMethodCallArg<A, M_2>) => import("../../types").UseMethodCallReturn<A, M_2>;
18
+ useVisitMethod: (functionName: FunctionName<A>) => import("@ic-reactor/core/dist/actor/types").VisitService<A>[FunctionName<A>];
19
+ initialize: () => Promise<void>;
20
+ };
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ var __rest = (this && this.__rest) || function (s, e) {
26
+ var t = {};
27
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
+ t[p] = s[p];
29
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
+ t[p[i]] = s[p[i]];
33
+ }
34
+ return t;
35
+ };
36
+ Object.defineProperty(exports, "__esModule", { value: true });
37
+ exports.extractActorHooks = exports.createReactorContext = void 0;
38
+ const react_1 = __importStar(require("react"));
39
+ const useReactor_1 = require("../../hooks/useReactor");
40
+ function createReactorContext(_a = {}) {
41
+ var { canisterId: defaultCanisterId } = _a, defaultConfig = __rest(_a, ["canisterId"]);
42
+ const ActorContext = (0, react_1.createContext)(null);
43
+ const ActorProvider = (_a) => {
44
+ var { children, canisterId = defaultCanisterId, loadingComponent = react_1.default.createElement("div", null, "Fetching canister...") } = _a, restConfig = __rest(_a, ["children", "canisterId", "loadingComponent"]);
45
+ if (!canisterId) {
46
+ throw new Error("canisterId is required");
47
+ }
48
+ const config = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, defaultConfig), restConfig)), [defaultConfig, restConfig]);
49
+ const { fetchError, fetching, hooks } = (0, useReactor_1.useReactor)(Object.assign({ canisterId }, config));
50
+ return (react_1.default.createElement(ActorContext.Provider, { value: hooks }, fetching || hooks === null ? fetchError !== null && fetchError !== void 0 ? fetchError : loadingComponent : children));
51
+ };
52
+ ActorProvider.displayName = "ActorProvider";
53
+ return Object.assign({ ActorProvider }, extractActorHooks(ActorContext));
54
+ }
55
+ exports.createReactorContext = createReactorContext;
56
+ function extractActorHooks(ActorContext) {
57
+ /**
58
+ * Hook for accessing the actor context, including the actor manager and state.
59
+ * @returns The actor context, including the actor manager and state.
60
+ * @example
61
+ * ```tsx
62
+ * function ActorComponent() {
63
+ * const { initialize, useActorState, useQueryCall, useUpdateCall, useMethodCall, useVisitMethod } = useActorContext();
64
+ * const { canisterId } = useActorState();
65
+ *
66
+ * return (
67
+ * <div>
68
+ * <p>Canister ID: {canisterId}</p>
69
+ * </div>
70
+ * );
71
+ * }
72
+ * ```
73
+ */
74
+ const useActorContext = () => {
75
+ const context = (0, react_1.useContext)(ActorContext);
76
+ if (!context) {
77
+ throw new Error("useActor must be used within a ActorProvider");
78
+ }
79
+ return context;
80
+ };
81
+ /**
82
+ * Initializes the actor manager, setting up the actor's state.
83
+ */
84
+ const initialize = () => useActorContext().initialize();
85
+ /**
86
+ * Hook for accessing the current state of the actor, including the canister ID.
87
+ *
88
+ * @returns An object containing the current state of the actor from Zustand's store and the canister ID.
89
+ * @example
90
+ * ```tsx
91
+ * function ActorStateComponent() {
92
+ * const { canisterId, initializing, error, initialized } = useActorState();
93
+ *
94
+ * return (
95
+ * <div>
96
+ * <p>Canister ID: {canisterId}</p>
97
+ * <p>Initializing: {initializing.toString()}</p>
98
+ * <p>Initialized: {initialized.toString()}</p>
99
+ * <p>Error: {error?.message}</p>
100
+ * </div>
101
+ * );
102
+ * }
103
+ *```
104
+ */
105
+ const useActorState = () => useActorContext().useActorState();
106
+ /**
107
+ * Hook for making query calls to actors. It supports automatic refetching on component mount and at specified intervals.
108
+ *
109
+ * @param options Configuration object for the query call, including refetching options and other configurations passed to useReactorCall.
110
+ * @returns An object containing the query call function and the current call state (data, error, loading, call, reset).
111
+ * @example
112
+ * ```tsx
113
+ * function QueryCallComponent() {
114
+ * const { call, data, loading } = useQueryCall({
115
+ * functionName: 'getUserProfile',
116
+ * args: ['123'],
117
+ * refetchOnMount: true,
118
+ * refetchInterval: 5000, // refetch every 5 seconds
119
+ * });
120
+ *
121
+ * if (loading) return <p>Loading profile...</p>;
122
+ *
123
+ * return (
124
+ * <div>
125
+ * <p>User Profile: {JSON.stringify(data)}</p>
126
+ * <button onClick={call}>Refetch</button>
127
+ * </div>
128
+ * );
129
+ * }
130
+ * ```
131
+ */
132
+ const useQueryCall = (args) => useActorContext().useQueryCall(args);
133
+ /**
134
+ * Hook for making update calls to actors, handling loading states, and managing errors. It supports custom event handlers for loading, success, and error events.
135
+ *
136
+ * @param options Configuration object for the actor method call, including the method name, arguments, and event handlers.
137
+ * @returns An object containing the method call function, a reset function to reset the call state to its default, and the current call state (data, error, loading, call, reset).
138
+ * @example
139
+ * ```tsx
140
+ * function UpdateCallComponent() {
141
+ * const { call, data, loading } = useUpdateCall({
142
+ * functionName: 'updateUserProfile',
143
+ * args: ['123', { name: 'John Doe' }],
144
+ * onLoading: (loading) => console.log('Loading:', loading),
145
+ * onError: (error) => console.error('Error:', error),
146
+ * onSuccess: (data) => console.log('Success:', data),
147
+ * });
148
+ *
149
+ * if (loading) return <p>Updating profile...</p>;
150
+ *
151
+ * return (
152
+ * <div>
153
+ * <p>Updated Profile: {JSON.stringify(data)}</p>
154
+ * <button onClick={call}>Update</button>
155
+ * </div>
156
+ * );
157
+ * }
158
+ * ```
159
+ */
160
+ const useUpdateCall = (args) => useActorContext().useUpdateCall(args);
161
+ /**
162
+ * Hook that combines useVisitMethod and useReactorCall for calling actor methods. It provides both the visit service for the method and the ability to make actor calls with state management.
163
+ *
164
+ * @param args Configuration object including the function name and arguments for the actor method call.
165
+ * @returns An object containing the visit function for the method and the current call state (data, error, loading).
166
+ */
167
+ const useMethodCall = (args) => useActorContext().useMethodCall(args);
168
+ /**
169
+ * Memoizes and returns a visit service function for a specific actor method.
170
+ *
171
+ * @param functionName The name of the actor method to visit.
172
+ * @returns The visit service function for the specified method.
173
+ */
174
+ const useVisitMethod = (functionName) => useActorContext().useVisitMethod(functionName);
175
+ return {
176
+ useActorState,
177
+ useQueryCall,
178
+ useUpdateCall,
179
+ useMethodCall,
180
+ useVisitMethod,
181
+ initialize,
182
+ };
183
+ }
184
+ exports.extractActorHooks = extractActorHooks;
@@ -1,15 +1,3 @@
1
- import React from "react";
2
- import { BaseActor, FunctionName, UseMethodCallArg, UseQueryCallArgs, UseUpdateCallArgs } from "../../types";
3
- import { CreateActorOptions, ActorContextType, ActorProviderProps } from "./types";
4
- export declare const ActorContext: React.Context<ActorContextType<BaseActor> | null>, ActorProvider: React.FC<ActorProviderProps>, useActorContext: () => ActorContextType<BaseActor>, useActorState: () => import("../../types").UseActorState, useQueryCall: <M extends string>(args: UseQueryCallArgs<BaseActor, M>) => import("../../types").ReactorCallReturn<BaseActor, M>, useUpdateCall: <M extends string>(args: UseUpdateCallArgs<BaseActor, M>) => import("../../types").ReactorCallReturn<BaseActor, M>, useMethodCall: <M extends string>(args: UseMethodCallArg<BaseActor, M>) => import("../../types").UseMethodCallReturn<BaseActor, M>, useVisitMethod: (functionName: string) => <V extends import("@dfinity/candid/lib/cjs/idl").Visitor<unknown, unknown>>(extractorClass: V, data?: import("@ic-reactor/core/dist/actor/types").VisitorType<V>["data"] | undefined) => ReturnType<V["visitFunc"]>;
5
- export declare function createReactorContext<Actor = BaseActor>({ canisterId: defaultCanisterId, ...defaultConfig }?: Partial<CreateActorOptions>): {
6
- ActorContext: React.Context<ActorContextType<BaseActor> | null>;
7
- ActorProvider: React.FC<ActorProviderProps>;
8
- useActorContext: () => ActorContextType<Actor>;
9
- useActorState: () => import("../../types").UseActorState;
10
- useQueryCall: <M extends FunctionName<Actor>>(args: UseQueryCallArgs<Actor, M>) => import("../../types").ReactorCallReturn<Actor, M>;
11
- useUpdateCall: <M_1 extends FunctionName<Actor>>(args: UseUpdateCallArgs<Actor, M_1>) => import("../../types").ReactorCallReturn<Actor, M_1>;
12
- useMethodCall: <M_2 extends FunctionName<Actor>>(args: UseMethodCallArg<Actor, M_2>) => import("../../types").UseMethodCallReturn<Actor, M_2>;
13
- useVisitMethod: (functionName: FunctionName<Actor>) => import("@ic-reactor/core/dist/actor/types").VisitService<Actor>[FunctionName<Actor>];
14
- initialize: () => Promise<void>;
15
- };
1
+ /// <reference types="react" />
2
+ export declare const ActorProvider: import("react").FC<import("./types").ActorProviderProps>, useActorState: () => import("../../types").UseActorState, useQueryCall: <M extends string>(args: import("../../types").UseQueryCallArgs<import("@ic-reactor/core/dist/types").BaseActor, M>) => import("../../types").ReactorCallReturn<import("@ic-reactor/core/dist/types").BaseActor, M>, useUpdateCall: <M extends string>(args: import("../../types").UseUpdateCallArgs<import("@ic-reactor/core/dist/types").BaseActor, M>) => import("../../types").ReactorCallReturn<import("@ic-reactor/core/dist/types").BaseActor, M>, useMethodCall: <M extends string>(args: import("../../types").UseMethodCallArg<import("@ic-reactor/core/dist/types").BaseActor, M>) => import("../../types").UseMethodCallReturn<import("@ic-reactor/core/dist/types").BaseActor, M>, useVisitMethod: (functionName: string) => <V extends import("@dfinity/candid/lib/cjs/idl").Visitor<unknown, unknown>>(extractorClass: V, data?: import("@ic-reactor/core/dist/types").VisitorType<V>["data"] | undefined) => ReturnType<V["visitFunc"]>;
3
+ export { createReactorContext, extractActorHooks } from "./context";
@@ -1,87 +1,9 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __rest = (this && this.__rest) || function (s, e) {
26
- var t = {};
27
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
28
- t[p] = s[p];
29
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
30
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
31
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
32
- t[p[i]] = s[p[i]];
33
- }
34
- return t;
35
- };
36
2
  var _a;
37
3
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.createReactorContext = exports.useVisitMethod = exports.useMethodCall = exports.useUpdateCall = exports.useQueryCall = exports.useActorState = exports.useActorContext = exports.ActorProvider = exports.ActorContext = void 0;
39
- const react_1 = __importStar(require("react"));
40
- const actor_1 = require("../../helpers/actor");
41
- const useReactor_1 = require("../../hooks/useReactor");
42
- _a = createReactorContext(), exports.ActorContext = _a.ActorContext, exports.ActorProvider = _a.ActorProvider, exports.useActorContext = _a.useActorContext, exports.useActorState = _a.useActorState, exports.useQueryCall = _a.useQueryCall, exports.useUpdateCall = _a.useUpdateCall, exports.useMethodCall = _a.useMethodCall, exports.useVisitMethod = _a.useVisitMethod;
43
- function createReactorContext(_a = {}) {
44
- var { canisterId: defaultCanisterId } = _a, defaultConfig = __rest(_a, ["canisterId"]);
45
- const ActorContext = (0, react_1.createContext)(null);
46
- const ActorProvider = (_a) => {
47
- var { children, canisterId = defaultCanisterId, loadingComponent = react_1.default.createElement("div", null, "Fetching canister...") } = _a, restConfig = __rest(_a, ["children", "canisterId", "loadingComponent"]);
48
- if (!canisterId) {
49
- throw new Error("canisterId is required");
50
- }
51
- const config = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, defaultConfig), restConfig)), [defaultConfig, restConfig]);
52
- const { actorManager, fetchError, fetching } = (0, useReactor_1.useReactor)(Object.assign({ canisterId }, config));
53
- const hooks = (0, react_1.useMemo)(() => {
54
- if (actorManager) {
55
- return (0, actor_1.getActorHooks)(actorManager);
56
- }
57
- return null;
58
- }, [actorManager === null || actorManager === void 0 ? void 0 : actorManager.canisterId]);
59
- return (react_1.default.createElement(ActorContext.Provider, { value: hooks }, fetching || hooks === null ? fetchError !== null && fetchError !== void 0 ? fetchError : loadingComponent : children));
60
- };
61
- ActorProvider.displayName = "ActorProvider";
62
- const useActorContext = () => {
63
- const context = (0, react_1.useContext)(ActorContext);
64
- if (!context) {
65
- throw new Error("useActor must be used within a ActorProvider");
66
- }
67
- return context;
68
- };
69
- const initialize = () => useActorContext().initialize();
70
- const useActorState = () => useActorContext().useActorState();
71
- const useQueryCall = (args) => useActorContext().useQueryCall(args);
72
- const useUpdateCall = (args) => useActorContext().useUpdateCall(args);
73
- const useMethodCall = (args) => useActorContext().useMethodCall(args);
74
- const useVisitMethod = (functionName) => useActorContext().useVisitMethod(functionName);
75
- return {
76
- ActorContext,
77
- ActorProvider,
78
- useActorContext,
79
- useActorState,
80
- useQueryCall,
81
- useUpdateCall,
82
- useMethodCall,
83
- useVisitMethod,
84
- initialize,
85
- };
86
- }
87
- exports.createReactorContext = createReactorContext;
4
+ exports.extractActorHooks = exports.createReactorContext = exports.useVisitMethod = exports.useMethodCall = exports.useUpdateCall = exports.useQueryCall = exports.useActorState = exports.ActorProvider = void 0;
5
+ const context_1 = require("./context");
6
+ _a = (0, context_1.createReactorContext)(), exports.ActorProvider = _a.ActorProvider, exports.useActorState = _a.useActorState, exports.useQueryCall = _a.useQueryCall, exports.useUpdateCall = _a.useUpdateCall, exports.useMethodCall = _a.useMethodCall, exports.useVisitMethod = _a.useVisitMethod;
7
+ var context_2 = require("./context");
8
+ Object.defineProperty(exports, "createReactorContext", { enumerable: true, get: function () { return context_2.createReactorContext; } });
9
+ Object.defineProperty(exports, "extractActorHooks", { enumerable: true, get: function () { return context_2.extractActorHooks; } });
package/dist/types.d.ts CHANGED
@@ -3,6 +3,7 @@ import type { ActorHooks, AgentHooks, AuthHooks } from "./helpers/types";
3
3
  export * from "@ic-reactor/core/dist/types";
4
4
  export * from "./provider/agent/types";
5
5
  export * from "./provider/actor/types";
6
+ export * from "./hooks/types";
6
7
  export * from "./helpers/types";
7
8
  export interface CreateReactorReturn<A> extends ActorHooks<A>, AuthHooks, AgentHooks {
8
9
  getAgent: () => HttpAgent;
package/dist/types.js CHANGED
@@ -17,4 +17,5 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("@ic-reactor/core/dist/types"), exports);
18
18
  __exportStar(require("./provider/agent/types"), exports);
19
19
  __exportStar(require("./provider/actor/types"), exports);
20
+ __exportStar(require("./hooks/types"), exports);
20
21
  __exportStar(require("./helpers/types"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ic-reactor/react",
3
- "version": "1.0.3",
3
+ "version": "1.0.4",
4
4
  "description": "A React library for interacting with Internet Computer canisters",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -48,5 +48,5 @@
48
48
  "react": ">=16.8",
49
49
  "zustand": "4.5"
50
50
  },
51
- "gitHead": "acf8b5da61713482264c9eb5c227dc94a7e43cbc"
51
+ "gitHead": "031413fceeddbdac2fa281e1e07940182ac1e1ef"
52
52
  }
@@ -1,18 +0,0 @@
1
- import type { IDL } from "@dfinity/candid";
2
- interface UseIDLFactoryArgs {
3
- canisterId: string;
4
- didjsCanisterId?: string;
5
- idlFactory?: IDL.InterfaceFactory;
6
- }
7
- export declare const useCandid: ({ canisterId, didjsCanisterId, idlFactory, }: UseIDLFactoryArgs) => {
8
- fetchCandid: () => Promise<import("@ic-reactor/core/dist/types").CandidDefenition | undefined>;
9
- candid: {
10
- idlFactory?: IDL.InterfaceFactory | undefined;
11
- init: ({ idl }: {
12
- idl: typeof IDL;
13
- }) => never[];
14
- };
15
- fetching: boolean;
16
- fetchError: string | null;
17
- };
18
- export {};
@@ -1,54 +0,0 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.useCandid = void 0;
13
- const react_1 = require("react");
14
- const core_1 = require("@ic-reactor/core");
15
- const agent_1 = require("../provider/agent");
16
- const DEFAULT_STATE = {
17
- candid: { idlFactory: undefined, init: () => [] },
18
- fetching: false,
19
- fetchError: null,
20
- };
21
- const useCandid = ({ canisterId, didjsCanisterId, idlFactory, }) => {
22
- const [{ candid, fetchError, fetching }, setCandid] = (0, react_1.useState)(Object.assign(Object.assign({}, DEFAULT_STATE), { candid: {
23
- idlFactory,
24
- init: () => [],
25
- } }));
26
- const agent = (0, agent_1.useAgent)();
27
- const fetchCandid = (0, react_1.useCallback)(() => __awaiter(void 0, void 0, void 0, function* () {
28
- if (!canisterId || !agent)
29
- return;
30
- setCandid((prevState) => (Object.assign(Object.assign({}, prevState), { candid: DEFAULT_STATE.candid, fetching: true, fetchError: null })));
31
- try {
32
- const candidManager = (0, core_1.createCandidAdapter)({ agent, didjsCanisterId });
33
- const fetchedCandid = yield candidManager.getCandidDefinition(canisterId);
34
- setCandid({
35
- candid: fetchedCandid,
36
- fetching: false,
37
- fetchError: null,
38
- });
39
- return fetchedCandid;
40
- }
41
- catch (err) {
42
- // eslint-disable-next-line no-console
43
- console.error(err);
44
- setCandid((prevState) => (Object.assign(Object.assign({}, prevState), { fetchError: `Error fetching canister ${canisterId}`, fetching: false })));
45
- }
46
- }), [canisterId, didjsCanisterId, agent]);
47
- (0, react_1.useEffect)(() => {
48
- if (!fetching && !idlFactory) {
49
- fetchCandid();
50
- }
51
- }, [fetchCandid]);
52
- return { fetchCandid, candid, fetching, fetchError };
53
- };
54
- exports.useCandid = useCandid;