Skip to content

Commit

Permalink
Update package.json scripts and typedoc configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
b3hr4d committed Feb 18, 2024
1 parent 0ee8ef9 commit 49efb9c
Show file tree
Hide file tree
Showing 14 changed files with 189 additions and 106 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
run: yarn build

- name: Generate Documentation
run: yarn docs
run: yarn docs:build

- name: Deploy to GitHub Pages
uses: JamesIves/github-pages-deploy-action@v4.5.0
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
"test": "lerna run test",
"lint": "eslint . --ext .ts",
"e2e": "cd e2e && sh ./test.sh",
"docs": "typedoc --options ./typedoc.json"
"docs:build": "typedoc --options ./typedoc.json",
"docs:serve": "npx serve@latest ./docs"
},
"publishConfig": {
"access": "public",
Expand Down
55 changes: 31 additions & 24 deletions packages/core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,26 +26,31 @@ yarn add @ic-reactor/core

To get started with ReActor, you'll need to initialize it with your actor configurations. Here's a basic example:

```javascript
```typescript
import { createReActor } from "@ic-reactor/core"
import { idlFactory, canisterId } from "./candid/backend"

const { actorStore, authStore, queryCall, updateCall } = createReActor(
(agent) => createActor("bd3sg-teaaa-aaaaa-qaaba-cai", { agent }),
{
host: "https://localhost:4943",
initializeOnMount: true,
}
)
const { actorStore, agentManager, queryCall, updateCall } = createReActor({
idlFactory,
canisterId,
host: "https://localhost:4943",
})
```

### Authenticating

```typescript
const identity = await agentManager.authenticate()
```

### Querying Data

```javascript
const { recall, subscribe, getState, initialData, intervalId } = queryCall({
functionName: "yourFunctionName",
args: ["arg1", "arg2"],
autoRefresh: true,
refreshInterval: 3000,
```typescript
const { requestHash, subscribe, dataPromise, call, getState } = queryCall({
functionName: "greet",
args: ["World"],
refetchOnMount: true,
refetchInterval: 1000,
})

// Subscribe to changes
Expand All @@ -54,13 +59,13 @@ const unsubscribe = subscribe((newState) => {
})

// Fetch data
recall().then((data) => {
// Handle initial data
call().then((data) => {
console.log(data)
})

// Get initial data
initialData.then((data) => {
// Handle initial data
dataPromise.then((data) => {
console.log(data)
})

// Clear interval if autoRefresh is enabled
Expand All @@ -71,23 +76,25 @@ if (intervalId) {

### Updating Data

```javascript
```typescript
const { call, getState, subscribe } = updateCall({
functionName: "yourUpdateFunction",
args: ["arg1", "arg2"],
})

call().then((result) => {
// Handle result
})

// Get state
const state = getState()
const { data, loading, error } = getState()

// Subscribe to changes
const unsubscribe = subscribe((newState) => {
console.log(newState)
// Handle new state
})

/* it can takes the replacement of the args call([newArg1, newArg2]) */
call().then((result) => {
// Handle result
})
```

## API Reference
Expand Down
29 changes: 27 additions & 2 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,41 @@ import type {
import { createReActorStore, generateRequestHash } from "@ic-reactor/store"
import {
ActorCallFunction,
ActorCoreActions,
ActorGetStateFunction,
ActorMethodCall,
ActorQuery,
ActorSubscribeFunction,
ActorUpdate,
} from "./types"

export const createReActor = <A = BaseActor>(options: CreateReActorOptions) => {
export * from "./types"

/**
* Create a new actor manager with the given options.
* Its create a new agent manager if not provided.
*
* @category Main
* @includeExample ./packages/core/README.md:30-91
*/

export const createReActor = <A = BaseActor>({
isLocalEnv,
withVisitor,
...options
}: CreateReActorOptions): ActorCoreActions<A> => {
isLocalEnv =
isLocalEnv ||
(typeof process !== "undefined" &&
(process.env.DFX_NETWORK === "local" ||
process.env.NODE_ENV === "development"))

const { agentManager, callMethod, actorStore, ...rest } =
createReActorStore<A>(options)
createReActorStore<A>({
isLocalEnv,
withVisitor,
...options,
})

const updateMethodState = <M extends FunctionName<A>>(
method: M,
Expand Down
15 changes: 14 additions & 1 deletion packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import type {
ActorMethodArgs,
ActorMethodReturnType,
ActorMethodState,
ActorStore,
AgentManager,
BaseActor,
CanisterId,
FunctionName,
UpdateAgentOptions,
VisitService,
} from "@ic-reactor/store"

export type ActorGetStateFunction<A, M extends FunctionName<A>> = {
Expand Down Expand Up @@ -70,7 +76,14 @@ export type ActorUpdate<A = Record<string, ActorMethod>> = <
options: ActorUpdateArgs<A, M>
) => ActorUpdateReturn<A, M>

export interface ActorCoreActions<A> {
export interface ActorCoreActions<A = BaseActor> {
actorStore: ActorStore<A>
agentManager: AgentManager
canisterId: CanisterId
getActor: () => null | A
initialize: (options?: UpdateAgentOptions) => Promise<void>
unsubscribeAgent: () => void
queryCall: ActorQuery<A>
updateCall: ActorUpdate<A>
visitFunction: VisitService<A>
}
3 changes: 2 additions & 1 deletion packages/core/test/simple.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ describe("My IC Store and Actions", () => {

const data = await dataPromise
console.log(data)
const stateData = userState("data")
const stateData = userState()

expect(data).toEqual(stateData)

Expand All @@ -64,6 +64,7 @@ describe("My IC Store and Actions", () => {
const { intervalId, dataPromise } = queryCall({
functionName: "timers",
refetchOnMount: true,
refetchInterval: 1000,
})

expect(intervalId).toBeDefined()
Expand Down
2 changes: 1 addition & 1 deletion packages/core/typedoc.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://typedoc.org/schema.json",
"entryPoints": ["./src"],
"name": "Store"
"name": "Core"
}
1 change: 1 addition & 0 deletions packages/react/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const createReActor: CreateReActor = <A = BaseActor>({

const actorManager = createReActorStore<A>({
isLocalEnv,
withVisitor,
...options,
})

Expand Down
7 changes: 5 additions & 2 deletions packages/store/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,13 @@ If you require more control over the agent's lifecycle or configuration, `@ic-re
// agent.ts
import { createAgentManager } from "@ic-reactor/store"

export const agentManager = createAgentManager() // Connects to the default IC network
export const agentManager = createAgentManager() // Connects to IC network by default

// Usage example
const identity = await agentManager.authenticate()
await agentManager.authenticate()
// Then use the store to access the authClient, identity, and more...
const { authClient, identity, authenticating } =
agentManager.authStore.getState()
```

**Local Agent Example:**
Expand Down
69 changes: 40 additions & 29 deletions packages/store/src/actor/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ import type { AgentManager, UpdateAgentOptions } from "../agent"
export * from "./types"

export class ActorManager<A = BaseActor> {
private actor: null | A = null
private idlFactory: IDL.InterfaceFactory
private _store: ActorStore<A>
private _actor: null | A = null
private _idlFactory: IDL.InterfaceFactory

public agentManager: AgentManager
public canisterId: CanisterId
public actorStore: ActorStore<A>
public visitFunction: VisitService<A>

private DEFAULT_ACTOR_STATE: ActorState<A> = {
private initialState: ActorState<A> = {
methodState: {} as ActorMethodStates<A>,
initializing: false,
initialized: false,
Expand All @@ -38,18 +38,18 @@ export class ActorManager<A = BaseActor> {
public unsubscribeAgent: () => void

private updateState = (newState: Partial<ActorState<A>>) => {
this.actorStore.setState((state) => ({ ...state, ...newState }))
this._store.setState((state) => ({ ...state, ...newState }))
}

constructor(reactorConfig: ActorManagerOptions) {
constructor(actorConfig: ActorManagerOptions) {
const {
agentManager,
canisterId,
idlFactory,
withVisitor = false,
withDevtools = false,
initializeOnCreate = true,
} = reactorConfig
} = actorConfig

this.agentManager = agentManager

Expand All @@ -58,7 +58,7 @@ export class ActorManager<A = BaseActor> {
)

this.canisterId = canisterId
this.idlFactory = idlFactory
this._idlFactory = idlFactory

if (withVisitor) {
this.visitFunction = this.extractService()
Expand All @@ -67,10 +67,10 @@ export class ActorManager<A = BaseActor> {
}

// Initialize stores
this.actorStore = createStoreWithOptionalDevtools(
this.DEFAULT_ACTOR_STATE,
{ withDevtools, store: `actor-${String(canisterId)}` }
)
this._store = createStoreWithOptionalDevtools(this.initialState, {
withDevtools,
store: `actor-${String(canisterId)}`,
})

if (initializeOnCreate) {
this.initializeActor(agentManager.getAgent())
Expand All @@ -82,7 +82,7 @@ export class ActorManager<A = BaseActor> {
}

public extractService(): VisitService<A> {
return this.idlFactory({ IDL })._fields.reduce((acc, service) => {
return this._idlFactory({ IDL })._fields.reduce((acc, service) => {
const functionName = service[0] as FunctionName<A>
const type = service[1]

Expand All @@ -103,7 +103,7 @@ export class ActorManager<A = BaseActor> {
} network`
)

const { idlFactory, canisterId } = this
const { _idlFactory: idlFactory, canisterId } = this

this.updateState({
initializing: true,
Expand All @@ -116,12 +116,12 @@ export class ActorManager<A = BaseActor> {
throw new Error("Agent not initialized")
}

this.actor = Actor.createActor<A>(idlFactory, {
this._actor = Actor.createActor<A>(idlFactory, {
agent,
canisterId,
})

if (!this.actor) {
if (!this._actor) {
throw new Error("Failed to initialize actor")
}

Expand All @@ -139,18 +139,18 @@ export class ActorManager<A = BaseActor> {
functionName: M,
...args: ActorMethodArgs<A[M]>
): Promise<ActorMethodReturnType<A[M]>> => {
if (!this.actor) {
if (!this._actor) {
throw new Error("Actor not initialized")
}

if (
!this.actor[functionName as keyof A] ||
typeof this.actor[functionName as keyof A] !== "function"
!this._actor[functionName as keyof A] ||
typeof this._actor[functionName as keyof A] !== "function"
) {
throw new Error(`Method ${String(functionName)} not found`)
}

const method = this.actor[functionName as keyof A] as (
const method = this._actor[functionName as keyof A] as (
...args: ActorMethodArgs<A[M]>
) => Promise<ActorMethodReturnType<A[M]>>

Expand All @@ -159,17 +159,28 @@ export class ActorManager<A = BaseActor> {
return data
}

public updateMethodState = (
newState: Partial<ActorState<A>["methodState"]>
) => {
this.actorStore.setState((state) => ({
...state,
methodState: { ...state.methodState, ...newState },
}))
get agent() {
return this.agentManager.getAgent()
}

public getActor = (): A | null => {
return this._actor
}

public getStore = (): ActorStore<A> => {
return this._store
}

public getState: ActorStore<A>["getState"] = () => {
return this._store.getState()
}

public subscribe: ActorStore<A>["subscribe"] = (listener) => {
return this._store.subscribe(listener)
}

public getActor = () => {
return this.actor
public setState: ActorStore<A>["setState"] = (updater) => {
return this._store.setState(updater)
}
}

Expand Down
Loading

0 comments on commit 49efb9c

Please sign in to comment.