Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
14bf33d
Added ethersjs's logger
vhurryharry Mar 4, 2021
c9e427a
Updated logger lib
vhurryharry Mar 5, 2021
ed31127
Fixed linting issue
vhurryharry Mar 5, 2021
12d2572
Fixed build script for logger
vhurryharry Mar 9, 2021
285c960
Added readme
vhurryharry Mar 9, 2021
aaf46dc
Initialize logger in the client-js
vhurryharry Mar 9, 2021
4ee5f93
Removed enable/disable logging
vhurryharry Mar 9, 2021
ca321fe
Added logging to web3api client
vhurryharry Mar 11, 2021
062d97b
Use opentelemetry-js
vhurryharry Mar 12, 2021
a895cf5
Add log to web3api client
vhurryharry Mar 15, 2021
374dd5f
Changed logging to static functions
vhurryharry Mar 18, 2021
aca2988
Changed package/logger name
vhurryharry Mar 18, 2021
3d63625
Fixed web3api client
vhurryharry Mar 24, 2021
e0f35ca
Added tracing to utils
vhurryharry Mar 24, 2021
6f69978
Added tracing to core/algorithms
vhurryharry Mar 25, 2021
225c8cd
Upgraded package version, fixed linting
vhurryharry Mar 25, 2021
24232d0
Fixed linting
vhurryharry Mar 25, 2021
bc3ce44
Fixed web3api client
vhurryharry Mar 25, 2021
1d40391
Added tracing to core manifest/types
vhurryharry Mar 25, 2021
4f564a8
Updated packages
vhurryharry Mar 26, 2021
4f7e636
Removed logging from utils, used stack for spans
vhurryharry Mar 29, 2021
3b5cc8e
Fixed creating tracer
vhurryharry Mar 29, 2021
a008a54
Updated start/end span
vhurryharry Mar 30, 2021
1f59abf
Fixed linting
vhurryharry Mar 30, 2021
7217538
Fixed parent configuration
vhurryharry Mar 30, 2021
b7aa279
Did yarn install
vhurryharry Mar 30, 2021
ee8c27f
Added readme
vhurryharry Mar 30, 2021
d617c4d
Fixed linting
vhurryharry Mar 30, 2021
e43cc4d
trying to fix ci
dOrgJelli Apr 26, 2021
b85ae48
merge prealpha-dev
dOrgJelli Apr 26, 2021
545ad26
update yarn.lock
dOrgJelli Apr 26, 2021
28d3bda
Merge branch 'prealpha-dev' into feature/core-logger
dOrgJelli Apr 26, 2021
646d86b
start refactor
dOrgJelli May 7, 2021
d4684c7
lint fix
dOrgJelli May 7, 2021
c2f8b82
revert wasm/utils changes
dOrgJelli May 7, 2021
5c8bf32
update PluginWeb3Api
dOrgJelli May 8, 2021
3435995
update WasmWeb3Api
dOrgJelli May 8, 2021
0fa6cc9
algorithms traced
dOrgJelli May 8, 2021
7c2bcc0
update manifest logic
dOrgJelli May 8, 2021
cc7e355
update core types
dOrgJelli May 8, 2021
70551a8
remove unneeded trace span
dOrgJelli May 8, 2021
269de2d
final updates
dOrgJelli May 8, 2021
2dd924b
lint fix
dOrgJelli May 8, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/js/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"@web3api/ipfs-plugin-js": "0.0.1-prealpha.21",
"@web3api/logger-plugin-js": "0.0.1-prealpha.21",
"@web3api/schema-parse": "0.0.1-prealpha.21",
"@web3api/tracing": "0.0.1-prealpha.21",
"graphql": "15.5.0",
"js-yaml": "3.14.0",
"web-worker": "1.0.0"
Expand Down
236 changes: 144 additions & 92 deletions packages/js/client/src/Web3ApiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import {
Manifest,
sanitizeUriRedirects,
} from "@web3api/core-js";
import { Tracer } from "@web3api/tracing";

export interface ClientConfig<TUri = string> {
redirects?: UriRedirect<TUri>[];
tracingEnabled?: boolean;
}

