Skip to content

Commit

Permalink
Move to Node-style callbacks in every subscription (#229)
Browse files Browse the repository at this point in the history
Contains the following changes:

- Add the `SubscriptionCallback` type.
- Add types to all the subscriptions methods.
- Move all the subscription methods to use node-style callbacks.
- Update documentation and examples.
  • Loading branch information
bpierre authored Aug 24, 2020
1 parent a948a29 commit e7f2e87
Show file tree
Hide file tree
Showing 35 changed files with 528 additions and 283 deletions.
4 changes: 3 additions & 1 deletion docs/advanced/low-level-queries.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ const subscription = wrapper.subscribeToQuery(
id: TOKEN_ID,
address: ACCOUNT_ADDRES,
},
results => {
(error, results) => {
if (error) throw error

// Handle each new result
const { miniMeToken } = results.data
}
Expand Down
30 changes: 15 additions & 15 deletions docs/connectors/finance-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ Get the list of transactions in the Finance app.

Subscribe to the list of transactions in the Finance app.

| Name | Type | Description |
| --------------- | ---------------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `transactions => void` | A callback that will get called every time the result gets updated. |
| returns | `Function` | Unsubscribe function. |
| Name | Type | Description |
| --------------- | ----------------------------------------------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `(error: Error, transactions: Transaction[]) => void` | A callback that will get called every time the result gets updated. |
| returns | `{ unsubscribe: () => void }` | Unsubscribe function. |

### Finance\#balance\(tokenAddress, filters\)

Expand All @@ -57,11 +57,11 @@ Get the balance of a token in the Finance app.

Subscribe to the balance of a token in the Finance app.

| Name | Type | Description |
| --------------- | ----------------- | ------------------------------------------------------------------- |
| `tokenAddress` | `String` | The address of the token. |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `balance => void` | A callback that will get called every time the result gets updated. |
| returns | `Function` | Unsubscribe function. |
| Name | Type | Description |
| --------------- | ----------------------------------------------- | ------------------------------------------------------------------- |
| `tokenAddress` | `String` | The address of the token. |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `(error: Error, balance: TokenBalance) => void` | A callback that will get called every time the result gets updated. |
| returns | `{ unsubscribe: () => void }` | Unsubscribe function. |
40 changes: 20 additions & 20 deletions docs/connectors/organizations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This is the main connector of the Aragon Connect library. It is responsible for parsing the organization’s data.

Currently a single flavor of this connector is available and comes built into the core library, connecting to a Subgraph data source,. We have plans to expand to other flavors, like an Ethereum connector that reduces the state directly from an Ethereum node’s JSON-RPC API, or a SQL connector that fetches data from a database, etc.
Currently a single flavor of this connector is available and comes built into the core library, connecting to a Subgraph (The Graph) data source,. We have plans to expand to other flavors, like an Ethereum connector that reduces the state directly from an Ethereum node’s JSON-RPC API, or a SQL connector that fetches data from a database, etc.

## Connector Interface

Expand Down Expand Up @@ -40,35 +40,35 @@ Perform a GraphQL query.

Perform a GraphQL query and parse the result.

| Name | Type | Description |
| -------- | -------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `parser` | `Function` | Parser function. |
| returns | `Promise<any>` | Query result data parsed. |
| Name | Type | Description |
| -------- | -------------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `parser` | `(data: any) => any` | Parser function. |
| returns | `Promise<any>` | Query result data parsed. |

**GraphQLWrapper\#subscribeToQuery\(query, args, callback\)**

Create a GraphQL subscription.

| Name | Type | Description |
| ---------- | ----------------------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `callback` | `Function` | Callback function call on every data update. |
| returns | `{ unsubscribe: () => void }` | Subscription handler. |
| Name | Type | Description |
| ---------- | --------------------------------------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `callback` | `(error: Error, result: QueryResult) => void` | Callback function call on every data update. |
| returns | `{ unsubscribe: () => void }` | Subscription handler. |

**GraphQLWrapper\#subscribeToQueryWithParser\(query, args, callback, parser\)**

Create a GraphQL subscription and parse the emitted results.

| Name | Type | Description |
| ---------- | ----------------------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `callback` | `Function` | Callback function call on every data update. |
| `parser` | `Function` | Parser function. |
| returns | `{ unsubscribe: () => void }` | Subscription handler. |
| Name | Type | Description |
| ---------- | ------------------------------------- | ------------------------------------------------- |
| `query` | `DocumentNode` | GraphQL query parsed in the standard GraphQL AST. |
| `args` | `any = {}` | Arguments to pass to fields in the query. |
| `callback` | `(error: Error, result: any) => void` | Callback function call on every data update. |
| `parser` | `(data: any) => any` | Parser function. |
| returns | `{ unsubscribe: () => void }` | Subscription handler. |

### Subgraph Schema

Expand Down
14 changes: 7 additions & 7 deletions docs/connectors/tokens-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ Get a list of token holders.

Subscribe to a list of token holders.

| Name | Type | Description |
| --------------- | ---------------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the token holders. |
| `filters.first` | `Number` | Maximum number of token holders. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of token holders. Defaults to `0`. |
| `callback` | `tokenHolders => void` | A callback that will get called every time the result gets updated. |
| returns | `Function` | Unsubscribe function. |
| Name | Type | Description |
| --------------- | ----------------------------------------------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the token holders. |
| `filters.first` | `Number` | Maximum number of token holders. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of token holders. Defaults to `0`. |
| `callback` | `(error: Error, tokenHolders: TokenHolder[]) => void` | A callback that will get called every time the result gets updated. |
| returns | `{ unsubscribe: () => void }` | Unsubscribe function. |
14 changes: 7 additions & 7 deletions docs/connectors/voting-app.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ Get the list of votes in the Voting app.

Subscribe to the list of votes in the Voting app.

| Name | Type | Description |
| --------------- | --------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `votes => void` | A callback that will get called every time the result gets updated. |
| returns | `Function` | Unsubscribe function. |
| Name | Type | Description |
| --------------- | --------------------------------------- | ------------------------------------------------------------------- |
| `filters` | `Object` | Optional object allowing to filter the votes. |
| `filters.first` | `Number` | Maximum number of votes. Defaults to `1000`. |
| `filters.skip` | `Number` | Skip a number of votes. Defaults to `0`. |
| `callback` | `(error: Error, votes: Vote[]) => void` | A callback that will get called every time the result gets updated. |
| returns | `{ unsubscribe: () => void }` | Unsubscribe function. |
6 changes: 5 additions & 1 deletion examples/nodejs/src/subscriptions-low-level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ async function main() {
}
`,
{},
(results: any) => {
(error: Error | null, results?: any) => {
if (error) {
console.error(error)
return
}
console.log(JSON.stringify(results.data, null, 2))
console.log(
`\nTry creating a new vote at https://rinkeby.aragon.org/#/${DAO_ADDRESS}/${VOTING_APP_ADDRESS}/`
Expand Down
20 changes: 14 additions & 6 deletions examples/nodejs/src/subscriptions-org.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,20 @@ async function main() {
network: 4,
})) as Organization

