velocious 1.0.447 → 1.0.448

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.
@@ -9,6 +9,43 @@ export type ConnectionCheckoutOptions = {
9
9
  */
10
10
  name?: string | undefined;
11
11
  };
12
+ /**
13
+ * DatabasePoolPendingCheckoutDebugSnapshot type.
14
+ */
15
+ export type DatabasePoolPendingCheckoutDebugSnapshot = {
16
+ /**
17
+ * - Human-readable checkout name.
18
+ */
19
+ checkoutName: string | undefined;
20
+ /**
21
+ * - Timestamp when the checkout started waiting.
22
+ */
23
+ enqueuedAt: number;
24
+ /**
25
+ * - Pending checkout queue index.
26
+ */
27
+ index: number;
28
+ /**
29
+ * - Milliseconds before the checkout times out, or null when disabled.
30
+ */
31
+ remainingTimeoutMs: number | null;
32
+ /**
33
+ * - Database configuration reuse key needed by the checkout.
34
+ */
35
+ reuseKey: string;
36
+ /**
37
+ * - Timestamp when the checkout will time out, or null when disabled.
38
+ */
39
+ timeoutAt: number | null;
40
+ /**
41
+ * - Timeout configured for the checkout, or null when disabled.
42
+ */
43
+ timeoutMillis: number | null;
44
+ /**
45
+ * - Milliseconds already spent waiting.
46
+ */
47
+ waitingForMs: number;
48
+ };
12
49
  /**
13
50
  * DatabasePoolDebugSnapshot type.
14
51
  */
