scratch-storage 5.0.10 → 6.0.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/.github/workflows/ci-cd.yml +10 -3
- package/.husky/commit-msg +0 -3
- package/dist/node/chunks/fetch-worker.7afe4ade866d6f6a3cb3.js +383 -0
- package/dist/node/chunks/fetch-worker.7afe4ade866d6f6a3cb3.js.map +1 -0
- package/dist/node/scratch-storage.js +376 -881
- package/dist/node/scratch-storage.js.map +1 -1
- package/dist/types/HostQueues.d.ts +20 -0
- package/dist/types/ScratchStorage.d.ts +2 -15
- package/dist/types/scratchFetch.d.ts +37 -15
- package/dist/web/chunks/fetch-worker.9fbe108071a9c5d6e70b.js +2 -0
- package/dist/web/chunks/{fetch-worker.4277f33a97fe995aa7dd.js.map → fetch-worker.9fbe108071a9c5d6e70b.js.map} +1 -1
- package/dist/web/chunks/fetch-worker.efebf27d479ab0f0d98c.js +394 -0
- package/dist/web/chunks/fetch-worker.efebf27d479ab0f0d98c.js.map +1 -0
- package/dist/web/scratch-storage.js +379 -884
- package/dist/web/scratch-storage.js.map +1 -1
- package/dist/web/scratch-storage.min.js +1 -1
- package/dist/web/scratch-storage.min.js.map +1 -1
- package/package.json +16 -14
- package/src/FetchTool.ts +3 -2
- package/src/FetchWorkerTool.worker.ts +94 -0
- package/src/HostQueues.ts +33 -0
- package/src/ScratchStorage.ts +1 -1
- package/src/{scratchFetch.js → scratchFetch.ts} +53 -34
- package/src/types.d.ts +4 -3
- package/test/build/api.test.js +60 -0
- package/test/build/scratchFetch.test.js +40 -0
- package/test/fixtures/known-assets.js +30 -2
- package/test/{__mocks__/cross-fetch.js → fixtures/mockFetch.js} +18 -17
- package/test/integration/download-known-assets.test.js +6 -3
- package/test/unit/fetch-tool.test.js +8 -7
- package/test/unit/metadata.test.js +9 -8
- package/tsconfig.json +0 -1
- package/tsconfig.test.json +1 -0
- package/dist/node/chunks/fetch-worker.56da39b0f4bad6747138.js +0 -809
- package/dist/node/chunks/fetch-worker.56da39b0f4bad6747138.js.map +0 -1
- package/dist/web/chunks/fetch-worker.4277f33a97fe995aa7dd.js +0 -2
- package/dist/web/chunks/fetch-worker.c813c32be403f91001ba.js +0 -820
- package/dist/web/chunks/fetch-worker.c813c32be403f91001ba.js.map +0 -1
- package/src/FetchWorkerTool.worker.js +0 -67
|
@@ -11,15 +11,15 @@
|
|
|
11
11
|
return /******/ (() => { // webpackBootstrap
|
|
12
12
|
/******/ var __webpack_modules__ = ({
|
|
13
13
|
|
|
14
|
-
/***/ 9
|
|
15
|
-
|
|
14
|
+
/***/ 9
|
|
15
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
16
16
|
|
|
17
17
|
module.exports = __webpack_require__(14)("iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAAAAADmVT4XAAADZElEQVR42u3a70vbQBgH8O/7vOibvsmbFUEEWUGGUhQ25nDuhSKIUFDxlYi0SAd94atRmFiHCH2x4W8iiNtwowXRgd1QipJYY3N/1F4kTQ6XLKS9yyHcvWyO8MnT5y53Tw5EcIMESIAESIAESIAESIAEPFVAq/6l8G4oAQCp4aniwbUVJ6BVzafwqKXy1VZMgNb+CHzbyK4ZB+Bi0nnk0VyhsDiSoAmvvnMHmGUVAF6UG+0ffsxRhsRHky/AyCsAUpumX0wAAIs6T4CxDADDtcdZsal6gjmdH8AsAEC6+s8Fa48SFExeAKusAEju+V367AmUCi9ANQ0AU3pwcOw2cMEH0FwAAKz5X228pRLR5AI4TgIAtIDL24oLUE94AB6W7LsH/cONN14Ilh44AOqD9s2LQR1KHiB9zgGgOSGeuA3ocPrME1Q4ANaceyePAzrcjHmAZYs9IBeW4/fzHiAwTCwAgTle9ACZK44ALDT9e6x7gL4aT0BQCHb4AqgA5/1TTOMLoJ7vZSMM0H/GHnCeDnu+CrU8vGYPcN5FADBYD0vCaYPDy+i0p337GSMsS1Z4vA3t9QgAZTt0IuIxFRPSKicAQHlvhk3FXF5GhBByMa8qo/sBO6BarwuYbYrYnFKDYEvE7phKgcxvEQBqnvhgiQCUOgoAO4C3JOS3L/hv23UXxVldBECfcueAqpAa0WGy/QeULREAY6aTXRFDgBuA13+ElOncAERMAGaA9hBQD4gQQHsIRE1AZoD2xrgQS5nOZyHgFKmWDSIG4GRAVidiAE4GRB6AzAB2AKIPQFaA5myHA5AV4ESNugZhC7BLR50lIBPAebrzBGQCKAFQNSIMcDvRTQIwAHxNApM3RBygGK0uyhxwOwGsPAgEnPWj5ycRCNiJtBHlAChGKQVwANzPY+CXSMDNWISiLA9AfRA5IhJQ68UnoQAt+AtOPIBKhJosF8B6UM0yLkAxQk2WCyDX9SiUh1gkQAIkoCuAvjGuquMbuijAtwG7MPL8yBICOHSPk3W8Ne8KcEUdmBi6FADYos+QleIH0N/ogOxd7AD6uAS6WRU8WcBdlgZMG/EnYUlwEpLLoQ4PjzGbiA5UsRMRsbQ+5ziDJmYqJuR6NaMomdXuFuZyPSABEiABEiABEiABEiAc8Bd6VyvCEKGqcQAAAABJRU5ErkJggg==")
|
|
18
18
|
|
|
19
|
-
/***/ }
|
|
19
|
+
/***/ },
|
|
20
20
|
|
|
21
|
-
/***/ 14
|
|
22
|
-
|
|
21
|
+
/***/ 14
|
|
22
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
23
23
|
|
|
24
24
|
"use strict";
|
|
25
25
|
/* provided dependency */ var Buffer = __webpack_require__(287)["hp"];
|
|
@@ -38,10 +38,10 @@ module.exports = function (base64Data) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
|
|
41
|
-
/***/ }
|
|
41
|
+
/***/ },
|
|
42
42
|
|
|
43
|
-
/***/ 15
|
|
44
|
-
|
|
43
|
+
/***/ 15
|
|
44
|
+
(module, exports, __webpack_require__) {
|
|
45
45
|
|
|
46
46
|
var Transform = __webpack_require__(408),
|
|
47
47
|
Filter = __webpack_require__(84);
|
|
@@ -90,10 +90,10 @@ exports.enable = function() {
|
|
|
90
90
|
|
|
91
91
|
|
|
92
92
|
|
|
93
|
-
/***/ }
|
|
93
|
+
/***/ },
|
|
94
94
|
|
|
95
|
-
/***/ 84
|
|
96
|
-
|
|
95
|
+
/***/ 84
|
|
96
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
97
97
|
|
|
98
98
|
// default filter
|
|
99
99
|
var Transform = __webpack_require__(408);
|
|
@@ -153,10 +153,10 @@ Filter.prototype.write = function(name, level, args) {
|
|
|
153
153
|
module.exports = Filter;
|
|
154
154
|
|
|
155
155
|
|
|
156
|
-
/***/ }
|
|
156
|
+
/***/ },
|
|
157
157
|
|
|
158
|
-
/***/ 113
|
|
159
|
-
|
|
158
|
+
/***/ 113
|
|
159
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
160
160
|
|
|
161
161
|
var Transform = __webpack_require__(408),
|
|
162
162
|
cache = false;
|
|
@@ -174,10 +174,10 @@ logger.write = function(name, level, args) {
|
|
|
174
174
|
|
|
175
175
|
module.exports = logger;
|
|
176
176
|
|
|
177
|
-
/***/ }
|
|
177
|
+
/***/ },
|
|
178
178
|
|
|
179
|
-
/***/ 173
|
|
180
|
-
|
|
179
|
+
/***/ 173
|
|
180
|
+
(module) {
|
|
181
181
|
|
|
182
182
|
function M() { this._events = {}; }
|
|
183
183
|
M.prototype = {
|
|
@@ -231,10 +231,10 @@ M.mixin = function(dest) {
|
|
|
231
231
|
module.exports = M;
|
|
232
232
|
|
|
233
233
|
|
|
234
|
-
/***/ }
|
|
234
|
+
/***/ },
|
|
235
235
|
|
|
236
|
-
/***/ 193
|
|
237
|
-
|
|
236
|
+
/***/ 193
|
|
237
|
+
(module) {
|
|
238
238
|
|
|
239
239
|
var hex = {
|
|
240
240
|
black: '#000',
|
|
@@ -258,10 +258,10 @@ function color(fg, isInverse) {
|
|
|
258
258
|
module.exports = color;
|
|
259
259
|
|
|
260
260
|
|
|
261
|
-
/***/ }
|
|
261
|
+
/***/ },
|
|
262
262
|
|
|
263
|
-
/***/ 251
|
|
264
|
-
|
|
263
|
+
/***/ 251
|
|
264
|
+
(__unused_webpack_module, exports) {
|
|
265
265
|
|
|
266
266
|
/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh <https://feross.org/opensource> */
|
|
267
267
|
exports.read = function (buffer, offset, isLE, mLen, nBytes) {
|
|
@@ -350,10 +350,10 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
|
|
|
350
350
|
}
|
|
351
351
|
|
|
352
352
|
|
|
353
|
-
/***/ }
|
|
353
|
+
/***/ },
|
|
354
354
|
|
|
355
|
-
/***/ 260
|
|
356
|
-
|
|
355
|
+
/***/ 260
|
|
356
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
357
357
|
|
|
358
358
|
var Transform = __webpack_require__(408);
|
|
359
359
|
|
|
@@ -389,10 +389,10 @@ logger.minilog = __webpack_require__(658);
|
|
|
389
389
|
module.exports = logger;
|
|
390
390
|
|
|
391
391
|
|
|
392
|
-
/***/ }
|
|
392
|
+
/***/ },
|
|
393
393
|
|
|
394
|
-
/***/ 287
|
|
395
|
-
|
|
394
|
+
/***/ 287
|
|
395
|
+
(__unused_webpack_module, exports, __webpack_require__) {
|
|
396
396
|
|
|
397
397
|
"use strict";
|
|
398
398
|
var __webpack_unused_export__;
|
|
@@ -2504,10 +2504,10 @@ function BufferBigIntNotDefined () {
|
|
|
2504
2504
|
}
|
|
2505
2505
|
|
|
2506
2506
|
|
|
2507
|
-
/***/ }
|
|
2507
|
+
/***/ },
|
|
2508
2508
|
|
|
2509
|
-
/***/ 386
|
|
2510
|
-
|
|
2509
|
+
/***/ 386
|
|
2510
|
+
(module, exports, __webpack_require__) {
|
|
2511
2511
|
|
|
2512
2512
|
var __WEBPACK_AMD_DEFINE_RESULT__;/**
|
|
2513
2513
|
* [js-md5]{@link https://github.com/emn178/js-md5}
|
|
@@ -3195,10 +3195,10 @@ var __WEBPACK_AMD_DEFINE_RESULT__;/**
|
|
|
3195
3195
|
})();
|
|
3196
3196
|
|
|
3197
3197
|
|
|
3198
|
-
/***/ }
|
|
3198
|
+
/***/ },
|
|
3199
3199
|
|
|
3200
|
-
/***/ 408
|
|
3201
|
-
|
|
3200
|
+
/***/ 408
|
|
3201
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3202
3202
|
|
|
3203
3203
|
var microee = __webpack_require__(173);
|
|
3204
3204
|
|
|
@@ -3274,10 +3274,10 @@ Transform.mixin = function(dest) {
|
|
|
3274
3274
|
module.exports = Transform;
|
|
3275
3275
|
|
|
3276
3276
|
|
|
3277
|
-
/***/ }
|
|
3277
|
+
/***/ },
|
|
3278
3278
|
|
|
3279
|
-
/***/ 526
|
|
3280
|
-
|
|
3279
|
+
/***/ 526
|
|
3280
|
+
(__unused_webpack_module, exports) {
|
|
3281
3281
|
|
|
3282
3282
|
"use strict";
|
|
3283
3283
|
|
|
@@ -3432,10 +3432,10 @@ function fromByteArray (uint8) {
|
|
|
3432
3432
|
}
|
|
3433
3433
|
|
|
3434
3434
|
|
|
3435
|
-
/***/ }
|
|
3435
|
+
/***/ },
|
|
3436
3436
|
|
|
3437
|
-
/***/ 557
|
|
3438
|
-
|
|
3437
|
+
/***/ 557
|
|
3438
|
+
(module, exports, __webpack_require__) {
|
|
3439
3439
|
|
|
3440
3440
|
var Minilog = __webpack_require__(15);
|
|
3441
3441
|
|
|
@@ -3481,10 +3481,10 @@ exports.backends = {
|
|
|
3481
3481
|
};
|
|
3482
3482
|
|
|
3483
3483
|
|
|
3484
|
-
/***/ }
|
|
3484
|
+
/***/ },
|
|
3485
3485
|
|
|
3486
|
-
/***/ 638
|
|
3487
|
-
|
|
3486
|
+
/***/ 638
|
|
3487
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3488
3488
|
|
|
3489
3489
|
var Transform = __webpack_require__(408),
|
|
3490
3490
|
color = __webpack_require__(193);
|
|
@@ -3506,10 +3506,10 @@ logger.pipe = function() { };
|
|
|
3506
3506
|
module.exports = logger;
|
|
3507
3507
|
|
|
3508
3508
|
|
|
3509
|
-
/***/ }
|
|
3509
|
+
/***/ },
|
|
3510
3510
|
|
|
3511
|
-
/***/ 658
|
|
3512
|
-
|
|
3511
|
+
/***/ 658
|
|
3512
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3513
3513
|
|
|
3514
3514
|
var Transform = __webpack_require__(408),
|
|
3515
3515
|
color = __webpack_require__(193),
|
|
@@ -3539,17 +3539,17 @@ logger.pipe = function() { };
|
|
|
3539
3539
|
module.exports = logger;
|
|
3540
3540
|
|
|
3541
3541
|
|
|
3542
|
-
/***/ }
|
|
3542
|
+
/***/ },
|
|
3543
3543
|
|
|
3544
|
-
/***/ 680
|
|
3545
|
-
|
|
3544
|
+
/***/ 680
|
|
3545
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3546
3546
|
|
|
3547
3547
|
module.exports = __webpack_require__(14)("UklGRiYAAABXQVZFZm10IBAAAAABAAEAIlYAAESsAAACABAAZGF0YQIAAAAAAA==")
|
|
3548
3548
|
|
|
3549
|
-
/***/ }
|
|
3549
|
+
/***/ },
|
|
3550
3550
|
|
|
3551
|
-
/***/ 692
|
|
3552
|
-
|
|
3551
|
+
/***/ 692
|
|
3552
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3553
3553
|
|
|
3554
3554
|
var Transform = __webpack_require__(408),
|
|
3555
3555
|
cache = [ ];
|
|
@@ -3567,10 +3567,10 @@ logger.empty = function() { cache = []; };
|
|
|
3567
3567
|
module.exports = logger;
|
|
3568
3568
|
|
|
3569
3569
|
|
|
3570
|
-
/***/ }
|
|
3570
|
+
/***/ },
|
|
3571
3571
|
|
|
3572
|
-
/***/ 740
|
|
3573
|
-
|
|
3572
|
+
/***/ 740
|
|
3573
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3574
3574
|
|
|
3575
3575
|
var Transform = __webpack_require__(408);
|
|
3576
3576
|
|
|
@@ -3648,10 +3648,10 @@ AjaxLogger.jQueryWait = function(onDone) {
|
|
|
3648
3648
|
module.exports = AjaxLogger;
|
|
3649
3649
|
|
|
3650
3650
|
|
|
3651
|
-
/***/ }
|
|
3651
|
+
/***/ },
|
|
3652
3652
|
|
|
3653
|
-
/***/ 767
|
|
3654
|
-
|
|
3653
|
+
/***/ 767
|
|
3654
|
+
(__unused_webpack_module, __unused_webpack_exports, __webpack_require__) {
|
|
3655
3655
|
|
|
3656
3656
|
"use strict";
|
|
3657
3657
|
(function(r){function x(){}function y(){}var z=String.fromCharCode,v={}.toString,A=v.call(r.SharedArrayBuffer),B=v(),q=r.Uint8Array,t=q||Array,w=q?ArrayBuffer:t,C=w.isView||function(g){return g&&"length"in g},D=v.call(w.prototype);w=y.prototype;var E=r.TextEncoder,a=new (q?Uint16Array:t)(32);x.prototype.decode=function(g){if(!C(g)){var l=v.call(g);if(l!==D&&l!==A&&l!==B)throw TypeError("Failed to execute 'decode' on 'TextDecoder': The provided value is not of type '(ArrayBuffer or ArrayBufferView)'");
|
|
@@ -3662,824 +3662,14 @@ f.subarray(0,c):f.slice(0,c)};E||(r.TextDecoder=x,r.TextEncoder=y)})(""+void 0==
|
|
|
3662
3662
|
//# sourceMappingURL=https://cdn.jsdelivr.net/gh/AnonyCo/FastestSmallestTextEncoderDecoder/EncoderDecoderTogether.min.js.map
|
|
3663
3663
|
|
|
3664
3664
|
|
|
3665
|
-
/***/ }
|
|
3665
|
+
/***/ },
|
|
3666
3666
|
|
|
3667
|
-
/***/ 914
|
|
3668
|
-
|
|
3667
|
+
/***/ 914
|
|
3668
|
+
(module, __unused_webpack_exports, __webpack_require__) {
|
|
3669
3669
|
|
|
3670
3670
|
module.exports = __webpack_require__(14)("PD94bWwgdmVyc2lvbj0iMS4wIj8+Cjxzdmcgd2lkdGg9IjEyOCIgaGVpZ2h0PSIxMjgiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6c3ZnPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiA8Zz4KICA8cmVjdCBmaWxsPSIjQ0NDIiBoZWlnaHQ9IjEyOCIgd2lkdGg9IjEyOCIvPgogIDx0ZXh0IGZpbGw9ImJsYWNrIiB5PSIxMDciIHg9IjM1LjUiIGZvbnQtc2l6ZT0iMTI4Ij4/PC90ZXh0PgogPC9nPgo8L3N2Zz4K")
|
|
3671
3671
|
|
|
3672
|
-
/***/ }
|
|
3673
|
-
|
|
3674
|
-
/***/ 945:
|
|
3675
|
-
/***/ ((module, exports, __webpack_require__) => {
|
|
3676
|
-
|
|
3677
|
-
// Save global object in a variable
|
|
3678
|
-
var __global__ =
|
|
3679
|
-
(typeof globalThis !== 'undefined' && globalThis) ||
|
|
3680
|
-
(typeof self !== 'undefined' && self) ||
|
|
3681
|
-
(typeof __webpack_require__.g !== 'undefined' && __webpack_require__.g);
|
|
3682
|
-
// Create an object that extends from __global__ without the fetch function
|
|
3683
|
-
var __globalThis__ = (function () {
|
|
3684
|
-
function F() {
|
|
3685
|
-
this.fetch = false;
|
|
3686
|
-
this.DOMException = __global__.DOMException
|
|
3687
|
-
}
|
|
3688
|
-
F.prototype = __global__; // Needed for feature detection on whatwg-fetch's code
|
|
3689
|
-
return new F();
|
|
3690
|
-
})();
|
|
3691
|
-
// Wraps whatwg-fetch with a function scope to hijack the global object
|
|
3692
|
-
// "globalThis" that's going to be patched
|
|
3693
|
-
(function(globalThis) {
|
|
3694
|
-
|
|
3695
|
-
var irrelevant = (function (exports) {
|
|
3696
|
-
|
|
3697
|
-
/* eslint-disable no-prototype-builtins */
|
|
3698
|
-
var g =
|
|
3699
|
-
(typeof globalThis !== 'undefined' && globalThis) ||
|
|
3700
|
-
(typeof self !== 'undefined' && self) ||
|
|
3701
|
-
// eslint-disable-next-line no-undef
|
|
3702
|
-
(typeof __webpack_require__.g !== 'undefined' && __webpack_require__.g) ||
|
|
3703
|
-
{};
|
|
3704
|
-
|
|
3705
|
-
var support = {
|
|
3706
|
-
searchParams: 'URLSearchParams' in g,
|
|
3707
|
-
iterable: 'Symbol' in g && 'iterator' in Symbol,
|
|
3708
|
-
blob:
|
|
3709
|
-
'FileReader' in g &&
|
|
3710
|
-
'Blob' in g &&
|
|
3711
|
-
(function() {
|
|
3712
|
-
try {
|
|
3713
|
-
new Blob();
|
|
3714
|
-
return true
|
|
3715
|
-
} catch (e) {
|
|
3716
|
-
return false
|
|
3717
|
-
}
|
|
3718
|
-
})(),
|
|
3719
|
-
formData: 'FormData' in g,
|
|
3720
|
-
arrayBuffer: 'ArrayBuffer' in g
|
|
3721
|
-
};
|
|
3722
|
-
|
|
3723
|
-
function isDataView(obj) {
|
|
3724
|
-
return obj && DataView.prototype.isPrototypeOf(obj)
|
|
3725
|
-
}
|
|
3726
|
-
|
|
3727
|
-
if (support.arrayBuffer) {
|
|
3728
|
-
var viewClasses = [
|
|
3729
|
-
'[object Int8Array]',
|
|
3730
|
-
'[object Uint8Array]',
|
|
3731
|
-
'[object Uint8ClampedArray]',
|
|
3732
|
-
'[object Int16Array]',
|
|
3733
|
-
'[object Uint16Array]',
|
|
3734
|
-
'[object Int32Array]',
|
|
3735
|
-
'[object Uint32Array]',
|
|
3736
|
-
'[object Float32Array]',
|
|
3737
|
-
'[object Float64Array]'
|
|
3738
|
-
];
|
|
3739
|
-
|
|
3740
|
-
var isArrayBufferView =
|
|
3741
|
-
ArrayBuffer.isView ||
|
|
3742
|
-
function(obj) {
|
|
3743
|
-
return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1
|
|
3744
|
-
};
|
|
3745
|
-
}
|
|
3746
|
-
|
|
3747
|
-
function normalizeName(name) {
|
|
3748
|
-
if (typeof name !== 'string') {
|
|
3749
|
-
name = String(name);
|
|
3750
|
-
}
|
|
3751
|
-
if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === '') {
|
|
3752
|
-
throw new TypeError('Invalid character in header field name: "' + name + '"')
|
|
3753
|
-
}
|
|
3754
|
-
return name.toLowerCase()
|
|
3755
|
-
}
|
|
3756
|
-
|
|
3757
|
-
function normalizeValue(value) {
|
|
3758
|
-
if (typeof value !== 'string') {
|
|
3759
|
-
value = String(value);
|
|
3760
|
-
}
|
|
3761
|
-
return value
|
|
3762
|
-
}
|
|
3763
|
-
|
|
3764
|
-
// Build a destructive iterator for the value list
|
|
3765
|
-
function iteratorFor(items) {
|
|
3766
|
-
var iterator = {
|
|
3767
|
-
next: function() {
|
|
3768
|
-
var value = items.shift();
|
|
3769
|
-
return {done: value === undefined, value: value}
|
|
3770
|
-
}
|
|
3771
|
-
};
|
|
3772
|
-
|
|
3773
|
-
if (support.iterable) {
|
|
3774
|
-
iterator[Symbol.iterator] = function() {
|
|
3775
|
-
return iterator
|
|
3776
|
-
};
|
|
3777
|
-
}
|
|
3778
|
-
|
|
3779
|
-
return iterator
|
|
3780
|
-
}
|
|
3781
|
-
|
|
3782
|
-
function Headers(headers) {
|
|
3783
|
-
this.map = {};
|
|
3784
|
-
|
|
3785
|
-
if (headers instanceof Headers) {
|
|
3786
|
-
headers.forEach(function(value, name) {
|
|
3787
|
-
this.append(name, value);
|
|
3788
|
-
}, this);
|
|
3789
|
-
} else if (Array.isArray(headers)) {
|
|
3790
|
-
headers.forEach(function(header) {
|
|
3791
|
-
if (header.length != 2) {
|
|
3792
|
-
throw new TypeError('Headers constructor: expected name/value pair to be length 2, found' + header.length)
|
|
3793
|
-
}
|
|
3794
|
-
this.append(header[0], header[1]);
|
|
3795
|
-
}, this);
|
|
3796
|
-
} else if (headers) {
|
|
3797
|
-
Object.getOwnPropertyNames(headers).forEach(function(name) {
|
|
3798
|
-
this.append(name, headers[name]);
|
|
3799
|
-
}, this);
|
|
3800
|
-
}
|
|
3801
|
-
}
|
|
3802
|
-
|
|
3803
|
-
Headers.prototype.append = function(name, value) {
|
|
3804
|
-
name = normalizeName(name);
|
|
3805
|
-
value = normalizeValue(value);
|
|
3806
|
-
var oldValue = this.map[name];
|
|
3807
|
-
this.map[name] = oldValue ? oldValue + ', ' + value : value;
|
|
3808
|
-
};
|
|
3809
|
-
|
|
3810
|
-
Headers.prototype['delete'] = function(name) {
|
|
3811
|
-
delete this.map[normalizeName(name)];
|
|
3812
|
-
};
|
|
3813
|
-
|
|
3814
|
-
Headers.prototype.get = function(name) {
|
|
3815
|
-
name = normalizeName(name);
|
|
3816
|
-
return this.has(name) ? this.map[name] : null
|
|
3817
|
-
};
|
|
3818
|
-
|
|
3819
|
-
Headers.prototype.has = function(name) {
|
|
3820
|
-
return this.map.hasOwnProperty(normalizeName(name))
|
|
3821
|
-
};
|
|
3822
|
-
|
|
3823
|
-
Headers.prototype.set = function(name, value) {
|
|
3824
|
-
this.map[normalizeName(name)] = normalizeValue(value);
|
|
3825
|
-
};
|
|
3826
|
-
|
|
3827
|
-
Headers.prototype.forEach = function(callback, thisArg) {
|
|
3828
|
-
for (var name in this.map) {
|
|
3829
|
-
if (this.map.hasOwnProperty(name)) {
|
|
3830
|
-
callback.call(thisArg, this.map[name], name, this);
|
|
3831
|
-
}
|
|
3832
|
-
}
|
|
3833
|
-
};
|
|
3834
|
-
|
|
3835
|
-
Headers.prototype.keys = function() {
|
|
3836
|
-
var items = [];
|
|
3837
|
-
this.forEach(function(value, name) {
|
|
3838
|
-
items.push(name);
|
|
3839
|
-
});
|
|
3840
|
-
return iteratorFor(items)
|
|
3841
|
-
};
|
|
3842
|
-
|
|
3843
|
-
Headers.prototype.values = function() {
|
|
3844
|
-
var items = [];
|
|
3845
|
-
this.forEach(function(value) {
|
|
3846
|
-
items.push(value);
|
|
3847
|
-
});
|
|
3848
|
-
return iteratorFor(items)
|
|
3849
|
-
};
|
|
3850
|
-
|
|
3851
|
-
Headers.prototype.entries = function() {
|
|
3852
|
-
var items = [];
|
|
3853
|
-
this.forEach(function(value, name) {
|
|
3854
|
-
items.push([name, value]);
|
|
3855
|
-
});
|
|
3856
|
-
return iteratorFor(items)
|
|
3857
|
-
};
|
|
3858
|
-
|
|
3859
|
-
if (support.iterable) {
|
|
3860
|
-
Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
|
|
3861
|
-
}
|
|
3862
|
-
|
|
3863
|
-
function consumed(body) {
|
|
3864
|
-
if (body._noBody) return
|
|
3865
|
-
if (body.bodyUsed) {
|
|
3866
|
-
return Promise.reject(new TypeError('Already read'))
|
|
3867
|
-
}
|
|
3868
|
-
body.bodyUsed = true;
|
|
3869
|
-
}
|
|
3870
|
-
|
|
3871
|
-
function fileReaderReady(reader) {
|
|
3872
|
-
return new Promise(function(resolve, reject) {
|
|
3873
|
-
reader.onload = function() {
|
|
3874
|
-
resolve(reader.result);
|
|
3875
|
-
};
|
|
3876
|
-
reader.onerror = function() {
|
|
3877
|
-
reject(reader.error);
|
|
3878
|
-
};
|
|
3879
|
-
})
|
|
3880
|
-
}
|
|
3881
|
-
|
|
3882
|
-
function readBlobAsArrayBuffer(blob) {
|
|
3883
|
-
var reader = new FileReader();
|
|
3884
|
-
var promise = fileReaderReady(reader);
|
|
3885
|
-
reader.readAsArrayBuffer(blob);
|
|
3886
|
-
return promise
|
|
3887
|
-
}
|
|
3888
|
-
|
|
3889
|
-
function readBlobAsText(blob) {
|
|
3890
|
-
var reader = new FileReader();
|
|
3891
|
-
var promise = fileReaderReady(reader);
|
|
3892
|
-
var match = /charset=([A-Za-z0-9_-]+)/.exec(blob.type);
|
|
3893
|
-
var encoding = match ? match[1] : 'utf-8';
|
|
3894
|
-
reader.readAsText(blob, encoding);
|
|
3895
|
-
return promise
|
|
3896
|
-
}
|
|
3897
|
-
|
|
3898
|
-
function readArrayBufferAsText(buf) {
|
|
3899
|
-
var view = new Uint8Array(buf);
|
|
3900
|
-
var chars = new Array(view.length);
|
|
3901
|
-
|
|
3902
|
-
for (var i = 0; i < view.length; i++) {
|
|
3903
|
-
chars[i] = String.fromCharCode(view[i]);
|
|
3904
|
-
}
|
|
3905
|
-
return chars.join('')
|
|
3906
|
-
}
|
|
3907
|
-
|
|
3908
|
-
function bufferClone(buf) {
|
|
3909
|
-
if (buf.slice) {
|
|
3910
|
-
return buf.slice(0)
|
|
3911
|
-
} else {
|
|
3912
|
-
var view = new Uint8Array(buf.byteLength);
|
|
3913
|
-
view.set(new Uint8Array(buf));
|
|
3914
|
-
return view.buffer
|
|
3915
|
-
}
|
|
3916
|
-
}
|
|
3917
|
-
|
|
3918
|
-
function Body() {
|
|
3919
|
-
this.bodyUsed = false;
|
|
3920
|
-
|
|
3921
|
-
this._initBody = function(body) {
|
|
3922
|
-
/*
|
|
3923
|
-
fetch-mock wraps the Response object in an ES6 Proxy to
|
|
3924
|
-
provide useful test harness features such as flush. However, on
|
|
3925
|
-
ES5 browsers without fetch or Proxy support pollyfills must be used;
|
|
3926
|
-
the proxy-pollyfill is unable to proxy an attribute unless it exists
|
|
3927
|
-
on the object before the Proxy is created. This change ensures
|
|
3928
|
-
Response.bodyUsed exists on the instance, while maintaining the
|
|
3929
|
-
semantic of setting Request.bodyUsed in the constructor before
|
|
3930
|
-
_initBody is called.
|
|
3931
|
-
*/
|
|
3932
|
-
// eslint-disable-next-line no-self-assign
|
|
3933
|
-
this.bodyUsed = this.bodyUsed;
|
|
3934
|
-
this._bodyInit = body;
|
|
3935
|
-
if (!body) {
|
|
3936
|
-
this._noBody = true;
|
|
3937
|
-
this._bodyText = '';
|
|
3938
|
-
} else if (typeof body === 'string') {
|
|
3939
|
-
this._bodyText = body;
|
|
3940
|
-
} else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
|
|
3941
|
-
this._bodyBlob = body;
|
|
3942
|
-
} else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
|
|
3943
|
-
this._bodyFormData = body;
|
|
3944
|
-
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
|
3945
|
-
this._bodyText = body.toString();
|
|
3946
|
-
} else if (support.arrayBuffer && support.blob && isDataView(body)) {
|
|
3947
|
-
this._bodyArrayBuffer = bufferClone(body.buffer);
|
|
3948
|
-
// IE 10-11 can't handle a DataView body.
|
|
3949
|
-
this._bodyInit = new Blob([this._bodyArrayBuffer]);
|
|
3950
|
-
} else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
|
|
3951
|
-
this._bodyArrayBuffer = bufferClone(body);
|
|
3952
|
-
} else {
|
|
3953
|
-
this._bodyText = body = Object.prototype.toString.call(body);
|
|
3954
|
-
}
|
|
3955
|
-
|
|
3956
|
-
if (!this.headers.get('content-type')) {
|
|
3957
|
-
if (typeof body === 'string') {
|
|
3958
|
-
this.headers.set('content-type', 'text/plain;charset=UTF-8');
|
|
3959
|
-
} else if (this._bodyBlob && this._bodyBlob.type) {
|
|
3960
|
-
this.headers.set('content-type', this._bodyBlob.type);
|
|
3961
|
-
} else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
|
|
3962
|
-
this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8');
|
|
3963
|
-
}
|
|
3964
|
-
}
|
|
3965
|
-
};
|
|
3966
|
-
|
|
3967
|
-
if (support.blob) {
|
|
3968
|
-
this.blob = function() {
|
|
3969
|
-
var rejected = consumed(this);
|
|
3970
|
-
if (rejected) {
|
|
3971
|
-
return rejected
|
|
3972
|
-
}
|
|
3973
|
-
|
|
3974
|
-
if (this._bodyBlob) {
|
|
3975
|
-
return Promise.resolve(this._bodyBlob)
|
|
3976
|
-
} else if (this._bodyArrayBuffer) {
|
|
3977
|
-
return Promise.resolve(new Blob([this._bodyArrayBuffer]))
|
|
3978
|
-
} else if (this._bodyFormData) {
|
|
3979
|
-
throw new Error('could not read FormData body as blob')
|
|
3980
|
-
} else {
|
|
3981
|
-
return Promise.resolve(new Blob([this._bodyText]))
|
|
3982
|
-
}
|
|
3983
|
-
};
|
|
3984
|
-
}
|
|
3985
|
-
|
|
3986
|
-
this.arrayBuffer = function() {
|
|
3987
|
-
if (this._bodyArrayBuffer) {
|
|
3988
|
-
var isConsumed = consumed(this);
|
|
3989
|
-
if (isConsumed) {
|
|
3990
|
-
return isConsumed
|
|
3991
|
-
} else if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
|
|
3992
|
-
return Promise.resolve(
|
|
3993
|
-
this._bodyArrayBuffer.buffer.slice(
|
|
3994
|
-
this._bodyArrayBuffer.byteOffset,
|
|
3995
|
-
this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
|
|
3996
|
-
)
|
|
3997
|
-
)
|
|
3998
|
-
} else {
|
|
3999
|
-
return Promise.resolve(this._bodyArrayBuffer)
|
|
4000
|
-
}
|
|
4001
|
-
} else if (support.blob) {
|
|
4002
|
-
return this.blob().then(readBlobAsArrayBuffer)
|
|
4003
|
-
} else {
|
|
4004
|
-
throw new Error('could not read as ArrayBuffer')
|
|
4005
|
-
}
|
|
4006
|
-
};
|
|
4007
|
-
|
|
4008
|
-
this.text = function() {
|
|
4009
|
-
var rejected = consumed(this);
|
|
4010
|
-
if (rejected) {
|
|
4011
|
-
return rejected
|
|
4012
|
-
}
|
|
4013
|
-
|
|
4014
|
-
if (this._bodyBlob) {
|
|
4015
|
-
return readBlobAsText(this._bodyBlob)
|
|
4016
|
-
} else if (this._bodyArrayBuffer) {
|
|
4017
|
-
return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer))
|
|
4018
|
-
} else if (this._bodyFormData) {
|
|
4019
|
-
throw new Error('could not read FormData body as text')
|
|
4020
|
-
} else {
|
|
4021
|
-
return Promise.resolve(this._bodyText)
|
|
4022
|
-
}
|
|
4023
|
-
};
|
|
4024
|
-
|
|
4025
|
-
if (support.formData) {
|
|
4026
|
-
this.formData = function() {
|
|
4027
|
-
return this.text().then(decode)
|
|
4028
|
-
};
|
|
4029
|
-
}
|
|
4030
|
-
|
|
4031
|
-
this.json = function() {
|
|
4032
|
-
return this.text().then(JSON.parse)
|
|
4033
|
-
};
|
|
4034
|
-
|
|
4035
|
-
return this
|
|
4036
|
-
}
|
|
4037
|
-
|
|
4038
|
-
// HTTP methods whose capitalization should be normalized
|
|
4039
|
-
var methods = ['CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'];
|
|
4040
|
-
|
|
4041
|
-
function normalizeMethod(method) {
|
|
4042
|
-
var upcased = method.toUpperCase();
|
|
4043
|
-
return methods.indexOf(upcased) > -1 ? upcased : method
|
|
4044
|
-
}
|
|
4045
|
-
|
|
4046
|
-
function Request(input, options) {
|
|
4047
|
-
if (!(this instanceof Request)) {
|
|
4048
|
-
throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
|
|
4049
|
-
}
|
|
4050
|
-
|
|
4051
|
-
options = options || {};
|
|
4052
|
-
var body = options.body;
|
|
4053
|
-
|
|
4054
|
-
if (input instanceof Request) {
|
|
4055
|
-
if (input.bodyUsed) {
|
|
4056
|
-
throw new TypeError('Already read')
|
|
4057
|
-
}
|
|
4058
|
-
this.url = input.url;
|
|
4059
|
-
this.credentials = input.credentials;
|
|
4060
|
-
if (!options.headers) {
|
|
4061
|
-
this.headers = new Headers(input.headers);
|
|
4062
|
-
}
|
|
4063
|
-
this.method = input.method;
|
|
4064
|
-
this.mode = input.mode;
|
|
4065
|
-
this.signal = input.signal;
|
|
4066
|
-
if (!body && input._bodyInit != null) {
|
|
4067
|
-
body = input._bodyInit;
|
|
4068
|
-
input.bodyUsed = true;
|
|
4069
|
-
}
|
|
4070
|
-
} else {
|
|
4071
|
-
this.url = String(input);
|
|
4072
|
-
}
|
|
4073
|
-
|
|
4074
|
-
this.credentials = options.credentials || this.credentials || 'same-origin';
|
|
4075
|
-
if (options.headers || !this.headers) {
|
|
4076
|
-
this.headers = new Headers(options.headers);
|
|
4077
|
-
}
|
|
4078
|
-
this.method = normalizeMethod(options.method || this.method || 'GET');
|
|
4079
|
-
this.mode = options.mode || this.mode || null;
|
|
4080
|
-
this.signal = options.signal || this.signal || (function () {
|
|
4081
|
-
if ('AbortController' in g) {
|
|
4082
|
-
var ctrl = new AbortController();
|
|
4083
|
-
return ctrl.signal;
|
|
4084
|
-
}
|
|
4085
|
-
}());
|
|
4086
|
-
this.referrer = null;
|
|
4087
|
-
|
|
4088
|
-
if ((this.method === 'GET' || this.method === 'HEAD') && body) {
|
|
4089
|
-
throw new TypeError('Body not allowed for GET or HEAD requests')
|
|
4090
|
-
}
|
|
4091
|
-
this._initBody(body);
|
|
4092
|
-
|
|
4093
|
-
if (this.method === 'GET' || this.method === 'HEAD') {
|
|
4094
|
-
if (options.cache === 'no-store' || options.cache === 'no-cache') {
|
|
4095
|
-
// Search for a '_' parameter in the query string
|
|
4096
|
-
var reParamSearch = /([?&])_=[^&]*/;
|
|
4097
|
-
if (reParamSearch.test(this.url)) {
|
|
4098
|
-
// If it already exists then set the value with the current time
|
|
4099
|
-
this.url = this.url.replace(reParamSearch, '$1_=' + new Date().getTime());
|
|
4100
|
-
} else {
|
|
4101
|
-
// Otherwise add a new '_' parameter to the end with the current time
|
|
4102
|
-
var reQueryString = /\?/;
|
|
4103
|
-
this.url += (reQueryString.test(this.url) ? '&' : '?') + '_=' + new Date().getTime();
|
|
4104
|
-
}
|
|
4105
|
-
}
|
|
4106
|
-
}
|
|
4107
|
-
}
|
|
4108
|
-
|
|
4109
|
-
Request.prototype.clone = function() {
|
|
4110
|
-
return new Request(this, {body: this._bodyInit})
|
|
4111
|
-
};
|
|
4112
|
-
|
|
4113
|
-
function decode(body) {
|
|
4114
|
-
var form = new FormData();
|
|
4115
|
-
body
|
|
4116
|
-
.trim()
|
|
4117
|
-
.split('&')
|
|
4118
|
-
.forEach(function(bytes) {
|
|
4119
|
-
if (bytes) {
|
|
4120
|
-
var split = bytes.split('=');
|
|
4121
|
-
var name = split.shift().replace(/\+/g, ' ');
|
|
4122
|
-
var value = split.join('=').replace(/\+/g, ' ');
|
|
4123
|
-
form.append(decodeURIComponent(name), decodeURIComponent(value));
|
|
4124
|
-
}
|
|
4125
|
-
});
|
|
4126
|
-
return form
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
|
-
function parseHeaders(rawHeaders) {
|
|
4130
|
-
var headers = new Headers();
|
|
4131
|
-
// Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space
|
|
4132
|
-
// https://tools.ietf.org/html/rfc7230#section-3.2
|
|
4133
|
-
var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ');
|
|
4134
|
-
// Avoiding split via regex to work around a common IE11 bug with the core-js 3.6.0 regex polyfill
|
|
4135
|
-
// https://github.com/github/fetch/issues/748
|
|
4136
|
-
// https://github.com/zloirock/core-js/issues/751
|
|
4137
|
-
preProcessedHeaders
|
|
4138
|
-
.split('\r')
|
|
4139
|
-
.map(function(header) {
|
|
4140
|
-
return header.indexOf('\n') === 0 ? header.substr(1, header.length) : header
|
|
4141
|
-
})
|
|
4142
|
-
.forEach(function(line) {
|
|
4143
|
-
var parts = line.split(':');
|
|
4144
|
-
var key = parts.shift().trim();
|
|
4145
|
-
if (key) {
|
|
4146
|
-
var value = parts.join(':').trim();
|
|
4147
|
-
try {
|
|
4148
|
-
headers.append(key, value);
|
|
4149
|
-
} catch (error) {
|
|
4150
|
-
console.warn('Response ' + error.message);
|
|
4151
|
-
}
|
|
4152
|
-
}
|
|
4153
|
-
});
|
|
4154
|
-
return headers
|
|
4155
|
-
}
|
|
4156
|
-
|
|
4157
|
-
Body.call(Request.prototype);
|
|
4158
|
-
|
|
4159
|
-
function Response(bodyInit, options) {
|
|
4160
|
-
if (!(this instanceof Response)) {
|
|
4161
|
-
throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.')
|
|
4162
|
-
}
|
|
4163
|
-
if (!options) {
|
|
4164
|
-
options = {};
|
|
4165
|
-
}
|
|
4166
|
-
|
|
4167
|
-
this.type = 'default';
|
|
4168
|
-
this.status = options.status === undefined ? 200 : options.status;
|
|
4169
|
-
if (this.status < 200 || this.status > 599) {
|
|
4170
|
-
throw new RangeError("Failed to construct 'Response': The status provided (0) is outside the range [200, 599].")
|
|
4171
|
-
}
|
|
4172
|
-
this.ok = this.status >= 200 && this.status < 300;
|
|
4173
|
-
this.statusText = options.statusText === undefined ? '' : '' + options.statusText;
|
|
4174
|
-
this.headers = new Headers(options.headers);
|
|
4175
|
-
this.url = options.url || '';
|
|
4176
|
-
this._initBody(bodyInit);
|
|
4177
|
-
}
|
|
4178
|
-
|
|
4179
|
-
Body.call(Response.prototype);
|
|
4180
|
-
|
|
4181
|
-
Response.prototype.clone = function() {
|
|
4182
|
-
return new Response(this._bodyInit, {
|
|
4183
|
-
status: this.status,
|
|
4184
|
-
statusText: this.statusText,
|
|
4185
|
-
headers: new Headers(this.headers),
|
|
4186
|
-
url: this.url
|
|
4187
|
-
})
|
|
4188
|
-
};
|
|
4189
|
-
|
|
4190
|
-
Response.error = function() {
|
|
4191
|
-
var response = new Response(null, {status: 200, statusText: ''});
|
|
4192
|
-
response.ok = false;
|
|
4193
|
-
response.status = 0;
|
|
4194
|
-
response.type = 'error';
|
|
4195
|
-
return response
|
|
4196
|
-
};
|
|
4197
|
-
|
|
4198
|
-
var redirectStatuses = [301, 302, 303, 307, 308];
|
|
4199
|
-
|
|
4200
|
-
Response.redirect = function(url, status) {
|
|
4201
|
-
if (redirectStatuses.indexOf(status) === -1) {
|
|
4202
|
-
throw new RangeError('Invalid status code')
|
|
4203
|
-
}
|
|
4204
|
-
|
|
4205
|
-
return new Response(null, {status: status, headers: {location: url}})
|
|
4206
|
-
};
|
|
4207
|
-
|
|
4208
|
-
exports.DOMException = g.DOMException;
|
|
4209
|
-
try {
|
|
4210
|
-
new exports.DOMException();
|
|
4211
|
-
} catch (err) {
|
|
4212
|
-
exports.DOMException = function(message, name) {
|
|
4213
|
-
this.message = message;
|
|
4214
|
-
this.name = name;
|
|
4215
|
-
var error = Error(message);
|
|
4216
|
-
this.stack = error.stack;
|
|
4217
|
-
};
|
|
4218
|
-
exports.DOMException.prototype = Object.create(Error.prototype);
|
|
4219
|
-
exports.DOMException.prototype.constructor = exports.DOMException;
|
|
4220
|
-
}
|
|
4221
|
-
|
|
4222
|
-
function fetch(input, init) {
|
|
4223
|
-
return new Promise(function(resolve, reject) {
|
|
4224
|
-
var request = new Request(input, init);
|
|
4225
|
-
|
|
4226
|
-
if (request.signal && request.signal.aborted) {
|
|
4227
|
-
return reject(new exports.DOMException('Aborted', 'AbortError'))
|
|
4228
|
-
}
|
|
4229
|
-
|
|
4230
|
-
var xhr = new XMLHttpRequest();
|
|
4231
|
-
|
|
4232
|
-
function abortXhr() {
|
|
4233
|
-
xhr.abort();
|
|
4234
|
-
}
|
|
4235
|
-
|
|
4236
|
-
xhr.onload = function() {
|
|
4237
|
-
var options = {
|
|
4238
|
-
statusText: xhr.statusText,
|
|
4239
|
-
headers: parseHeaders(xhr.getAllResponseHeaders() || '')
|
|
4240
|
-
};
|
|
4241
|
-
// This check if specifically for when a user fetches a file locally from the file system
|
|
4242
|
-
// Only if the status is out of a normal range
|
|
4243
|
-
if (request.url.indexOf('file://') === 0 && (xhr.status < 200 || xhr.status > 599)) {
|
|
4244
|
-
options.status = 200;
|
|
4245
|
-
} else {
|
|
4246
|
-
options.status = xhr.status;
|
|
4247
|
-
}
|
|
4248
|
-
options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL');
|
|
4249
|
-
var body = 'response' in xhr ? xhr.response : xhr.responseText;
|
|
4250
|
-
setTimeout(function() {
|
|
4251
|
-
resolve(new Response(body, options));
|
|
4252
|
-
}, 0);
|
|
4253
|
-
};
|
|
4254
|
-
|
|
4255
|
-
xhr.onerror = function() {
|
|
4256
|
-
setTimeout(function() {
|
|
4257
|
-
reject(new TypeError('Network request failed'));
|
|
4258
|
-
}, 0);
|
|
4259
|
-
};
|
|
4260
|
-
|
|
4261
|
-
xhr.ontimeout = function() {
|
|
4262
|
-
setTimeout(function() {
|
|
4263
|
-
reject(new TypeError('Network request timed out'));
|
|
4264
|
-
}, 0);
|
|
4265
|
-
};
|
|
4266
|
-
|
|
4267
|
-
xhr.onabort = function() {
|
|
4268
|
-
setTimeout(function() {
|
|
4269
|
-
reject(new exports.DOMException('Aborted', 'AbortError'));
|
|
4270
|
-
}, 0);
|
|
4271
|
-
};
|
|
4272
|
-
|
|
4273
|
-
function fixUrl(url) {
|
|
4274
|
-
try {
|
|
4275
|
-
return url === '' && g.location.href ? g.location.href : url
|
|
4276
|
-
} catch (e) {
|
|
4277
|
-
return url
|
|
4278
|
-
}
|
|
4279
|
-
}
|
|
4280
|
-
|
|
4281
|
-
xhr.open(request.method, fixUrl(request.url), true);
|
|
4282
|
-
|
|
4283
|
-
if (request.credentials === 'include') {
|
|
4284
|
-
xhr.withCredentials = true;
|
|
4285
|
-
} else if (request.credentials === 'omit') {
|
|
4286
|
-
xhr.withCredentials = false;
|
|
4287
|
-
}
|
|
4288
|
-
|
|
4289
|
-
if ('responseType' in xhr) {
|
|
4290
|
-
if (support.blob) {
|
|
4291
|
-
xhr.responseType = 'blob';
|
|
4292
|
-
} else if (
|
|
4293
|
-
support.arrayBuffer
|
|
4294
|
-
) {
|
|
4295
|
-
xhr.responseType = 'arraybuffer';
|
|
4296
|
-
}
|
|
4297
|
-
}
|
|
4298
|
-
|
|
4299
|
-
if (init && typeof init.headers === 'object' && !(init.headers instanceof Headers || (g.Headers && init.headers instanceof g.Headers))) {
|
|
4300
|
-
var names = [];
|
|
4301
|
-
Object.getOwnPropertyNames(init.headers).forEach(function(name) {
|
|
4302
|
-
names.push(normalizeName(name));
|
|
4303
|
-
xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
|
|
4304
|
-
});
|
|
4305
|
-
request.headers.forEach(function(value, name) {
|
|
4306
|
-
if (names.indexOf(name) === -1) {
|
|
4307
|
-
xhr.setRequestHeader(name, value);
|
|
4308
|
-
}
|
|
4309
|
-
});
|
|
4310
|
-
} else {
|
|
4311
|
-
request.headers.forEach(function(value, name) {
|
|
4312
|
-
xhr.setRequestHeader(name, value);
|
|
4313
|
-
});
|
|
4314
|
-
}
|
|
4315
|
-
|
|
4316
|
-
if (request.signal) {
|
|
4317
|
-
request.signal.addEventListener('abort', abortXhr);
|
|
4318
|
-
|
|
4319
|
-
xhr.onreadystatechange = function() {
|
|
4320
|
-
// DONE (success or failure)
|
|
4321
|
-
if (xhr.readyState === 4) {
|
|
4322
|
-
request.signal.removeEventListener('abort', abortXhr);
|
|
4323
|
-
}
|
|
4324
|
-
};
|
|
4325
|
-
}
|
|
4326
|
-
|
|
4327
|
-
xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit);
|
|
4328
|
-
})
|
|
4329
|
-
}
|
|
4330
|
-
|
|
4331
|
-
fetch.polyfill = true;
|
|
4332
|
-
|
|
4333
|
-
if (!g.fetch) {
|
|
4334
|
-
g.fetch = fetch;
|
|
4335
|
-
g.Headers = Headers;
|
|
4336
|
-
g.Request = Request;
|
|
4337
|
-
g.Response = Response;
|
|
4338
|
-
}
|
|
4339
|
-
|
|
4340
|
-
exports.Headers = Headers;
|
|
4341
|
-
exports.Request = Request;
|
|
4342
|
-
exports.Response = Response;
|
|
4343
|
-
exports.fetch = fetch;
|
|
4344
|
-
|
|
4345
|
-
return exports;
|
|
4346
|
-
|
|
4347
|
-
})({});
|
|
4348
|
-
})(__globalThis__);
|
|
4349
|
-
// This is a ponyfill, so...
|
|
4350
|
-
__globalThis__.fetch.ponyfill = true;
|
|
4351
|
-
delete __globalThis__.fetch.polyfill;
|
|
4352
|
-
// Choose between native implementation (__global__) or custom implementation (__globalThis__)
|
|
4353
|
-
var ctx = __global__.fetch ? __global__ : __globalThis__;
|
|
4354
|
-
exports = ctx.fetch // To enable: import fetch from 'cross-fetch'
|
|
4355
|
-
exports["default"] = ctx.fetch // For TypeScript consumers without esModuleInterop.
|
|
4356
|
-
exports.fetch = ctx.fetch // To enable: import {fetch} from 'cross-fetch'
|
|
4357
|
-
exports.Headers = ctx.Headers
|
|
4358
|
-
exports.Request = ctx.Request
|
|
4359
|
-
exports.Response = ctx.Response
|
|
4360
|
-
module.exports = exports
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
/***/ }),
|
|
4364
|
-
|
|
4365
|
-
/***/ 953:
|
|
4366
|
-
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
|
|
4367
|
-
|
|
4368
|
-
const crossFetch = __webpack_require__(945);
|
|
4369
|
-
|
|
4370
|
-
/**
|
|
4371
|
-
* Metadata header names
|
|
4372
|
-
* @enum {string} The enum value is the name of the associated header.
|
|
4373
|
-
* @readonly
|
|
4374
|
-
*/
|
|
4375
|
-
const RequestMetadata = {
|
|
4376
|
-
/** The ID of the project associated with this request */
|
|
4377
|
-
ProjectId: 'X-Project-ID',
|
|
4378
|
-
/** The ID of the project run associated with this request */
|
|
4379
|
-
RunId: 'X-Run-ID'
|
|
4380
|
-
};
|
|
4381
|
-
|
|
4382
|
-
/**
|
|
4383
|
-
* Metadata headers for requests
|
|
4384
|
-
* @type {Headers}
|
|
4385
|
-
*/
|
|
4386
|
-
const metadata = new crossFetch.Headers();
|
|
4387
|
-
|
|
4388
|
-
/**
|
|
4389
|
-
* Check if there is any metadata to apply.
|
|
4390
|
-
* @returns {boolean} true if `metadata` has contents, or false if it is empty.
|
|
4391
|
-
*/
|
|
4392
|
-
const hasMetadata = () => {
|
|
4393
|
-
/* global self */
|
|
4394
|
-
const searchParams = typeof self !== 'undefined' && self && self.location && self.location.search && self.location.search.split(/[?&]/) || [];
|
|
4395
|
-
if (!searchParams.includes('scratchMetadata=1')) {
|
|
4396
|
-
// for now, disable this feature unless scratchMetadata=1
|
|
4397
|
-
// TODO: remove this check once we're sure the feature works correctly in production
|
|
4398
|
-
return false;
|
|
4399
|
-
}
|
|
4400
|
-
for (const _ of metadata) {
|
|
4401
|
-
return true;
|
|
4402
|
-
}
|
|
4403
|
-
return false;
|
|
4404
|
-
};
|
|
4405
|
-
|
|
4406
|
-
/**
|
|
4407
|
-
* Non-destructively merge any metadata state (if any) with the provided options object (if any).
|
|
4408
|
-
* If there is metadata state but no options object is provided, make a new object.
|
|
4409
|
-
* If there is no metadata state, return the provided options parameter without modification.
|
|
4410
|
-
* If there is metadata and an options object is provided, modify a copy and return it.
|
|
4411
|
-
* Headers in the provided options object may override headers generated from metadata state.
|
|
4412
|
-
* @param {RequestInit} [options] The initial request options. May be null or undefined.
|
|
4413
|
-
* @returns {RequestInit|undefined} the provided options parameter without modification, or a new options object.
|
|
4414
|
-
*/
|
|
4415
|
-
const applyMetadata = options => {
|
|
4416
|
-
if (hasMetadata()) {
|
|
4417
|
-
const augmentedOptions = Object.assign({}, options);
|
|
4418
|
-
augmentedOptions.headers = new crossFetch.Headers(metadata);
|
|
4419
|
-
if (options && options.headers) {
|
|
4420
|
-
// the Fetch spec says options.headers could be:
|
|
4421
|
-
// "A Headers object, an object literal, or an array of two-item arrays to set request's headers."
|
|
4422
|
-
// turn it into a Headers object to be sure of how to interact with it
|
|
4423
|
-
const overrideHeaders = options.headers instanceof crossFetch.Headers ? options.headers : new crossFetch.Headers(options.headers);
|
|
4424
|
-
for (const [name, value] of overrideHeaders.entries()) {
|
|
4425
|
-
augmentedOptions.headers.set(name, value);
|
|
4426
|
-
}
|
|
4427
|
-
}
|
|
4428
|
-
return augmentedOptions;
|
|
4429
|
-
}
|
|
4430
|
-
return options;
|
|
4431
|
-
};
|
|
4432
|
-
|
|
4433
|
-
/**
|
|
4434
|
-
* Make a network request.
|
|
4435
|
-
* This is a wrapper for the global fetch method, adding some Scratch-specific functionality.
|
|
4436
|
-
* @param {RequestInfo|URL} resource The resource to fetch.
|
|
4437
|
-
* @param {RequestInit} options Optional object containing custom settings for this request.
|
|
4438
|
-
* @see {@link https://developer.mozilla.org/docs/Web/API/fetch} for more about the fetch API.
|
|
4439
|
-
* @returns {Promise<Response>} A promise for the response to the request.
|
|
4440
|
-
*/
|
|
4441
|
-
const scratchFetch = (resource, options) => {
|
|
4442
|
-
const augmentedOptions = applyMetadata(options);
|
|
4443
|
-
return crossFetch(resource, augmentedOptions);
|
|
4444
|
-
};
|
|
4445
|
-
|
|
4446
|
-
/**
|
|
4447
|
-
* Set the value of a named request metadata item.
|
|
4448
|
-
* Setting the value to `null` or `undefined` will NOT remove the item.
|
|
4449
|
-
* Use `unsetMetadata` for that.
|
|
4450
|
-
* @param {RequestMetadata} name The name of the metadata item to set.
|
|
4451
|
-
* @param {any} value The value to set (will be converted to a string).
|
|
4452
|
-
*/
|
|
4453
|
-
const setMetadata = (name, value) => {
|
|
4454
|
-
metadata.set(name, value);
|
|
4455
|
-
};
|
|
4456
|
-
|
|
4457
|
-
/**
|
|
4458
|
-
* Remove a named request metadata item.
|
|
4459
|
-
* @param {RequestMetadata} name The name of the metadata item to remove.
|
|
4460
|
-
*/
|
|
4461
|
-
const unsetMetadata = name => {
|
|
4462
|
-
metadata.delete(name);
|
|
4463
|
-
};
|
|
4464
|
-
|
|
4465
|
-
/**
|
|
4466
|
-
* Retrieve a named request metadata item.
|
|
4467
|
-
* Only for use in tests. At the time of writing, used in scratch-vm tests.
|
|
4468
|
-
* @param {RequestMetadata} name The name of the metadata item to retrieve.
|
|
4469
|
-
* @returns {any} value The value of the metadata item, or `undefined` if it was not found.
|
|
4470
|
-
*/
|
|
4471
|
-
const getMetadata = name => metadata.get(name);
|
|
4472
|
-
module.exports = {
|
|
4473
|
-
Headers: crossFetch.Headers,
|
|
4474
|
-
RequestMetadata,
|
|
4475
|
-
applyMetadata,
|
|
4476
|
-
scratchFetch,
|
|
4477
|
-
setMetadata,
|
|
4478
|
-
unsetMetadata,
|
|
4479
|
-
getMetadata
|
|
4480
|
-
};
|
|
4481
|
-
|
|
4482
|
-
/***/ })
|
|
3672
|
+
/***/ }
|
|
4483
3673
|
|
|
4484
3674
|
/******/ });
|
|
4485
3675
|
/************************************************************************/
|
|
@@ -4545,7 +3735,7 @@ module.exports = {
|
|
|
4545
3735
|
/******/ // This function allow to reference async chunks
|
|
4546
3736
|
/******/ __webpack_require__.u = (chunkId) => {
|
|
4547
3737
|
/******/ // return url for filenames based on template
|
|
4548
|
-
/******/ return "chunks/" + "fetch-worker" + "." + "
|
|
3738
|
+
/******/ return "chunks/" + "fetch-worker" + "." + "efebf27d479ab0f0d98c" + ".js";
|
|
4549
3739
|
/******/ };
|
|
4550
3740
|
/******/ })();
|
|
4551
3741
|
/******/
|
|
@@ -4625,6 +3815,20 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
4625
3815
|
ScratchStorage: () => (/* reexport */ ScratchStorage)
|
|
4626
3816
|
});
|
|
4627
3817
|
|
|
3818
|
+
// NAMESPACE OBJECT: ./src/scratchFetch.ts
|
|
3819
|
+
var scratchFetch_namespaceObject = {};
|
|
3820
|
+
__webpack_require__.r(scratchFetch_namespaceObject);
|
|
3821
|
+
__webpack_require__.d(scratchFetch_namespaceObject, {
|
|
3822
|
+
Headers: () => (Headers),
|
|
3823
|
+
RequestMetadata: () => (RequestMetadata),
|
|
3824
|
+
applyMetadata: () => (applyMetadata),
|
|
3825
|
+
getMetadata: () => (getMetadata),
|
|
3826
|
+
hasMetadata: () => (hasMetadata),
|
|
3827
|
+
scratchFetch: () => (scratchFetch),
|
|
3828
|
+
setMetadata: () => (setMetadata),
|
|
3829
|
+
unsetMetadata: () => (unsetMetadata)
|
|
3830
|
+
});
|
|
3831
|
+
|
|
4628
3832
|
// EXTERNAL MODULE: ./node_modules/minilog/lib/web/index.js
|
|
4629
3833
|
var web = __webpack_require__(557);
|
|
4630
3834
|
var web_default = /*#__PURE__*/__webpack_require__.n(web);
|
|
@@ -5015,9 +4219,295 @@ class BuiltinHelper extends Helper {
|
|
|
5015
4219
|
return Promise.resolve(this.get(assetId));
|
|
5016
4220
|
}
|
|
5017
4221
|
}
|
|
5018
|
-
|
|
5019
|
-
|
|
5020
|
-
|
|
4222
|
+
;// ./node_modules/@scratch/task-herder/dist/task-herder.js
|
|
4223
|
+
const CancelReason = {
|
|
4224
|
+
QueueCostLimitExceeded: "Queue cost limit exceeded",
|
|
4225
|
+
Aborted: "Task aborted",
|
|
4226
|
+
Cancel: "Task cancelled",
|
|
4227
|
+
TaskTooExpensive: "Task cost exceeds maximum bucket size"
|
|
4228
|
+
};
|
|
4229
|
+
function PromiseWithResolvers() {
|
|
4230
|
+
let e, t;
|
|
4231
|
+
return {
|
|
4232
|
+
promise: new Promise((n, r) => {
|
|
4233
|
+
e = n, t = r;
|
|
4234
|
+
}),
|
|
4235
|
+
resolve: e,
|
|
4236
|
+
reject: t
|
|
4237
|
+
};
|
|
4238
|
+
}
|
|
4239
|
+
var TaskRecord = class {
|
|
4240
|
+
cost;
|
|
4241
|
+
promise;
|
|
4242
|
+
run;
|
|
4243
|
+
cancel;
|
|
4244
|
+
constructor(e, n = {}) {
|
|
4245
|
+
this.cost = n.cost ?? 1;
|
|
4246
|
+
let { promise: r, resolve: i, reject: a } = PromiseWithResolvers();
|
|
4247
|
+
this.promise = r, this.cancel = (e) => {
|
|
4248
|
+
a(e);
|
|
4249
|
+
}, this.run = async () => {
|
|
4250
|
+
try {
|
|
4251
|
+
i(await e());
|
|
4252
|
+
} catch (e) {
|
|
4253
|
+
a(e);
|
|
4254
|
+
}
|
|
4255
|
+
};
|
|
4256
|
+
}
|
|
4257
|
+
}, TaskQueue = class {
|
|
4258
|
+
burstLimit;
|
|
4259
|
+
sustainRate;
|
|
4260
|
+
queueCostLimit;
|
|
4261
|
+
concurrencyLimit;
|
|
4262
|
+
tokenCount;
|
|
4263
|
+
runningTasks = 0;
|
|
4264
|
+
pendingTaskRecords = [];
|
|
4265
|
+
lastRefillTime = Date.now();
|
|
4266
|
+
onTaskAdded = PromiseWithResolvers().resolve;
|
|
4267
|
+
onTaskFinished = PromiseWithResolvers().resolve;
|
|
4268
|
+
constructor(e) {
|
|
4269
|
+
this.burstLimit = e.burstLimit, this.sustainRate = e.sustainRate, this.tokenCount = e.startingTokens ?? e.burstLimit, this.queueCostLimit = e.queueCostLimit ?? Infinity, this.concurrencyLimit = e.concurrency ?? 1, this.runTasks();
|
|
4270
|
+
}
|
|
4271
|
+
get length() {
|
|
4272
|
+
return this.pendingTaskRecords.length;
|
|
4273
|
+
}
|
|
4274
|
+
get options() {
|
|
4275
|
+
return {
|
|
4276
|
+
burstLimit: this.burstLimit,
|
|
4277
|
+
sustainRate: this.sustainRate,
|
|
4278
|
+
startingTokens: this.tokenCount,
|
|
4279
|
+
queueCostLimit: this.queueCostLimit,
|
|
4280
|
+
concurrency: this.concurrencyLimit
|
|
4281
|
+
};
|
|
4282
|
+
}
|
|
4283
|
+
do(t, r = {}) {
|
|
4284
|
+
let i = new TaskRecord(t, r);
|
|
4285
|
+
return i.cost > this.burstLimit ? Promise.reject(Error(CancelReason.TaskTooExpensive)) : this.queueCostLimit < Infinity && this.pendingTaskRecords.reduce((e, t) => e + t.cost, i.cost) > this.queueCostLimit ? Promise.reject(Error(CancelReason.QueueCostLimitExceeded)) : (this.pendingTaskRecords.push(i), r.signal?.addEventListener("abort", () => {
|
|
4286
|
+
this.cancel(i.promise, Error(CancelReason.Aborted));
|
|
4287
|
+
}), this.onTaskAdded(), i.promise);
|
|
4288
|
+
}
|
|
4289
|
+
cancel(t, n) {
|
|
4290
|
+
let r = this.pendingTaskRecords.findIndex((e) => e.promise === t);
|
|
4291
|
+
if (r !== -1) {
|
|
4292
|
+
let [t] = this.pendingTaskRecords.splice(r, 1);
|
|
4293
|
+
return t.cancel(n ?? Error(CancelReason.Cancel)), !0;
|
|
4294
|
+
}
|
|
4295
|
+
return !1;
|
|
4296
|
+
}
|
|
4297
|
+
cancelAll(t) {
|
|
4298
|
+
let n = this.pendingTaskRecords;
|
|
4299
|
+
return this.pendingTaskRecords = [], t ??= Error(CancelReason.Cancel), n.forEach((e) => {
|
|
4300
|
+
e.cancel(t);
|
|
4301
|
+
}), n.length;
|
|
4302
|
+
}
|
|
4303
|
+
refillAndSpend(e) {
|
|
4304
|
+
return this.refill(), this.spend(e);
|
|
4305
|
+
}
|
|
4306
|
+
refill() {
|
|
4307
|
+
let e = Date.now(), t = e - this.lastRefillTime;
|
|
4308
|
+
if (t <= 0) return;
|
|
4309
|
+
this.lastRefillTime = e;
|
|
4310
|
+
let n = t / 1e3 * this.sustainRate;
|
|
4311
|
+
this.tokenCount = Math.min(this.burstLimit, this.tokenCount + n);
|
|
4312
|
+
}
|
|
4313
|
+
spend(e) {
|
|
4314
|
+
return this.tokenCount >= e ? (this.tokenCount -= e, !0) : !1;
|
|
4315
|
+
}
|
|
4316
|
+
async runTasks() {
|
|
4317
|
+
for (;;) {
|
|
4318
|
+
let n = this.pendingTaskRecords.shift();
|
|
4319
|
+
if (!n) {
|
|
4320
|
+
let { promise: e, resolve: n } = PromiseWithResolvers();
|
|
4321
|
+
this.onTaskAdded = n, await e;
|
|
4322
|
+
continue;
|
|
4323
|
+
}
|
|
4324
|
+
if (n.cost > this.burstLimit) {
|
|
4325
|
+
n.cancel(Error(CancelReason.TaskTooExpensive));
|
|
4326
|
+
continue;
|
|
4327
|
+
}
|
|
4328
|
+
if (this.refillAndSpend(n.cost)) {
|
|
4329
|
+
if (this.runningTasks >= this.concurrencyLimit) {
|
|
4330
|
+
let { promise: e, resolve: n } = PromiseWithResolvers();
|
|
4331
|
+
this.onTaskFinished = n, await e;
|
|
4332
|
+
}
|
|
4333
|
+
this.runTask(n);
|
|
4334
|
+
} else {
|
|
4335
|
+
this.pendingTaskRecords.unshift(n);
|
|
4336
|
+
let e = Math.max(n.cost - this.tokenCount, 0), t = Math.ceil(1e3 * e / this.sustainRate);
|
|
4337
|
+
await new Promise((e) => setTimeout(e, t));
|
|
4338
|
+
}
|
|
4339
|
+
}
|
|
4340
|
+
}
|
|
4341
|
+
async runTask(e) {
|
|
4342
|
+
this.runningTasks++;
|
|
4343
|
+
try {
|
|
4344
|
+
await e.run();
|
|
4345
|
+
} finally {
|
|
4346
|
+
this.runningTasks--, this.onTaskFinished();
|
|
4347
|
+
}
|
|
4348
|
+
}
|
|
4349
|
+
}, QueueManager = class {
|
|
4350
|
+
queues;
|
|
4351
|
+
defaultOptions;
|
|
4352
|
+
constructor(e, t) {
|
|
4353
|
+
this.queues = new Map(t), this.defaultOptions = e;
|
|
4354
|
+
}
|
|
4355
|
+
create(e, t = {}) {
|
|
4356
|
+
let n = new TaskQueue({
|
|
4357
|
+
...this.defaultOptions,
|
|
4358
|
+
...t
|
|
4359
|
+
});
|
|
4360
|
+
return this.queues.set(e, n), n;
|
|
4361
|
+
}
|
|
4362
|
+
get(e) {
|
|
4363
|
+
return this.queues.get(e);
|
|
4364
|
+
}
|
|
4365
|
+
getOrCreate(e, t = {}) {
|
|
4366
|
+
return this.get(e) ?? this.create(e, t);
|
|
4367
|
+
}
|
|
4368
|
+
options() {
|
|
4369
|
+
return { ...this.defaultOptions };
|
|
4370
|
+
}
|
|
4371
|
+
};
|
|
4372
|
+
|
|
4373
|
+
|
|
4374
|
+
;// ./src/HostQueues.ts
|
|
4375
|
+
|
|
4376
|
+
/**
|
|
4377
|
+
* @summary A set of generous limits, for things like downloading assets from CDN.
|
|
4378
|
+
* @description
|
|
4379
|
+
* In practice, these limits seem to lead to slightly better performance than no limits at all, mostly due to the
|
|
4380
|
+
* concurrency limit. For example, on my development computer & my relatively fast residential connection, a
|
|
4381
|
+
* concurrency limit of 4 loads a particular test project in 21 seconds, as opposed to 25 seconds when I bypass the
|
|
4382
|
+
* queue and call `fetch` directly. In that test, my setup downloads about 50 assets per second, so this set of options
|
|
4383
|
+
* only affects concurrency and doesn't actually throttle the downloads. Limiting concurrency also fixes the issue
|
|
4384
|
+
* where very large projects (thousands of assets) can lead to browser failures like `net::ERR_INSUFFICIENT_RESOURCES`.
|
|
4385
|
+
* The exact concurrency limit doesn't seem to matter much since the browser limits parallel connections itself. It
|
|
4386
|
+
* just needs to be high enough to avoid bubbles in the download pipeline and low enough to avoid resource exhaustion.
|
|
4387
|
+
* @see {@link https://github.com/scratchfoundation/scratch-gui/issues/7111}
|
|
4388
|
+
*/
|
|
4389
|
+
const AssetQueueOptions = {
|
|
4390
|
+
burstLimit: 64,
|
|
4391
|
+
sustainRate: 64,
|
|
4392
|
+
// WARNING: asset download concurrency >=5 can lead to corrupted buffers on Chrome (December 2025, Chrome 142.0)
|
|
4393
|
+
// when using Scratch's bitmap load pipeline. Marking the canvas context as `{willReadFrequently: true}` seems to
|
|
4394
|
+
// eliminate that issue, so maybe the problem is related to hardware acceleration.
|
|
4395
|
+
concurrency: 64
|
|
4396
|
+
};
|
|
4397
|
+
/**
|
|
4398
|
+
* Central registry of per-host queues.
|
|
4399
|
+
* Uses strict limits by default. Override these strict limits as needed for specific hosts.
|
|
4400
|
+
*/
|
|
4401
|
+
const hostQueueManager = new QueueManager({
|
|
4402
|
+
burstLimit: 5,
|
|
4403
|
+
sustainRate: 1,
|
|
4404
|
+
concurrency: 1
|
|
4405
|
+
});
|
|
4406
|
+
;// ./src/scratchFetch.ts
|
|
4407
|
+
|
|
4408
|
+
const Headers = globalThis.Headers;
|
|
4409
|
+
/**
|
|
4410
|
+
* Metadata header names.
|
|
4411
|
+
* The enum value is the name of the associated header.
|
|
4412
|
+
*/
|
|
4413
|
+
var RequestMetadata;
|
|
4414
|
+
(function (RequestMetadata) {
|
|
4415
|
+
/** The ID of the project associated with this request */
|
|
4416
|
+
RequestMetadata["ProjectId"] = "X-Project-ID";
|
|
4417
|
+
/** The ID of the project run associated with this request */
|
|
4418
|
+
RequestMetadata["RunId"] = "X-Run-ID";
|
|
4419
|
+
})(RequestMetadata || (RequestMetadata = {}));
|
|
4420
|
+
/**
|
|
4421
|
+
* Metadata headers for requests.
|
|
4422
|
+
*/
|
|
4423
|
+
const metadata = new Headers();
|
|
4424
|
+
/**
|
|
4425
|
+
* Check if there is any metadata to apply.
|
|
4426
|
+
* @returns {boolean} true if `metadata` has contents, or false if it is empty.
|
|
4427
|
+
*/
|
|
4428
|
+
const hasMetadata = () => {
|
|
4429
|
+
const searchParams = typeof self !== 'undefined' && self && self.location && self.location.search && self.location.search.split(/[?&]/) || [];
|
|
4430
|
+
if (!searchParams.includes('scratchMetadata=1')) {
|
|
4431
|
+
// for now, disable this feature unless scratchMetadata=1
|
|
4432
|
+
// TODO: remove this check once we're sure the feature works correctly in production
|
|
4433
|
+
return false;
|
|
4434
|
+
}
|
|
4435
|
+
for (const _ of metadata) {
|
|
4436
|
+
return true;
|
|
4437
|
+
}
|
|
4438
|
+
return false;
|
|
4439
|
+
};
|
|
4440
|
+
/**
|
|
4441
|
+
* Non-destructively merge any metadata state (if any) with the provided options object (if any).
|
|
4442
|
+
* If there is metadata state but no options object is provided, make a new object.
|
|
4443
|
+
* If there is no metadata state, return the provided options parameter without modification.
|
|
4444
|
+
* If there is metadata and an options object is provided, modify a copy and return it.
|
|
4445
|
+
* Headers in the provided options object may override headers generated from metadata state.
|
|
4446
|
+
* @param {RequestInit} [options] The initial request options. May be null or undefined.
|
|
4447
|
+
* @returns {RequestInit|undefined} the provided options parameter without modification, or a new options object.
|
|
4448
|
+
*/
|
|
4449
|
+
const applyMetadata = options => {
|
|
4450
|
+
if (hasMetadata()) {
|
|
4451
|
+
const augmentedOptions = Object.assign({}, options);
|
|
4452
|
+
augmentedOptions.headers = new Headers(metadata);
|
|
4453
|
+
if (options && options.headers) {
|
|
4454
|
+
// the Fetch spec says options.headers could be:
|
|
4455
|
+
// "A Headers object, an object literal, or an array of two-item arrays to set request's headers."
|
|
4456
|
+
// turn it into a Headers object to be sure of how to interact with it
|
|
4457
|
+
const overrideHeaders = options.headers instanceof Headers ? options.headers : new Headers(options.headers);
|
|
4458
|
+
for (const [name, value] of overrideHeaders.entries()) {
|
|
4459
|
+
augmentedOptions.headers.set(name, value);
|
|
4460
|
+
}
|
|
4461
|
+
}
|
|
4462
|
+
return augmentedOptions;
|
|
4463
|
+
}
|
|
4464
|
+
return options;
|
|
4465
|
+
};
|
|
4466
|
+
/**
|
|
4467
|
+
* Make a network request.
|
|
4468
|
+
* This is a wrapper for the global fetch method, adding some Scratch-specific functionality.
|
|
4469
|
+
* @param {RequestInfo|URL} resource The resource to fetch.
|
|
4470
|
+
* @param {RequestInit} [requestOptions] Optional object containing custom settings for this request.
|
|
4471
|
+
* @param {ScratchFetchOptions} [scratchOptions] Optional Scratch-specific settings for this request.
|
|
4472
|
+
* @see {@link https://developer.mozilla.org/docs/Web/API/fetch} for more about the fetch API.
|
|
4473
|
+
* @returns {Promise<Response>} A promise for the response to the request.
|
|
4474
|
+
*/
|
|
4475
|
+
const scratchFetch = (resource, requestOptions, scratchOptions) => {
|
|
4476
|
+
requestOptions = applyMetadata(requestOptions);
|
|
4477
|
+
let queueName = scratchOptions === null || scratchOptions === void 0 ? void 0 : scratchOptions.queueName;
|
|
4478
|
+
if (!queueName) {
|
|
4479
|
+
// Normalize resource to a Request object. The `fetch` call will do this anyway, so it's not much extra work,
|
|
4480
|
+
// but it guarantees availability of the URL for queue naming.
|
|
4481
|
+
resource = new Request(resource, requestOptions);
|
|
4482
|
+
queueName = new URL(resource.url).hostname;
|
|
4483
|
+
}
|
|
4484
|
+
const queue = hostQueueManager.getOrCreate(queueName, scratchOptions === null || scratchOptions === void 0 ? void 0 : scratchOptions.queueOptions);
|
|
4485
|
+
return queue.do(() => fetch(resource, requestOptions));
|
|
4486
|
+
};
|
|
4487
|
+
/**
|
|
4488
|
+
* Set the value of a named request metadata item.
|
|
4489
|
+
* Setting the value to `null` or `undefined` will NOT remove the item.
|
|
4490
|
+
* Use `unsetMetadata` for that.
|
|
4491
|
+
* @param {RequestMetadata} name The name of the metadata item to set.
|
|
4492
|
+
* @param {any} value The value to set (will be converted to a string).
|
|
4493
|
+
*/
|
|
4494
|
+
const setMetadata = (name, value) => {
|
|
4495
|
+
metadata.set(name, value);
|
|
4496
|
+
};
|
|
4497
|
+
/**
|
|
4498
|
+
* Remove a named request metadata item.
|
|
4499
|
+
* @param {RequestMetadata} name The name of the metadata item to remove.
|
|
4500
|
+
*/
|
|
4501
|
+
const unsetMetadata = name => {
|
|
4502
|
+
metadata.delete(name);
|
|
4503
|
+
};
|
|
4504
|
+
/**
|
|
4505
|
+
* Retrieve a named request metadata item.
|
|
4506
|
+
* Only for use in tests. At the time of writing, used in scratch-vm tests.
|
|
4507
|
+
* @param {RequestMetadata} name The name of the metadata item to retrieve.
|
|
4508
|
+
* @returns {string|null} The value of the metadata item, or `null` if it was not found.
|
|
4509
|
+
*/
|
|
4510
|
+
const getMetadata = name => metadata.get(name);
|
|
5021
4511
|
;// ./src/FetchWorkerTool.ts
|
|
5022
4512
|
const _excluded = ["url"];
|
|
5023
4513
|
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
@@ -5118,14 +4608,14 @@ class PrivateFetchWorkerTool {
|
|
|
5118
4608
|
return new Promise((resolve, reject) => {
|
|
5119
4609
|
// TODO: Use a Scratch standard ID generator ...
|
|
5120
4610
|
const id = Math.random().toString(16).substring(2);
|
|
5121
|
-
const augmentedOptions =
|
|
4611
|
+
const augmentedOptions = applyMetadata(Object.assign({
|
|
5122
4612
|
method: 'GET'
|
|
5123
4613
|
}, options));
|
|
5124
4614
|
// the Fetch spec says options.headers could be:
|
|
5125
4615
|
// "A Headers object, an object literal, or an array of two-item arrays to set request's headers."
|
|
5126
4616
|
// structured clone (postMessage) doesn't support Headers objects
|
|
5127
4617
|
// so turn it into an array of two-item arrays to make it to the worker intact
|
|
5128
|
-
if (augmentedOptions && augmentedOptions.headers instanceof
|
|
4618
|
+
if (augmentedOptions && augmentedOptions.headers instanceof Headers) {
|
|
5129
4619
|
augmentedOptions.headers = Array.from(augmentedOptions.headers.entries());
|
|
5130
4620
|
}
|
|
5131
4621
|
worker.postMessage({
|
|
@@ -5217,6 +4707,7 @@ const FetchTool_excluded = ["url"],
|
|
|
5217
4707
|
function FetchTool_objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = FetchTool_objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
5218
4708
|
function FetchTool_objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
5219
4709
|
|
|
4710
|
+
|
|
5220
4711
|
/**
|
|
5221
4712
|
* @typedef {Request & {withCredentials: boolean}} ScratchSendRequest
|
|
5222
4713
|
*/
|
|
@@ -5242,9 +4733,11 @@ class FetchTool {
|
|
|
5242
4733
|
url
|
|
5243
4734
|
} = _ref,
|
|
5244
4735
|
options = FetchTool_objectWithoutProperties(_ref, FetchTool_excluded);
|
|
5245
|
-
return
|
|
4736
|
+
return scratchFetch(url, Object.assign({
|
|
5246
4737
|
method: 'GET'
|
|
5247
|
-
}, options)
|
|
4738
|
+
}, options), {
|
|
4739
|
+
queueOptions: AssetQueueOptions
|
|
4740
|
+
}).then(result => {
|
|
5248
4741
|
if (result.ok) return result.arrayBuffer().then(b => new Uint8Array(b));
|
|
5249
4742
|
if (result.status === 404) return null;
|
|
5250
4743
|
return Promise.reject(result.status); // TODO: we should throw a proper error
|
|
@@ -5269,9 +4762,11 @@ class FetchTool {
|
|
|
5269
4762
|
withCredentials = false
|
|
5270
4763
|
} = _ref2,
|
|
5271
4764
|
options = FetchTool_objectWithoutProperties(_ref2, _excluded2);
|
|
5272
|
-
return
|
|
4765
|
+
return scratchFetch(url, Object.assign({
|
|
5273
4766
|
credentials: withCredentials ? 'include' : 'omit'
|
|
5274
|
-
}, options)
|
|
4767
|
+
}, options), {
|
|
4768
|
+
queueOptions: AssetQueueOptions
|
|
4769
|
+
}).then(response => {
|
|
5275
4770
|
if (response.ok) return response.text();
|
|
5276
4771
|
return Promise.reject(response.status);
|
|
5277
4772
|
});
|
|
@@ -5593,7 +5088,7 @@ class ScratchStorage {
|
|
|
5593
5088
|
* @returns {module} the scratchFetch module, with properties for `scratchFetch`, `setMetadata`, etc.
|
|
5594
5089
|
*/
|
|
5595
5090
|
get scratchFetch() {
|
|
5596
|
-
return
|
|
5091
|
+
return scratchFetch_namespaceObject;
|
|
5597
5092
|
}
|
|
5598
5093
|
/**
|
|
5599
5094
|
* @deprecated Please use the `Asset` member of a storage instance instead.
|