export class Web3ApiClient implements Client {
Expand All @@ -30,28 +32,54 @@ export class Web3ApiClient implements Client {
// and handle cases where the are multiple jumps. For exmaple, if
// A => B => C, then the cache should have A => C, and B => C.
private _apiCache: ApiCache = new Map<string, Api>();
private _config: ClientConfig<Uri>;
private _config: ClientConfig<Uri> = {};

constructor(config?: ClientConfig) {
if (config) {
this._config = {
...config,
redirects: config.redirects
? sanitizeUriRedirects(config.redirects)
: [],
};
} else {
this._config = {
redirects: [],
};
try {
if (!config) {
this._config = {
redirects: [],
tracingEnabled: false,
};
}

this.tracingEnabled(!!config?.tracingEnabled);

Tracer.startSpan("Web3ApiClient: constructor");

if (config) {
this._config = {
...config,
redirects: config.redirects
? sanitizeUriRedirects(config.redirects)
: [],
};
}

if (!this._config.redirects) {
this._config.redirects = [];
}

// Add all default redirects
this._config.redirects.push(...getDefaultRedirects());

Tracer.setAttribute("config", this._config);
} catch (error) {
Tracer.recordException(error);
throw error;
} finally {
Tracer.endSpan();
}
}

if (!this._config.redirects) {
this._config.redirects = [];
public tracingEnabled(enable: boolean): void {
if (enable) {
Tracer.enableTracing("Web3ApiClient");
} else {
Tracer.disableTracing();
}

// Add all default redirects (IPFS, ETH, ENS)
this._config.redirects.push(...getDefaultRedirects());
this._config.tracingEnabled = enable;
}

public redirects(): readonly UriRedirect<Uri>[] {
Expand All @@ -64,103 +92,127 @@ export class Web3ApiClient implements Client {
>(
options: QueryApiOptions<TVariables, string>
): Promise<QueryApiResult<TData>> {
try {
const { uri, query, variables } = options;

// Convert the query string into a query document
const queryDocument =
typeof query === "string" ? createQueryDocument(query) : query;

// Parse the query to understand what's being invoked
const queryInvocations = parseQuery(
new Uri(uri),
queryDocument,
variables
);

// Execute all invocations in parallel
const parallelInvocations: Promise<{
name: string;
result: InvokeApiResult<unknown>;
}>[] = [];

for (const invocationName of Object.keys(queryInvocations)) {
parallelInvocations.push(
this.invoke({
...queryInvocations[invocationName],
uri: queryInvocations[invocationName].uri.uri,
decode: true,
}).then((result) => ({
name: invocationName,
result,
}))
const run = Tracer.traceFunc(
"Web3ApiClient: query",
async (
options: QueryApiOptions<TVariables, string>
): Promise<QueryApiResult<TData>> => {
const { uri, query, variables } = options;

// Convert the query string into a query document
const queryDocument =
typeof query === "string" ? createQueryDocument(query) : query;

// Parse the query to understand what's being invoked
const queryInvocations = parseQuery(
new Uri(uri),
queryDocument,
variables
);
}

// Await the invocations
const invocationResults = await Promise.all(parallelInvocations);
// Execute all invocations in parallel
const parallelInvocations: Promise<{
name: string;
result: InvokeApiResult<unknown>;
}>[] = [];

for (const invocationName of Object.keys(queryInvocations)) {
parallelInvocations.push(
this.invoke({
...queryInvocations[invocationName],
uri: queryInvocations[invocationName].uri.uri,
decode: true,
}).then((result) => ({
name: invocationName,
result,
}))
);
}

// Await the invocations
const invocationResults = await Promise.all(parallelInvocations);

// Aggregate all invocation results
const data: Record<string, unknown> = {};
const errors: Error[] = [];
Tracer.addEvent("invocationResults", invocationResults);

for (const invocation of invocationResults) {
data[invocation.name] = invocation.result.data;
if (invocation.result.error) {
errors.push(invocation.result.error);
// Aggregate all invocation results
const data: Record<string, unknown> = {};
const errors: Error[] = [];

for (const invocation of invocationResults) {
data[invocation.name] = invocation.result.data;
if (invocation.result.error) {
errors.push(invocation.result.error);
}
}

return {
data: data as TData,
errors: errors.length === 0 ? undefined : errors,
};
}
);

return {
data: data as TData,
errors: errors.length === 0 ? undefined : errors,
};
} catch (error) {
return await run(options).catch((error) => {
if (error.length) {
return { errors: error };
} else {
return { errors: [error] };
}
}
});
}

public async invoke<TData = unknown>(
options: InvokeApiOptions<string>
): Promise<InvokeApiResult<TData>> {
try {
const uri = new Uri(options.uri);
const api = await this.loadWeb3Api(uri);
return (await api.invoke(
{
...options,
uri,
},
this
)) as TData;
} catch (error) {
return { error: error };
}
const run = Tracer.traceFunc(
"Web3ApiClient: invoke",
async (
options: InvokeApiOptions<string>
): Promise<InvokeApiResult<TData>> => {
const uri = new Uri(options.uri);
const api = await this.loadWeb3Api(uri);

const result = (await api.invoke(
{
...options,
uri,
},
this
)) as TData;

return result;
}
);

return run(options);
}

public async loadWeb3Api(uri: Uri): Promise<Api> {
let api = this._apiCache.get(uri.uri);

if (!api) {
api = await resolveUri(
uri,
this,
(uri: Uri, plugin: PluginPackage) => new PluginWeb3Api(uri, plugin),
(uri: Uri, manifest: Manifest, apiResolver: Uri) =>
new WasmWeb3Api(uri, manifest, apiResolver)
);

if (!api) {
throw Error(`Unable to resolve Web3API at uri: ${uri}`);
}
const run = Tracer.traceFunc(
"Web3ApiClient: loadWeb3Api",
async (uri: Uri): Promise<Api> => {
let api = this._apiCache.get(uri.uri);

if (!api) {
api = await resolveUri(
uri,
this,
(uri: Uri, plugin: PluginPackage) => new PluginWeb3Api(uri, plugin),
(uri: Uri, manifest: Manifest, apiResolver: Uri) =>
new WasmWeb3Api(uri, manifest, apiResolver)
);

if (!api) {
throw Error(`Unable to resolve Web3API at uri: ${uri}`);
}

this._apiCache.set(uri.uri, api);
}

this._apiCache.set(uri.uri, api);
}
return api;
}
);

return api;
return run(uri);
}
}
Loading