Skip to content

Commit 32cf7d9

Browse files
committed
#build
1 parent 9ae0efb commit 32cf7d9

13 files changed

Lines changed: 191223 additions & 0 deletions

generated/index.ts

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// @ts-nocheck
2+
import type {
3+
query_rootGenqlSelection,
4+
query_root,
5+
mutation_rootGenqlSelection,
6+
mutation_root,
7+
subscription_rootGenqlSelection,
8+
subscription_root,
9+
} from './schema'
10+
import {
11+
linkTypeMap,
12+
createClient as createClientOriginal,
13+
generateGraphqlOperation,
14+
type FieldsSelection,
15+
type GraphqlOperation,
16+
type ClientOptions,
17+
GenqlError,
18+
} from './runtime'
19+
export type { FieldsSelection } from './runtime'
20+
export { GenqlError }
21+
22+
import types from './types'
23+
export * from './schema'
24+
const typeMap = linkTypeMap(types as any)
25+
26+
export interface Client {
27+
query<R extends query_rootGenqlSelection>(
28+
request: R & { __name?: string },
29+
): Promise<FieldsSelection<query_root, R>>
30+
31+
mutation<R extends mutation_rootGenqlSelection>(
32+
request: R & { __name?: string },
33+
): Promise<FieldsSelection<mutation_root, R>>
34+
}
35+
36+
export const createClient = function (options?: ClientOptions): Client {
37+
return createClientOriginal({
38+
url: 'http://hasura:8080/v1/graphql',
39+
40+
...options,
41+
queryRoot: typeMap.Query!,
42+
mutationRoot: typeMap.Mutation!,
43+
subscriptionRoot: typeMap.Subscription!,
44+
}) as any
45+
}
46+
47+
export const everything = {
48+
__scalar: true,
49+
}
50+
51+
export type QueryResult<fields extends query_rootGenqlSelection> =
52+
FieldsSelection<query_root, fields>
53+
export const generateQueryOp: (
54+
fields: query_rootGenqlSelection & { __name?: string },
55+
) => GraphqlOperation = function (fields) {
56+
return generateGraphqlOperation('query', typeMap.Query!, fields as any)
57+
}
58+
59+
export type MutationResult<fields extends mutation_rootGenqlSelection> =
60+
FieldsSelection<mutation_root, fields>
61+
export const generateMutationOp: (
62+
fields: mutation_rootGenqlSelection & { __name?: string },
63+
) => GraphqlOperation = function (fields) {
64+
return generateGraphqlOperation('mutation', typeMap.Mutation!, fields as any)
65+
}
66+
67+
export type SubscriptionResult<fields extends subscription_rootGenqlSelection> =
68+
FieldsSelection<subscription_root, fields>
69+
export const generateSubscriptionOp: (
70+
fields: subscription_rootGenqlSelection & { __name?: string },
71+
) => GraphqlOperation = function (fields) {
72+
return generateGraphqlOperation(
73+
'subscription',
74+
typeMap.Subscription!,
75+
fields as any,
76+
)
77+
}

generated/runtime/batcher.ts

