From 3febbe1d23056a5afd08ffa41d45c289006b9f32 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Wed, 7 Jul 2021 15:50:44 -0500 Subject: [PATCH 01/16] untested first draft of client.subscribe(...) --- packages/js/client/src/Web3ApiClient.ts | 48 +++++++++++++++ packages/js/core/src/types/Subscription.ts | 68 ++++++++++++++++++++++ packages/js/core/src/types/index.ts | 3 +- 3 files changed, 118 insertions(+), 1 deletion(-) create mode 100644 packages/js/core/src/types/Subscription.ts diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index 629a1b852b..743df1cc76 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -18,6 +18,8 @@ import { InvokeApiResult, Web3ApiManifest, sanitizeUriRedirects, + Subscription, + SubscribeOptions, } from "@web3api/core-js"; import { Tracer } from "@web3api/tracing-js"; @@ -187,6 +189,52 @@ export class Web3ApiClient implements Client { return run(options); } + public subscribe< + TData extends Record = Record, + TVariables extends Record = Record + >(options: SubscribeOptions): Subscription { + const { uri, query, variables, frequency: freq } = options; + + let queryApiResult: QueryApiResult = { + data: undefined, + errors: undefined, + }; + + let _pipe: ((result?: TData) => void) | undefined = undefined; + + /* eslint-disable prettier/prettier */ + const delay = ( + (freq.hours ?? 0) * 3600 + + (freq.min ?? 0) * 60 + + (freq.sec ?? 0) + ) * 1000; + /* eslint-enable prettier/prettier */ + + const timeout: NodeJS.Timeout = setInterval(async () => { + queryApiResult = await this.query({ uri, query, variables }); + if (_pipe) { + _pipe(queryApiResult.data); + } + }, delay); + + const subscription: Subscription = { + data: queryApiResult.data, + errors: queryApiResult.errors, + stop: () => clearInterval(timeout), + pipe: ( + fn: (result?: TData) => void | Promise + ): Subscription => { + _pipe = fn; + if (queryApiResult.data) { + _pipe(queryApiResult.data); + } + return subscription; + }, + }; + + return subscription; + } + public async loadWeb3Api(uri: Uri): Promise { const run = Tracer.traceFunc( "Web3ApiClient: loadWeb3Api", diff --git a/packages/js/core/src/types/Subscription.ts b/packages/js/core/src/types/Subscription.ts new file mode 100644 index 0000000000..69aedff0bc --- /dev/null +++ b/packages/js/core/src/types/Subscription.ts @@ -0,0 +1,68 @@ +import { Uri } from "./Uri"; +import { QueryApiOptions, QueryApiResult, QueryDocument } from "./Query"; + +/** Defines the frequency of API invocations for an API subscription */ +export interface SubscriptionFrequency { + sec?: number; + min?: number; + hours?: number; +} + +/** Options required for an API subscription. */ +export interface SubscribeOptions< + TVariables extends Record = Record, + TUri = Uri +> extends QueryApiOptions { + /** The API's URI */ + uri: TUri; + + /** + * The GraphQL query to parse and execute, leading to one or more + * API invocations. + */ + query: string | QueryDocument; + + /** + * Variables referenced within the query string via GraphQL's '$variable' syntax. + */ + variables?: TVariables; + + /** + * The frequency of API invocations. + */ + frequency: SubscriptionFrequency; +} + +/** + * The result of an API subscription, which periodically calls + * a query and provides the QueryApiResult + * + * @template TData Type of the query result data. + */ +export interface Subscription< + TData extends Record = Record +> extends QueryApiResult { + /** + * Result data from latest query. The type of this value is a named map, + * where the key is the method's name, and value is the [[InvokeApiResult]]'s data. + * This is done to allow for parallel invocations within a + * single query document. In case of method name collisions, + * a postfix of `_0` will be applied, where 0 will be incremented for + * each occurrence. If undefined, it means either the first + * call has not yet been completed or something went wrong. + * If something went wrong, errors should be populated with information as to + * what happened. Null is used to represent an intentionally null result. + */ + data?: TData; + + /** Errors encountered during latest query. */ + errors?: Error[]; + + /** Cancels subscription. */ + stop(): void; + + /** Sets a function that will be called after each completed query. + * The function is also called immediately if the first query has been + * completed and data is available */ + pipe(fn: (result?: TData) => void | Promise): this; +} diff --git a/packages/js/core/src/types/index.ts b/packages/js/core/src/types/index.ts index a1b8371f88..5cfdeb05cd 100644 --- a/packages/js/core/src/types/index.ts +++ b/packages/js/core/src/types/index.ts @@ -1,8 +1,9 @@ export * from "./Api"; export * from "./Client"; +export * from "./Invoke"; export * from "./MaybeAsync"; export * from "./Plugin"; export * from "./Query"; -export * from "./Invoke"; +export * from "./Subscription"; export * from "./Uri"; export * from "./UriRedirect"; From 4c69d8504365380bdae012552d508a0c27aee24c Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 12 Jul 2021 12:13:22 -0500 Subject: [PATCH 02/16] implemented Subscription interface, client.subscribe(...) function, and tests --- packages/js/client/package.json | 2 +- packages/js/client/src/Web3ApiClient.ts | 77 +++--- .../js/client/src/__tests__/subscribe.spec.ts | 232 ++++++++++++++++++ packages/js/core/src/types/Subscription.ts | 52 +--- 4 files changed, 292 insertions(+), 71 deletions(-) create mode 100644 packages/js/client/src/__tests__/subscribe.spec.ts diff --git a/packages/js/client/package.json b/packages/js/client/package.json index f20b3cce7a..5a9db419f4 100644 --- a/packages/js/client/package.json +++ b/packages/js/client/package.json @@ -19,7 +19,7 @@ "build": "rimraf ./build && tsc --project tsconfig.build.json && npx webpack-cli --config webpack.config.js", "prebuild": "ts-node ./scripts/extractPluginConfigs.ts", "lint": "eslint --color --ext .ts src/", - "test": "cross-env TEST=true jest --passWithNoTests --runInBand --verbose", + "test": "cross-env TEST=true jest --passWithNoTests --runInBand --verbose --detectOpenHandles", "test:ci": "cross-env TEST=true jest --passWithNoTests --runInBand --verbose", "test:watch": "cross-env TEST=true jest --watch --passWithNoTests --verbose" }, diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index 743df1cc76..49fbe56c52 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -31,7 +31,7 @@ export interface ClientConfig { export class Web3ApiClient implements Client { // TODO: the API cache needs to be more like a routing table. // It should help us keep track of what URI's map to what APIs, - // and handle cases where the are multiple jumps. For exmaple, if + // and handle cases where the are multiple jumps. For example, if // A => B => C, then the cache should have A => C, and B => C. private _apiCache: ApiCache = new Map(); private _config: ClientConfig = {}; @@ -194,41 +194,62 @@ export class Web3ApiClient implements Client { TVariables extends Record = Record >(options: SubscribeOptions): Subscription { const { uri, query, variables, frequency: freq } = options; - - let queryApiResult: QueryApiResult = { - data: undefined, - errors: undefined, - }; - - let _pipe: ((result?: TData) => void) | undefined = undefined; - + // eslint-disable-next-line @typescript-eslint/no-this-alias + const client: Web3ApiClient = this; + // calculate interval between queries, in milliseconds, 1 min default value /* eslint-disable prettier/prettier */ - const delay = ( + let frequency: number; + if (freq && (freq.ms || freq.sec || freq.min || freq.hours)) { + frequency = (freq.ms ?? 0) + ( (freq.hours ?? 0) * 3600 + (freq.min ?? 0) * 60 + (freq.sec ?? 0) - ) * 1000; + ) * 1000 + } else { + frequency = 60000; + } /* eslint-enable prettier/prettier */ - const timeout: NodeJS.Timeout = setInterval(async () => { - queryApiResult = await this.query({ uri, query, variables }); - if (_pipe) { - _pipe(queryApiResult.data); - } - }, delay); - const subscription: Subscription = { - data: queryApiResult.data, - errors: queryApiResult.errors, - stop: () => clearInterval(timeout), - pipe: ( - fn: (result?: TData) => void | Promise - ): Subscription => { - _pipe = fn; - if (queryApiResult.data) { - _pipe(queryApiResult.data); + frequency: frequency, + isActive: false, + stop(): void { + subscription.isActive = false; + }, + async *[Symbol.asyncIterator](): AsyncGenerator> { + subscription.isActive = true; + let timeout: NodeJS.Timeout | undefined = undefined; + try { + let readyVals = 0; + let sleep: ((value?: unknown) => void) | undefined; + timeout = setInterval(async () => { + readyVals++; + if (sleep) { + sleep(); + sleep = undefined; + } + }, frequency); + + while (subscription.isActive) { + if (readyVals === 0) { + await new Promise((r) => (sleep = r)); + } + for (; readyVals > 0; readyVals--) { + if (!subscription.isActive) break; + const result: QueryApiResult = await client.query({ + uri: uri, + query: query, + variables: variables, + }); + yield result; + } + } + } finally { + if (timeout) { + clearInterval(timeout); + } + subscription.isActive = false; } - return subscription; }, }; diff --git a/packages/js/client/src/__tests__/subscribe.spec.ts b/packages/js/client/src/__tests__/subscribe.spec.ts new file mode 100644 index 0000000000..708fcb4f47 --- /dev/null +++ b/packages/js/client/src/__tests__/subscribe.spec.ts @@ -0,0 +1,232 @@ +import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; +import { createWeb3ApiClient } from "../createWeb3ApiClient"; +import { GetPathToTestApis } from "../../../../test-cases"; +import { Subscription } from "@web3api/core-js"; + +jest.setTimeout(60000); + +describe("Web3ApiClient: subscribe", () => { + let ipfsProvider: string; + let ethProvider: string; + let ensAddress: string; + + beforeAll(async () => { + const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); + ipfsProvider = ipfs; + ethProvider = ethereum; + ensAddress = ens; + }); + + afterAll(async () => { + await stopTestEnvironment(); + }); + + const getClient = async () => { + return createWeb3ApiClient({ + ethereum: { + networks: { + testnet: { + provider: ethProvider + }, + }, + defaultNetwork: "testnet" + }, + ipfs: { provider: ipfsProvider }, + ens: { + addresses: { + testnet: ensAddress + } + } + }) + } + + it("simple-storage: subscribe", async () => { + // set up client and api + const client = await getClient(); + const api = await buildAndDeployApi( + `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensAddress + ); + const ensUri = `ens/testnet/${api.ensDomain}`; + const ipfsUri = `ipfs/${api.ipfsCid}`; + + // deploy simple-storage contract + const deploy = await client.query<{ + deployContract: string; + }>({ + uri: ensUri, + query: ` + mutation { + deployContract( + connection: { + networkNameOrChainId: "testnet" + } + ) + } + `, + }); + expect(deploy.errors).toBeFalsy(); + expect(deploy.data).toBeTruthy(); + expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); + if (!deploy.data) { + return; + } + const address = deploy.data.deployContract; + + // test subscription + let results: number[] = []; + let value = 0; + + const setter = setInterval(async() => { + await client.query<{ + setData: string; + }>({ + uri: ipfsUri, + query: ` + mutation { + setData( + address: $address + value: $value + ) + } + `, + variables: { + address: address, + value: value++, + }, + }); + }, 4500); + + const getSubscription: Subscription<{ + getData: number; + }> = client.subscribe<{ + getData: number; + }>({ + uri: ensUri, + query: ` + query { + getData( + address: $address + ) + } + `, + variables: { + address + }, + frequency: { ms: 5000 } + }); + + for await (let query of getSubscription) { + expect(query.errors).toBeFalsy(); + const val = query.data?.getData; + if (val !== undefined) { + results.push(val); + if (val >= 3) { + break; + } + } + } + clearInterval(setter); + + expect(results).toStrictEqual([0, 1, 2, 3]); + }); + + it("simple-storage: subscription early stop", async () => { + // set up client and api + const client = await getClient(); + const api = await buildAndDeployApi( + `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensAddress + ); + const ensUri = `ens/testnet/${api.ensDomain}`; + const ipfsUri = `ipfs/${api.ipfsCid}`; + + // deploy simple-storage contract + const deploy = await client.query<{ + deployContract: string; + }>({ + uri: ensUri, + query: ` + mutation { + deployContract( + connection: { + networkNameOrChainId: "testnet" + } + ) + } + `, + }); + expect(deploy.errors).toBeFalsy(); + expect(deploy.data).toBeTruthy(); + expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); + if (!deploy.data) { + return; + } + const address = deploy.data.deployContract; + + // test subscription + let results: number[] = []; + let value = 0; + + const setter = setInterval(async() => { + await client.query<{ + setData: string; + }>({ + uri: ipfsUri, + query: ` + mutation { + setData( + address: $address + value: $value + ) + } + `, + variables: { + address: address, + value: value++, + }, + }); + }, 4500); + + const getSubscription: Subscription<{ + getData: number; + }> = client.subscribe<{ + getData: number; + }>({ + uri: ensUri, + query: ` + query { + getData( + address: $address + ) + } + `, + variables: { + address + }, + frequency: { ms: 5000 } + }); + + new Promise(async () => { + for await (let query of getSubscription) { + expect(query.errors).toBeFalsy(); + const val = query.data?.getData; + if (val !== undefined) { + results.push(val); + if (val >= 3) { + break; + } + } + } + } + ); + await new Promise(r => setTimeout(r, 10000)); + getSubscription.stop(); + clearInterval(setter); + + expect(results).toContain(0); + expect(results).not.toContain(3); + }); +}); \ No newline at end of file diff --git a/packages/js/core/src/types/Subscription.ts b/packages/js/core/src/types/Subscription.ts index 69aedff0bc..3d2661cbd4 100644 --- a/packages/js/core/src/types/Subscription.ts +++ b/packages/js/core/src/types/Subscription.ts @@ -1,8 +1,9 @@ import { Uri } from "./Uri"; -import { QueryApiOptions, QueryApiResult, QueryDocument } from "./Query"; +import { QueryApiOptions, QueryApiResult } from "./Query"; /** Defines the frequency of API invocations for an API subscription */ export interface SubscriptionFrequency { + ms?: number; sec?: number; min?: number; hours?: number; @@ -13,56 +14,23 @@ export interface SubscribeOptions< TVariables extends Record = Record, TUri = Uri > extends QueryApiOptions { - /** The API's URI */ - uri: TUri; - - /** - * The GraphQL query to parse and execute, leading to one or more - * API invocations. - */ - query: string | QueryDocument; - - /** - * Variables referenced within the query string via GraphQL's '$variable' syntax. - */ - variables?: TVariables; - /** - * The frequency of API invocations. + * The frequency of API invocations. Defaults to one query per minute. */ - frequency: SubscriptionFrequency; + frequency?: SubscriptionFrequency; } /** * The result of an API subscription, which periodically calls - * a query and provides the QueryApiResult + * a query and provides the QueryApiResult. Implements AsyncIterableIterator. * - * @template TData Type of the query result data. + * @template TData Type of the query result. */ export interface Subscription< TData extends Record = Record -> extends QueryApiResult { - /** - * Result data from latest query. The type of this value is a named map, - * where the key is the method's name, and value is the [[InvokeApiResult]]'s data. - * This is done to allow for parallel invocations within a - * single query document. In case of method name collisions, - * a postfix of `_0` will be applied, where 0 will be incremented for - * each occurrence. If undefined, it means either the first - * call has not yet been completed or something went wrong. - * If something went wrong, errors should be populated with information as to - * what happened. Null is used to represent an intentionally null result. - */ - data?: TData; - - /** Errors encountered during latest query. */ - errors?: Error[]; - - /** Cancels subscription. */ +> { + frequency: number; + isActive: boolean; stop(): void; - - /** Sets a function that will be called after each completed query. - * The function is also called immediately if the first query has been - * completed and data is available */ - pipe(fn: (result?: TData) => void | Promise): this; + [Symbol.asyncIterator](): AsyncGenerator>; } From bfd489f34e89bd82d1c89bee1fc0242ff3c982d3 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 12 Jul 2021 12:40:07 -0500 Subject: [PATCH 03/16] added tracing to subscribe, added documentation to Subscription type --- packages/js/client/src/Web3ApiClient.ts | 125 +++++++++++---------- packages/js/core/src/types/Subscription.ts | 19 +++- 2 files changed, 83 insertions(+), 61 deletions(-) diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index 49fbe56c52..dd3ffc1598 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -193,67 +193,76 @@ export class Web3ApiClient implements Client { TData extends Record = Record, TVariables extends Record = Record >(options: SubscribeOptions): Subscription { - const { uri, query, variables, frequency: freq } = options; - // eslint-disable-next-line @typescript-eslint/no-this-alias - const client: Web3ApiClient = this; - // calculate interval between queries, in milliseconds, 1 min default value - /* eslint-disable prettier/prettier */ - let frequency: number; - if (freq && (freq.ms || freq.sec || freq.min || freq.hours)) { - frequency = (freq.ms ?? 0) + ( - (freq.hours ?? 0) * 3600 + - (freq.min ?? 0) * 60 + - (freq.sec ?? 0) - ) * 1000 - } else { - frequency = 60000; - } - /* eslint-enable prettier/prettier */ - - const subscription: Subscription = { - frequency: frequency, - isActive: false, - stop(): void { - subscription.isActive = false; - }, - async *[Symbol.asyncIterator](): AsyncGenerator> { - subscription.isActive = true; - let timeout: NodeJS.Timeout | undefined = undefined; - try { - let readyVals = 0; - let sleep: ((value?: unknown) => void) | undefined; - timeout = setInterval(async () => { - readyVals++; - if (sleep) { - sleep(); - sleep = undefined; - } - }, frequency); + const run = Tracer.traceFunc( + "Web3ApiClient: subscribe", + (options: SubscribeOptions): Subscription => { + const { uri, query, variables, frequency: freq } = options; + // eslint-disable-next-line @typescript-eslint/no-this-alias + const client: Web3ApiClient = this; + // calculate interval between queries, in milliseconds, 1 min default value + /* eslint-disable prettier/prettier */ + let frequency: number; + if (freq && (freq.ms || freq.sec || freq.min || freq.hours)) { + frequency = (freq.ms ?? 0) + ( + (freq.hours ?? 0) * 3600 + + (freq.min ?? 0) * 60 + + (freq.sec ?? 0) + ) * 1000 + } else { + frequency = 60000; + } + /* eslint-enable prettier/prettier */ - while (subscription.isActive) { - if (readyVals === 0) { - await new Promise((r) => (sleep = r)); - } - for (; readyVals > 0; readyVals--) { - if (!subscription.isActive) break; - const result: QueryApiResult = await client.query({ - uri: uri, - query: query, - variables: variables, - }); - yield result; + const subscription: Subscription = { + frequency: frequency, + isActive: false, + stop(): void { + subscription.isActive = false; + }, + async *[Symbol.asyncIterator](): AsyncGenerator< + QueryApiResult + > { + subscription.isActive = true; + let timeout: NodeJS.Timeout | undefined = undefined; + try { + let readyVals = 0; + let sleep: ((value?: unknown) => void) | undefined; + timeout = setInterval(async () => { + readyVals++; + if (sleep) { + sleep(); + sleep = undefined; + } + }, frequency); + + while (subscription.isActive) { + if (readyVals === 0) { + await new Promise((r) => (sleep = r)); + } + for (; readyVals > 0; readyVals--) { + if (!subscription.isActive) break; + const result: QueryApiResult = await client.query({ + uri: uri, + query: query, + variables: variables, + }); + yield result; + } + } + } finally { + if (timeout) { + clearInterval(timeout); + } + subscription.isActive = false; } - } - } finally { - if (timeout) { - clearInterval(timeout); - } - subscription.isActive = false; - } - }, - }; + }, + }; - return subscription; + return subscription; + } + ); + + return run(options); } public async loadWeb3Api(uri: Uri): Promise { diff --git a/packages/js/core/src/types/Subscription.ts b/packages/js/core/src/types/Subscription.ts index 3d2661cbd4..444ddf5e50 100644 --- a/packages/js/core/src/types/Subscription.ts +++ b/packages/js/core/src/types/Subscription.ts @@ -21,16 +21,29 @@ export interface SubscribeOptions< } /** - * The result of an API subscription, which periodically calls - * a query and provides the QueryApiResult. Implements AsyncIterableIterator. - * + * An API subscription, which implements the AsyncIterator protocol, is an + * AsyncIterable that yields query results at a specified frequency. * @template TData Type of the query result. */ export interface Subscription< TData extends Record = Record > { + /** + * The frequency of API invocations. + */ frequency: number; + /** + * Indicates whether the subscription is currently active. + */ isActive: boolean; + /** + * Stops subscription. If a query has been called but has not yet returned, + * that query will be completed and its result will be yielded. + */ stop(): void; + /** + * Implementation of AsyncIterator protocol makes the Subscription an + * AsyncIterable, allowing use in for await...of loops. + */ [Symbol.asyncIterator](): AsyncGenerator>; } From 1b7e2d6e0d13e27062e285c452a9448c645feeab Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 12 Jul 2021 13:09:59 -0500 Subject: [PATCH 04/16] added subscribe function overloads --- packages/js/client/src/Web3ApiClient.ts | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index 1818ac4a69..6587db1ab7 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -248,10 +248,28 @@ export class Web3ApiClient implements Client { public subscribe< TData extends Record = Record, TVariables extends Record = Record - >(options: SubscribeOptions): Subscription { + >(options: SubscribeOptions): Subscription; + public subscribe< + TData extends Record = Record, + TVariables extends Record = Record + >(options: SubscribeOptions): Subscription; + public subscribe< + TData extends Record = Record, + TVariables extends Record = Record + >(options: SubscribeOptions): Subscription { + let typedOptions: SubscribeOptions; + if (typeof options.uri === "string") { + typedOptions = { + ...options, + uri: new Uri(options.uri), + }; + } else { + typedOptions = options as QueryApiOptions; + } + const run = Tracer.traceFunc( "Web3ApiClient: subscribe", - (options: SubscribeOptions): Subscription => { + (options: SubscribeOptions): Subscription => { const { uri, query, variables, frequency: freq } = options; // eslint-disable-next-line @typescript-eslint/no-this-alias const client: Web3ApiClient = this; @@ -318,7 +336,7 @@ export class Web3ApiClient implements Client { } ); - return run(options); + return run(typedOptions); } public async loadWeb3Api(uri: string): Promise; From fa8553c9c61492367a7f05f85557b62b9f7441d7 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 12 Jul 2021 13:58:25 -0500 Subject: [PATCH 05/16] lint --- packages/cli/src/lib/helpers/manifest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cli/src/lib/helpers/manifest.ts b/packages/cli/src/lib/helpers/manifest.ts index f9ff2b4346..daae688fa4 100644 --- a/packages/cli/src/lib/helpers/manifest.ts +++ b/packages/cli/src/lib/helpers/manifest.ts @@ -68,7 +68,7 @@ export async function loadBuildManifest( } // Load the custom json-schema extension if it exists - let configSchemaPath = path.join( + const configSchemaPath = path.join( path.dirname(manifestPath), "/web3api.build.ext.json" ); From 5f3347dddb5175d659e6910472ba28777df09113 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Wed, 14 Jul 2021 16:04:30 -0700 Subject: [PATCH 06/16] moved subscribe tests to Web3ApiClient.spec.ts --- .../src/__tests__/Web3ApiClient.spec.ts | 192 ++++++++++++++- .../js/client/src/__tests__/subscribe.spec.ts | 232 ------------------ 2 files changed, 191 insertions(+), 233 deletions(-) delete mode 100644 packages/js/client/src/__tests__/subscribe.spec.ts diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 487a270b3a..1f8c42cd35 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -1,7 +1,7 @@ import { ClientConfig, createWeb3ApiClient, - Plugin, + Plugin, Subscription, Uri } from "../"; import { @@ -1438,4 +1438,194 @@ describe("Web3ApiClient", () => { expect(mutation.data?.mutationMethod).toBe(1); expect(mutation.data?.abstractMutationMethod).toBe(2); }); + + it("simple-storage: subscribe", async () => { + // set up client and api + const client = await getClient(); + const api = await buildAndDeployApi( + `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensAddress + ); + const ensUri = `ens/testnet/${api.ensDomain}`; + const ipfsUri = `ipfs/${api.ipfsCid}`; + + // deploy simple-storage contract + const deploy = await client.query<{ + deployContract: string; + }>({ + uri: ensUri, + query: ` + mutation { + deployContract( + connection: { + networkNameOrChainId: "testnet" + } + ) + } + `, + }); + expect(deploy.errors).toBeFalsy(); + expect(deploy.data).toBeTruthy(); + expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); + if (!deploy.data) { + return; + } + const address = deploy.data.deployContract; + + // test subscription + let results: number[] = []; + let value = 0; + + const setter = setInterval(async() => { + await client.query<{ + setData: string; + }>({ + uri: ipfsUri, + query: ` + mutation { + setData( + address: $address + value: $value + ) + } + `, + variables: { + address: address, + value: value++, + }, + }); + }, 4500); + + const getSubscription: Subscription<{ + getData: number; + }> = client.subscribe<{ + getData: number; + }>({ + uri: ensUri, + query: ` + query { + getData( + address: $address + ) + } + `, + variables: { + address + }, + frequency: { ms: 5000 } + }); + + for await (let query of getSubscription) { + expect(query.errors).toBeFalsy(); + const val = query.data?.getData; + if (val !== undefined) { + results.push(val); + if (val >= 3) { + break; + } + } + } + clearInterval(setter); + + expect(results).toStrictEqual([0, 1, 2, 3]); + }); + + it("simple-storage: subscription early stop", async () => { + // set up client and api + const client = await getClient(); + const api = await buildAndDeployApi( + `${GetPathToTestApis()}/simple-storage`, + ipfsProvider, + ensAddress + ); + const ensUri = `ens/testnet/${api.ensDomain}`; + const ipfsUri = `ipfs/${api.ipfsCid}`; + + // deploy simple-storage contract + const deploy = await client.query<{ + deployContract: string; + }>({ + uri: ensUri, + query: ` + mutation { + deployContract( + connection: { + networkNameOrChainId: "testnet" + } + ) + } + `, + }); + expect(deploy.errors).toBeFalsy(); + expect(deploy.data).toBeTruthy(); + expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); + if (!deploy.data) { + return; + } + const address = deploy.data.deployContract; + + // test subscription + let results: number[] = []; + let value = 0; + + const setter = setInterval(async() => { + await client.query<{ + setData: string; + }>({ + uri: ipfsUri, + query: ` + mutation { + setData( + address: $address + value: $value + ) + } + `, + variables: { + address: address, + value: value++, + }, + }); + }, 4500); + + const getSubscription: Subscription<{ + getData: number; + }> = client.subscribe<{ + getData: number; + }>({ + uri: ensUri, + query: ` + query { + getData( + address: $address + ) + } + `, + variables: { + address + }, + frequency: { ms: 5000 } + }); + + new Promise(async () => { + for await (let query of getSubscription) { + expect(query.errors).toBeFalsy(); + const val = query.data?.getData; + if (val !== undefined) { + results.push(val); + if (val >= 3) { + break; + } + } + } + } + ); + await new Promise(r => setTimeout(r, 10000)); + getSubscription.stop(); + clearInterval(setter); + + expect(results).toContain(0); + expect(results).not.toContain(3); + }); }); diff --git a/packages/js/client/src/__tests__/subscribe.spec.ts b/packages/js/client/src/__tests__/subscribe.spec.ts deleted file mode 100644 index 708fcb4f47..0000000000 --- a/packages/js/client/src/__tests__/subscribe.spec.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; -import { createWeb3ApiClient } from "../createWeb3ApiClient"; -import { GetPathToTestApis } from "../../../../test-cases"; -import { Subscription } from "@web3api/core-js"; - -jest.setTimeout(60000); - -describe("Web3ApiClient: subscribe", () => { - let ipfsProvider: string; - let ethProvider: string; - let ensAddress: string; - - beforeAll(async () => { - const { ipfs, ethereum, ensAddress: ens } = await initTestEnvironment(); - ipfsProvider = ipfs; - ethProvider = ethereum; - ensAddress = ens; - }); - - afterAll(async () => { - await stopTestEnvironment(); - }); - - const getClient = async () => { - return createWeb3ApiClient({ - ethereum: { - networks: { - testnet: { - provider: ethProvider - }, - }, - defaultNetwork: "testnet" - }, - ipfs: { provider: ipfsProvider }, - ens: { - addresses: { - testnet: ensAddress - } - } - }) - } - - it("simple-storage: subscribe", async () => { - // set up client and api - const client = await getClient(); - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); - const ensUri = `ens/testnet/${api.ensDomain}`; - const ipfsUri = `ipfs/${api.ipfsCid}`; - - // deploy simple-storage contract - const deploy = await client.query<{ - deployContract: string; - }>({ - uri: ensUri, - query: ` - mutation { - deployContract( - connection: { - networkNameOrChainId: "testnet" - } - ) - } - `, - }); - expect(deploy.errors).toBeFalsy(); - expect(deploy.data).toBeTruthy(); - expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); - if (!deploy.data) { - return; - } - const address = deploy.data.deployContract; - - // test subscription - let results: number[] = []; - let value = 0; - - const setter = setInterval(async() => { - await client.query<{ - setData: string; - }>({ - uri: ipfsUri, - query: ` - mutation { - setData( - address: $address - value: $value - ) - } - `, - variables: { - address: address, - value: value++, - }, - }); - }, 4500); - - const getSubscription: Subscription<{ - getData: number; - }> = client.subscribe<{ - getData: number; - }>({ - uri: ensUri, - query: ` - query { - getData( - address: $address - ) - } - `, - variables: { - address - }, - frequency: { ms: 5000 } - }); - - for await (let query of getSubscription) { - expect(query.errors).toBeFalsy(); - const val = query.data?.getData; - if (val !== undefined) { - results.push(val); - if (val >= 3) { - break; - } - } - } - clearInterval(setter); - - expect(results).toStrictEqual([0, 1, 2, 3]); - }); - - it("simple-storage: subscription early stop", async () => { - // set up client and api - const client = await getClient(); - const api = await buildAndDeployApi( - `${GetPathToTestApis()}/simple-storage`, - ipfsProvider, - ensAddress - ); - const ensUri = `ens/testnet/${api.ensDomain}`; - const ipfsUri = `ipfs/${api.ipfsCid}`; - - // deploy simple-storage contract - const deploy = await client.query<{ - deployContract: string; - }>({ - uri: ensUri, - query: ` - mutation { - deployContract( - connection: { - networkNameOrChainId: "testnet" - } - ) - } - `, - }); - expect(deploy.errors).toBeFalsy(); - expect(deploy.data).toBeTruthy(); - expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); - if (!deploy.data) { - return; - } - const address = deploy.data.deployContract; - - // test subscription - let results: number[] = []; - let value = 0; - - const setter = setInterval(async() => { - await client.query<{ - setData: string; - }>({ - uri: ipfsUri, - query: ` - mutation { - setData( - address: $address - value: $value - ) - } - `, - variables: { - address: address, - value: value++, - }, - }); - }, 4500); - - const getSubscription: Subscription<{ - getData: number; - }> = client.subscribe<{ - getData: number; - }>({ - uri: ensUri, - query: ` - query { - getData( - address: $address - ) - } - `, - variables: { - address - }, - frequency: { ms: 5000 } - }); - - new Promise(async () => { - for await (let query of getSubscription) { - expect(query.errors).toBeFalsy(); - const val = query.data?.getData; - if (val !== undefined) { - results.push(val); - if (val >= 3) { - break; - } - } - } - } - ); - await new Promise(r => setTimeout(r, 10000)); - getSubscription.stop(); - clearInterval(setter); - - expect(results).toContain(0); - expect(results).not.toContain(3); - }); -}); \ No newline at end of file From 8784cde105d775e2bef382ed30a0d7920bbb93fe Mon Sep 17 00:00:00 2001 From: krisbitney Date: Wed, 14 Jul 2021 16:44:35 -0700 Subject: [PATCH 07/16] added explicit connection argument to queries for subscribe tests --- .../src/__tests__/Web3ApiClient.spec.ts | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 1f8c42cd35..10be6205b9 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -1440,17 +1440,17 @@ describe("Web3ApiClient", () => { }); it("simple-storage: subscribe", async () => { - // set up client and api - const client = await getClient(); const api = await buildAndDeployApi( `${GetPathToTestApis()}/simple-storage`, ipfsProvider, ensAddress ); + + const client = await getClient(); + const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; - // deploy simple-storage contract const deploy = await client.query<{ deployContract: string; }>({ @@ -1465,13 +1465,12 @@ describe("Web3ApiClient", () => { } `, }); + expect(deploy.errors).toBeFalsy(); expect(deploy.data).toBeTruthy(); expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); - if (!deploy.data) { - return; - } - const address = deploy.data.deployContract; + + const address = deploy.data?.deployContract; // test subscription let results: number[] = []; @@ -1487,6 +1486,9 @@ describe("Web3ApiClient", () => { setData( address: $address value: $value + connection: { + networkNameOrChainId: "testnet" + } ) } `, @@ -1495,7 +1497,7 @@ describe("Web3ApiClient", () => { value: value++, }, }); - }, 4500); + }, 3000); const getSubscription: Subscription<{ getData: number; @@ -1507,13 +1509,16 @@ describe("Web3ApiClient", () => { query { getData( address: $address + connection: { + networkNameOrChainId: "testnet" + } ) } `, variables: { address }, - frequency: { ms: 5000 } + frequency: { ms: 3500 } }); for await (let query of getSubscription) { @@ -1532,38 +1537,37 @@ describe("Web3ApiClient", () => { }); it("simple-storage: subscription early stop", async () => { - // set up client and api - const client = await getClient(); const api = await buildAndDeployApi( `${GetPathToTestApis()}/simple-storage`, ipfsProvider, ensAddress ); + + const client = await getClient(); + const ensUri = `ens/testnet/${api.ensDomain}`; const ipfsUri = `ipfs/${api.ipfsCid}`; - // deploy simple-storage contract const deploy = await client.query<{ deployContract: string; }>({ uri: ensUri, query: ` - mutation { - deployContract( - connection: { - networkNameOrChainId: "testnet" - } - ) - } - `, + mutation { + deployContract( + connection: { + networkNameOrChainId: "testnet" + } + ) + } + `, }); + expect(deploy.errors).toBeFalsy(); expect(deploy.data).toBeTruthy(); expect(deploy.data?.deployContract.indexOf("0x")).toBeGreaterThan(-1); - if (!deploy.data) { - return; - } - const address = deploy.data.deployContract; + + const address = deploy.data?.deployContract; // test subscription let results: number[] = []; @@ -1579,6 +1583,9 @@ describe("Web3ApiClient", () => { setData( address: $address value: $value + connection: { + networkNameOrChainId: "testnet" + } ) } `, @@ -1587,7 +1594,7 @@ describe("Web3ApiClient", () => { value: value++, }, }); - }, 4500); + }, 3000); const getSubscription: Subscription<{ getData: number; @@ -1599,13 +1606,16 @@ describe("Web3ApiClient", () => { query { getData( address: $address + connection: { + networkNameOrChainId: "testnet" + } ) } `, variables: { address }, - frequency: { ms: 5000 } + frequency: { ms: 3500 } }); new Promise(async () => { @@ -1621,7 +1631,7 @@ describe("Web3ApiClient", () => { } } ); - await new Promise(r => setTimeout(r, 10000)); + await new Promise(r => setTimeout(r, 7000)); getSubscription.stop(); clearInterval(setter); From ab1e4cec677d0ad080efdf1eefcfc95aacdb4e2a Mon Sep 17 00:00:00 2001 From: krisbitney Date: Thu, 15 Jul 2021 17:10:16 -0700 Subject: [PATCH 08/16] adjusted test parameters for subscribe --- packages/js/client/src/__tests__/Web3ApiClient.spec.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 10be6205b9..c07aa524b3 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -1497,7 +1497,7 @@ describe("Web3ApiClient", () => { value: value++, }, }); - }, 3000); + }, 4000); const getSubscription: Subscription<{ getData: number; @@ -1518,7 +1518,7 @@ describe("Web3ApiClient", () => { variables: { address }, - frequency: { ms: 3500 } + frequency: { ms: 4500 } }); for await (let query of getSubscription) { @@ -1594,7 +1594,7 @@ describe("Web3ApiClient", () => { value: value++, }, }); - }, 3000); + }, 4000); const getSubscription: Subscription<{ getData: number; @@ -1615,7 +1615,7 @@ describe("Web3ApiClient", () => { variables: { address }, - frequency: { ms: 3500 } + frequency: { ms: 4500 } }); new Promise(async () => { @@ -1631,7 +1631,7 @@ describe("Web3ApiClient", () => { } } ); - await new Promise(r => setTimeout(r, 7000)); + await new Promise(r => setTimeout(r, 8000)); getSubscription.stop(); clearInterval(setter); From 72341d20820a41f9b4054cd71149342c78a1b716 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Thu, 15 Jul 2021 17:41:46 -0700 Subject: [PATCH 09/16] adjusted test parameters for subscribe --- packages/js/client/src/__tests__/Web3ApiClient.spec.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index c07aa524b3..6a8c9812d1 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -1526,14 +1526,14 @@ describe("Web3ApiClient", () => { const val = query.data?.getData; if (val !== undefined) { results.push(val); - if (val >= 3) { + if (val >= 2) { break; } } } clearInterval(setter); - expect(results).toStrictEqual([0, 1, 2, 3]); + expect(results).toStrictEqual([0, 1, 2]); }); it("simple-storage: subscription early stop", async () => { @@ -1624,7 +1624,7 @@ describe("Web3ApiClient", () => { const val = query.data?.getData; if (val !== undefined) { results.push(val); - if (val >= 3) { + if (val >= 2) { break; } } @@ -1636,6 +1636,6 @@ describe("Web3ApiClient", () => { clearInterval(setter); expect(results).toContain(0); - expect(results).not.toContain(3); + expect(results).not.toContain(2); }); }); From 213fdc40ab249370a402ac6d1799ddd0452cd4e8 Mon Sep 17 00:00:00 2001 From: krisbitney Date: Mon, 30 Aug 2021 18:18:59 -0600 Subject: [PATCH 10/16] updated uniswap v2 api tests to work with prealpha.36 client config format --- .../src/__tests__/e2e/fetch_e2e.spec.ts | 8 ++-- .../src/__tests__/e2e/pair_e2e.spec.ts | 8 ++-- .../src/__tests__/e2e/route_e2e.spec.ts | 8 ++-- .../src/__tests__/e2e/router_e2e.spec.ts | 8 ++-- .../src/__tests__/e2e/swap_e2e.spec.ts | 8 ++-- .../src/__tests__/e2e/trade_e2e.spec.ts | 8 ++-- .../src/__tests__/query/router.spec.ts | 44 ++++++++--------- .../apis/uniswapv2/src/__tests__/testUtils.ts | 48 ++++++++++++------- 8 files changed, 78 insertions(+), 62 deletions(-) diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/fetch_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/fetch_e2e.spec.ts index 2edf89acb1..4f2a1ec4ab 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/fetch_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/fetch_e2e.spec.ts @@ -1,8 +1,8 @@ import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { ChainId, Pair, Token, TokenAmount } from "./types"; import path from "path"; -import { getRedirects, getTokenList } from "../testUtils"; +import { getPlugins, getTokenList } from "../testUtils"; import * as uni from "@uniswap/sdk"; import * as ethers from "ethers"; @@ -20,8 +20,8 @@ describe("Fetch", () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "/../../../"); const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/pair_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/pair_e2e.spec.ts index 938db4d0b2..5a09793f8f 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/pair_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/pair_e2e.spec.ts @@ -1,8 +1,8 @@ -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; import * as path from "path"; import { Pair, Token, TokenAmount } from "./types"; -import { getPairData, getRedirects, getTokenList, getUniPairs } from "../testUtils"; +import { getPairData, getPlugins, getTokenList, getUniPairs } from "../testUtils"; import * as uni from "@uniswap/sdk"; jest.setTimeout(150000); @@ -17,8 +17,8 @@ describe('Pair', () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "/../../../"); const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/route_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/route_e2e.spec.ts index 22d3bce2ec..e0a45e4880 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/route_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/route_e2e.spec.ts @@ -1,8 +1,8 @@ -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; import * as path from "path"; import { Pair, Route, Token } from "./types"; -import { getPairData, getRedirects, getTokenList, getUniPairs } from "../testUtils"; +import { getPairData, getPlugins, getTokenList, getUniPairs } from "../testUtils"; import * as uni from "@uniswap/sdk"; jest.setTimeout(360000); @@ -19,8 +19,8 @@ describe('Route', () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "/../../../"); const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/router_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/router_e2e.spec.ts index e6b58e3565..099777f3cf 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/router_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/router_e2e.spec.ts @@ -1,5 +1,5 @@ import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { ChainId, Pair, @@ -16,7 +16,7 @@ import { getBestTradeExactIn, getBestTradeExactOut, getPairData, - getRedirects, + getPlugins, getTokenList, getUniPairs } from "../testUtils"; @@ -40,8 +40,8 @@ describe("Router", () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects: redirects, tracingEnabled: true }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "../../../../"); diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts index 7e80a5726c..a23edd12d4 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts @@ -1,8 +1,8 @@ import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { Currency, Pair, Token, Trade, TxResponse } from "./types"; import path from "path"; -import { getRedirects, getTokenList } from "../testUtils"; +import { getPlugins, getTokenList } from "../testUtils"; import { Contract, ethers, providers } from "ethers"; import erc20ABI from "./testData/erc20ABI.json"; @@ -23,8 +23,8 @@ describe("Swap", () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects: redirects, tracingEnabled: true }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "../../../../"); diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/trade_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/trade_e2e.spec.ts index 54febdb770..0ab7df7d09 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/trade_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/trade_e2e.spec.ts @@ -1,8 +1,8 @@ -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, Web3ApiClient } from "@web3api/client-js"; import { buildAndDeployApi, initTestEnvironment, stopTestEnvironment } from "@web3api/test-env-js"; import * as path from "path"; import { ChainId, Pair, Route, Token, TokenAmount, Trade } from "./types"; -import { getPairData, getRedirects, getTokenList, getUniPairs } from "../testUtils"; +import { getPairData, getPlugins, getTokenList, getUniPairs } from "../testUtils"; import * as uni from "@uniswap/sdk"; jest.setTimeout(120000); @@ -19,8 +19,8 @@ describe('trade e2e', () => { beforeAll(async () => { const { ethereum: testEnvEtherem, ensAddress, ipfs } = await initTestEnvironment(); // get client - const redirects: UriRedirect[] = getRedirects(testEnvEtherem, ipfs, ensAddress); - client = new Web3ApiClient({ redirects }); + const config: ClientConfig = getPlugins(testEnvEtherem, ipfs, ensAddress); + client = new Web3ApiClient(config); // deploy api const apiPath: string = path.resolve(__dirname + "/../../../"); const api = await buildAndDeployApi(apiPath, ipfs, ensAddress); diff --git a/packages/apis/uniswapv2/src/__tests__/query/router.spec.ts b/packages/apis/uniswapv2/src/__tests__/query/router.spec.ts index ea6e1e8bc7..8e95feaa43 100644 --- a/packages/apis/uniswapv2/src/__tests__/query/router.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/query/router.spec.ts @@ -82,7 +82,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -96,7 +96,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x64"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -126,7 +126,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromNull(), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromValue(50), feeOnTransfer: Nullable.fromNull() @@ -164,7 +164,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -179,7 +179,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -201,7 +201,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -216,7 +216,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); }); @@ -244,7 +244,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -258,7 +258,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x80"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -288,7 +288,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -303,7 +303,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -325,7 +325,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromNull() @@ -340,7 +340,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); }); @@ -373,7 +373,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) @@ -387,7 +387,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x64"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -413,7 +413,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) @@ -428,7 +428,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); @@ -450,7 +450,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) @@ -465,7 +465,7 @@ describe("swapCallParameters", () => { "0x0000000000000000000000000000000000000004" ]); expect(result.value).toStrictEqual("0x0"); - const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; + const deadlineDifference = (Date.now() / 1000) as number - parseInt(result.args[result.args.length - 1]) as number; expect(deadlineDifference < 5).toBe(true); }); }); @@ -494,7 +494,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) @@ -530,7 +530,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) @@ -558,7 +558,7 @@ describe("swapCallParameters", () => { tradeOptions: { ttl: Nullable.fromValue(50), recipient: "0x0000000000000000000000000000000000000004", - unixTimestamp: Date.now() / 1000, + unixTimestamp: Date.now() / 1000, allowedSlippage: "0.01", deadline: Nullable.fromNull(), feeOnTransfer: Nullable.fromValue(true) diff --git a/packages/apis/uniswapv2/src/__tests__/testUtils.ts b/packages/apis/uniswapv2/src/__tests__/testUtils.ts index 337af10dcb..6f7a1ee2ba 100644 --- a/packages/apis/uniswapv2/src/__tests__/testUtils.ts +++ b/packages/apis/uniswapv2/src/__tests__/testUtils.ts @@ -1,5 +1,5 @@ import { BestTradeOptions, ChainId, Pair, Token, TokenAmount, Trade } from "./e2e/types"; -import { UriRedirect, Web3ApiClient } from "@web3api/client-js"; +import { ClientConfig, coreInterfaceUris, Web3ApiClient } from "@web3api/client-js"; import { ethereumPlugin } from "@web3api/ethereum-plugin-js"; import { ipfsPlugin } from "@web3api/ipfs-plugin-js"; import { ensPlugin } from "@web3api/ens-plugin-js"; @@ -13,7 +13,7 @@ interface TestEnvironment { ipfs: string; ethereum: string; ensAddress: string; - redirects: UriRedirect[]; + clientConfig: ClientConfig; } export async function getEnsUri(): Promise { @@ -26,15 +26,25 @@ export async function getEnsUri(): Promise { export async function getProviders(): Promise { const { data: { ipfs, ethereum }, } = await axios.get("http://localhost:4040/providers"); const { data } = await axios.get("http://localhost:4040/deploy-ens"); - const redirects: UriRedirect[] = getRedirects(ethereum, ipfs, data.ensAddress); - return { ipfs, ethereum, ensAddress: data.ensAddress, redirects }; + const clientConfig: ClientConfig = getPlugins(ethereum, ipfs, data.ensAddress); + return { ipfs, ethereum, ensAddress: data.ensAddress, clientConfig, }; } -export function getRedirects(ethereum: string, ipfs: string, ensAddress: string): UriRedirect[] { - return [ - { - from: "ens/ethereum.web3api.eth", - to: ethereumPlugin({ +export function getPlugins(ethereum: string, ipfs: string, ensAddress: string): ClientConfig { + return { + redirects: [], + plugins: [ + { + uri: "w3://ens/ipfs.web3api.eth", + plugin: ipfsPlugin({ provider: ipfs }), + }, + { + uri: "w3://ens/ens.web3api.eth", + plugin: ensPlugin({ addresses: { testnet: ensAddress } }), + }, + { + uri: "w3://ens/ethereum.web3api.eth", + plugin: ethereumPlugin({ networks: { testnet: { provider: ethereum @@ -44,17 +54,23 @@ export function getRedirects(ethereum: string, ipfs: string, ensAddress: string) }, }, defaultNetwork: "testnet" - }) + }), }, + ], + interfaces: [ { - from: "w3://ens/ipfs.web3api.eth", - to: ipfsPlugin({ provider: ipfs }), + interface: coreInterfaceUris.uriResolver.uri, + implementations: [ + "w3://ens/ipfs.web3api.eth", + "w3://ens/ens.web3api.eth", + ], }, { - from: "w3://ens/ens.web3api.eth", - to: ensPlugin({ addresses: { testnet: ensAddress } }), - } - ]; + interface: coreInterfaceUris.logger.uri, + implementations: ["w3://ens/js-logger.web3api.eth"], + }, + ], + }; } export async function getTokenList(): Promise { From 24d10499d3dfef6f065539d6831219710bc86640 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 02:54:23 -0400 Subject: [PATCH 11/16] minor edits --- packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts | 2 +- .../web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.5.ts | 1 + .../web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.5.ts | 1 + .../web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.5.ts | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts b/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts index a23edd12d4..8feafc8ae2 100644 --- a/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts +++ b/packages/apis/uniswapv2/src/__tests__/e2e/swap_e2e.spec.ts @@ -6,7 +6,7 @@ import { getPlugins, getTokenList } from "../testUtils"; import { Contract, ethers, providers } from "ethers"; import erc20ABI from "./testData/erc20ABI.json"; -jest.setTimeout(120000); +jest.setTimeout(360000); describe("Swap", () => { diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.5.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.5.ts index c946c5800b..910340d870 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.5.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.1_to_0.0.1-prealpha.5.ts @@ -4,6 +4,7 @@ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.1"; import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.5"; export function migrate(old: OldManifest): NewManifest { + delete old.repository; const module = old.mutation || old.query; if (!module) { diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.5.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.5.ts index a9025251c8..95c59c4516 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.5.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.2_to_0.0.1-prealpha.5.ts @@ -4,6 +4,7 @@ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.2"; import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.5"; export function migrate(old: OldManifest): NewManifest { + delete old.repository; return { ...old, __type: "Web3ApiManifest", diff --git a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.5.ts b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.5.ts index 863a08926e..3cf5f2e411 100644 --- a/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.5.ts +++ b/packages/js/core/src/manifest/formats/web3api/migrators/0.0.1-prealpha.3_to_0.0.1-prealpha.5.ts @@ -4,6 +4,7 @@ import { Web3ApiManifest as OldManifest } from "../0.0.1-prealpha.3"; import { Web3ApiManifest as NewManifest } from "../0.0.1-prealpha.5"; export function migrate(old: OldManifest): NewManifest { + delete old.repository; let language = old.language; if (!language) { From 187c0cb31885fa7c8661b17cb05a2930693427a7 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 03:50:11 -0400 Subject: [PATCH 12/16] fix client test --- packages/js/client/src/__tests__/Web3ApiClient.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts index 98859b2aba..f180ce8bac 100644 --- a/packages/js/client/src/__tests__/Web3ApiClient.spec.ts +++ b/packages/js/client/src/__tests__/Web3ApiClient.spec.ts @@ -1824,6 +1824,7 @@ scalar Int16 scalar Int32 scalar Bytes scalar BigInt +scalar JSON directive @imported( uri: String! From 77ea81574227a57e4f4b636deb1e7e629474dcdb Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 15:07:50 -0400 Subject: [PATCH 13/16] lint fix --- packages/js/client/src/Web3ApiClient.ts | 4 ++-- packages/js/core/src/types/Client.ts | 5 ++++- packages/js/core/src/types/Invoke.ts | 9 ++------- packages/js/core/src/types/Query.ts | 4 +--- 4 files changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index df67ad5a06..4171368dd5 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -133,7 +133,7 @@ export class Web3ApiClient implements Client { ): Promise> { const typedOptions: QueryApiOptions = { ...options, - uri: this._toUri(options.uri) + uri: this._toUri(options.uri), }; const run = Tracer.traceFunc( @@ -232,7 +232,7 @@ export class Web3ApiClient implements Client { >(options: SubscribeOptions): Subscription { const typedOptions: SubscribeOptions = { ...options, - uri: this._toUri(options.uri) + uri: this._toUri(options.uri), }; const run = Tracer.traceFunc( diff --git a/packages/js/core/src/types/Client.ts b/packages/js/core/src/types/Client.ts index e33e78277c..865e3ebc2c 100644 --- a/packages/js/core/src/types/Client.ts +++ b/packages/js/core/src/types/Client.ts @@ -14,7 +14,10 @@ export interface GetImplementationsOptions { applyRedirects?: boolean; } -export interface Client extends QueryHandler, SubscriptionHandler, InvokeHandler { +export interface Client + extends QueryHandler, + SubscriptionHandler, + InvokeHandler { getSchema(uri: TUri): Promise; getManifest( diff --git a/packages/js/core/src/types/Invoke.ts b/packages/js/core/src/types/Invoke.ts index e379dd475a..811715fcf8 100644 --- a/packages/js/core/src/types/Invoke.ts +++ b/packages/js/core/src/types/Invoke.ts @@ -3,9 +3,7 @@ import { Uri } from "."; export type InvokableModules = "query" | "mutation"; /** Options required for an API invocation. */ -export interface InvokeApiOptions< - TUri extends Uri | string = string -> { +export interface InvokeApiOptions { /** The API's URI */ uri: TUri; @@ -55,10 +53,7 @@ export interface InvokeApiResult { } export interface InvokeHandler { - invoke< - TData = unknown, - TUri extends Uri | string = string - >( + invoke( options: InvokeApiOptions ): Promise>; } diff --git a/packages/js/core/src/types/Query.ts b/packages/js/core/src/types/Query.ts index 676ad58811..e6f8af8042 100644 --- a/packages/js/core/src/types/Query.ts +++ b/packages/js/core/src/types/Query.ts @@ -60,9 +60,7 @@ export interface QueryApiResult< errors?: Error[]; } -export interface QueryApiInvocations< - TUri extends Uri | string = string -> { +export interface QueryApiInvocations { [methodOrAlias: string]: InvokeApiOptions; } From 81d01f8e04014af9878506a23a663b7c40b9ca8d Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 15:29:34 -0400 Subject: [PATCH 14/16] minor styling changes --- packages/js/client/src/Web3ApiClient.ts | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/js/client/src/Web3ApiClient.ts b/packages/js/client/src/Web3ApiClient.ts index 4171368dd5..e1a14bd465 100644 --- a/packages/js/client/src/Web3ApiClient.ts +++ b/packages/js/client/src/Web3ApiClient.ts @@ -241,15 +241,16 @@ export class Web3ApiClient implements Client { const { uri, query, variables, frequency: freq } = options; // eslint-disable-next-line @typescript-eslint/no-this-alias const client: Web3ApiClient = this; + // calculate interval between queries, in milliseconds, 1 min default value /* eslint-disable prettier/prettier */ let frequency: number; if (freq && (freq.ms || freq.sec || freq.min || freq.hours)) { - frequency = (freq.ms ?? 0) + ( + frequency = (freq.ms ?? 0) + (( (freq.hours ?? 0) * 3600 + (freq.min ?? 0) * 60 + (freq.sec ?? 0) - ) * 1000 + ) * 1000); } else { frequency = 60000; } @@ -264,12 +265,14 @@ export class Web3ApiClient implements Client { async *[Symbol.asyncIterator](): AsyncGenerator< QueryApiResult > { - subscription.isActive = true; let timeout: NodeJS.Timeout | undefined = undefined; + subscription.isActive = true; + try { let readyVals = 0; let sleep: ((value?: unknown) => void) | undefined; - timeout = setInterval(async () => { + + timeout = setInterval(() => { readyVals++; if (sleep) { sleep(); @@ -281,13 +284,18 @@ export class Web3ApiClient implements Client { if (readyVals === 0) { await new Promise((r) => (sleep = r)); } + for (; readyVals > 0; readyVals--) { - if (!subscription.isActive) break; + if (!subscription.isActive) { + break; + } + const result: QueryApiResult = await client.query({ uri: uri, query: query, variables: variables, }); + yield result; } } From 679ff6ce67311c7d9a40fffa958cd15f84389079 Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 17:13:10 -0400 Subject: [PATCH 15/16] init --- packages/js/tracing/package.json | 2 +- packages/js/tracing/src/declarations.d.ts | 4 ++ packages/js/tracing/src/index.ts | 4 +- packages/js/tracing/tsconfig.json | 5 ++- yarn.lock | 48 +++-------------------- 5 files changed, 15 insertions(+), 48 deletions(-) create mode 100644 packages/js/tracing/src/declarations.d.ts diff --git a/packages/js/tracing/package.json b/packages/js/tracing/package.json index 98165132a0..d10f107d37 100644 --- a/packages/js/tracing/package.json +++ b/packages/js/tracing/package.json @@ -29,7 +29,7 @@ "@opentelemetry/propagator-b3": "0.20.0", "@opentelemetry/tracing": "0.20.0", "@opentelemetry/web": "0.20.0", - "util-inspect": "0.1.8" + "browser-util-inspect": "0.2.0" }, "devDependencies": { "@types/jest": "26.0.8", diff --git a/packages/js/tracing/src/declarations.d.ts b/packages/js/tracing/src/declarations.d.ts new file mode 100644 index 0000000000..337dc43f99 --- /dev/null +++ b/packages/js/tracing/src/declarations.d.ts @@ -0,0 +1,4 @@ +declare module "browser-util-inspect" { + function inspect(obj: unknown): unknown; + export = inspect; +} diff --git a/packages/js/tracing/src/index.ts b/packages/js/tracing/src/index.ts index bd6b3cbe30..875e8d2f38 100644 --- a/packages/js/tracing/src/index.ts +++ b/packages/js/tracing/src/index.ts @@ -6,9 +6,7 @@ import { import { ZipkinExporter } from "@opentelemetry/exporter-zipkin"; import { WebTracerProvider } from "@opentelemetry/web"; import * as api from "@opentelemetry/api"; - -// eslint-disable-next-line @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports -const inspect = require("util-inspect"); +import inspect from "browser-util-inspect"; type MaybeAsync = Promise | T; diff --git a/packages/js/tracing/tsconfig.json b/packages/js/tracing/tsconfig.json index 5d37204c00..fd4ebb1a2c 100644 --- a/packages/js/tracing/tsconfig.json +++ b/packages/js/tracing/tsconfig.json @@ -1,7 +1,10 @@ { "extends": "../../../tsconfig", "compilerOptions": { - "outDir": "build" + "outDir": "build", + "typeRoots": [ + "./src/**/*.d.ts" + ] }, "include": [ "./src/**/*.ts" diff --git a/yarn.lock b/yarn.lock index 93dbc76aec..e60ad09b66 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4927,16 +4927,6 @@ array-includes@^3.0.3, array-includes@^3.1.1: get-intrinsic "^1.1.1" is-string "^1.0.5" -array-map@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" - integrity sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI= - -array-reduce@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" - integrity sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys= - array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" @@ -6121,6 +6111,11 @@ browser-resolve@^1.11.3: dependencies: resolve "1.1.7" +browser-util-inspect@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browser-util-inspect/-/browser-util-inspect-0.2.0.tgz#cdda8ce1a4a07a4386035168a228c8777bff459c" + integrity sha1-zdqM4aSgekOGA1FooijId3v/RZw= + browserify-aes@^1.0.0, browserify-aes@^1.0.4, browserify-aes@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -9720,11 +9715,6 @@ for-own@^0.1.3: dependencies: for-in "^1.0.1" -foreach@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.4.tgz#cc5d0d8ae1d46cc9a555c2682f910977859935df" - integrity sha1-zF0NiuHUbMmlVcJoL5EJd4WZNd8= - foreach@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" @@ -10941,11 +10931,6 @@ indexes-of@^1.0.1: resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= -indexof@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" - integrity sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10= - infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" @@ -13403,11 +13388,6 @@ json-text-sequence@~0.1.0: dependencies: delimit-stream "0.1.0" -json3@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.0.tgz#0e9e7f6c5d270b758929af4d6fefdc84bd66e259" - integrity sha1-Dp5/bF0nC3WJKa9Nb+/chL1m4lk= - json3@^3.3.2: version "3.3.3" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" @@ -15254,11 +15234,6 @@ object-is@^1.0.1: call-bind "^1.0.2" define-properties "^1.1.3" -object-keys@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.5.0.tgz#09e211f3e00318afc4f592e36e7cdc10d9ad7293" - integrity sha1-CeIR8+ADGK/E9ZLjbnzcENmtcpM= - object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" @@ -19999,19 +19974,6 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util-inspect@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/util-inspect/-/util-inspect-0.1.8.tgz#2b39dbcd2d921f2d8430923caff40f4b5cea5db1" - integrity sha1-KznbzS2SHy2EMJI8r/QPS1zqXbE= - dependencies: - array-map "0.0.0" - array-reduce "0.0.0" - foreach "2.0.4" - indexof "0.0.1" - isarray "0.0.1" - json3 "3.3.0" - object-keys "0.5.0" - util-promisify@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/util-promisify/-/util-promisify-2.1.0.tgz#3c2236476c4d32c5ff3c47002add7c13b9a82a53" From 4e37d30e945c2ef5a2c4510bfa74a32ecafe528b Mon Sep 17 00:00:00 2001 From: dOrgJelli Date: Fri, 17 Sep 2021 17:17:22 -0400 Subject: [PATCH 16/16] prep 0.0.1-prealpha.43 --- CHANGELOG.md | 7 +++++++ VERSION | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 108cb6a7dc..35c227d729 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# Web3API 0.0.1-prealpha.43 +## Features +* `@web3api/client-js`: Added the `client.subscribe(...)` method, enabling users to easily send queries at a specified frequency. + +## Bugs +* `@web3api/tracing-js`: Replaced the `util-inspect` dependency with a browser compatible one. + # Web3API 0.0.1-prealpha.42 ## Bugs * `@web3api/schema-parse`: Removed unnecessary sanitization for imported methods without any arguments. diff --git a/VERSION b/VERSION index 79e7320abe..1ba059a174 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.0.1-prealpha.42 \ No newline at end of file +0.0.1-prealpha.43 \ No newline at end of file