@@ -40,7 +77,7 @@ export type DatabasePoolDebugSnapshot = {
40
77
  /**
41
78
  * - Waiting checkout snapshots.
42
79
  */
43
- pendingCheckouts?: Record<string, any>[] | undefined;
80
+ pendingCheckouts?: DatabasePoolPendingCheckoutDebugSnapshot[] | undefined;
44
81
  /**
45
82
  * - Number of queued checkout requests.
46
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/base.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/base.js"],"names":[],"mappings":"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"}
@@ -8,6 +8,18 @@ export const POOL_CONFIGURATION_KEY = Symbol("velociousPoolConfigurationKey");
8
8
  * @typedef {object} ConnectionCheckoutOptions
9
9
  * @property {string} [name] - Human-readable name for the checked-out connection.
10
10
  */
11
+ /**
12
+ * DatabasePoolPendingCheckoutDebugSnapshot type.
13
+ * @typedef {object} DatabasePoolPendingCheckoutDebugSnapshot
14
+ * @property {string | undefined} checkoutName - Human-readable checkout name.
15
+ * @property {number} enqueuedAt - Timestamp when the checkout started waiting.
16
+ * @property {number} index - Pending checkout queue index.
17
+ * @property {number | null} remainingTimeoutMs - Milliseconds before the checkout times out, or null when disabled.
18
+ * @property {string} reuseKey - Database configuration reuse key needed by the checkout.
19
+ * @property {number | null} timeoutAt - Timestamp when the checkout will time out, or null when disabled.
20
+ * @property {number | null} timeoutMillis - Timeout configured for the checkout, or null when disabled.
21
+ * @property {number} waitingForMs - Milliseconds already spent waiting.
22
+ */
11
23
  /**
12
24
  * DatabasePoolDebugSnapshot type.
13
25
  * @typedef {object} DatabasePoolDebugSnapshot
@@ -17,7 +29,7 @@ export const POOL_CONFIGURATION_KEY = Symbol("velociousPoolConfigurationKey");
17
29
  * @property {number} idleCount - Number of idle connections.
18
30
  * @property {string} identifier - Database identifier.
19
31
  * @property {number} inUseCount - Number of checked-out connections.
20
- * @property {Array<Record<string, ?>>} [pendingCheckouts] - Waiting checkout snapshots.
32
+ * @property {Array<DatabasePoolPendingCheckoutDebugSnapshot>} [pendingCheckouts] - Waiting checkout snapshots.
21
33
  * @property {number} pendingCheckoutCount - Number of queued checkout requests.
22
34
  * @property {string} poolClass - Pool class name.
23
35
  */
@@ -332,4 +344,4 @@ class VelociousDatabasePoolBase {
332
344
  }
333
345
  baseMethodsForward(VelociousDatabasePoolBase);
334
346
  export default VelociousDatabasePoolBase;
335
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhYmFzZS9wb29sL2Jhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sYUFBYSxNQUFNLHdCQUF3QixDQUFBO0FBQ2xELE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sa0JBQWtCLE1BQU0sMkJBQTJCLENBQUE7QUFFMUQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUE7QUFFN0U7Ozs7R0FJRztBQUVIOzs7Ozs7Ozs7Ozs7R0FZRztBQUVIOzs0REFFNEQ7QUFDNUQsTUFBTSxNQUFNLEdBQUc7SUFDYixXQUFXLEVBQUUsSUFBSTtDQUNsQixDQUFBO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsZUFBZSxDQUFDLEtBQUs7SUFDNUIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekIsT0FBTyxJQUFJLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFBO0lBQ3RFLENBQUM7SUFFRCxJQUFJLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN2QyxNQUFNLE9BQU8sR0FBRyxNQUFNO2FBQ25CLElBQUksQ0FBQzs7NENBRThCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUM1QyxJQUFJLEVBQUU7YUFDTixHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxlQUFlLENBQUM7OzhGQUU4QixDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFD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N0IsSUFBSSxFQUFFLGNBQWMsQ0FBQyxJQUFJO1lBQ3pCLFdBQVcsRUFBRSxjQUFjLENBQUMsV0FBVztZQUN2QyxRQUFRLEVBQUUsY0FBYyxDQUFDLFFBQVE7U0FDbEMsQ0FBQTtJQUNILENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILHVCQUF1QixDQUFDLFVBQVUsRUFBRSxPQUFPLEdBQUcsRUFBRTtRQUM5QyxNQUFNLHFCQUFxQixHQUFHOzs2SEFFdUYsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBRWxJLE9BQU87WUFDTCxHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsRUFBRTtZQUNoQyxHQUFHLE9BQU87WUFDVixRQUFRLEVBQUUscUJBQXFCLENBQUMsc0JBQXNCLENBQUM7U0FDeEQsQ0FBQTtJQUNILENBQUM7SUFFRDs7O09BR0c7SUFDSCxLQUFLLENBQUMsUUFBUSxLQUFJLENBQUM7Q0FDcEI7QUFFRCxrQkFBa0IsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO0FBRTdDLGVBQWUseUJBQXlCLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IENvbmZpZ3VyYXRpb24gZnJvbSBcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vLi4vbG9nZ2VyLmpzXCJcbmltcG9ydCBiYXNlTWV0aG9kc0ZvcndhcmQgZnJvbSBcIi4vYmFzZS1tZXRob2RzLWZvcndhcmQuanNcIlxuXG5leHBvcnQgY29uc3QgUE9PTF9DT05GSUdVUkFUSU9OX0tFWSA9IFN5bWJvbChcInZlbG9jaW91c1Bvb2xDb25maWd1cmF0aW9uS2V5XCIpXG5cbi8qKlxuICogQ29ubmVjdGlvbkNoZWNrb3V0T3B0aW9ucyB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gQ29ubmVjdGlvbkNoZWNrb3V0T3B0aW9uc1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFtuYW1lXSAtIEh1bWFuLXJlYWRhYmxlIG5hbWUgZm9yIHRoZSBjaGVja2VkLW91dCBjb25uZWN0aW9uLlxuICovXG5cbi8qKlxuICogRGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdCB0eXBlLlxuICogQHR5cGVkZWYge29iamVjdH0gRGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdFxuICogQHByb3BlcnR5IHtSZWNvcmQ8c3RyaW5nLCA/Pn0gY29uZmlndXJhdGlvbiAtIFNhbml0aXplZCByZXNvbHZlZCBkYXRhYmFzZSBjb25maWd1cmF0aW9uLlxuICogQHByb3BlcnR5IHtBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59IGNvbm5lY3Rpb25zIC0gTGl2ZSBjb25uZWN0aW9uIHNuYXBzaG90cy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZCAtIE51bWJlciBvZiBpbi1wcm9ncmVzcyBjb25uZWN0aW9uIHNwYXducy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpZGxlQ291bnQgLSBOdW1iZXIgb2YgaWRsZSBjb25uZWN0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZGVudGlmaWVyIC0gRGF0YWJhc2UgaWRlbnRpZmllci5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpblVzZUNvdW50IC0gTnVtYmVyIG9mIGNoZWNrZWQtb3V0IGNvbm5lY3Rpb25zLlxuICogQHByb3BlcnR5IHtBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj59IFtwZW5kaW5nQ2hlY2tvdXRzXSAtIFdhaXRpbmcgY2hlY2tvdXQgc25hcHNob3RzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHBlbmRpbmdDaGVja291dENvdW50IC0gTnVtYmVyIG9mIHF1ZXVlZCBjaGVja291dCByZXF1ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwb29sQ2xhc3MgLSBQb29sIGNsYXNzIG5hbWUuXG4gKi9cblxuLyoqXG4gKiBTaGFyZWQuXG4gIEB0eXBlIHt7Y3VycmVudFBvb2w6IFZlbG9jaW91c0RhdGFiYXNlUG9vbEJhc2UgfCBudWxsfX0gKi9cbmNvbnN0IHNoYXJlZCA9IHtcbiAgY3VycmVudFBvb2w6IG51bGxcbn1cblxuLyoqXG4gKiBSdW5zIHN0YWJsZSBzdHJpbmdpZnkuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gVmFsdWUgdG8gc3RyaW5naWZ5LlxuICogQHJldHVybnMge3N0cmluZ30gLSBTdGFibGUgSlNPTiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIHN0YWJsZVN0cmluZ2lmeSh2YWx1ZSkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gYFske3ZhbHVlLm1hcCgoZW50cnkpID0+IHN0YWJsZVN0cmluZ2lmeShlbnRyeSkpLmpvaW4oXCIsXCIpfV1gXG4gIH1cblxuICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdFxuICAgICAgLmtleXMoLyoqXG4gICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHZhbHVlKSlcbiAgICAgIC5zb3J0KClcbiAgICAgIC5tYXAoKGtleSkgPT4gYCR7SlNPTi5zdHJpbmdpZnkoa2V5KX06JHtzdGFibGVTdHJpbmdpZnkoLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICh2YWx1ZSlba2V5XSl9YClcblxuICAgIHJldHVybiBgeyR7ZW50cmllcy5qb2luKFwiLFwiKX19YFxuICB9XG5cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKVxufVxuXG5jbGFzcyBWZWxvY2lvdXNEYXRhYmFzZVBvb2xCYXNlIHtcbiAgLyoqXG4gICAqIFdpdGhvdXQgY3VycmVudCBjb25uZWN0aW9uIGNvbnRleHQuXG4gICAgQHR5cGUge3VuZGVmaW5lZCB8ICgoY2FsbGJhY2s6ICgpID0+ID8pID0+ID8pfSAqL1xuICBfd2l0aG91dEN1cnJlbnRDb25uZWN0aW9uQ29udGV4dCA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBSdW5zIGN1cnJlbnQuXG4gICAqIEByZXR1cm5zIHtWZWxvY2lvdXNEYXRhYmFzZVBvb2xCYXNlfSAtIFRoZSBjdXJyZW50LlxuICAgKi9cbiAgc3RhdGljIGN1cnJlbnQoKSB7XG4gICAgaWYgKCFzaGFyZWQuY3VycmVudFBvb2wpIHRocm93IG5ldyBFcnJvcihcIkEgZGF0YWJhc2UgcG9vbCBoYXNuJ3QgYmVlbiBzZXRcIilcblxuICAgIHJldHVybiBzaGFyZWQuY3VycmVudFBvb2xcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgYW55IGdsb2JhbCBjb25uZWN0aW9ucyBmb3IgdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBjbGVhckdsb2JhbENvbm5lY3Rpb25zKCkge31cblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtDb25maWd1cmF0aW9ufSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5pZGVudGlmaWVyIC0gSWRlbnRpZmllci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBpZGVudGlmaWVyfSkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb24gfHwgQ29uZmlndXJhdGlvbi5jdXJyZW50KClcblxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjb25maWd1cmF0aW9uIGdpdmVuXCIpXG4gICAgaWYgKCFpZGVudGlmaWVyKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBpZGVudGlmaWVyIHdhcyBnaXZlblwiKVxuXG4gICAgdGhpcy5pZGVudGlmaWVyID0gaWRlbnRpZmllclxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2hlY2tpbi5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IF9jb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICovXG4gIGNoZWNraW4oX2Nvbm5lY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCInY2hlY2tpbicgbm90IGltcGxlbWVudGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjaGVja291dC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbkNoZWNrb3V0T3B0aW9uc30gW19vcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjaGVja291dC5cbiAgICovXG4gIGNoZWNrb3V0KF9vcHRpb25zKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiJ2NoZWNrb3V0JyBub3QgaW1wbGVtZW50ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjdXJyZW50IGNvbm5lY3Rpb24uXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi5cbiAgICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIidnZXRDdXJyZW50Q29ubmVjdGlvbicgbm90IGltcGxlbWVudGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29ubmVjdGlvbiBwaW5uZWQgdG8gdGhlIGN1cnJlbnQgY29udGV4dCwgaWYgYW55LlxuICAgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGRlZmVycyB0byBgZ2V0Q3VycmVudENvbm5lY3Rpb25gLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGN1cnJlbnQgY29udGV4dCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdpdGhvdXQgY3VycmVudCBjb25uZWN0aW9uIGNvbnRleHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7KCkgPT4gVH0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4gd2l0aG91dCA/IGN1cnJlbnQgY29ubmVjdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7VH0gLSBDYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICB3aXRob3V0Q3VycmVudENvbm5lY3Rpb25Db250ZXh0KGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX3dpdGhvdXRDdXJyZW50Q29ubmVjdGlvbkNvbnRleHQpIHJldHVybiAvKiogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLiBAdHlwZSB7VH0gKi8gKHRoaXMuX3dpdGhvdXRDdXJyZW50Q29ubmVjdGlvbkNvbnRleHQoY2FsbGJhY2spKVxuXG4gICAgcmV0dXJuIGNhbGxiYWNrKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBwb29sIGlkZW50aWZpZXIuXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZ3VyYXRpb24ucmVzb2x2ZURhdGFiYXNlQ29uZmlndXJhdGlvbih0aGlzLmlkZW50aWZpZXIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gUmV1c2Uga2V5IGZvciB0aGUgY3VycmVudGx5IHJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoKSB7XG4gICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcblxuICAgIHJldHVybiBzdGFibGVTdHJpbmdpZnkoe1xuICAgICAgZGF0YWJhc2U6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5kYXRhYmFzZSxcbiAgICAgIGhvc3Q6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5ob3N0LFxuICAgICAgbmFtZTogZGF0YWJhc2VDb25maWd1cmF0aW9uLm5hbWUsXG4gICAgICBwb3J0OiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24ucG9ydCxcbiAgICAgIHNjaGVtYTogZGF0YWJhc2VDb25maWd1cmF0aW9uLnNjaGVtYSxcbiAgICAgIHNjaGVtYUNhY2hlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24uc2NoZW1hQ2FjaGUsXG4gICAgICBzcWxDb25maWc6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5zcWxDb25maWcsXG4gICAgICB0eXBlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udHlwZSxcbiAgICAgIHVzZURhdGFiYXNlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udXNlRGF0YWJhc2UsXG4gICAgICB1c2VybmFtZTogZGF0YWJhc2VDb25maWd1cmF0aW9uLnVzZXJuYW1lXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbm5lY3Rpb24gbWF0Y2hlcyBjdXJyZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGNvbm5lY3Rpb24gbWF0Y2hlcyBjdXJyZW50IHJlc29sdmVkIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBjb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbldpdGhQb29sS2V5W1BPT0xfQ09ORklHVVJBVElPTl9LRVldID09PSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHNjaGVtYSBtZXRhZGF0YSBjYWNoZWQgYnkgdGhpcyBwb29sJ3MgY3VycmVudCBjb25uZWN0aW9uLlxuICAgKiBQb29scyB0aGF0IGtlZXAgbXVsdGlwbGUgY29ubmVjdGlvbnMgYWxpdmUgc2hvdWxkIG92ZXJyaWRlIHRoaXMgdG8gY2xlYXIgZXZlcnkgbGl2ZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjbGVhclNjaGVtYUNhY2hlKCkge1xuICAgIHRoaXMuX2NsZWFyQ29ubmVjdGlvblNjaGVtYUNhY2hlKHRoaXMuZ2V0Q3VycmVudENvbm5lY3Rpb24oKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsZWFyIGNvbm5lY3Rpb24gc2NoZW1hIGNhY2hlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB3aG9zZSBsb2NhbCBzY2hlbWEgY2FjaGUgc2hvdWxkIGJlIGNsZWFyZWQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIF9jbGVhckNvbm5lY3Rpb25TY2hlbWFDYWNoZShjb25uZWN0aW9uKSB7XG4gICAgY29ubmVjdGlvbi5fY2xlYXJMb2NhbFNjaGVtYUNhY2hlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHByaW1hcnkga2V5IHR5cGUuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBwcmltYXJ5IGtleSB0eXBlLlxuICAgKi9cbiAgcHJpbWFyeUtleVR5cGUoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiJ3ByaW1hcnlLZXlUeXBlJyBub3QgaW1wbGVtZW50ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBjdXJyZW50LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRDdXJyZW50KCkge1xuICAgIHNoYXJlZC5jdXJyZW50UG9vbCA9IHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBkcml2ZXIgY2xhc3MuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkcml2ZXJDbGFzcyAtIERyaXZlciBjbGFzcy5cbiAgICovXG4gIHNldERyaXZlckNsYXNzKGRyaXZlckNsYXNzKSB7XG4gICAgdGhpcy5kcml2ZXJDbGFzcyA9IGRyaXZlckNsYXNzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzcGF3biBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgc3Bhd24gY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcInNwYXduQ29ubmVjdGlvblwiLCB7aWRlbnRpZmllcjogdGhpcy5pZGVudGlmaWVyLCBkYXRhYmFzZUNvbmZpZ30pXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25XaXRoQ29uZmlndXJhdGlvbihkYXRhYmFzZUNvbmZpZylcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25XaXRoUG9vbEtleSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0/OiBzdHJpbmd9fSAqLyAoY29ubmVjdGlvbilcbiAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHtcbiAgICAgIHRoaXMuY2xlYXJTY2hlbWFDYWNoZSgpXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uY2xlYXJTY2hlbWFDYWNoZXNGb3JSZXVzZUtleSh0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3Bhd24gY29ubmVjdGlvbiB3aXRoIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBjb25maWcgLSBDb25maWd1cmF0aW9uIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIHNwYXduIGNvbm5lY3Rpb24gd2l0aCBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oY29uZmlnKSB7XG4gICAgY29uc3QgRHJpdmVyQ2xhc3MgPSBjb25maWcuZHJpdmVyIHx8IHRoaXMuZHJpdmVyQ2xhc3NcblxuICAgIGlmICghRHJpdmVyQ2xhc3MpIHRocm93IG5ldyBFcnJvcihcIk5vIGRyaXZlciBjbGFzcyBzZXQgaW4gZGF0YWJhc2UgcG9vbCBvciBpbiBnaXZlbiBjb25maWdcIilcblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgRHJpdmVyQ2xhc3MoY29uZmlnLCB0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5jb25uZWN0KClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb25BZnRlckZhaWxlZENvbm5lY3QoY29ubmVjdGlvbilcbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIGNvbm5lY3Rpb24gYWZ0ZXIgZmFpbGVkIGNvbm5lY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNsZWFudXAgaGFzIGJlZW4gYXR0ZW1wdGVkLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VDb25uZWN0aW9uQWZ0ZXJGYWlsZWRDb25uZWN0KGNvbm5lY3Rpb24pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5jbG9zZSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMubG9nZ2VyLndhcm4oXCJGYWlsZWQgdG8gY2xvc2UgZGF0YWJhc2UgY29ubmVjdGlvbiBhZnRlciBjb25uZWN0IGZhaWxlZFwiLCB7ZXJyb3J9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdpdGggY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbkNoZWNrb3V0T3B0aW9ucyB8IGZ1bmN0aW9uKGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA6IFByb21pc2U8VD59IF9vcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW19jYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgd2l0aENvbm5lY3Rpb24oX29wdGlvbnNPckNhbGxiYWNrLCBfY2FsbGJhY2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCInd2l0aENvbm5lY3Rpb24nIG5vdCBpbXBsZW1lbnRlZFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgYSByZXVzYWJsZSBjb25uZWN0aW9uIGV4aXN0cyBmb3IgY29udGV4dHMgd2hlcmUgQXN5bmNMb2NhbFN0b3JhZ2UgaXNuJ3Qgc2V0LlxuICAgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGp1c3QgY2hlY2tzIG91dCBhIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBnbG9iYWwgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUdsb2JhbENvbm5lY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuY2hlY2tvdXQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGRlYnVnIHNuYXBzaG90LlxuICAgKiBAcmV0dXJucyB7RGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdH0gLSBEaWFnbm9zdGljIHNuYXBzaG90IGZvciB0aGlzIHBvb2wuXG4gICAqL1xuICBnZXREZWJ1Z1NuYXBzaG90KCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmRlYnVnQ29uZmlndXJhdGlvblNuYXBzaG90KCksXG4gICAgICBjb25uZWN0aW9uczogW10sXG4gICAgICBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZDogMCxcbiAgICAgIGlkZW50aWZpZXI6IHRoaXMuaWRlbnRpZmllcixcbiAgICAgIGlkbGVDb3VudDogMCxcbiAgICAgIGluVXNlQ291bnQ6IDAsXG4gICAgICBwZW5kaW5nQ2hlY2tvdXRDb3VudDogMCxcbiAgICAgIHBvb2xDbGFzczogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGVidWcgY29uZmlndXJhdGlvbiBzbmFwc2hvdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsID8+fSAtIFNhbml0aXplZCByZXNvbHZlZCBkYXRhYmFzZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgZGVidWdDb25maWd1cmF0aW9uU25hcHNob3QoKSB7XG4gICAgY29uc3QgZGF0YWJhc2VDb25maWcgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IHBvb2xDb25maWcgPSBkYXRhYmFzZUNvbmZpZy5wb29sXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YWJhc2U6IGRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlLFxuICAgICAgZHJpdmVyOiBkYXRhYmFzZUNvbmZpZy5kcml2ZXI/Lm5hbWUsXG4gICAgICBob3N0OiBkYXRhYmFzZUNvbmZpZy5ob3N0LFxuICAgICAgbWlncmF0aW9uczogZGF0YWJhc2VDb25maWcubWlncmF0aW9ucyxcbiAgICAgIG5hbWU6IGRhdGFiYXNlQ29uZmlnLm5hbWUsXG4gICAgICBwb29sOiBwb29sQ29uZmlnID8ge2lkbGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmlkbGVUaW1lb3V0TWlsbGlzLCBtYXg6IHBvb2xDb25maWcubWF4fSA6IHVuZGVmaW5lZCxcbiAgICAgIHBvcnQ6IGRhdGFiYXNlQ29uZmlnLnBvcnQsXG4gICAgICBzY2hlbWE6IGRhdGFiYXNlQ29uZmlnLnNjaGVtYSxcbiAgICAgIHR5cGU6IGRhdGFiYXNlQ29uZmlnLnR5cGUsXG4gICAgICB1c2VEYXRhYmFzZTogZGF0YWJhc2VDb25maWcudXNlRGF0YWJhc2UsXG4gICAgICB1c2VybmFtZTogZGF0YWJhc2VDb25maWcudXNlcm5hbWVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWJ1ZyBjb25uZWN0aW9uIHNuYXBzaG90LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gZGV0YWlscyAtIEV4dHJhIGRpYWdub3N0aWMgZmllbGRzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gQ29ubmVjdGlvbiBkaWFnbm9zdGljIHNuYXBzaG90LlxuICAgKi9cbiAgZGVidWdDb25uZWN0aW9uU25hcHNob3QoY29ubmVjdGlvbiwgZGV0YWlscyA9IHt9KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbldpdGhQb29sS2V5ID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmNvbm5lY3Rpb24uZ2V0RGVidWdTbmFwc2hvdCgpLFxuICAgICAgLi4uZGV0YWlscyxcbiAgICAgIHJldXNlS2V5OiBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFsbCBjb25uZWN0aW9ucyBmb3IgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VBbGwoKSB7fVxufVxuXG5iYXNlTWV0aG9kc0ZvcndhcmQoVmVsb2Npb3VzRGF0YWJhc2VQb29sQmFzZSlcblxuZXhwb3J0IGRlZmF1bHQgVmVsb2Npb3VzRGF0YWJhc2VQb29sQmFzZVxuIl19
347
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9kYXRhYmFzZS9wb29sL2Jhc2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sYUFBYSxNQUFNLHdCQUF3QixDQUFBO0FBQ2xELE9BQU8sTUFBTSxNQUFNLGlCQUFpQixDQUFBO0FBQ3BDLE9BQU8sa0JBQWtCLE1BQU0sMkJBQTJCLENBQUE7QUFFMUQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsTUFBTSxDQUFDLCtCQUErQixDQUFDLENBQUE7QUFFN0U7Ozs7R0FJRztBQUVIOzs7Ozs7Ozs7OztHQVdHO0FBRUg7Ozs7Ozs7Ozs7OztHQVlHO0FBRUg7OzREQUU0RDtBQUM1RCxNQUFNLE1BQU0sR0FBRztJQUNiLFdBQVcsRUFBRSxJQUFJO0NBQ2xCLENBQUE7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxlQUFlLENBQUMsS0FBSztJQUM1QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN6QixPQUFPLElBQUksS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUE7SUFDdEUsQ0FBQztJQUVELElBQUksS0FBSyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sT0FBTyxHQUFHLE1BQU07YUFDbkIsSUFBSSxDQUFDOzs0Q0FFOEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzVDLElBQUksRUFBRTthQUNOLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxJQUFJLGVBQWUsQ0FBQzs7OEZBRThCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFH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RSxjQUFjLENBQUMsTUFBTTtZQUM3QixJQUFJLEVBQUUsY0FBYyxDQUFDLElBQUk7WUFDekIsV0FBVyxFQUFFLGNBQWMsQ0FBQyxXQUFXO1lBQ3ZDLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUTtTQUNsQyxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsdUJBQXVCLENBQUMsVUFBVSxFQUFFLE9BQU8sR0FBRyxFQUFFO1FBQzlDLE1BQU0scUJBQXFCLEdBQUc7OzZIQUV1RixDQUFDLENBQUMsVUFBVSxDQUFDLENBQUE7UUFFbEksT0FBTztZQUNMLEdBQUcsVUFBVSxDQUFDLGdCQUFnQixFQUFFO1lBQ2hDLEdBQUcsT0FBTztZQUNWLFFBQVEsRUFBRSxxQkFBcUIsQ0FBQyxzQkFBc0IsQ0FBQztTQUN4RCxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxRQUFRLEtBQUksQ0FBQztDQUNwQjtBQUVELGtCQUFrQixDQUFDLHlCQUF5QixDQUFDLENBQUE7QUFFN0MsZUFBZSx5QkFBeUIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQ29uZmlndXJhdGlvbiBmcm9tIFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi8uLi9sb2dnZXIuanNcIlxuaW1wb3J0IGJhc2VNZXRob2RzRm9yd2FyZCBmcm9tIFwiLi9iYXNlLW1ldGhvZHMtZm9yd2FyZC5qc1wiXG5cbmV4cG9ydCBjb25zdCBQT09MX0NPTkZJR1VSQVRJT05fS0VZID0gU3ltYm9sKFwidmVsb2Npb3VzUG9vbENvbmZpZ3VyYXRpb25LZXlcIilcblxuLyoqXG4gKiBDb25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBDb25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW25hbWVdIC0gSHVtYW4tcmVhZGFibGUgbmFtZSBmb3IgdGhlIGNoZWNrZWQtb3V0IGNvbm5lY3Rpb24uXG4gKi9cblxuLyoqXG4gKiBEYXRhYmFzZVBvb2xQZW5kaW5nQ2hlY2tvdXREZWJ1Z1NuYXBzaG90IHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBEYXRhYmFzZVBvb2xQZW5kaW5nQ2hlY2tvdXREZWJ1Z1NuYXBzaG90XG4gKiBAcHJvcGVydHkge3N0cmluZyB8IHVuZGVmaW5lZH0gY2hlY2tvdXROYW1lIC0gSHVtYW4tcmVhZGFibGUgY2hlY2tvdXQgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBlbnF1ZXVlZEF0IC0gVGltZXN0YW1wIHdoZW4gdGhlIGNoZWNrb3V0IHN0YXJ0ZWQgd2FpdGluZy5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBpbmRleCAtIFBlbmRpbmcgY2hlY2tvdXQgcXVldWUgaW5kZXguXG4gKiBAcHJvcGVydHkge251bWJlciB8IG51bGx9IHJlbWFpbmluZ1RpbWVvdXRNcyAtIE1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIGNoZWNrb3V0IHRpbWVzIG91dCwgb3IgbnVsbCB3aGVuIGRpc2FibGVkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkgbmVlZGVkIGJ5IHRoZSBjaGVja291dC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gdGltZW91dEF0IC0gVGltZXN0YW1wIHdoZW4gdGhlIGNoZWNrb3V0IHdpbGwgdGltZSBvdXQsIG9yIG51bGwgd2hlbiBkaXNhYmxlZC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyIHwgbnVsbH0gdGltZW91dE1pbGxpcyAtIFRpbWVvdXQgY29uZmlndXJlZCBmb3IgdGhlIGNoZWNrb3V0LCBvciBudWxsIHdoZW4gZGlzYWJsZWQuXG4gKiBAcHJvcGVydHkge251bWJlcn0gd2FpdGluZ0Zvck1zIC0gTWlsbGlzZWNvbmRzIGFscmVhZHkgc3BlbnQgd2FpdGluZy5cbiAqL1xuXG4vKipcbiAqIERhdGFiYXNlUG9vbERlYnVnU25hcHNob3QgdHlwZS5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IERhdGFiYXNlUG9vbERlYnVnU25hcHNob3RcbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgPz59IGNvbmZpZ3VyYXRpb24gLSBTYW5pdGl6ZWQgcmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlndXJhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8UmVjb3JkPHN0cmluZywgPz4+fSBjb25uZWN0aW9ucyAtIExpdmUgY29ubmVjdGlvbiBzbmFwc2hvdHMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gY29ubmVjdGlvbnNCZWluZ1NwYXduZWQgLSBOdW1iZXIgb2YgaW4tcHJvZ3Jlc3MgY29ubmVjdGlvbiBzcGF3bnMuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaWRsZUNvdW50IC0gTnVtYmVyIG9mIGlkbGUgY29ubmVjdGlvbnMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gaWRlbnRpZmllciAtIERhdGFiYXNlIGlkZW50aWZpZXIuXG4gKiBAcHJvcGVydHkge251bWJlcn0gaW5Vc2VDb3VudCAtIE51bWJlciBvZiBjaGVja2VkLW91dCBjb25uZWN0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7QXJyYXk8RGF0YWJhc2VQb29sUGVuZGluZ0NoZWNrb3V0RGVidWdTbmFwc2hvdD59IFtwZW5kaW5nQ2hlY2tvdXRzXSAtIFdhaXRpbmcgY2hlY2tvdXQgc25hcHNob3RzLlxuICogQHByb3BlcnR5IHtudW1iZXJ9IHBlbmRpbmdDaGVja291dENvdW50IC0gTnVtYmVyIG9mIHF1ZXVlZCBjaGVja291dCByZXF1ZXN0cy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBwb29sQ2xhc3MgLSBQb29sIGNsYXNzIG5hbWUuXG4gKi9cblxuLyoqXG4gKiBTaGFyZWQuXG4gIEB0eXBlIHt7Y3VycmVudFBvb2w6IFZlbG9jaW91c0RhdGFiYXNlUG9vbEJhc2UgfCBudWxsfX0gKi9cbmNvbnN0IHNoYXJlZCA9IHtcbiAgY3VycmVudFBvb2w6IG51bGxcbn1cblxuLyoqXG4gKiBSdW5zIHN0YWJsZSBzdHJpbmdpZnkuXG4gKiBAcGFyYW0gez99IHZhbHVlIC0gVmFsdWUgdG8gc3RyaW5naWZ5LlxuICogQHJldHVybnMge3N0cmluZ30gLSBTdGFibGUgSlNPTiBzdHJpbmcuXG4gKi9cbmZ1bmN0aW9uIHN0YWJsZVN0cmluZ2lmeSh2YWx1ZSkge1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICByZXR1cm4gYFske3ZhbHVlLm1hcCgoZW50cnkpID0+IHN0YWJsZVN0cmluZ2lmeShlbnRyeSkpLmpvaW4oXCIsXCIpfV1gXG4gIH1cblxuICBpZiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiKSB7XG4gICAgY29uc3QgZW50cmllcyA9IE9iamVjdFxuICAgICAgLmtleXMoLyoqXG4gICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHZhbHVlKSlcbiAgICAgIC5zb3J0KClcbiAgICAgIC5tYXAoKGtleSkgPT4gYCR7SlNPTi5zdHJpbmdpZnkoa2V5KX06JHtzdGFibGVTdHJpbmdpZnkoLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovICh2YWx1ZSlba2V5XSl9YClcblxuICAgIHJldHVybiBgeyR7ZW50cmllcy5qb2luKFwiLFwiKX19YFxuICB9XG5cbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlKVxufVxuXG5jbGFzcyBWZWxvY2lvdXNEYXRhYmFzZVBvb2xCYXNlIHtcbiAgLyoqXG4gICAqIFdpdGhvdXQgY3VycmVudCBjb25uZWN0aW9uIGNvbnRleHQuXG4gICAgQHR5cGUge3VuZGVmaW5lZCB8ICgoY2FsbGJhY2s6ICgpID0+ID8pID0+ID8pfSAqL1xuICBfd2l0aG91dEN1cnJlbnRDb25uZWN0aW9uQ29udGV4dCA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBSdW5zIGN1cnJlbnQuXG4gICAqIEByZXR1cm5zIHtWZWxvY2lvdXNEYXRhYmFzZVBvb2xCYXNlfSAtIFRoZSBjdXJyZW50LlxuICAgKi9cbiAgc3RhdGljIGN1cnJlbnQoKSB7XG4gICAgaWYgKCFzaGFyZWQuY3VycmVudFBvb2wpIHRocm93IG5ldyBFcnJvcihcIkEgZGF0YWJhc2UgcG9vbCBoYXNuJ3QgYmVlbiBzZXRcIilcblxuICAgIHJldHVybiBzaGFyZWQuY3VycmVudFBvb2xcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgYW55IGdsb2JhbCBjb25uZWN0aW9ucyBmb3IgdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBjbGVhckdsb2JhbENvbm5lY3Rpb25zKCkge31cblxuICAvKipcbiAgICogUnVucyBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtDb25maWd1cmF0aW9ufSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5pZGVudGlmaWVyIC0gSWRlbnRpZmllci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBpZGVudGlmaWVyfSkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb24gfHwgQ29uZmlndXJhdGlvbi5jdXJyZW50KClcblxuICAgIGlmICghdGhpcy5jb25maWd1cmF0aW9uKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBjb25maWd1cmF0aW9uIGdpdmVuXCIpXG4gICAgaWYgKCFpZGVudGlmaWVyKSB0aHJvdyBuZXcgRXJyb3IoXCJObyBpZGVudGlmaWVyIHdhcyBnaXZlblwiKVxuXG4gICAgdGhpcy5pZGVudGlmaWVyID0gaWRlbnRpZmllclxuICAgIHRoaXMubG9nZ2VyID0gbmV3IExvZ2dlcih0aGlzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgY2hlY2tpbi5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IF9jb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICovXG4gIGNoZWNraW4oX2Nvbm5lY3Rpb24pIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCInY2hlY2tpbicgbm90IGltcGxlbWVudGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBjaGVja291dC5cbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbkNoZWNrb3V0T3B0aW9uc30gW19vcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjaGVja291dC5cbiAgICovXG4gIGNoZWNrb3V0KF9vcHRpb25zKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiJ2NoZWNrb3V0JyBub3QgaW1wbGVtZW50ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjdXJyZW50IGNvbm5lY3Rpb24uXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi5cbiAgICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIidnZXRDdXJyZW50Q29ubmVjdGlvbicgbm90IGltcGxlbWVudGVkXCIpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29ubmVjdGlvbiBwaW5uZWQgdG8gdGhlIGN1cnJlbnQgY29udGV4dCwgaWYgYW55LlxuICAgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGRlZmVycyB0byBgZ2V0Q3VycmVudENvbm5lY3Rpb25gLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGN1cnJlbnQgY29udGV4dCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdpdGhvdXQgY3VycmVudCBjb25uZWN0aW9uIGNvbnRleHQuXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7KCkgPT4gVH0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBydW4gd2l0aG91dCA/IGN1cnJlbnQgY29ubmVjdGlvbiBjb250ZXh0LlxuICAgKiBAcmV0dXJucyB7VH0gLSBDYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICB3aXRob3V0Q3VycmVudENvbm5lY3Rpb25Db250ZXh0KGNhbGxiYWNrKSB7XG4gICAgaWYgKHRoaXMuX3dpdGhvdXRDdXJyZW50Q29ubmVjdGlvbkNvbnRleHQpIHJldHVybiAvKiogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLiBAdHlwZSB7VH0gKi8gKHRoaXMuX3dpdGhvdXRDdXJyZW50Q29ubmVjdGlvbkNvbnRleHQoY2FsbGJhY2spKVxuXG4gICAgcmV0dXJuIGNhbGxiYWNrKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBwb29sIGlkZW50aWZpZXIuXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZ3VyYXRpb24ucmVzb2x2ZURhdGFiYXNlQ29uZmlndXJhdGlvbih0aGlzLmlkZW50aWZpZXIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gUmV1c2Uga2V5IGZvciB0aGUgY3VycmVudGx5IHJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBnZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoKSB7XG4gICAgY29uc3QgZGF0YWJhc2VDb25maWd1cmF0aW9uID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcblxuICAgIHJldHVybiBzdGFibGVTdHJpbmdpZnkoe1xuICAgICAgZGF0YWJhc2U6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5kYXRhYmFzZSxcbiAgICAgIGhvc3Q6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5ob3N0LFxuICAgICAgbmFtZTogZGF0YWJhc2VDb25maWd1cmF0aW9uLm5hbWUsXG4gICAgICBwb3J0OiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24ucG9ydCxcbiAgICAgIHNjaGVtYTogZGF0YWJhc2VDb25maWd1cmF0aW9uLnNjaGVtYSxcbiAgICAgIHNjaGVtYUNhY2hlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24uc2NoZW1hQ2FjaGUsXG4gICAgICBzcWxDb25maWc6IGRhdGFiYXNlQ29uZmlndXJhdGlvbi5zcWxDb25maWcsXG4gICAgICB0eXBlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udHlwZSxcbiAgICAgIHVzZURhdGFiYXNlOiBkYXRhYmFzZUNvbmZpZ3VyYXRpb24udXNlRGF0YWJhc2UsXG4gICAgICB1c2VybmFtZTogZGF0YWJhc2VDb25maWd1cmF0aW9uLnVzZXJuYW1lXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbm5lY3Rpb24gbWF0Y2hlcyBjdXJyZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGNvbm5lY3Rpb24gbWF0Y2hlcyBjdXJyZW50IHJlc29sdmVkIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBjb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbldpdGhQb29sS2V5W1BPT0xfQ09ORklHVVJBVElPTl9LRVldID09PSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHNjaGVtYSBtZXRhZGF0YSBjYWNoZWQgYnkgdGhpcyBwb29sJ3MgY3VycmVudCBjb25uZWN0aW9uLlxuICAgKiBQb29scyB0aGF0IGtlZXAgbXVsdGlwbGUgY29ubmVjdGlvbnMgYWxpdmUgc2hvdWxkIG92ZXJyaWRlIHRoaXMgdG8gY2xlYXIgZXZlcnkgbGl2ZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjbGVhclNjaGVtYUNhY2hlKCkge1xuICAgIHRoaXMuX2NsZWFyQ29ubmVjdGlvblNjaGVtYUNhY2hlKHRoaXMuZ2V0Q3VycmVudENvbm5lY3Rpb24oKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsZWFyIGNvbm5lY3Rpb24gc2NoZW1hIGNhY2hlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB3aG9zZSBsb2NhbCBzY2hlbWEgY2FjaGUgc2hvdWxkIGJlIGNsZWFyZWQuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIF9jbGVhckNvbm5lY3Rpb25TY2hlbWFDYWNoZShjb25uZWN0aW9uKSB7XG4gICAgY29ubmVjdGlvbi5fY2xlYXJMb2NhbFNjaGVtYUNhY2hlKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHByaW1hcnkga2V5IHR5cGUuXG4gICAqIEBhYnN0cmFjdFxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBwcmltYXJ5IGtleSB0eXBlLlxuICAgKi9cbiAgcHJpbWFyeUtleVR5cGUoKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiJ3ByaW1hcnlLZXlUeXBlJyBub3QgaW1wbGVtZW50ZWRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBjdXJyZW50LlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRDdXJyZW50KCkge1xuICAgIHNoYXJlZC5jdXJyZW50UG9vbCA9IHRoaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBkcml2ZXIgY2xhc3MuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBkcml2ZXJDbGFzcyAtIERyaXZlciBjbGFzcy5cbiAgICovXG4gIHNldERyaXZlckNsYXNzKGRyaXZlckNsYXNzKSB7XG4gICAgdGhpcy5kcml2ZXJDbGFzcyA9IGRyaXZlckNsYXNzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzcGF3biBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgc3Bhd24gY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG5cbiAgICB0aGlzLmxvZ2dlci5kZWJ1ZyhcInNwYXduQ29ubmVjdGlvblwiLCB7aWRlbnRpZmllcjogdGhpcy5pZGVudGlmaWVyLCBkYXRhYmFzZUNvbmZpZ30pXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25XaXRoQ29uZmlndXJhdGlvbihkYXRhYmFzZUNvbmZpZylcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25XaXRoUG9vbEtleSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0/OiBzdHJpbmd9fSAqLyAoY29ubmVjdGlvbilcbiAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHtcbiAgICAgIHRoaXMuY2xlYXJTY2hlbWFDYWNoZSgpXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb24uY2xlYXJTY2hlbWFDYWNoZXNGb3JSZXVzZUtleSh0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc3Bhd24gY29ubmVjdGlvbiB3aXRoIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBjb25maWcgLSBDb25maWd1cmF0aW9uIG9iamVjdC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIHNwYXduIGNvbm5lY3Rpb24gd2l0aCBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oY29uZmlnKSB7XG4gICAgY29uc3QgRHJpdmVyQ2xhc3MgPSBjb25maWcuZHJpdmVyIHx8IHRoaXMuZHJpdmVyQ2xhc3NcblxuICAgIGlmICghRHJpdmVyQ2xhc3MpIHRocm93IG5ldyBFcnJvcihcIk5vIGRyaXZlciBjbGFzcyBzZXQgaW4gZGF0YWJhc2UgcG9vbCBvciBpbiBnaXZlbiBjb25maWdcIilcblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBuZXcgRHJpdmVyQ2xhc3MoY29uZmlnLCB0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5jb25uZWN0KClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb25BZnRlckZhaWxlZENvbm5lY3QoY29ubmVjdGlvbilcbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGNsb3NlIGNvbm5lY3Rpb24gYWZ0ZXIgZmFpbGVkIGNvbm5lY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNsZWFudXAgaGFzIGJlZW4gYXR0ZW1wdGVkLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VDb25uZWN0aW9uQWZ0ZXJGYWlsZWRDb25uZWN0KGNvbm5lY3Rpb24pIHtcbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5jbG9zZSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRoaXMubG9nZ2VyLndhcm4oXCJGYWlsZWQgdG8gY2xvc2UgZGF0YWJhc2UgY29ubmVjdGlvbiBhZnRlciBjb25uZWN0IGZhaWxlZFwiLCB7ZXJyb3J9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHdpdGggY29ubmVjdGlvbi5cbiAgICogQHRlbXBsYXRlIFRcbiAgICogQGFic3RyYWN0XG4gICAqIEBwYXJhbSB7Q29ubmVjdGlvbkNoZWNrb3V0T3B0aW9ucyB8IGZ1bmN0aW9uKGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA6IFByb21pc2U8VD59IF9vcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW19jYWxsYmFja10gLSBDYWxsYmFjayBmdW5jdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgd2l0aENvbm5lY3Rpb24oX29wdGlvbnNPckNhbGxiYWNrLCBfY2FsbGJhY2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCInd2l0aENvbm5lY3Rpb24nIG5vdCBpbXBsZW1lbnRlZFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIEVuc3VyZXMgYSByZXVzYWJsZSBjb25uZWN0aW9uIGV4aXN0cyBmb3IgY29udGV4dHMgd2hlcmUgQXN5bmNMb2NhbFN0b3JhZ2UgaXNuJ3Qgc2V0LlxuICAgKiBEZWZhdWx0IGltcGxlbWVudGF0aW9uIGp1c3QgY2hlY2tzIG91dCBhIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBnbG9iYWwgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUdsb2JhbENvbm5lY3Rpb24oKSB7XG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuY2hlY2tvdXQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGRlYnVnIHNuYXBzaG90LlxuICAgKiBAcmV0dXJucyB7RGF0YWJhc2VQb29sRGVidWdTbmFwc2hvdH0gLSBEaWFnbm9zdGljIHNuYXBzaG90IGZvciB0aGlzIHBvb2wuXG4gICAqL1xuICBnZXREZWJ1Z1NuYXBzaG90KCkge1xuICAgIHJldHVybiB7XG4gICAgICBjb25maWd1cmF0aW9uOiB0aGlzLmRlYnVnQ29uZmlndXJhdGlvblNuYXBzaG90KCksXG4gICAgICBjb25uZWN0aW9uczogW10sXG4gICAgICBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZDogMCxcbiAgICAgIGlkZW50aWZpZXI6IHRoaXMuaWRlbnRpZmllcixcbiAgICAgIGlkbGVDb3VudDogMCxcbiAgICAgIGluVXNlQ291bnQ6IDAsXG4gICAgICBwZW5kaW5nQ2hlY2tvdXRDb3VudDogMCxcbiAgICAgIHBvb2xDbGFzczogdGhpcy5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGVidWcgY29uZmlndXJhdGlvbiBzbmFwc2hvdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsID8+fSAtIFNhbml0aXplZCByZXNvbHZlZCBkYXRhYmFzZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgZGVidWdDb25maWd1cmF0aW9uU25hcHNob3QoKSB7XG4gICAgY29uc3QgZGF0YWJhc2VDb25maWcgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKVxuICAgIGNvbnN0IHBvb2xDb25maWcgPSBkYXRhYmFzZUNvbmZpZy5wb29sXG5cbiAgICByZXR1cm4ge1xuICAgICAgZGF0YWJhc2U6IGRhdGFiYXNlQ29uZmlnLmRhdGFiYXNlLFxuICAgICAgZHJpdmVyOiBkYXRhYmFzZUNvbmZpZy5kcml2ZXI/Lm5hbWUsXG4gICAgICBob3N0OiBkYXRhYmFzZUNvbmZpZy5ob3N0LFxuICAgICAgbWlncmF0aW9uczogZGF0YWJhc2VDb25maWcubWlncmF0aW9ucyxcbiAgICAgIG5hbWU6IGRhdGFiYXNlQ29uZmlnLm5hbWUsXG4gICAgICBwb29sOiBwb29sQ29uZmlnID8ge2lkbGVUaW1lb3V0TWlsbGlzOiBwb29sQ29uZmlnLmlkbGVUaW1lb3V0TWlsbGlzLCBtYXg6IHBvb2xDb25maWcubWF4fSA6IHVuZGVmaW5lZCxcbiAgICAgIHBvcnQ6IGRhdGFiYXNlQ29uZmlnLnBvcnQsXG4gICAgICBzY2hlbWE6IGRhdGFiYXNlQ29uZmlnLnNjaGVtYSxcbiAgICAgIHR5cGU6IGRhdGFiYXNlQ29uZmlnLnR5cGUsXG4gICAgICB1c2VEYXRhYmFzZTogZGF0YWJhc2VDb25maWcudXNlRGF0YWJhc2UsXG4gICAgICB1c2VybmFtZTogZGF0YWJhc2VDb25maWcudXNlcm5hbWVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWJ1ZyBjb25uZWN0aW9uIHNuYXBzaG90LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gRGF0YWJhc2UgY29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gZGV0YWlscyAtIEV4dHJhIGRpYWdub3N0aWMgZmllbGRzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IC0gQ29ubmVjdGlvbiBkaWFnbm9zdGljIHNuYXBzaG90LlxuICAgKi9cbiAgZGVidWdDb25uZWN0aW9uU25hcHNob3QoY29ubmVjdGlvbiwgZGV0YWlscyA9IHt9KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbldpdGhQb29sS2V5ID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC4uLmNvbm5lY3Rpb24uZ2V0RGVidWdTbmFwc2hvdCgpLFxuICAgICAgLi4uZGV0YWlscyxcbiAgICAgIHJldXNlS2V5OiBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFsbCBjb25uZWN0aW9ucyBmb3IgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VBbGwoKSB7fVxufVxuXG5iYXNlTWV0aG9kc0ZvcndhcmQoVmVsb2Npb3VzRGF0YWJhc2VQb29sQmFzZSlcblxuZXhwb3J0IGRlZmF1bHQgVmVsb2Npb3VzRGF0YWJhc2VQb29sQmFzZVxuIl19
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "velocious": "build/bin/velocious.js"
4
4
  },