Lines changed: 275 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,275 @@
1+
// @ts-nocheck
2+
import type { GraphqlOperation } from './generateGraphqlOperation'
3+
import { GenqlError } from './error'
4+
5+
type Variables = Record<string, any>
6+
7+
type QueryError = Error & {
8+
message: string
9+
10+
locations?: Array<{
11+
line: number
12+
column: number
13+
}>
14+
path?: any
15+
rid: string
16+
details?: Record<string, any>
17+
}
18+
type Result = {
19+
data: Record<string, any>
20+
errors: Array<QueryError>
21+
}
22+
type Fetcher = (
23+
batchedQuery: GraphqlOperation | Array<GraphqlOperation>,
24+
) => Promise<Array<Result>>
25+
type Options = {
26+
batchInterval?: number
27+
shouldBatch?: boolean
28+
maxBatchSize?: number
29+
}
30+
type Queue = Array<{
31+
request: GraphqlOperation
32+
resolve: (...args: Array<any>) => any
33+
reject: (...args: Array<any>) => any
34+
}>
35+
36+
/**
37+
* takes a list of requests (queue) and batches them into a single server request.
38+
* It will then resolve each individual requests promise with the appropriate data.
39+
* @private
40+
* @param {QueryBatcher} client - the client to use
41+
* @param {Queue} queue - the list of requests to batch
42+
*/
43+
function dispatchQueueBatch(client: QueryBatcher, queue: Queue): void {
44+
let batchedQuery: any = queue.map((item) => item.request)
45+
46+
if (batchedQuery.length === 1) {
47+
batchedQuery = batchedQuery[0]
48+
}
49+
(() => {
50+
try {
51+
return client.fetcher(batchedQuery);
52+
} catch(e) {
53+
return Promise.reject(e);
54+
}
55+
})().then((responses: any) => {
56+
if (queue.length === 1 && !Array.isArray(responses)) {
57+
if (responses.errors && responses.errors.length) {
58+
queue[0].reject(
59+
new GenqlError(responses.errors, responses.data),
60+
)
61+
return
62+
}
63+
64+
queue[0].resolve(responses)
65+
return
66+
} else if (responses.length !== queue.length) {
67+
throw new Error('response length did not match query length')
68+
}
69+
70+
for (let i = 0; i < queue.length; i++) {
71+
if (responses[i].errors && responses[i].errors.length) {
72+
queue[i].reject(
73+
new GenqlError(responses[i].errors, responses[i].data),
74+
)
75+
} else {
76+
queue[i].resolve(responses[i])
77+
}
78+
}
79+
})
80+
.catch((e) => {
81+
for (let i = 0; i < queue.length; i++) {
82+
queue[i].reject(e)
83+
}
84+
});
85+
}
86+
87+
/**
88+
* creates a list of requests to batch according to max batch size.
89+
* @private
90+
* @param {QueryBatcher} client - the client to create list of requests from from
91+
* @param {Options} options - the options for the batch
92+
*/
93+
function dispatchQueue(client: QueryBatcher, options: Options): void {
94+
const queue = client._queue
95+
const maxBatchSize = options.maxBatchSize || 0
96+
client._queue = []
97+
98+
if (maxBatchSize > 0 && maxBatchSize < queue.length) {
99+
for (let i = 0; i < queue.length / maxBatchSize; i++) {
100+
dispatchQueueBatch(
101+
client,
102+
queue.slice(i * maxBatchSize, (i + 1) * maxBatchSize),
103+
)
104+
}
105+
} else {
106+
dispatchQueueBatch(client, queue)
107+
}
108+
}
109+
/**
110+
* Create a batcher client.
111+
* @param {Fetcher} fetcher - A function that can handle the network requests to graphql endpoint
112+
* @param {Options} options - the options to be used by client
113+
* @param {boolean} options.shouldBatch - should the client batch requests. (default true)
114+
* @param {integer} options.batchInterval - duration (in MS) of each batch window. (default 6)
115+
* @param {integer} options.maxBatchSize - max number of requests in a batch. (default 0)
116+
* @param {boolean} options.defaultHeaders - default headers to include with every request
117+
*
118+
* @example
119+
* const fetcher = batchedQuery => fetch('path/to/graphql', {
120+
* method: 'post',
121+
* headers: {
122+
* Accept: 'application/json',
123+
* 'Content-Type': 'application/json',
124+
* },
125+
* body: JSON.stringify(batchedQuery),
126+
* credentials: 'include',
127+
* })
128+
* .then(response => response.json())
129+
*
130+
* const client = new QueryBatcher(fetcher, { maxBatchSize: 10 })
131+
*/
132+
133+
export class QueryBatcher {
134+
fetcher: Fetcher
135+
_options: Options
136+
_queue: Queue
137+
138+
constructor(
139+
fetcher: Fetcher,
140+
{
141+
batchInterval = 6,
142+
shouldBatch = true,
143+
maxBatchSize = 0,
144+
}: Options = {},
145+
) {
146+
this.fetcher = fetcher
147+
this._options = {
148+
batchInterval,
149+
shouldBatch,
150+
maxBatchSize,
151+
}
152+
this._queue = []
153+
}
154+
155+
/**
156+
* Fetch will send a graphql request and return the parsed json.
157+
* @param {string} query - the graphql query.
158+
* @param {Variables} variables - any variables you wish to inject as key/value pairs.
159+
* @param {[string]} operationName - the graphql operationName.
160+
* @param {Options} overrides - the client options overrides.
161+
*
162+
* @return {promise} resolves to parsed json of server response
163+
*
164+
* @example
165+
* client.fetch(`
166+
* query getHuman($id: ID!) {
167+
* human(id: $id) {
168+
* name
169+
* height
170+
* }
171+
* }
172+
* `, { id: "1001" }, 'getHuman')
173+
* .then(human => {
174+
* // do something with human
175+
* console.log(human);
176+
* });
177+
*/
178+
fetch(
179+
query: string,
180+
variables?: Variables,
181+
operationName?: string,
182+
overrides: Options = {},
183+
): Promise<Result> {
184+
const request: GraphqlOperation = {
185+
query,
186+
}
187+
const options = Object.assign({}, this._options, overrides)
188+
189+
if (variables) {
190+
request.variables = variables
191+
}
192+
193+
if (operationName) {
194+
request.operationName = operationName
195+
}
196+
197+
const promise = new Promise<Result>((resolve, reject) => {
198+
this._queue.push({
199+
request,
200+
resolve,
201+
reject,
202+
})
203+
204+
if (this._queue.length === 1) {
205+
if (options.shouldBatch) {
206+
setTimeout(
207+
() => dispatchQueue(this, options),
208+
options.batchInterval,
209+
)
210+
} else {
211+
dispatchQueue(this, options)
212+
}
213+
}
214+
})
215+
return promise
216+
}
217+
218+
/**
219+
* Fetch will send a graphql request and return the parsed json.
220+
* @param {string} query - the graphql query.
221+
* @param {Variables} variables - any variables you wish to inject as key/value pairs.
222+
* @param {[string]} operationName - the graphql operationName.
223+
* @param {Options} overrides - the client options overrides.
224+
*
225+
* @return {Promise<Array<Result>>} resolves to parsed json of server response
226+
*
227+
* @example
228+
* client.forceFetch(`
229+
* query getHuman($id: ID!) {
230+
* human(id: $id) {
231+
* name
232+
* height
233+
* }
234+
* }
235+
* `, { id: "1001" }, 'getHuman')
236+
* .then(human => {
237+
* // do something with human
238+
* console.log(human);
239+
* });
240+
*/
241+
forceFetch(
242+
query: string,
243+
variables?: Variables,
244+
operationName?: string,
245+
overrides: Options = {},
246+
): Promise<Result> {
247+
const request: GraphqlOperation = {
248+
query,
249+
}
250+
const options = Object.assign({}, this._options, overrides, {
251+
shouldBatch: false,
252+
})
253+
254+
if (variables) {
255+
request.variables = variables
256+
}
257+
258+
if (operationName) {
259+
request.operationName = operationName
260+
}
261+
262+
const promise = new Promise<Result>((resolve, reject) => {
263+
const client = new QueryBatcher(this.fetcher, this._options)
264+
client._queue = [
265+
{
266+
request,
267+
resolve,
268+
reject,
269+
},
270+
]
271+
dispatchQueue(client, options)
272+
})
273+
return promise
274+
}
275+
}

0 commit comments

Comments
 (0)