@graphql-box/worker-client 5.4.6 → 5.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/dist/production.analysis.txt +20 -20
- package/dist/types/cjs/main.d.cts +11 -0
- package/dist/types/cjs/main.d.cts.map +1 -1
- package/dist/types/cjs/types.d.cts +16 -1
- package/dist/types/cjs/types.d.cts.map +1 -1
- package/dist/types/esm/main.d.ts +11 -0
- package/dist/types/esm/main.d.ts.map +1 -1
- package/dist/types/esm/types.d.ts +16 -1
- package/dist/types/esm/types.d.ts.map +1 -1
- package/dist/types/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +7 -3
- package/src/main.ts +106 -4
- package/src/types.ts +17 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphql-box/worker-client",
|
|
3
3
|
"description": "The GraphQL Box web worker client module.",
|
|
4
|
-
"version": "5.4.
|
|
4
|
+
"version": "5.4.7",
|
|
5
5
|
"author": "Dylan Aubrey",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://github.com/badbatch/graphql-box",
|
|
@@ -46,13 +46,17 @@
|
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"graphql": "<17",
|
|
49
|
-
"@graphql-box/
|
|
49
|
+
"@graphql-box/cache-manager": "5.4.3",
|
|
50
|
+
"@graphql-box/client": "5.4.3",
|
|
51
|
+
"@graphql-box/request-parser": "5.4.2"
|
|
50
52
|
},
|
|
51
53
|
"devDependencies": {
|
|
52
54
|
"cts-types": "^0.0.8",
|
|
53
55
|
"del-cli": "^6.0.0",
|
|
54
56
|
"graphql": "^16.9.0",
|
|
55
|
-
"@graphql-box/
|
|
57
|
+
"@graphql-box/cache-manager": "5.4.3",
|
|
58
|
+
"@graphql-box/request-parser": "5.4.2",
|
|
59
|
+
"@graphql-box/client": "5.4.3"
|
|
56
60
|
},
|
|
57
61
|
"keywords": [
|
|
58
62
|
"client",
|
package/src/main.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { type CoreWorker } from '@cachemap/core-worker';
|
|
2
|
+
import { type CacheManagerDef } from '@graphql-box/cache-manager';
|
|
2
3
|
import {
|
|
3
4
|
type DebugManagerDef,
|
|
4
5
|
type PartialRequestContext,
|
|
5
6
|
type PartialRequestResult,
|
|
7
|
+
type PartialResponseData,
|
|
6
8
|
REQUEST_RESOLVED,
|
|
9
|
+
type RawResponseDataWithMaybeCacheMetadata,
|
|
7
10
|
type RequestContext,
|
|
8
11
|
type RequestOptions,
|
|
9
12
|
SUBSCRIPTION_RESOLVED,
|
|
@@ -17,6 +20,7 @@ import {
|
|
|
17
20
|
isPlainObject,
|
|
18
21
|
rehydrateCacheMetadata,
|
|
19
22
|
} from '@graphql-box/helpers';
|
|
23
|
+
import { type RequestParserDef } from '@graphql-box/request-parser';
|
|
20
24
|
import { EventEmitter } from 'eventemitter3';
|
|
21
25
|
import { OperationTypeNode } from 'graphql';
|
|
22
26
|
import { isError } from 'lodash-es';
|
|
@@ -34,8 +38,26 @@ import {
|
|
|
34
38
|
} from './types.ts';
|
|
35
39
|
|
|
36
40
|
export class WorkerClient {
|
|
37
|
-
private static _getMessageContext({
|
|
38
|
-
|
|
41
|
+
private static _getMessageContext({
|
|
42
|
+
hasDeferOrStream = false,
|
|
43
|
+
operation,
|
|
44
|
+
requestID,
|
|
45
|
+
}: RequestContext): MessageContext {
|
|
46
|
+
return { hasDeferOrStream, operation, requestID };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
private static _resolve(
|
|
50
|
+
{ cacheMetadata, ...rest }: PartialResponseData,
|
|
51
|
+
options: RequestOptions,
|
|
52
|
+
{ requestID }: RequestContext,
|
|
53
|
+
): PartialRequestResult {
|
|
54
|
+
const result: PartialRequestResult = { ...rest, requestID };
|
|
55
|
+
|
|
56
|
+
if (options.returnCacheMetadata && cacheMetadata) {
|
|
57
|
+
result._cacheMetadata = cacheMetadata;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return result;
|
|
39
61
|
}
|
|
40
62
|
|
|
41
63
|
private _onMessage = ({ data }: MessageEvent<MessageResponsePayload>): void => {
|
|
@@ -92,16 +114,35 @@ export class WorkerClient {
|
|
|
92
114
|
stats: { endTime: this._debugManager.now() },
|
|
93
115
|
});
|
|
94
116
|
|
|
117
|
+
if (context.operation === OperationTypeNode.QUERY && pending.requestData && pending.options && pending.context) {
|
|
118
|
+
void this._cacheManager.cacheQuery(
|
|
119
|
+
pending.requestData,
|
|
120
|
+
undefined,
|
|
121
|
+
// Need to look at what type guards can be put in place
|
|
122
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
123
|
+
response as RawResponseDataWithMaybeCacheMetadata,
|
|
124
|
+
pending.options,
|
|
125
|
+
pending.context,
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
|
|
95
129
|
pending.resolve(response);
|
|
96
130
|
}
|
|
97
131
|
};
|
|
98
132
|
|
|
133
|
+
/**
|
|
134
|
+
* This cache instance does not actually store anything itself,
|
|
135
|
+
* it is for communicating with the worker cache that the worker
|
|
136
|
+
* client is using within the worker.
|
|
137
|
+
*/
|
|
99
138
|
private _cache: CoreWorker;
|
|
139
|
+
private _cacheManager: CacheManagerDef;
|
|
100
140
|
private _debugManager: DebugManagerDef | null;
|
|
101
141
|
private _eventEmitter: EventEmitter;
|
|
102
142
|
private _experimentalDeferStreamSupport: boolean;
|
|
103
143
|
private _messageQueue: MessageRequestPayload[] = [];
|
|
104
144
|
private _pending: PendingTracker = new Map();
|
|
145
|
+
private _requestParser: RequestParserDef;
|
|
105
146
|
private _worker: Worker | undefined;
|
|
106
147
|
|
|
107
148
|
constructor(options: UserOptions) {
|
|
@@ -115,6 +156,14 @@ export class WorkerClient {
|
|
|
115
156
|
errors.push(new ArgsError('@graphql-box/worker-client expected options.cache.'));
|
|
116
157
|
}
|
|
117
158
|
|
|
159
|
+
if (!('cacheManager' in options)) {
|
|
160
|
+
errors.push(new ArgsError('@graphql-box/worker-client expected options.cacheManager.'));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
if (!('requestParser' in options)) {
|
|
164
|
+
errors.push(new ArgsError('@graphql-box/worker-client expected options.requestParser.'));
|
|
165
|
+
}
|
|
166
|
+
|
|
118
167
|
if (!options.lazyWorkerInit && !('worker' in options)) {
|
|
119
168
|
errors.push(new ArgsError('@graphql-box/worker-client expected options.worker.'));
|
|
120
169
|
}
|
|
@@ -124,9 +173,11 @@ export class WorkerClient {
|
|
|
124
173
|
}
|
|
125
174
|
|
|
126
175
|
this._cache = options.cache;
|
|
176
|
+
this._cacheManager = options.cacheManager;
|
|
127
177
|
this._debugManager = options.debugManager ?? null;
|
|
128
178
|
this._eventEmitter = new EventEmitter();
|
|
129
179
|
this._experimentalDeferStreamSupport = options.experimentalDeferStreamSupport ?? false;
|
|
180
|
+
this._requestParser = options.requestParser;
|
|
130
181
|
|
|
131
182
|
if (typeof options.worker === 'function') {
|
|
132
183
|
Promise.resolve(options.worker())
|
|
@@ -148,12 +199,16 @@ export class WorkerClient {
|
|
|
148
199
|
return this._cache;
|
|
149
200
|
}
|
|
150
201
|
|
|
202
|
+
get cacheManager(): CacheManagerDef {
|
|
203
|
+
return this._cacheManager;
|
|
204
|
+
}
|
|
205
|
+
|
|
151
206
|
public async mutate(request: string, options: RequestOptions = {}, context: PartialRequestContext = {}) {
|
|
152
207
|
return this._request(request, options, this._getRequestContext(OperationTypeNode.MUTATION, request, context));
|
|
153
208
|
}
|
|
154
209
|
|
|
155
210
|
public async query(request: string, options: RequestOptions = {}, context: PartialRequestContext = {}) {
|
|
156
|
-
return this.
|
|
211
|
+
return this._query(request, options, this._getRequestContext(OperationTypeNode.QUERY, request, context));
|
|
157
212
|
}
|
|
158
213
|
|
|
159
214
|
public async request(request: string, options: RequestOptions = {}, context: PartialRequestContext = {}) {
|
|
@@ -201,12 +256,59 @@ export class WorkerClient {
|
|
|
201
256
|
};
|
|
202
257
|
}
|
|
203
258
|
|
|
259
|
+
private async _query(
|
|
260
|
+
request: string,
|
|
261
|
+
options: RequestOptions,
|
|
262
|
+
context: RequestContext,
|
|
263
|
+
): Promise<PartialRequestResult | AsyncIterableIterator<PartialRequestResult | undefined>> {
|
|
264
|
+
try {
|
|
265
|
+
const { ast, request: updateRequest } = this._requestParser.updateRequest(request, options, context);
|
|
266
|
+
const requestData = { ast, hash: hashRequest(updateRequest), request: updateRequest };
|
|
267
|
+
const checkResult = await this._cacheManager.checkQueryResponseCacheEntry(requestData.hash, options, context);
|
|
268
|
+
|
|
269
|
+
if (checkResult) {
|
|
270
|
+
return WorkerClient._resolve(checkResult, options, context);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
return await new Promise((resolve: PendingResolver) => {
|
|
274
|
+
if (this._worker) {
|
|
275
|
+
this._worker.postMessage({
|
|
276
|
+
context: WorkerClient._getMessageContext(context),
|
|
277
|
+
method: REQUEST,
|
|
278
|
+
options,
|
|
279
|
+
request,
|
|
280
|
+
type: GRAPHQL_BOX,
|
|
281
|
+
});
|
|
282
|
+
} else {
|
|
283
|
+
this._messageQueue.push({
|
|
284
|
+
context: WorkerClient._getMessageContext(context),
|
|
285
|
+
method: REQUEST,
|
|
286
|
+
options,
|
|
287
|
+
request,
|
|
288
|
+
type: GRAPHQL_BOX,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
this._pending.set(context.requestID, { context, options, requestData, resolve });
|
|
293
|
+
});
|
|
294
|
+
} catch (error) {
|
|
295
|
+
const confirmedError = isError(error)
|
|
296
|
+
? error
|
|
297
|
+
: new Error('@graphql-box/worker-client request had an unexpected error.');
|
|
298
|
+
|
|
299
|
+
return { errors: [confirmedError], requestID: context.requestID };
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
204
303
|
private _releaseMessageQueue(): void {
|
|
205
304
|
if (!this._worker) {
|
|
206
305
|
throw new Error('A worker is required for the WorkerClient to work correctly.');
|
|
207
306
|
}
|
|
208
307
|
|
|
209
|
-
|
|
308
|
+
const messageQueue = [...this._messageQueue];
|
|
309
|
+
this._messageQueue = [];
|
|
310
|
+
|
|
311
|
+
for (const message of messageQueue) {
|
|
210
312
|
this._worker.postMessage(message);
|
|
211
313
|
}
|
|
212
314
|
}
|
package/src/types.ts
CHANGED
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { type CoreWorker } from '@cachemap/core-worker';
|
|
2
|
+
import { type CacheManagerDef } from '@graphql-box/cache-manager';
|
|
2
3
|
import { type Client } from '@graphql-box/client';
|
|
3
4
|
import {
|
|
4
5
|
type DebugManagerDef,
|
|
5
6
|
type PartialRawFetchData,
|
|
6
7
|
type PartialRequestResult,
|
|
8
|
+
type RequestContext,
|
|
9
|
+
type RequestData,
|
|
7
10
|
type RequestOptions,
|
|
8
11
|
} from '@graphql-box/core';
|
|
12
|
+
import { type RequestParserDef } from '@graphql-box/request-parser';
|
|
13
|
+
import { type OperationTypeNode } from 'graphql';
|
|
9
14
|
|
|
10
15
|
export interface UserOptions {
|
|
11
16
|
/**
|
|
12
17
|
* The cache.
|
|
13
18
|
*/
|
|
14
19
|
cache: CoreWorker;
|
|
20
|
+
/**
|
|
21
|
+
* The curried function to initialize the cache manager.
|
|
22
|
+
*/
|
|
23
|
+
cacheManager: CacheManagerDef;
|
|
15
24
|
/**
|
|
16
25
|
* The debug manager.
|
|
17
26
|
*/
|
|
@@ -26,6 +35,10 @@ export interface UserOptions {
|
|
|
26
35
|
* initialise the worker after the constructor.
|
|
27
36
|
*/
|
|
28
37
|
lazyWorkerInit?: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* The curried function to initialzie the request parser.
|
|
40
|
+
*/
|
|
41
|
+
requestParser: RequestParserDef;
|
|
29
42
|
/**
|
|
30
43
|
* The web worker instance.
|
|
31
44
|
*/
|
|
@@ -39,6 +52,9 @@ export type PendingResolver = (
|
|
|
39
52
|
) => void;
|
|
40
53
|
|
|
41
54
|
export interface PendingData {
|
|
55
|
+
context?: RequestContext;
|
|
56
|
+
options?: RequestOptions;
|
|
57
|
+
requestData?: RequestData;
|
|
42
58
|
resolve: PendingResolver;
|
|
43
59
|
}
|
|
44
60
|
|
|
@@ -61,6 +77,7 @@ export interface MessageResponsePayload {
|
|
|
61
77
|
|
|
62
78
|
export interface MessageContext {
|
|
63
79
|
hasDeferOrStream: boolean;
|
|
80
|
+
operation: OperationTypeNode;
|
|
64
81
|
requestID: string;
|
|
65
82
|
}
|
|
66
83
|
|