5
5
  "name": "velocious",
6
- "version": "1.0.447",
6
+ "version": "1.0.448",
7
7
  "main": "build/index.js",
8
8
  "types": "build/index.d.ts",
9
9
  "files": [
@@ -47,12 +47,14 @@
47
47
  * @property {number | null} [pool.max] - Maximum number of connections. Set null to disable the cap.
48
48
  * @property {number} [pool.min] - Minimum number of connections.
49
49
  * @property {number} [pool.idleTimeoutMillis] - Idle timeout before releasing a connection.
50
+ * @property {number | null} [pool.checkoutTimeoutMillis] - Timeout while waiting for an available connection after the max connection cap is reached. Set null to wait indefinitely.
50
51
  * @property {string} [server] - SQL server hostname.
51
52
  * @property {string} [user] - SQL username.
52
53
  */
53
54
 
54
55
  /**
55
56
  * @typedef {object} DatabasePoolConfiguration
57
+ * @property {number | null} [checkoutTimeoutMillis] - Timeout while a checkout waits for an available async-tracked connection after the max live connection cap is reached. Set null to wait indefinitely. Default: 10000.
56
58
  * @property {number | null} [idleTimeoutMillis] - Idle timeout before closing a checked-in async-tracked connection. Set null to disable idle reaping. Default: 5000.
57
59
  * @property {number | null} [max] - Maximum live async-tracked connections for this pool. Defaults to 10. Extra checkouts wait until a matching connection is checked in or capacity is freed. Set null to disable the cap.
58
60
  */
@@ -8,6 +8,7 @@ const IDLE_CONNECTION_CHECKED_IN_AT = Symbol("velociousIdleConnectionCheckedInAt
8
8
  const CONNECTION_CHECKED_OUT_AT = Symbol("velociousConnectionCheckedOutAt")
9
9
  const DEFAULT_MAX_CONNECTIONS = 10
10
10
  const DEFAULT_IDLE_TIMEOUT_MILLIS = 5000
11
+ const DEFAULT_CHECKOUT_TIMEOUT_MILLIS = 10000
11
12
 
12
13
  /**
13
14
  * PendingCheckout type.
@@ -18,6 +19,9 @@ const DEFAULT_IDLE_TIMEOUT_MILLIS = 5000
18
19
  * @property {string} reuseKey - Database configuration reuse key needed by the checkout.
19
20
  * @property {(connection: import("../drivers/base.js").default) => void} resolve - Resolves with an activated connection.
20
21
  * @property {(error: Error) => void} reject - Rejects when checkout cannot complete.
22
+ * @property {number | null} timeoutAt - Timestamp when the checkout will time out, or null when disabled.
23
+ * @property {number | null} timeoutMillis - Milliseconds to wait before rejecting, or null when disabled.
24
+ * @property {ReturnType<typeof setTimeout> | undefined} timeoutTimer - Timer that rejects the pending checkout.
21
25
  */
22
26
 
23
27
  export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends BasePool {
@@ -281,17 +285,39 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
281
285
 
282
286
  /**
283
287
  * Runs max connections.
284
- * @returns {number | undefined} - Configured max live connections.
288
+ * @returns {number | null} - Configured max live connections.
285
289
  */
286
290
  maxConnections() {
287
291
  const value = this.getConfiguration().pool?.max
288
292
 
289
- if (value === null) return
293
+ if (value === null) return null
290
294
  if (this.validMaxConnections(value)) return value
291
295
 
292
296
  return DEFAULT_MAX_CONNECTIONS
293
297
  }
294
298
 
299
+ /**
300
+ * Runs checkout timeout millis.
301
+ * @returns {number | null} - Pending checkout timeout in milliseconds, or null when disabled.
302
+ */
303
+ checkoutTimeoutMillis() {
304
+ const value = this.getConfiguration().pool?.checkoutTimeoutMillis
305
+
306
+ if (value === null) return null
307
+ if (this.validCheckoutTimeoutMillis(value)) return value
308
+
309
+ return DEFAULT_CHECKOUT_TIMEOUT_MILLIS
310
+ }
311
+
312
+ /**
313
+ * Runs valid checkout timeout millis.
314
+ * @param {?} value - Candidate checkout timeout.
315
+ * @returns {value is number} - Whether the value is a valid timeout.
316
+ */
317
+ validCheckoutTimeoutMillis(value) {
318
+ return typeof value === "number" && Number.isFinite(value) && value >= 0
319
+ }
320
+
295
321
  /**
296
322
  * Runs valid max connections.
297
323
  * @param {?} value - Candidate max connection count.
@@ -322,7 +348,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
322
348
  canSpawnConnection() {
323
349
  const maxConnections = this.maxConnections()
324
350
 
325
- return maxConnections === undefined || this.liveConnectionCount() < maxConnections
351
+ return maxConnections === null || this.liveConnectionCount() < maxConnections
326
352
  }
327
353
 
328
354
  /**
@@ -361,7 +387,23 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
361
387
  */
362
388
  async waitForCheckout(databaseConfig, reuseKey, options = {}) {
363
389
  return await new Promise((resolve, reject) => {
364
- this.pendingCheckouts.push({databaseConfig, enqueuedAt: Date.now(), options, reject, resolve, reuseKey})
390
+ const enqueuedAt = Date.now()
391
+ const timeoutMillis = this.checkoutTimeoutMillis()
392
+ /** @type {PendingCheckout} */
393
+ const checkout = {
394
+ databaseConfig,
395
+ enqueuedAt,
396
+ options,
397
+ reject,
398
+ resolve,
399
+ reuseKey,
400
+ timeoutAt: timeoutMillis === null ? null : enqueuedAt + timeoutMillis,
401
+ timeoutMillis,
402
+ timeoutTimer: undefined
403
+ }
404
+
405
+ checkout.timeoutTimer = this.startPendingCheckoutTimeout(checkout)
406
+ this.pendingCheckouts.push(checkout)
365
407
  void this.drainPendingCheckouts().catch((error) => {
366
408
  const checkoutError = error instanceof Error ? error : new Error("Failed to drain pending database connection checkouts.", {cause: error})
367
409
 
@@ -400,17 +442,19 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
400
442
  const checkout = this.pendingCheckouts[0]
401
443
 
402
444
  if (await this.closeIdleConnectionForPendingCheckoutCapacity(checkout)) continue
445
+ if (!this.pendingCheckouts.includes(checkout)) continue
403
446
  if (this.canSpawnConnection()) {
404
- this.pendingCheckouts.shift()
447
+ this.removePendingCheckoutAt(0)
405
448
  await this.spawnAndResolvePendingCheckout(checkout)
406
449
  continue
407
450
  }
408
451
 
409
452
  const reapedConnection = await this.idleConnectionForPendingCheckout(checkout)
410
453
 
454
+ if (!this.pendingCheckouts.includes(checkout)) continue
411
455
  if (!reapedConnection) return
412
456
 
413
- this.pendingCheckouts.shift()
457
+ this.removePendingCheckoutAt(0)
414
458
  await this.resolvePendingCheckout(checkout, reapedConnection)
415
459
  }
416
460
  }
@@ -426,7 +470,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
426
470
 
427
471
  if (!connection) continue
428
472
 
429
- this.pendingCheckouts.splice(index, 1)
473
+ this.removePendingCheckoutAt(index)
430
474
  await this.resolvePendingCheckout(checkout, connection)
431
475
 
432
476
  return true
@@ -435,6 +479,71 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
435
479
  return false
436
480
  }
437
481
 
482
+ /**
483
+ * Runs remove pending checkout at.
484
+ * @param {number} index - Pending checkout index.
485
+ * @returns {PendingCheckout} - Removed checkout.
486
+ */
487
+ removePendingCheckoutAt(index) {
488
+ const checkout = this.pendingCheckouts.splice(index, 1)[0]
489
+
490
+ this.clearPendingCheckoutTimeout(checkout)
491
+
492
+ return checkout
493
+ }
494
+
495
+ /**
496
+ * Runs start pending checkout timeout.
497
+ * @param {PendingCheckout} checkout - Pending checkout to time out.
498
+ * @returns {ReturnType<typeof setTimeout> | undefined} - Timer, if timeout is enabled.
499
+ */
500
+ startPendingCheckoutTimeout(checkout) {
501
+ if (checkout.timeoutMillis === null) return undefined
502
+
503
+ const timer = setTimeout(() => {
504
+ this.timeoutPendingCheckout(checkout)
505
+ }, checkout.timeoutMillis)
506
+
507
+ return timer
508
+ }
509
+
510
+ /**
511
+ * Runs timeout pending checkout.
512
+ * @param {PendingCheckout} checkout - Pending checkout to reject.
513
+ * @returns {void}
514
+ */
515
+ timeoutPendingCheckout(checkout) {
516
+ const index = this.pendingCheckouts.indexOf(checkout)
517
+
518
+ if (index === -1) return
519
+
520
+ this.removePendingCheckoutAt(index)
521
+ checkout.reject(this.pendingCheckoutTimeoutError(checkout))
522
+ }
523
+
524
+ /**
525
+ * Runs pending checkout timeout error.
526
+ * @param {PendingCheckout} checkout - Timed-out checkout.
527
+ * @returns {Error} - Timeout error.
528
+ */
529
+ pendingCheckoutTimeoutError(checkout) {
530
+ const checkoutName = checkout.options.name ? ` Checkout name: ${JSON.stringify(checkout.options.name)}.` : ""
531
+
532
+ return new Error(`Timed out after ${checkout.timeoutMillis}ms waiting for database connection checkout from pool "${this.identifier}".${checkoutName}`)
533
+ }
534
+
535
+ /**
536
+ * Runs clear pending checkout timeout.
537
+ * @param {PendingCheckout} checkout - Pending checkout.
538
+ * @returns {void}
539
+ */
540
+ clearPendingCheckoutTimeout(checkout) {
541
+ if (!checkout.timeoutTimer) return
542
+
543
+ clearTimeout(checkout.timeoutTimer)
544
+ checkout.timeoutTimer = undefined
545
+ }
546
+
438
547
  /**
439
548
  * Runs close idle connection for pending checkout capacity.
440
549
  * @param {PendingCheckout} checkout - Checkout waiting for a connection.
@@ -472,6 +581,8 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
472
581
  if (connection) return connection
473
582
 
474
583
  await this.reapIdleConnections()
584
+ if (!this.pendingCheckouts.includes(checkout)) return
585
+
475
586
  connection = this.takeIdleConnectionForReuseKey(checkout.reuseKey, {includeOpenTransactions: false})
476
587
 
477
588
  return connection
@@ -762,14 +873,17 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
762
873
  /**
763
874
  * Runs pending checkout debug snapshots.
764
875
  * @param {number} now - Current timestamp.
765
- * @returns {Array<Record<string, ?>>} - Pending checkout snapshots.
876
+ * @returns {import("./base.js").DatabasePoolPendingCheckoutDebugSnapshot[]} - Pending checkout snapshots.
766
877
  */
767
878
  pendingCheckoutDebugSnapshots(now) {
768
879
  return this.pendingCheckouts.map((checkout, index) => ({
769
880
  checkoutName: checkout.options.name,
770
881
  enqueuedAt: checkout.enqueuedAt,
771
882
  index,
883
+ remainingTimeoutMs: checkout.timeoutAt === null ? null : Math.max(0, checkout.timeoutAt - now),
772
884
  reuseKey: checkout.reuseKey,
885
+ timeoutAt: checkout.timeoutAt,
886
+ timeoutMillis: checkout.timeoutMillis,
773
887
  waitingForMs: Math.max(0, now - checkout.enqueuedAt)
774
888
  }))
775
889
  }
@@ -1131,6 +1245,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
1131
1245
  this.pendingCheckouts = []
1132
1246
 
1133
1247
  for (const checkout of pendingCheckouts) {
1248
+ this.clearPendingCheckoutTimeout(checkout)
1134
1249
  checkout.reject(error)
1135
1250
  }
1136
1251
  }
@@ -12,6 +12,19 @@ export const POOL_CONFIGURATION_KEY = Symbol("velociousPoolConfigurationKey")
12
12
  * @property {string} [name] - Human-readable name for the checked-out connection.
13
13
  */
14
14
 
15
+ /**
16
+ * DatabasePoolPendingCheckoutDebugSnapshot type.
17
+ * @typedef {object} DatabasePoolPendingCheckoutDebugSnapshot
18
+ * @property {string | undefined} checkoutName - Human-readable checkout name.
19
+ * @property {number} enqueuedAt - Timestamp when the checkout started waiting.
20
+ * @property {number} index - Pending checkout queue index.
21
+ * @property {number | null} remainingTimeoutMs - Milliseconds before the checkout times out, or null when disabled.
22
+ * @property {string} reuseKey - Database configuration reuse key needed by the checkout.
23
+ * @property {number | null} timeoutAt - Timestamp when the checkout will time out, or null when disabled.
24
+ * @property {number | null} timeoutMillis - Timeout configured for the checkout, or null when disabled.
25
+ * @property {number} waitingForMs - Milliseconds already spent waiting.
26
+ */
27
+
15
28
  /**
16
29
  * DatabasePoolDebugSnapshot type.
17
30
  * @typedef {object} DatabasePoolDebugSnapshot
@@ -21,7 +34,7 @@ export const POOL_CONFIGURATION_KEY = Symbol("velociousPoolConfigurationKey")
21
34
  * @property {number} idleCount - Number of idle connections.
22
35
  * @property {string} identifier - Database identifier.
23
36
  * @property {number} inUseCount - Number of checked-out connections.
24
- * @property {Array<Record<string, ?>>} [pendingCheckouts] - Waiting checkout snapshots.
37
+ * @property {Array<DatabasePoolPendingCheckoutDebugSnapshot>} [pendingCheckouts] - Waiting checkout snapshots.
25
38
  * @property {number} pendingCheckoutCount - Number of queued checkout requests.
26
39
  * @property {string} poolClass - Pool class name.
27
40
  */