Skip to content

Commit

Permalink
cleanup fetching logic
Browse files Browse the repository at this point in the history
  • Loading branch information
tgriesser committed May 12, 2022
1 parent 7c3f791 commit 9554901
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 23 deletions.
25 changes: 13 additions & 12 deletions packages/data-context/src/sources/RemoteRequestDataSource.ts
Expand Up @@ -99,24 +99,24 @@ export class RemoteRequestDataSource {

const cachedData = ctx.cloud.readFromCache(params)

// If we have stale data, and we should fetch - fetch the data
if (cachedData?.stale && shouldFetch) {
// Otherwise, fetch it
this.#executeRemote(params)

return {
...partialResult,
status: 'FETCHING',
}
}

if (cachedData) {
// If we have the data, but it's marked as stale (meaning this is a partial eager response)
if (cachedData.stale) {
// If we're not fetching, say it's not fetched but put the data under dataRaw for debugging
if (!shouldFetch) {
return {
...partialResult,
status: 'NOT_FETCHED',
dataRaw: cachedData.data,
}
}

// Otherwise, fetch it
this.#executeRemote(params)

return {
...partialResult,
status: 'FETCHING',
status: 'NOT_FETCHED',
dataRaw: cachedData.data,
}
}
Expand All @@ -137,6 +137,7 @@ export class RemoteRequestDataSource {
}
}

// Otherwise, fetch it
this.#executeRemote(params)

return {
Expand Down
Expand Up @@ -21,23 +21,23 @@ describe('RemoteRequestDataSource', () => {
describe('makeRefetchableId', () => {
it('creates an identifier from the fieldType, operationHash, operationVariables', () => {
const id = remoteRequestSource.makeRefetchableId(
'RemoteFetchableCloudUser',
'RemoteFetchableCloudProjectSpec',
crypto.createHash('sha1').update('query ...').digest('hex'),
{ b: '2', a: 1 },
)

expect(id).to.eql('UmVtb3RlRmV0Y2hhYmxlQ2xvdWRVc2VyOjVjYzI1ZDhhMzlhNjU0ZWIyM2I1MjU3MzQ1YWJiZjQyYmU0MGM4ZDE6ZXlKaElqb3hMQ0ppSWpvaU1pSjk=')
expect(Buffer.from(id, 'base64').toString('utf-8')).to.eql('RemoteFetchableCloudUser:5cc25d8a39a654eb23b5257345abbf42be40c8d1:eyJhIjoxLCJiIjoiMiJ9')
expect(Buffer.from(id, 'base64').toString('utf-8')).to.eql('RemoteFetchableCloudProjectSpec:5cc25d8a39a654eb23b5257345abbf42be40c8d1:eyJhIjoxLCJiIjoiMiJ9')
})

it('stable stringifies via stringifyVariables', () => {
const id = remoteRequestSource.makeRefetchableId(
'RemoteFetchableCloudUser',
'RemoteFetchableCloudProjectSpec',
crypto.createHash('sha1').update('query ...').digest('hex'),
{ b: '2', a: 1 },
)
const id2 = remoteRequestSource.makeRefetchableId(
'RemoteFetchableCloudUser',
'RemoteFetchableCloudProjectSpec',
crypto.createHash('sha1').update('query ...').digest('hex'),
{ a: 1, b: '2' },
)
Expand All @@ -49,7 +49,7 @@ describe('RemoteRequestDataSource', () => {
describe('unpackFetchableNodeId', () => {
it('takes the identifier created from makeRefetchableId and decodes the variables', () => {
expect(remoteRequestSource.unpackFetchableNodeId('UmVtb3RlRmV0Y2hhYmxlQ2xvdWRVc2VyOjVjYzI1ZDhhMzlhNjU0ZWIyM2I1MjU3MzQ1YWJiZjQyYmU0MGM4ZDE6ZXlKaElqb3hMQ0ppSWpvaU1pSjk=')).to.eql({
name: 'RemoteFetchableCloudUser',
name: 'RemoteFetchableCloudProjectSpec',
operationHash: '5cc25d8a39a654eb23b5257345abbf42be40c8d1',
operationVariables: { a: 1, b: '2' },
})
Expand Down
16 changes: 10 additions & 6 deletions packages/graphql/src/plugins/nexusRemoteFieldPlugin.ts
Expand Up @@ -13,6 +13,10 @@ export type RemoteFieldDefinitionConfig<TypeName extends string, FieldName exten
* The type we expect to resolve as the "data"
*/
type: CloudRemoteTargets
/**
* Args to make available to the field definition
*/
args?: core.ArgsRecord
/**
* Optional description for the field
*/
Expand Down Expand Up @@ -41,18 +45,18 @@ export type RemoteFieldDefinitionConfig<TypeName extends string, FieldName exten
} & AdditionalRemoteFieldProps<TypeName, FieldName, RemoteField>

// If not every member of CloudQueryArgs is provided, then we will not issue the request
export type AdditionalRemoteFieldProps<TypeName extends string, FieldName extends string, RemoteField extends CloudQueryFields> = CloudQueryArgs<RemoteField> extends never ? {
queryArgs?: RemoteQueryArgsResolver<TypeName, FieldName, CloudQueryArgs<RemoteField>>
export type AdditionalRemoteFieldProps<TypeName extends string, FieldName extends string, RemoteField extends CloudQueryFields> = RemoteField extends never ? {
queryArgs?: RemoteQueryArgsResolver<TypeName, FieldName, any>
} : {
queryArgs: RemoteQueryArgsResolver<TypeName, FieldName, CloudQueryArgs<RemoteField>>
queryArgs: RemoteQueryArgsResolver<TypeName, FieldName, RemoteField>
}

export type RemoteQueryArgsResolver<TypeName extends string, FieldName extends string, RemoteArgs> = (
export type RemoteQueryArgsResolver<TypeName extends string, FieldName extends string, RemoteField extends CloudQueryFields> = (
source: core.SourceValue<TypeName>,
args: core.ArgsValue<TypeName, FieldName>,
ctx: DataContext,
info: GraphQLResolveInfo
) => core.MaybePromise<RemoteArgs | false>
) => core.MaybePromise<CloudQueryArgs<RemoteField> | false>

export const remoteFieldPlugin = plugin({
name: 'remoteFieldPlugin',
Expand Down Expand Up @@ -117,7 +121,7 @@ export const remoteFieldPlugin = plugin({
t.field(fieldName, {
type: fieldType as any,
description: fieldConfig.description ?? 'Wrapper for resolving remote data associated with this field',

args: fieldConfig.args ?? {},
// Wrap with a batch resolver, so we aren't doing the same info parsing for each row
resolve: createBatchResolver((sources, args, ctx, info) => {
return ctx.remoteRequest.batchResolveRemoteFields(fieldConfig, sources, args, ctx, info)
Expand Down

0 comments on commit 9554901

Please sign in to comment.