const subscription = org.onPermissions((permissions: Permission[]) => {
permissions.map(console.log)
console.log(
`\nTry creating or granting new permissions at https://rinkeby.aragon.org/#/${ORG_ADDRESS}/permissions/`
)
})
const subscription = org.onPermissions(
(error: Error | null, permissions?: Permission[]) => {
if (error) {
console.error(error)
return
}
for (const permission of permissions as Permission[]) {
console.log(permission)
}
console.log(
`\nTry creating or granting new permissions at https://rinkeby.aragon.org/#/${ORG_ADDRESS}/permissions/`
)
}
)

await keepRunning()

Expand Down
16 changes: 12 additions & 4 deletions examples/nodejs/src/subscriptions-tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,18 @@ async function main() {
console.log(`\nToken:`)
console.log(token)

const subscription = tokens.onHolders((holders: TokenHolder[]) => {
console.log(`\nHolders:`)
holders.map(console.log)
})
const subscription = tokens.onHolders(
(error: Error | null, holders?: TokenHolder[]) => {
if (error) {
console.error(error)
return
}
console.log(`\nHolders:`)
for (const holder of holders as TokenHolder[]) {
console.log(holder)
}
}
)

// await keepRunning()

Expand Down
65 changes: 41 additions & 24 deletions examples/nodejs/src/subscriptions-voting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,52 @@ async function main() {
const org = await connect(ORG_ADDRESS, 'thegraph', { network: 4 })
const voting = await connectVoting(org.app(VOTING_APP_ADDRESS))

const votesSubscription = voting.onVotes({}, (votes: Vote[]) => {
console.log('\nVotes: ')
votes
.map((vote, index) => ({
index,
title: vote.metadata,
id: vote.id,
}))
.forEach((vote) => {
console.log(vote)
})
console.log(
`\nTry creating a new vote at https://rinkeby.aragon.org/#/${ORG_ADDRESS}/${VOTING_APP_ADDRESS}/\n`
)
})
const votesSubscription = voting.onVotes(
{},
(error: Error | null, votes?: Vote[]) => {
if (error) {
console.error(error)
return
}
console.log('\nVotes: ')

votes = votes as Vote[]

votes
.map((vote, index) => ({
index,
title: vote.metadata,
id: vote.id,
}))
.forEach((vote) => {
console.log(vote)
})

console.log(
`\nTry creating a new vote at https://rinkeby.aragon.org/#/${ORG_ADDRESS}/${VOTING_APP_ADDRESS}/\n`
)
}
)

const votes = await voting.votes()
const vote1 = votes[1]
console.log(`Vote #1: `, vote1)

const castsSubscription = vote1.onCasts((casts: Cast[]) => {
console.log(`\nCasts:`)
casts.forEach((cast) => {
console.log(cast)
})
console.log(
`\nTry casting a vote on https://rinkeby.aragon.org/#/${ORG_ADDRESS}/${VOTING_APP_ADDRESS}/vote/1 (You must first mint yourself a token in the Token Manager)\n`
)
})
const castsSubscription = vote1.onCasts(
(error: Error | null, casts?: Cast[]) => {
if (error) {
console.error(error)
return
}
console.log(`\nCasts:`)
for (const cast of casts as Cast[]) {
console.log(cast)
}
console.log(
`\nTry casting a vote on https://rinkeby.aragon.org/#/${ORG_ADDRESS}/${VOTING_APP_ADDRESS}/vote/1 (You must first mint yourself a token in the Token Manager)\n`
)
}
)

await keepRunning()

Expand Down
22 changes: 17 additions & 5 deletions packages/connect-agreement/src/models/Agreement.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { Address, SubscriptionHandler } from '@aragon/connect-types'
import {
Address,
SubscriptionCallback,
SubscriptionHandler,
} from '@aragon/connect-types'

import Signer from './Signer'
import Version from './Version'
Expand Down Expand Up @@ -36,7 +40,9 @@ export default class Agreement {
return this.#connector.currentVersion(this.#address)
}

onCurrentVersion(callback: Function): SubscriptionHandler {
onCurrentVersion(
callback: SubscriptionCallback<Version>
): SubscriptionHandler {
return this.#connector.onCurrentVersion(this.#address, callback)
}

Expand All @@ -48,7 +54,10 @@ export default class Agreement {
return this.#connector.version(this.versionId(versionNumber))
}

onVersion(versionNumber: string, callback: Function): SubscriptionHandler {
onVersion(
versionNumber: string,
callback: SubscriptionCallback<Version>
): SubscriptionHandler {
return this.#connector.onVersion(this.versionId(versionNumber), callback)
}

Expand All @@ -58,7 +67,7 @@ export default class Agreement {

onVersions(
{ first = 1000, skip = 0 } = {},
callback: Function
callback: SubscriptionCallback<Version[]>
): SubscriptionHandler {
return this.#connector.onVersions(this.#address, first, skip, callback)
}
Expand All @@ -71,7 +80,10 @@ export default class Agreement {
return this.#connector.signer(this.signerId(signerAddress))
}

onSigner(signerAddress: string, callback: Function): SubscriptionHandler {
onSigner(
signerAddress: string,
callback: SubscriptionCallback<Signer>
): SubscriptionHandler {
return this.#connector.onSigner(this.signerId(signerAddress), callback)
}
}
7 changes: 5 additions & 2 deletions packages/connect-agreement/src/models/Signer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { SubscriptionHandler } from '@aragon/connect-types'
import {
SubscriptionCallback,
SubscriptionHandler,
} from '@aragon/connect-types'

import Signature from '../models/Signature'
import { SignerData, IAgreementConnector } from '../types'
Expand Down Expand Up @@ -36,7 +39,7 @@ export default class Signer {

onSignatures(
{ first = 1000, skip = 0 } = {},
callback: Function
callback: SubscriptionCallback<Signature[]>
): SubscriptionHandler {
return this.#connector.onSignatures(this.id, first, skip, callback)
}
Expand Down
Loading

0 comments on commit e7f2e87

Please sign in to comment.