@haneullabs/utils 0.1.0
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/CHANGELOG.md +25 -0
- package/README.md +5 -0
- package/dist/cjs/b58.d.ts +2 -0
- package/dist/cjs/b58.js +28 -0
- package/dist/cjs/b58.js.map +7 -0
- package/dist/cjs/b64.d.ts +2 -0
- package/dist/cjs/b64.js +40 -0
- package/dist/cjs/b64.js.map +7 -0
- package/dist/cjs/chunk.d.ts +1 -0
- package/dist/cjs/chunk.js +29 -0
- package/dist/cjs/chunk.js.map +7 -0
- package/dist/cjs/dataloader.d.ts +129 -0
- package/dist/cjs/dataloader.js +318 -0
- package/dist/cjs/dataloader.js.map +7 -0
- package/dist/cjs/hex.d.ts +2 -0
- package/dist/cjs/hex.js +37 -0
- package/dist/cjs/hex.js.map +7 -0
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.js +38 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/package.json +5 -0
- package/dist/cjs/types.d.ts +4 -0
- package/dist/cjs/types.js +17 -0
- package/dist/cjs/types.js.map +7 -0
- package/dist/cjs/with-resolver.d.ts +6 -0
- package/dist/cjs/with-resolver.js +37 -0
- package/dist/cjs/with-resolver.js.map +7 -0
- package/dist/esm/b58.d.ts +2 -0
- package/dist/esm/b58.js +8 -0
- package/dist/esm/b58.js.map +7 -0
- package/dist/esm/b64.d.ts +2 -0
- package/dist/esm/b64.js +20 -0
- package/dist/esm/b64.js.map +7 -0
- package/dist/esm/chunk.d.ts +1 -0
- package/dist/esm/chunk.js +9 -0
- package/dist/esm/chunk.js.map +7 -0
- package/dist/esm/dataloader.d.ts +129 -0
- package/dist/esm/dataloader.js +298 -0
- package/dist/esm/dataloader.js.map +7 -0
- package/dist/esm/hex.d.ts +2 -0
- package/dist/esm/hex.js +17 -0
- package/dist/esm/hex.js.map +7 -0
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.js +18 -0
- package/dist/esm/index.js.map +7 -0
- package/dist/esm/package.json +5 -0
- package/dist/esm/types.d.ts +4 -0
- package/dist/esm/types.js +1 -0
- package/dist/esm/types.js.map +7 -0
- package/dist/esm/with-resolver.d.ts +6 -0
- package/dist/esm/with-resolver.js +17 -0
- package/dist/esm/with-resolver.js.map +7 -0
- package/dist/tsconfig.esm.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +53 -0
- package/src/b58.ts +7 -0
- package/src/b64.ts +22 -0
- package/src/chunk.ts +8 -0
- package/src/dataloader.ts +518 -0
- package/src/hex.ts +18 -0
- package/src/index.ts +10 -0
- package/src/types.ts +13 -0
- package/src/with-resolver.ts +24 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# @haneullabs/utils
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- ea1ac70: Update dependencies and improve support for typescript 5.9
|
|
8
|
+
|
|
9
|
+
## 0.1.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- 1c4a82d: update links in package.json
|
|
14
|
+
|
|
15
|
+
## 0.1.0
|
|
16
|
+
|
|
17
|
+
### Minor Changes
|
|
18
|
+
|
|
19
|
+
- a00522b: Add dataloader
|
|
20
|
+
|
|
21
|
+
## 0.0.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- bb7c03a: Update dependencies
|
package/README.md
ADDED
package/dist/cjs/b58.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var b58_exports = {};
|
|
20
|
+
__export(b58_exports, {
|
|
21
|
+
fromBase58: () => fromBase58,
|
|
22
|
+
toBase58: () => toBase58
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(b58_exports);
|
|
25
|
+
var import_base = require("@scure/base");
|
|
26
|
+
const toBase58 = (buffer) => import_base.base58.encode(buffer);
|
|
27
|
+
const fromBase58 = (str) => import_base.base58.decode(str);
|
|
28
|
+
//# sourceMappingURL=b58.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/b58.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nimport { base58 } from '@scure/base';\n\nexport const toBase58 = (buffer: Uint8Array) => base58.encode(buffer);\nexport const fromBase58 = (str: string) => base58.decode(str) as Uint8Array<ArrayBuffer>;\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,kBAAuB;AAEhB,MAAM,WAAW,CAAC,WAAuB,mBAAO,OAAO,MAAM;AAC7D,MAAM,aAAa,CAAC,QAAgB,mBAAO,OAAO,GAAG;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/cjs/b64.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var b64_exports = {};
|
|
20
|
+
__export(b64_exports, {
|
|
21
|
+
fromBase64: () => fromBase64,
|
|
22
|
+
toBase64: () => toBase64
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(b64_exports);
|
|
25
|
+
function fromBase64(base64String) {
|
|
26
|
+
return Uint8Array.from(atob(base64String), (char) => char.charCodeAt(0));
|
|
27
|
+
}
|
|
28
|
+
const CHUNK_SIZE = 8192;
|
|
29
|
+
function toBase64(bytes) {
|
|
30
|
+
if (bytes.length < CHUNK_SIZE) {
|
|
31
|
+
return btoa(String.fromCharCode(...bytes));
|
|
32
|
+
}
|
|
33
|
+
let output = "";
|
|
34
|
+
for (var i = 0; i < bytes.length; i += CHUNK_SIZE) {
|
|
35
|
+
const chunk = bytes.slice(i, i + CHUNK_SIZE);
|
|
36
|
+
output += String.fromCharCode(...chunk);
|
|
37
|
+
}
|
|
38
|
+
return btoa(output);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=b64.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/b64.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport function fromBase64(base64String: string): Uint8Array<ArrayBuffer> {\n\treturn Uint8Array.from(atob(base64String), (char) => char.charCodeAt(0));\n}\n\nconst CHUNK_SIZE = 8192;\nexport function toBase64(bytes: Uint8Array): string {\n\t// Special-case the simple case for speed's sake.\n\tif (bytes.length < CHUNK_SIZE) {\n\t\treturn btoa(String.fromCharCode(...bytes));\n\t}\n\n\tlet output = '';\n\tfor (var i = 0; i < bytes.length; i += CHUNK_SIZE) {\n\t\tconst chunk = bytes.slice(i, i + CHUNK_SIZE);\n\t\toutput += String.fromCharCode(...chunk);\n\t}\n\n\treturn btoa(output);\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,SAAS,WAAW,cAA+C;AACzE,SAAO,WAAW,KAAK,KAAK,YAAY,GAAG,CAAC,SAAS,KAAK,WAAW,CAAC,CAAC;AACxE;AAEA,MAAM,aAAa;AACZ,SAAS,SAAS,OAA2B;AAEnD,MAAI,MAAM,SAAS,YAAY;AAC9B,WAAO,KAAK,OAAO,aAAa,GAAG,KAAK,CAAC;AAAA,EAC1C;AAEA,MAAI,SAAS;AACb,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK,YAAY;AAClD,UAAM,QAAQ,MAAM,MAAM,GAAG,IAAI,UAAU;AAC3C,cAAU,OAAO,aAAa,GAAG,KAAK;AAAA,EACvC;AAEA,SAAO,KAAK,MAAM;AACnB;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function chunk<T>(array: readonly T[], size: number): T[][];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var chunk_exports = {};
|
|
20
|
+
__export(chunk_exports, {
|
|
21
|
+
chunk: () => chunk
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(chunk_exports);
|
|
24
|
+
function chunk(array, size) {
|
|
25
|
+
return Array.from({ length: Math.ceil(array.length / size) }, (_, i) => {
|
|
26
|
+
return array.slice(i * size, (i + 1) * size);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=chunk.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/chunk.ts"],
|
|
4
|
+
"sourcesContent": ["// Copyright (c) Mysten Labs, Inc.\n// SPDX-License-Identifier: Apache-2.0\n\nexport function chunk<T>(array: readonly T[], size: number): T[][] {\n\treturn Array.from({ length: Math.ceil(array.length / size) }, (_, i) => {\n\t\treturn array.slice(i * size, (i + 1) * size);\n\t});\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAGO,SAAS,MAAS,OAAqB,MAAqB;AAClE,SAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,KAAK,MAAM,SAAS,IAAI,EAAE,GAAG,CAAC,GAAG,MAAM;AACvE,WAAO,MAAM,MAAM,IAAI,OAAO,IAAI,KAAK,IAAI;AAAA,EAC5C,CAAC;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/** Copied from https://github.com/graphql/dataloader/blob/a10773043d41a56bde4219c155fcf5633e6c9bcb/src/index.js */
|
|
2
|
+
/**
|
|
3
|
+
* A `DataLoader` creates a public API for loading data from a particular
|
|
4
|
+
* data back-end with unique keys such as the `id` column of a SQL table or
|
|
5
|
+
* document name in a MongoDB database, given a batch loading function.
|
|
6
|
+
*
|
|
7
|
+
* Each `DataLoader` instance contains a unique memoized cache. Use caution when
|
|
8
|
+
* used in long-lived applications or those which serve many users with
|
|
9
|
+
* different access permissions and consider creating a new instance per
|
|
10
|
+
* web request.
|
|
11
|
+
*/
|
|
12
|
+
export declare class DataLoader<K, V, C = K> {
|
|
13
|
+
constructor(batchLoadFn: DataLoader.BatchLoadFn<K, V>, options?: DataLoader.Options<K, V, C>);
|
|
14
|
+
_batchLoadFn: DataLoader.BatchLoadFn<K, V>;
|
|
15
|
+
_maxBatchSize: number;
|
|
16
|
+
_batchScheduleFn: (cb: () => void) => void;
|
|
17
|
+
_cacheKeyFn: (key: K) => C;
|
|
18
|
+
_cacheMap: DataLoader.CacheMap<C, Promise<V>> | null;
|
|
19
|
+
_batch: Batch<K, V> | null;
|
|
20
|
+
/**
|
|
21
|
+
* Loads a key, returning a `Promise` for the value represented by that key.
|
|
22
|
+
*/
|
|
23
|
+
load(key: K): Promise<V>;
|
|
24
|
+
/**
|
|
25
|
+
* Loads multiple keys, promising an array of values:
|
|
26
|
+
*
|
|
27
|
+
* var [ a, b ] = await myLoader.loadMany([ 'a', 'b' ]);
|
|
28
|
+
*
|
|
29
|
+
* This is similar to the more verbose:
|
|
30
|
+
*
|
|
31
|
+
* var [ a, b ] = await Promise.all([
|
|
32
|
+
* myLoader.load('a'),
|
|
33
|
+
* myLoader.load('b')
|
|
34
|
+
* ]);
|
|
35
|
+
*
|
|
36
|
+
* However it is different in the case where any load fails. Where
|
|
37
|
+
* Promise.all() would reject, loadMany() always resolves, however each result
|
|
38
|
+
* is either a value or an Error instance.
|
|
39
|
+
*
|
|
40
|
+
* var [ a, b, c ] = await myLoader.loadMany([ 'a', 'b', 'badkey' ]);
|
|
41
|
+
* // c instanceof Error
|
|
42
|
+
*
|
|
43
|
+
*/
|
|
44
|
+
loadMany(keys: ReadonlyArray<K>): Promise<Array<V | Error>>;
|
|
45
|
+
/**
|
|
46
|
+
* Clears the value at `key` from the cache, if it exists. Returns itself for
|
|
47
|
+
* method chaining.
|
|
48
|
+
*/
|
|
49
|
+
clear(key: K): this;
|
|
50
|
+
/**
|
|
51
|
+
* Clears the entire cache. To be used when some event results in unknown
|
|
52
|
+
* invalidations across this particular `DataLoader`. Returns itself for
|
|
53
|
+
* method chaining.
|
|
54
|
+
*/
|
|
55
|
+
clearAll(): this;
|
|
56
|
+
/**
|
|
57
|
+
* Adds the provided key and value to the cache. If the key already
|
|
58
|
+
* exists, no change is made. Returns itself for method chaining.
|
|
59
|
+
*
|
|
60
|
+
* To prime the cache with an error at a key, provide an Error instance.
|
|
61
|
+
*/
|
|
62
|
+
prime(key: K, value: V | Promise<V> | Error): this;
|
|
63
|
+
/**
|
|
64
|
+
* The name given to this `DataLoader` instance. Useful for APM tools.
|
|
65
|
+
*
|
|
66
|
+
* Is `null` if not set in the constructor.
|
|
67
|
+
*/
|
|
68
|
+
name: string | null;
|
|
69
|
+
}
|
|
70
|
+
type Batch<K, V> = {
|
|
71
|
+
hasDispatched: boolean;
|
|
72
|
+
keys: Array<K>;
|
|
73
|
+
callbacks: Array<{
|
|
74
|
+
resolve: (value: V) => void;
|
|
75
|
+
reject: (error: Error) => void;
|
|
76
|
+
}>;
|
|
77
|
+
cacheHits?: Array<() => void>;
|
|
78
|
+
};
|
|
79
|
+
export declare namespace DataLoader {
|
|
80
|
+
type CacheMap<K, V> = {
|
|
81
|
+
get(key: K): V | void;
|
|
82
|
+
set(key: K, value: V): any;
|
|
83
|
+
delete(key: K): any;
|
|
84
|
+
clear(): any;
|
|
85
|
+
};
|
|
86
|
+
type BatchLoadFn<K, V> = (keys: ReadonlyArray<K>) => PromiseLike<ArrayLike<V | Error>>;
|
|
87
|
+
type Options<K, V, C = K> = {
|
|
88
|
+
/**
|
|
89
|
+
* Default `true`. Set to `false` to disable batching, invoking
|
|
90
|
+
* `batchLoadFn` with a single load key. This is equivalent to setting
|
|
91
|
+
* `maxBatchSize` to `1`.
|
|
92
|
+
*/
|
|
93
|
+
batch?: boolean;
|
|
94
|
+
/**
|
|
95
|
+
* Default `Infinity`. Limits the number of items that get passed in to the
|
|
96
|
+
* `batchLoadFn`. May be set to `1` to disable batching.
|
|
97
|
+
*/
|
|
98
|
+
maxBatchSize?: number;
|
|
99
|
+
/**
|
|
100
|
+
* Default see https://github.com/graphql/dataloader#batch-scheduling.
|
|
101
|
+
* A function to schedule the later execution of a batch. The function is
|
|
102
|
+
* expected to call the provided callback in the immediate future.
|
|
103
|
+
*/
|
|
104
|
+
batchScheduleFn?: (callback: () => void) => void;
|
|
105
|
+
/**
|
|
106
|
+
* Default `true`. Set to `false` to disable memoization caching, creating a
|
|
107
|
+
* new Promise and new key in the `batchLoadFn` for every load of the same
|
|
108
|
+
* key. This is equivalent to setting `cacheMap` to `null`.
|
|
109
|
+
*/
|
|
110
|
+
cache?: boolean;
|
|
111
|
+
/**
|
|
112
|
+
* Default `key => key`. Produces cache key for a given load key. Useful
|
|
113
|
+
* when keys are objects and two objects should be considered equivalent.
|
|
114
|
+
*/
|
|
115
|
+
cacheKeyFn?: (key: K) => C;
|
|
116
|
+
/**
|
|
117
|
+
* Default `new Map()`. Instance of `Map` (or an object with a similar API)
|
|
118
|
+
* to be used as cache. May be set to `null` to disable caching.
|
|
119
|
+
*/
|
|
120
|
+
cacheMap?: CacheMap<C, Promise<V>> | null;
|
|
121
|
+
/**
|
|
122
|
+
* The name given to this `DataLoader` instance. Useful for APM tools.
|
|
123
|
+
*
|
|
124
|
+
* Is `null` if not set in the constructor.
|
|
125
|
+
*/
|
|
126
|
+
name?: string | null;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
export {};
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var dataloader_exports = {};
|
|
20
|
+
__export(dataloader_exports, {
|
|
21
|
+
DataLoader: () => DataLoader
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(dataloader_exports);
|
|
24
|
+
class DataLoader {
|
|
25
|
+
constructor(batchLoadFn, options) {
|
|
26
|
+
if (typeof batchLoadFn !== "function") {
|
|
27
|
+
throw new TypeError(
|
|
28
|
+
`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: ${batchLoadFn}.`
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
this._batchLoadFn = batchLoadFn;
|
|
32
|
+
this._maxBatchSize = getValidMaxBatchSize(options);
|
|
33
|
+
this._batchScheduleFn = getValidBatchScheduleFn(options);
|
|
34
|
+
this._cacheKeyFn = getValidCacheKeyFn(options);
|
|
35
|
+
this._cacheMap = getValidCacheMap(options);
|
|
36
|
+
this._batch = null;
|
|
37
|
+
this.name = getValidName(options);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Loads a key, returning a `Promise` for the value represented by that key.
|
|
41
|
+
*/
|
|
42
|
+
load(key) {
|
|
43
|
+
if (key === null || key === void 0) {
|
|
44
|
+
throw new TypeError(
|
|
45
|
+
`The loader.load() function must be called with a value, but got: ${String(key)}.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
const batch = getCurrentBatch(this);
|
|
49
|
+
const cacheMap = this._cacheMap;
|
|
50
|
+
let cacheKey;
|
|
51
|
+
if (cacheMap) {
|
|
52
|
+
cacheKey = this._cacheKeyFn(key);
|
|
53
|
+
const cachedPromise = cacheMap.get(cacheKey);
|
|
54
|
+
if (cachedPromise) {
|
|
55
|
+
const cacheHits = batch.cacheHits || (batch.cacheHits = []);
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
cacheHits.push(() => {
|
|
58
|
+
resolve(cachedPromise);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
batch.keys.push(key);
|
|
64
|
+
const promise = new Promise((resolve, reject) => {
|
|
65
|
+
batch.callbacks.push({ resolve, reject });
|
|
66
|
+
});
|
|
67
|
+
if (cacheMap) {
|
|
68
|
+
cacheMap.set(cacheKey, promise);
|
|
69
|
+
}
|
|
70
|
+
return promise;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Loads multiple keys, promising an array of values:
|
|
74
|
+
*
|
|
75
|
+
* var [ a, b ] = await myLoader.loadMany([ 'a', 'b' ]);
|
|
76
|
+
*
|
|
77
|
+
* This is similar to the more verbose:
|
|
78
|
+
*
|
|
79
|
+
* var [ a, b ] = await Promise.all([
|
|
80
|
+
* myLoader.load('a'),
|
|
81
|
+
* myLoader.load('b')
|
|
82
|
+
* ]);
|
|
83
|
+
*
|
|
84
|
+
* However it is different in the case where any load fails. Where
|
|
85
|
+
* Promise.all() would reject, loadMany() always resolves, however each result
|
|
86
|
+
* is either a value or an Error instance.
|
|
87
|
+
*
|
|
88
|
+
* var [ a, b, c ] = await myLoader.loadMany([ 'a', 'b', 'badkey' ]);
|
|
89
|
+
* // c instanceof Error
|
|
90
|
+
*
|
|
91
|
+
*/
|
|
92
|
+
loadMany(keys) {
|
|
93
|
+
if (!isArrayLike(keys)) {
|
|
94
|
+
throw new TypeError(
|
|
95
|
+
`The loader.loadMany() function must be called with Array<key>, but got: ${keys}.`
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
const loadPromises = [];
|
|
99
|
+
for (let i = 0; i < keys.length; i++) {
|
|
100
|
+
loadPromises.push(this.load(keys[i]).catch((error) => error));
|
|
101
|
+
}
|
|
102
|
+
return Promise.all(loadPromises);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Clears the value at `key` from the cache, if it exists. Returns itself for
|
|
106
|
+
* method chaining.
|
|
107
|
+
*/
|
|
108
|
+
clear(key) {
|
|
109
|
+
const cacheMap = this._cacheMap;
|
|
110
|
+
if (cacheMap) {
|
|
111
|
+
const cacheKey = this._cacheKeyFn(key);
|
|
112
|
+
cacheMap.delete(cacheKey);
|
|
113
|
+
}
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Clears the entire cache. To be used when some event results in unknown
|
|
118
|
+
* invalidations across this particular `DataLoader`. Returns itself for
|
|
119
|
+
* method chaining.
|
|
120
|
+
*/
|
|
121
|
+
clearAll() {
|
|
122
|
+
const cacheMap = this._cacheMap;
|
|
123
|
+
if (cacheMap) {
|
|
124
|
+
cacheMap.clear();
|
|
125
|
+
}
|
|
126
|
+
return this;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Adds the provided key and value to the cache. If the key already
|
|
130
|
+
* exists, no change is made. Returns itself for method chaining.
|
|
131
|
+
*
|
|
132
|
+
* To prime the cache with an error at a key, provide an Error instance.
|
|
133
|
+
*/
|
|
134
|
+
prime(key, value) {
|
|
135
|
+
const cacheMap = this._cacheMap;
|
|
136
|
+
if (cacheMap) {
|
|
137
|
+
const cacheKey = this._cacheKeyFn(key);
|
|
138
|
+
if (cacheMap.get(cacheKey) === void 0) {
|
|
139
|
+
let promise;
|
|
140
|
+
if (value instanceof Error) {
|
|
141
|
+
promise = Promise.reject(value);
|
|
142
|
+
promise.catch(() => {
|
|
143
|
+
});
|
|
144
|
+
} else {
|
|
145
|
+
promise = Promise.resolve(value);
|
|
146
|
+
}
|
|
147
|
+
cacheMap.set(cacheKey, promise);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
return this;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
const enqueuePostPromiseJob = (
|
|
154
|
+
// @ts-ignore
|
|
155
|
+
typeof process === "object" && typeof process.nextTick === "function" ? function(fn) {
|
|
156
|
+
if (!resolvedPromise) {
|
|
157
|
+
resolvedPromise = Promise.resolve();
|
|
158
|
+
}
|
|
159
|
+
resolvedPromise.then(() => {
|
|
160
|
+
process.nextTick(fn);
|
|
161
|
+
});
|
|
162
|
+
} : (
|
|
163
|
+
// @ts-ignore
|
|
164
|
+
typeof setImmediate === "function" ? function(fn) {
|
|
165
|
+
setImmediate(fn);
|
|
166
|
+
} : function(fn) {
|
|
167
|
+
setTimeout(fn);
|
|
168
|
+
}
|
|
169
|
+
)
|
|
170
|
+
);
|
|
171
|
+
let resolvedPromise;
|
|
172
|
+
function getCurrentBatch(loader) {
|
|
173
|
+
const existingBatch = loader._batch;
|
|
174
|
+
if (existingBatch !== null && !existingBatch.hasDispatched && existingBatch.keys.length < loader._maxBatchSize) {
|
|
175
|
+
return existingBatch;
|
|
176
|
+
}
|
|
177
|
+
const newBatch = { hasDispatched: false, keys: [], callbacks: [] };
|
|
178
|
+
loader._batch = newBatch;
|
|
179
|
+
loader._batchScheduleFn(() => {
|
|
180
|
+
dispatchBatch(loader, newBatch);
|
|
181
|
+
});
|
|
182
|
+
return newBatch;
|
|
183
|
+
}
|
|
184
|
+
function dispatchBatch(loader, batch) {
|
|
185
|
+
batch.hasDispatched = true;
|
|
186
|
+
if (batch.keys.length === 0) {
|
|
187
|
+
resolveCacheHits(batch);
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
let batchPromise;
|
|
191
|
+
try {
|
|
192
|
+
batchPromise = loader._batchLoadFn(batch.keys);
|
|
193
|
+
} catch (e) {
|
|
194
|
+
return failedDispatch(
|
|
195
|
+
loader,
|
|
196
|
+
batch,
|
|
197
|
+
new TypeError(
|
|
198
|
+
`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: ${String(e)}.`
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
if (!batchPromise || typeof batchPromise.then !== "function") {
|
|
203
|
+
return failedDispatch(
|
|
204
|
+
loader,
|
|
205
|
+
batch,
|
|
206
|
+
new TypeError(
|
|
207
|
+
`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: ${String(batchPromise)}.`
|
|
208
|
+
)
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
Promise.resolve(batchPromise).then((values) => {
|
|
212
|
+
if (!isArrayLike(values)) {
|
|
213
|
+
throw new TypeError(
|
|
214
|
+
`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: ${String(values)}.`
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
if (values.length !== batch.keys.length) {
|
|
218
|
+
throw new TypeError(
|
|
219
|
+
`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.
|
|
220
|
+
|
|
221
|
+
Keys:
|
|
222
|
+
${String(batch.keys)}
|
|
223
|
+
|
|
224
|
+
Values:
|
|
225
|
+
${String(values)}`
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
resolveCacheHits(batch);
|
|
229
|
+
for (let i = 0; i < batch.callbacks.length; i++) {
|
|
230
|
+
const value = values[i];
|
|
231
|
+
if (value instanceof Error) {
|
|
232
|
+
batch.callbacks[i].reject(value);
|
|
233
|
+
} else {
|
|
234
|
+
batch.callbacks[i].resolve(value);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}).catch((error) => {
|
|
238
|
+
failedDispatch(loader, batch, error);
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
function failedDispatch(loader, batch, error) {
|
|
242
|
+
resolveCacheHits(batch);
|
|
243
|
+
for (let i = 0; i < batch.keys.length; i++) {
|
|
244
|
+
loader.clear(batch.keys[i]);
|
|
245
|
+
batch.callbacks[i].reject(error);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function resolveCacheHits(batch) {
|
|
249
|
+
if (batch.cacheHits) {
|
|
250
|
+
for (let i = 0; i < batch.cacheHits.length; i++) {
|
|
251
|
+
batch.cacheHits[i]();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function getValidMaxBatchSize(options) {
|
|
256
|
+
const shouldBatch = !options || options.batch !== false;
|
|
257
|
+
if (!shouldBatch) {
|
|
258
|
+
return 1;
|
|
259
|
+
}
|
|
260
|
+
const maxBatchSize = options && options.maxBatchSize;
|
|
261
|
+
if (maxBatchSize === void 0) {
|
|
262
|
+
return Infinity;
|
|
263
|
+
}
|
|
264
|
+
if (typeof maxBatchSize !== "number" || maxBatchSize < 1) {
|
|
265
|
+
throw new TypeError(`maxBatchSize must be a positive number: ${maxBatchSize}`);
|
|
266
|
+
}
|
|
267
|
+
return maxBatchSize;
|
|
268
|
+
}
|
|
269
|
+
function getValidBatchScheduleFn(options) {
|
|
270
|
+
const batchScheduleFn = options && options.batchScheduleFn;
|
|
271
|
+
if (batchScheduleFn === void 0) {
|
|
272
|
+
return enqueuePostPromiseJob;
|
|
273
|
+
}
|
|
274
|
+
if (typeof batchScheduleFn !== "function") {
|
|
275
|
+
throw new TypeError(`batchScheduleFn must be a function: ${batchScheduleFn}`);
|
|
276
|
+
}
|
|
277
|
+
return batchScheduleFn;
|
|
278
|
+
}
|
|
279
|
+
function getValidCacheKeyFn(options) {
|
|
280
|
+
const cacheKeyFn = options && options.cacheKeyFn;
|
|
281
|
+
if (cacheKeyFn === void 0) {
|
|
282
|
+
return (key) => key;
|
|
283
|
+
}
|
|
284
|
+
if (typeof cacheKeyFn !== "function") {
|
|
285
|
+
throw new TypeError(`cacheKeyFn must be a function: ${cacheKeyFn}`);
|
|
286
|
+
}
|
|
287
|
+
return cacheKeyFn;
|
|
288
|
+
}
|
|
289
|
+
function getValidCacheMap(options) {
|
|
290
|
+
const shouldCache = !options || options.cache !== false;
|
|
291
|
+
if (!shouldCache) {
|
|
292
|
+
return null;
|
|
293
|
+
}
|
|
294
|
+
const cacheMap = options && options.cacheMap;
|
|
295
|
+
if (cacheMap === void 0) {
|
|
296
|
+
return /* @__PURE__ */ new Map();
|
|
297
|
+
}
|
|
298
|
+
if (cacheMap !== null) {
|
|
299
|
+
const cacheFunctions = ["get", "set", "delete", "clear"];
|
|
300
|
+
const missingFunctions = cacheFunctions.filter(
|
|
301
|
+
(fnName) => cacheMap && typeof cacheMap[fnName] !== "function"
|
|
302
|
+
);
|
|
303
|
+
if (missingFunctions.length !== 0) {
|
|
304
|
+
throw new TypeError("Custom cacheMap missing methods: " + missingFunctions.join(", "));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
return cacheMap;
|
|
308
|
+
}
|
|
309
|
+
function getValidName(options) {
|
|
310
|
+
if (options && options.name) {
|
|
311
|
+
return options.name;
|
|
312
|
+
}
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
function isArrayLike(x) {
|
|
316
|
+
return typeof x === "object" && x !== null && "length" in x && typeof x.length === "number" && (x.length === 0 || x.length > 0 && Object.prototype.hasOwnProperty.call(x, x.length - 1));
|
|
317
|
+
}
|
|
318
|
+
//# sourceMappingURL=dataloader.js.map
|