Skip to content

Commit

Permalink
feat(rpc-client): adds reproduce
Browse files Browse the repository at this point in the history
  • Loading branch information
rafamel committed Oct 25, 2019
1 parent f6cca63 commit ee26db7
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/rpc-client/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export { default } from './client';
export * from './client';
export * from './obtain';
export * from './generate';
export * from './reproduce';
100 changes: 100 additions & 0 deletions packages/rpc-client/src/reproduce.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import {
CollectionTree,
CollectionTreeImplementation,
toImplementation,
isServiceQuery,
isServiceMutation,
isServiceSubscription,
query,
mutation,
subscription,
ErrorTypeImplementation,
error,
intercepts,
intercept,
PublicError,
CollectionError,
collections,
types,
references
} from '@karmic/core';
import RPCClient from './client';
import { catchError } from 'rxjs/operators';
import { throwError } from 'rxjs';

export interface RPCReproduceOptions {
proxyError: RPCReproduceProxyError;
}

export interface RPCReproduceProxyError {
name: string;
type: ErrorTypeImplementation;
}

/**
* Creates a `CollectionTreeImplementation` from a tree definition,
* resolving all service calls through the client.
*/
export async function reproduce(
collection: CollectionTree | Promise<CollectionTree>,
rpc: RPCClient,
options?: RPCReproduceOptions
): Promise<CollectionTreeImplementation> {
const opts = Object.assign(
{
proxyError: {
name: 'ProxyError',
type: error({ code: 'ServerGateway' })
}
},
options
);

const implementation = collections(
toImplementation(await collection, (service, info) => {
const { types } = service;
if (isServiceQuery(service)) {
return query({
types,
resolve: (data: any) => rpc.query(info.route.join(':'), data)
});
} else if (isServiceMutation(service)) {
return mutation({
types,
resolve: (data: any) => rpc.mutation(info.route.join(':'), data)
});
} else if (isServiceSubscription(service)) {
return subscription({
types,
resolve: (data: any) => rpc.subscription(info.route.join(':'), data)
});
} else {
throw Error(`Invalid service kind: ${JSON.stringify(service)}`);
}
}),
types({ [opts.proxyError.name]: opts.proxyError.type })
);

return intercepts(
implementation,
intercept({
errors: references(implementation, [opts.proxyError.name]),
factory: () => (data, context, info, next) => {
return next(data).pipe(
catchError((err) => {
return throwError(
err instanceof PublicError
? err
: new CollectionError(
implementation,
opts.proxyError.name,
err,
true
)
);
})
);
}
})
);
}

0 comments on commit ee26db7

Please sign in to comment.