@amazon/vinyl-util 1.2.0 → 2.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.
Files changed (81) hide show
  1. package/dist/browserTestUtil/index.js +1850 -1850
  2. package/dist/browserTestUtil/index.js.map +4 -4
  3. package/dist/browserTestUtil/types/current/index.d.ts +17 -17
  4. package/dist/browserTestUtil/types/current/index.d.ts.map +1 -1
  5. package/dist/browserTestUtil/types/current/index.js +17 -17
  6. package/dist/browserTestUtil/types/current/tsconfig.tsbuildinfo +1 -1
  7. package/dist/browserTestUtil/types/ts3.7/index.d.ts +17 -17
  8. package/dist/browserTestUtil/types/ts4.1/index.d.ts +17 -17
  9. package/dist/browserTestUtil/types/ts4.7/index.d.ts +17 -17
  10. package/dist/index.cjs +4997 -4967
  11. package/dist/index.cjs.map +4 -4
  12. package/dist/index.js +4997 -4967
  13. package/dist/index.js.map +4 -4
  14. package/dist/polyfill/index.d.ts +1 -0
  15. package/dist/polyfill/index.d.ts.map +1 -1
  16. package/dist/polyfill/index.js +166 -103
  17. package/dist/polyfill/index.js.map +3 -3
  18. package/dist/polyfill/tsconfig.tsbuildinfo +1 -1
  19. package/dist/test/benchmark.es5.js +68 -68
  20. package/dist/test/benchmark.js +1518 -1517
  21. package/dist/test/benchmark.js.map +4 -4
  22. package/dist/testUtil/index.js +418 -418
  23. package/dist/testUtil/index.js.map +4 -4
  24. package/dist/testUtil/types/current/index.d.ts +16 -16
  25. package/dist/testUtil/types/current/index.d.ts.map +1 -1
  26. package/dist/testUtil/types/current/index.js +16 -16
  27. package/dist/testUtil/types/current/reporters/LogReporter.d.ts +1 -0
  28. package/dist/testUtil/types/current/reporters/LogReporter.d.ts.map +1 -1
  29. package/dist/testUtil/types/current/reporters/LogReporter.js +8 -0
  30. package/dist/testUtil/types/current/tsconfig.tsbuildinfo +1 -1
  31. package/dist/testUtil/types/current/util/event/createEventSpy.d.ts.map +1 -1
  32. package/dist/testUtil/types/current/util/event/createEventSpy.js +6 -4
  33. package/dist/testUtil/types/ts3.7/index.d.ts +16 -16
  34. package/dist/testUtil/types/ts3.7/reporters/LogReporter.d.ts +1 -0
  35. package/dist/testUtil/types/ts4.1/index.d.ts +16 -16
  36. package/dist/testUtil/types/ts4.1/reporters/LogReporter.d.ts +1 -0
  37. package/dist/testUtil/types/ts4.7/index.d.ts +16 -16
  38. package/dist/testUtil/types/ts4.7/reporters/LogReporter.d.ts +1 -0
  39. package/dist/types/current/event/nextEventAsPromise.d.ts +14 -4
  40. package/dist/types/current/event/nextEventAsPromise.d.ts.map +1 -1
  41. package/dist/types/current/event/nextEventAsPromise.js +8 -2
  42. package/dist/types/current/index.d.ts +114 -113
  43. package/dist/types/current/index.d.ts.map +1 -1
  44. package/dist/types/current/index.js +114 -113
  45. package/dist/types/current/tsconfig.tsbuildinfo +1 -1
  46. package/dist/types/current/util/async/poll.d.ts +34 -0
  47. package/dist/types/current/util/async/poll.d.ts.map +1 -0
  48. package/dist/types/current/util/async/poll.js +31 -0
  49. package/dist/types/current/util/async/sleep.d.ts +2 -1
  50. package/dist/types/current/util/async/sleep.d.ts.map +1 -1
  51. package/dist/types/current/util/async/timeout.d.ts +32 -10
  52. package/dist/types/current/util/async/timeout.d.ts.map +1 -1
  53. package/dist/types/current/util/async/timeout.js +7 -11
  54. package/dist/types/current/util/map/map.d.ts +1 -2
  55. package/dist/types/current/util/map/map.d.ts.map +1 -1
  56. package/dist/types/current/util/url/resolveUrl.d.ts +2 -1
  57. package/dist/types/current/util/url/resolveUrl.d.ts.map +1 -1
  58. package/dist/types/current/util/url/resolveUrl.js +9 -3
  59. package/dist/types/ts3.7/event/nextEventAsPromise.d.ts +14 -4
  60. package/dist/types/ts3.7/index.d.ts +114 -113
  61. package/dist/types/ts3.7/util/async/poll.d.ts +34 -0
  62. package/dist/types/ts3.7/util/async/sleep.d.ts +2 -1
  63. package/dist/types/ts3.7/util/async/timeout.d.ts +32 -10
  64. package/dist/types/ts3.7/util/map/map.d.ts +1 -2
  65. package/dist/types/ts3.7/util/url/resolveUrl.d.ts +2 -1
  66. package/dist/types/ts4.1/event/nextEventAsPromise.d.ts +14 -4
  67. package/dist/types/ts4.1/index.d.ts +114 -113
  68. package/dist/types/ts4.1/util/async/poll.d.ts +34 -0
  69. package/dist/types/ts4.1/util/async/sleep.d.ts +2 -1
  70. package/dist/types/ts4.1/util/async/timeout.d.ts +32 -10
  71. package/dist/types/ts4.1/util/map/map.d.ts +1 -2
  72. package/dist/types/ts4.1/util/url/resolveUrl.d.ts +2 -1
  73. package/dist/types/ts4.7/event/nextEventAsPromise.d.ts +14 -4
  74. package/dist/types/ts4.7/index.d.ts +114 -113
  75. package/dist/types/ts4.7/util/async/poll.d.ts +34 -0
  76. package/dist/types/ts4.7/util/async/sleep.d.ts +2 -1
  77. package/dist/types/ts4.7/util/async/timeout.d.ts +32 -10
  78. package/dist/types/ts4.7/util/map/map.d.ts +1 -2
  79. package/dist/types/ts4.7/util/url/resolveUrl.d.ts +2 -1
  80. package/dist/unit/types/current/tsconfig.tsbuildinfo +1 -1
  81. package/package.json +11 -11
@@ -30,475 +30,452 @@
30
30
  };
31
31
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
32
 
33
- // test/browserTestUtil/mock/createSpyFactory.ts
34
- var createSpy = jasmine.createSpy;
35
- function createSpy2(key) {
36
- return createSpy(String(key));
37
- }
33
+ // src/error/ErrorOrigin.ts
34
+ var ErrorOrigin = {
35
+ /**
36
+ * The error originated from Vinyl and was reported from the uncaught exception or promise
37
+ * rejection handlers.
38
+ */
39
+ UNCAUGHT: "uncaught",
40
+ /**
41
+ * The error originated from Vinyl and was caught.
42
+ */
43
+ INTERNAL: "internal",
44
+ /**
45
+ * A Vinyl interface was used incorrectly by a consumer.
46
+ */
47
+ API: "api",
48
+ /**
49
+ * The error originated from a failed service call (500 errors).
50
+ */
51
+ SERVICE_EXTERNAL: "serviceExternal",
52
+ /**
53
+ * The error originated from a failed service call (400 errors).
54
+ */
55
+ SERVICE_INTERNAL: "serviceInternal",
56
+ /**
57
+ * The error originated from a problem playing provided media.
58
+ * The reporter is from a component such as the element, source buffer, media source, etc.
59
+ */
60
+ MEDIA: "media",
61
+ /**
62
+ * The error originated from a problem parsing input data.
63
+ * Such as a malformed Dash or HLS manifest.
64
+ */
65
+ PARSING: "parsing",
66
+ /**
67
+ * The error originated from an incompatibility with browser APIs,
68
+ * such as EME.
69
+ */
70
+ COMPATIBILITY: "compatibility",
71
+ /**
72
+ * The error originated from DRM.
73
+ * This does not include internal or service errors, only errors from the creation of media keys or media key
74
+ * sessions.
75
+ */
76
+ DRM: "drm"
77
+ };
38
78
 
39
- // test/browserTestUtil/mock/dom/lib.dom.ts
40
- var MockAbortSignal = class {
41
- constructor() {
42
- __publicField(this, "aborted", false);
43
- __publicField(this, "onabort", null);
44
- __publicField(this, "reason");
45
- __publicField(this, "throwIfAborted", createSpy2("throwIfAborted"));
46
- __publicField(this, "addEventListener", createSpy2("addEventListener"));
47
- __publicField(this, "removeEventListener", createSpy2(
48
- "removeEventListener"
49
- ));
50
- __publicField(this, "dispatchEvent", createSpy2("dispatchEvent"));
79
+ // src/error/ReportableError.ts
80
+ var ReportableError = class _ReportableError extends Error {
81
+ constructor(message, origin = ErrorOrigin.INTERNAL, level = "fatal" /* FATAL */) {
82
+ super(message);
83
+ __publicField(this, "origin", origin);
84
+ __publicField(this, "level", level);
85
+ Object.setPrototypeOf(this, _ReportableError.prototype);
51
86
  }
52
- };
53
- var MockMediaSource = class {
54
- constructor() {
55
- __publicField(this, "activeSourceBuffers");
56
- __publicField(this, "duration", 0);
57
- __publicField(this, "onsourceclose", null);
58
- __publicField(this, "onsourceended", null);
59
- __publicField(this, "onsourceopen", null);
60
- __publicField(this, "readyState", "closed");
61
- __publicField(this, "sourceBuffers");
62
- __publicField(this, "addSourceBuffer", createSpy2("addSourceBuffer"));
63
- __publicField(this, "clearLiveSeekableRange", createSpy2(
64
- "clearLiveSeekableRange"
65
- ));
66
- __publicField(this, "endOfStream", createSpy2("endOfStream"));
67
- __publicField(this, "removeSourceBuffer", createSpy2("removeSourceBuffer"));
68
- __publicField(this, "setLiveSeekableRange", createSpy2(
69
- "setLiveSeekableRange"
70
- ));
71
- __publicField(this, "addEventListener", createSpy2("addEventListener"));
72
- __publicField(this, "removeEventListener", createSpy2(
73
- "removeEventListener"
74
- ));
75
- __publicField(this, "dispatchEvent", createSpy2("dispatchEvent"));
87
+ get [Symbol.toStringTag]() {
88
+ return "ReportableError";
89
+ }
90
+ get name() {
91
+ return this[Symbol.toStringTag];
92
+ }
93
+ /**
94
+ * All ReportableError instances must be serializable.
95
+ */
96
+ toJSON() {
97
+ return {
98
+ level: this.level,
99
+ message: this.message,
100
+ name: this.name,
101
+ origin: this.origin,
102
+ stack: this.stack
103
+ };
76
104
  }
77
105
  };
78
106
 
79
- // test/browserTestUtil/mock/dom/globals.ts
80
- var MockMediaSourceGlobal = class extends MockMediaSource {
81
- };
82
- __publicField(MockMediaSourceGlobal, "canConstructInDedicatedWorker", false);
83
- __publicField(MockMediaSourceGlobal, "isTypeSupported", createSpy2(
84
- "isTypeSupported"
85
- ));
86
- var MockAbortSignalGlobal = class extends MockAbortSignal {
107
+ // src/error/IllegalArgumentError.ts
108
+ var IllegalArgumentError = class _IllegalArgumentError extends ReportableError {
109
+ constructor(message, isInternal = true) {
110
+ super(message, isInternal ? ErrorOrigin.INTERNAL : ErrorOrigin.API);
111
+ __publicField(this, "isInternal", isInternal);
112
+ Object.setPrototypeOf(this, _IllegalArgumentError.prototype);
113
+ }
114
+ get [Symbol.toStringTag]() {
115
+ return "IllegalArgumentError";
116
+ }
87
117
  };
88
- __publicField(MockAbortSignalGlobal, "abort", createSpy2("abort"));
89
- __publicField(MockAbortSignalGlobal, "any", createSpy2("any"));
90
- __publicField(MockAbortSignalGlobal, "timeout", createSpy2("timeout"));
91
-
92
- // test/browserTestUtil/expect/expectNothing.ts
93
- function expectNothing() {
94
- expect(true).toBeTruthy();
95
- }
96
-
97
- // test/browserTestUtil/env/jasmineEnv.ts
98
- var nextTestTimeoutOverridden = false;
99
- function setTestTimeout(timeout) {
100
- let originalTimeout = null;
101
- beforeEach(() => {
102
- originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
103
- if (!nextTestTimeoutOverridden)
104
- jasmine.DEFAULT_TIMEOUT_INTERVAL = timeout * 1e3;
105
- });
106
- afterEach(() => {
107
- if (originalTimeout) jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
108
- if (nextTestTimeoutOverridden) nextTestTimeoutOverridden = false;
109
- });
110
- }
111
118
 
112
- // test/browserTestUtil/benchmark/Benchmark.ts
113
- var now;
114
- if (typeof window !== "undefined" && typeof window.performance !== "undefined" && typeof window.performance.now !== "undefined") {
115
- now = () => window.performance.now();
116
- } else if (typeof self !== "undefined" && typeof self.performance !== "undefined" && typeof self.performance.now !== "undefined") {
117
- now = () => self.performance.now();
118
- } else {
119
- now = () => Date.now();
120
- }
121
- var BenchmarkRunResults = class {
122
- constructor(name) {
123
- __publicField(this, "name", name);
124
- __publicField(this, "cycleResults", []);
125
- __publicField(this, "_totalSamples", 0);
126
- }
127
- get totalSamples() {
128
- return this._totalSamples;
119
+ // src/util/collection/LinkedList.ts
120
+ var LinkedList = class {
121
+ constructor() {
122
+ __publicField(this, "_head", null);
123
+ __publicField(this, "_tail", null);
129
124
  }
130
- get cycleResultsNoOutliers() {
131
- const sD = this.standardDeviation;
132
- const avg = average(this.cycleResults);
133
- return this.cycleResults.filter((e) => {
134
- const zScore = (avg - e) / sD;
135
- return Math.abs(zScore) < 3;
136
- });
125
+ /**
126
+ * Returns the current head.
127
+ */
128
+ get head() {
129
+ return this._head;
137
130
  }
138
131
  /**
139
- * Returns the mean ops per second minus outliers of greater than 3 standard deviations.
132
+ * Returns the current tail.
140
133
  */
141
- get meanOpsPerSec() {
142
- return average(this.cycleResultsNoOutliers);
134
+ get tail() {
135
+ return this._tail;
143
136
  }
144
- get standardDeviation() {
145
- return standardDeviation(this.cycleResults);
137
+ /**
138
+ * Returns true if the list is empty.
139
+ */
140
+ get empty() {
141
+ return this._head === null;
146
142
  }
147
- get variance() {
148
- return this.standardDeviation / this.meanOpsPerSec;
143
+ /**
144
+ * Creates a new node for the given value, adding it to the end of the list.
145
+ *
146
+ * @param value
147
+ * @return Returns the newly created node.
148
+ */
149
+ push(value) {
150
+ const node = {
151
+ previous: this._tail,
152
+ value,
153
+ removed: false,
154
+ next: null
155
+ };
156
+ this.pushNode(node);
157
+ return node;
149
158
  }
150
159
  /**
151
- * Returns the mean ops / s ± variance % as a string.
160
+ * Appends all given values to the end of this list.
161
+ *
162
+ * @param values
152
163
  */
153
- get meanOpsStr() {
154
- const mean = this.meanOpsPerSec.toLocaleString(void 0, {
155
- maximumSignificantDigits: 4
156
- });
157
- const variance = this.variance.toLocaleString(void 0, {
158
- style: "percent"
159
- });
160
- return `${mean} \xB1${variance}`;
164
+ pushAll(...values) {
165
+ for (const value of values) {
166
+ this.push(value);
167
+ }
161
168
  }
162
- add(cycle) {
163
- const opsPerSecond = cycle.ops / cycle.duration;
164
- let index = this.cycleResults.findIndex((value) => opsPerSecond < value);
165
- if (index < 0) index = this.cycleResults.length;
166
- this.cycleResults.splice(index, 0, opsPerSecond);
167
- this._totalSamples += cycle.ops;
169
+ /**
170
+ * Appends the given node to the tail of this list.
171
+ * If the node is already at the tail, it will no-op.
172
+ * If the node is in this list, it will be removed.
173
+ *
174
+ * @param node The node to add or move to the tail of this list.
175
+ */
176
+ pushNode(node) {
177
+ if (this._tail === node) return;
178
+ this.remove(node);
179
+ node.removed = false;
180
+ node.next = null;
181
+ node.previous = this._tail;
182
+ if (this._tail) this._tail.next = node;
183
+ this._tail = node;
184
+ if (!this._head) this._head = node;
168
185
  }
169
- toString() {
170
- if (!this.cycleResults.length) return "No results";
171
- return `${this.name}: ${this.meanOpsStr} ops/sec`;
172
- }
173
- };
174
- var RunResultsComparison = class {
175
- constructor(name, results) {
176
- __publicField(this, "name", name);
177
- /**
178
- * Sorted by median ops/s from slowest to fastest.
179
- */
180
- __publicField(this, "results");
181
- this.results = results.sort((a, b) => {
182
- return a.meanOpsPerSec - b.meanOpsPerSec;
183
- });
186
+ /**
187
+ * Removes the last node (the tail), returning it.
188
+ * If this list is empty, null is returned.
189
+ */
190
+ pop() {
191
+ const node = this._tail;
192
+ if (!node) return null;
193
+ this.remove(node);
194
+ return node;
184
195
  }
185
- logToTable() {
186
- const r = this.results.map((run) => {
187
- const variance = run.variance.toLocaleString(void 0, {
188
- style: "percent"
189
- });
190
- const mean = run.meanOpsPerSec.toLocaleString(void 0, {
191
- maximumSignificantDigits: 4
192
- });
193
- return {
194
- Name: run.name,
195
- Mean: `${mean} \xB1${variance}`,
196
- Samples: run.totalSamples,
197
- Compare: this.runComparisonToString(run)
198
- };
199
- });
200
- const table = r.reduce((acc, _a) => {
201
- var _b = _a, { Name } = _b, x = __objRest(_b, ["Name"]);
202
- acc[Name] = x;
203
- return acc;
204
- }, {});
205
- console.log("\n" + this.name);
206
- console.table(table);
196
+ /**
197
+ * Creates a new node, adding it to the front of the list.
198
+ *
199
+ * @param value The value to box in a linked node.
200
+ * @return Returns the new node.
201
+ */
202
+ unshift(value) {
203
+ const node = {
204
+ previous: null,
205
+ value,
206
+ removed: true,
207
+ next: this._head
208
+ };
209
+ this.unshiftNode(node);
210
+ return node;
207
211
  }
208
- runComparisonToString(run) {
209
- var _a, _b;
210
- const baseline = (_b = (_a = this.results[0]) == null ? void 0 : _a.meanOpsPerSec) != null ? _b : 0;
211
- const fasterPercent = run.meanOpsPerSec / baseline - 1;
212
- return fasterPercent < 0.01 ? "-" : fasterPercent.toLocaleString(void 0, {
213
- style: "percent"
214
- }) + " faster";
212
+ /**
213
+ * Prepends all the given values to the head of this list.
214
+ * The values will maintain their order.
215
+ *
216
+ * E.g.
217
+ * ```
218
+ * list.unshiftAll(8, 9, 10) // 8, 9, 10
219
+ * list.unshiftAll(4, 5, 6, 7) // 4, 5, 6, 7, 8, 9, 10
220
+ * list.unshiftAll(1, 2, 3) // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
221
+ * ```
222
+ *
223
+ * @param values The values to box in linked nodes.
224
+ */
225
+ unshiftAll(...values) {
226
+ for (let i = values.length - 1; i >= 0; i--) {
227
+ this.unshift(values[i]);
228
+ }
215
229
  }
216
- };
217
- function compareResults(name, ...results) {
218
- return new RunResultsComparison(name, results);
219
- }
220
- var defaultBenchmarkOptions = {
221
- warmupTime: 0.5,
222
- maxCycleDuration: 0.5,
223
- cycles: 9
224
- };
225
- var _Benchmark = class _Benchmark {
226
230
  /**
227
- * Constructs a new Benchmark.
231
+ * Prepends the given node to the head of this list.
232
+ * - If the node is already at the head, it will no-op.
233
+ * - If the node is in this list, it will be removed.
228
234
  *
229
- * @param name The name of the benchmark, to be used when logging.
230
- * @param executor The method to execute and measure. If this method returns a promise, the
231
- * promise will be awaited. The executor should either always return a promise, or never.
232
- * @param options Optional configuration for the benchmark.
235
+ * @param node The node to add or move to the head of this list.
233
236
  */
234
- constructor(name, executor, options) {
235
- __publicField(this, "name", name);
236
- __publicField(this, "executor", executor);
237
- __publicField(this, "options");
238
- this.options = __spreadValues(__spreadValues({}, defaultBenchmarkOptions), options);
237
+ unshiftNode(node) {
238
+ if (this._head === node) return;
239
+ this.remove(node);
240
+ node.removed = false;
241
+ node.previous = null;
242
+ node.next = this._head;
243
+ if (this._head) this._head.previous = node;
244
+ this._head = node;
245
+ if (!this._tail) this._tail = node;
239
246
  }
240
- async run() {
241
- const opts = this.options;
242
- await _Benchmark.semaphore;
243
- const warmupTimeMs = opts.warmupTime * 1e3;
244
- const cycleStart = now();
245
- let isAsync = false;
246
- do {
247
- const result = this.executor();
248
- isAsync = isAsync || result && typeof result.then === "function";
249
- if (isAsync) await result;
250
- } while (now() - cycleStart < warmupTimeMs);
251
- const resultsPromise = (async () => {
252
- const results = new BenchmarkRunResults(this.name);
253
- for (let i = 0; i < opts.cycles; i++) {
254
- const cycleResults = await this.runCycle(isAsync);
255
- results.add(cycleResults);
256
- await nextFrame();
257
- }
258
- return results;
259
- })();
260
- _Benchmark.semaphore = resultsPromise;
261
- return await resultsPromise;
247
+ /**
248
+ * Removes the first node (the head), returning it.
249
+ * - If this list is empty, null is returned.
250
+ */
251
+ shift() {
252
+ const node = this._head;
253
+ if (!node) return null;
254
+ this.remove(node);
255
+ return node;
262
256
  }
263
257
  /**
264
- * Runs one cycle. A cycle will repeat the executor approximately `options.maxCycleDuration`
265
- * seconds.
258
+ * Removes the given linked node.
266
259
  *
267
- * @param isAsync
268
- * @return Returns the duration (in seconds) and number of operations the cycle repeated.
260
+ * @param node
269
261
  */
270
- async runCycle(isAsync) {
271
- const cycleMs = this.options.maxCycleDuration * 1e3;
272
- let ops = 0;
273
- const cycleStart = now();
274
- do {
275
- const result = this.executor();
276
- if (isAsync) await result;
277
- ops++;
278
- } while (now() - cycleStart < cycleMs);
279
- const duration = (now() - cycleStart) / 1e3;
280
- return {
281
- duration,
282
- ops
283
- };
284
- }
285
- };
286
- __publicField(_Benchmark, "semaphore", nextFrame());
287
- var Benchmark = _Benchmark;
288
- function benchmark(name, executor, options) {
289
- const benchmark2 = new Benchmark(name, executor, options);
290
- return benchmark2.run().then((results) => {
291
- console.log(results.toString());
292
- return results;
293
- });
294
- }
295
- function nextFrame() {
296
- return new Promise((resolve) => {
297
- setTimeout(resolve);
298
- });
299
- }
300
- function standardDeviation(values) {
301
- const avg = average(values);
302
- const squareDiffs = values.map((value) => {
303
- const diff = value - avg;
304
- return diff * diff;
305
- });
306
- const avgSquareDiff = average(squareDiffs);
307
- return Math.sqrt(avgSquareDiff);
308
- }
309
- function average(values) {
310
- const sum = values.reduce((acc, value) => acc + value, 0);
311
- return sum / values.length;
312
- }
313
-
314
- // test/benchmark/setup.ts
315
- function setupBenchmark() {
316
- setTestTimeout(180);
317
- afterEach(expectNothing);
318
- }
319
- var comparisons = [];
320
- function addComparison(comparison) {
321
- comparisons.push(comparison);
322
- }
323
- function addBenchmarks(name, ...results) {
324
- const comparison = compareResults(name, ...results);
325
- comparison.logToTable();
326
- comparisons.push(comparison);
327
- }
328
- if (typeof document !== "undefined") {
329
- jasmine.getEnv().addReporter({
330
- jasmineDone: () => {
331
- var _a;
332
- console.log("Tests complete");
333
- const jasmineContainer = document.getElementsByClassName(
334
- "jasmine_html-reporter"
335
- )[0];
336
- (_a = jasmineContainer.parentElement) == null ? void 0 : _a.removeChild(jasmineContainer);
337
- const container = createEl("div", document.body);
338
- container.id = "benchmarkResults";
339
- const sortedComparisons = [...comparisons].sort(
340
- (a, b) => a.name > b.name ? 1 : -1
341
- );
342
- for (const comparison of sortedComparisons) {
343
- toTableHtml(comparison, container);
344
- }
345
- }
346
- });
347
- }
348
- function toTableHtml(comparison, parent) {
349
- const container = createEl("div", parent);
350
- container.className = "benchmarkComparison";
351
- const title = createEl("h2", container);
352
- title.innerText = comparison.name;
353
- const table = createEl("table", container);
354
- const head = createEl("thead", table);
355
- const headRow = createEl("tr", head);
356
- const name = createEl("th", headRow);
357
- name.innerText = "Name";
358
- const median = createEl("th", headRow);
359
- median.innerText = "Mean ops/s";
360
- const samples = createEl("th", headRow);
361
- samples.innerText = "Samples";
362
- const compare = createEl("th", headRow);
363
- compare.innerText = "% Comparison";
364
- const body = createEl("tbody", table);
365
- comparison.results.forEach((result) => {
366
- const row = createEl("tr", body);
367
- createEl("th", row).innerText = result.name;
368
- createEl("td", row).innerText = result.meanOpsStr;
369
- createEl("td", row).innerText = result.totalSamples.toLocaleString();
370
- createEl("td", row).innerText = comparison.runComparisonToString(result);
371
- });
372
- return container;
373
- }
374
- function createEl(tagName, parent, options) {
375
- const element = document.createElement(tagName, options);
376
- if (parent) parent.appendChild(element);
377
- return element;
378
- }
379
-
380
- // src/util/type.ts
381
- function covariant() {
382
- return void 0;
383
- }
384
-
385
- // src/util/url/resolveUrl.ts
386
- function resolveUrl(relative, base) {
387
- if (relative.indexOf("://") > 0) return relative;
388
- if (relative.startsWith("//")) {
389
- const schemeEnd2 = base.indexOf("://");
390
- return base.substring(0, schemeEnd2 + 1) + relative;
262
+ remove(node) {
263
+ if (node.removed) return;
264
+ node.removed = true;
265
+ if (node.previous) node.previous.next = node.next;
266
+ if (node.next) node.next.previous = node.previous;
267
+ if (this._head === node) this._head = node.next;
268
+ if (this._tail === node) this._tail = node.previous;
391
269
  }
392
- const schemeEnd = base.indexOf("://") + 3;
393
- const pathStart = base.indexOf("/", schemeEnd);
394
- const origin = pathStart === -1 ? base : base.substring(0, pathStart);
395
- if (relative.startsWith("/")) return origin + relative;
396
- if (relative === "") return base;
397
- const basePath = pathStart === -1 ? "/" : base.substring(pathStart);
398
- const lastSlash = basePath.lastIndexOf("/");
399
- const dir = basePath.substring(0, lastSlash + 1);
400
- return origin + resolveDots(dir + relative);
401
- }
402
- function resolveDots(path) {
403
- if (path.indexOf(".") === -1) return path;
404
- const parts = path.split("/");
405
- const out = [];
406
- for (let i = 0; i < parts.length; i++) {
407
- const p = parts[i];
408
- if (p === "..") {
409
- if (out.length > 1) out.pop();
410
- } else if (p !== ".") {
411
- out.push(p);
270
+ /**
271
+ * Inserts the given node before pointer node.
272
+ *
273
+ * @param node The node to insert before pointer. If this node is currently in this list, it
274
+ * will first be removed.
275
+ * @param pointer The pointer node.
276
+ */
277
+ insertNodeBefore(node, pointer) {
278
+ if (!node.removed && node.next === pointer) return;
279
+ this.remove(node);
280
+ node.removed = false;
281
+ if (pointer.previous) {
282
+ pointer.previous.next = node;
283
+ node.previous = pointer.previous;
284
+ } else {
285
+ this._head = node;
286
+ node.previous = null;
412
287
  }
288
+ node.next = pointer;
289
+ pointer.previous = node;
413
290
  }
414
- return out.join("/");
415
- }
416
-
417
- // src/error/ErrorOrigin.ts
418
- var ErrorOrigin = {
419
291
  /**
420
- * The error originated from Vinyl and was reported from the uncaught exception or promise
421
- * rejection handlers.
292
+ * Inserts the given node after pointer node.
293
+ *
294
+ * @param node The node to insert after pointer. If this node is currently in this list, it
295
+ * will first be removed.
296
+ * @param pointer The pointer node.
422
297
  */
423
- UNCAUGHT: "uncaught",
298
+ insertNodeAfter(node, pointer) {
299
+ if (!node.removed && node.previous === pointer) return;
300
+ this.remove(node);
301
+ node.removed = false;
302
+ if (pointer.next) {
303
+ pointer.next.previous = node;
304
+ node.next = pointer.next;
305
+ } else {
306
+ this._tail = node;
307
+ node.next = null;
308
+ }
309
+ node.previous = pointer;
310
+ pointer.next = node;
311
+ }
424
312
  /**
425
- * The error originated from Vinyl and was caught.
313
+ * Iterates over every element, invoking the given callback.
314
+ *
315
+ * @param callback
426
316
  */
427
- INTERNAL: "internal",
317
+ forEach(callback) {
318
+ let current = this._head;
319
+ while (current) {
320
+ if (!current.removed) callback(current.value);
321
+ current = current.next;
322
+ }
323
+ }
428
324
  /**
429
- * A Vinyl interface was used incorrectly by a consumer.
325
+ * Similar to `Array.prototype.some`, returns true if at least one element passes the given
326
+ * predicate.
327
+ *
328
+ * @param predicate
430
329
  */
431
- API: "api",
330
+ some(predicate) {
331
+ let current = this._head;
332
+ while (current) {
333
+ if (!current.removed && predicate(current.value)) return true;
334
+ current = current.next;
335
+ }
336
+ return false;
337
+ }
432
338
  /**
433
- * The error originated from a failed service call (500 errors).
339
+ * Returns the first node matching the given predicate.
340
+ *
341
+ * @param predicate A function where, when true is returned, returns the current node.
434
342
  */
435
- SERVICE_EXTERNAL: "serviceExternal",
343
+ find(predicate) {
344
+ let current = this._head;
345
+ while (current) {
346
+ if (!current.removed && predicate(current.value)) return current;
347
+ current = current.next;
348
+ }
349
+ return null;
350
+ }
436
351
  /**
437
- * The error originated from a failed service call (400 errors).
352
+ * Returns the last node matching the given predicate.
353
+ *
354
+ * @param predicate A function where, when true is returned, returns the current node.
438
355
  */
439
- SERVICE_INTERNAL: "serviceInternal",
356
+ findLast(predicate) {
357
+ let current = this._tail;
358
+ while (current) {
359
+ if (!current.removed && predicate(current.value)) return current;
360
+ current = current.previous;
361
+ }
362
+ return null;
363
+ }
440
364
  /**
441
- * The error originated from a problem playing provided media.
442
- * The reporter is from a component such as the element, source buffer, media source, etc.
365
+ * Clears this list.
443
366
  */
444
- MEDIA: "media",
367
+ clear() {
368
+ let current = this._head;
369
+ while (current != null) {
370
+ const next = current.next;
371
+ current.removed = true;
372
+ current = next;
373
+ }
374
+ this._head = null;
375
+ this._tail = null;
376
+ }
445
377
  /**
446
- * The error originated from a problem parsing input data.
447
- * Such as a malformed Dash or HLS manifest.
378
+ * Returns a new iterator, starting at the head.
448
379
  */
449
- PARSING: "parsing",
380
+ [Symbol.iterator]() {
381
+ return this.createIterator(this._head, null, (node) => node.next);
382
+ }
450
383
  /**
451
- * The error originated from an incompatibility with browser APIs,
452
- * such as EME.
384
+ * Returns a new reversed iterable where the iterator starts at the tail, moving backwards
385
+ * to the head.
453
386
  */
454
- COMPATIBILITY: "compatibility",
387
+ reversed() {
388
+ return this.createIterator(this._tail, null, (node) => node.previous);
389
+ }
455
390
  /**
456
- * The error originated from DRM.
457
- * This does not include internal or service errors, only errors from the creation of media keys or media key
458
- * sessions.
391
+ * Creates an iterable iterator, starting at the specified node, getting the next node from
392
+ * the next() function.
393
+ *
394
+ * Note that using iterators is not as performant as {@link some} or {@link forEach}
395
+ *
396
+ * @param start The starting node. (inclusive)
397
+ * @param end The ending node (exclusive).
398
+ * @param next A method that is given the current node, and returns the next node.
459
399
  */
460
- DRM: "drm"
400
+ createIterator(start, end, next) {
401
+ let current = start;
402
+ return {
403
+ [Symbol.iterator]() {
404
+ return this;
405
+ },
406
+ next: () => {
407
+ if (current === end || !current) {
408
+ return {
409
+ value: void 0,
410
+ done: true
411
+ };
412
+ }
413
+ const result = {
414
+ value: current.value,
415
+ done: false
416
+ };
417
+ current = next(current);
418
+ while (current == null ? void 0 : current.removed) {
419
+ current = next(current);
420
+ }
421
+ return result;
422
+ }
423
+ };
424
+ }
461
425
  };
462
426
 
463
- // src/error/ReportableError.ts
464
- var ReportableError = class _ReportableError extends Error {
465
- constructor(message, origin = ErrorOrigin.INTERNAL, level = "fatal" /* FATAL */) {
466
- super(message);
467
- __publicField(this, "origin", origin);
468
- __publicField(this, "level", level);
469
- Object.setPrototypeOf(this, _ReportableError.prototype);
427
+ // src/event/Signal.ts
428
+ var SignalImpl = class {
429
+ constructor() {
430
+ __publicField(this, "handlers", new LinkedList());
470
431
  }
471
- get [Symbol.toStringTag]() {
472
- return "ReportableError";
432
+ get empty() {
433
+ return this.handlers.empty;
473
434
  }
474
- get name() {
475
- return this[Symbol.toStringTag];
435
+ listen(handler, options) {
436
+ const remove2 = () => this.handlers.remove(node);
437
+ const node = this.handlers.push(
438
+ (options == null ? void 0 : options.once) ? (event) => {
439
+ remove2();
440
+ handler(event);
441
+ } : handler
442
+ );
443
+ return remove2;
476
444
  }
477
445
  /**
478
- * All ReportableError instances must be serializable.
446
+ * Invokes all handlers, providing the given event.
447
+ *
448
+ * Handlers may add/remove callbacks or do a nested dispatch.
449
+ *
450
+ * If a handler is added within a handler, the new handler will not be invoked until the
451
+ * next dispatch.
452
+ *
453
+ * @param event
479
454
  */
480
- toJSON() {
481
- return {
482
- level: this.level,
483
- message: this.message,
484
- name: this.name,
485
- origin: this.origin,
486
- stack: this.stack
487
- };
455
+ dispatch(event) {
456
+ const handlers = this.handlers;
457
+ const tail = handlers.tail;
458
+ handlers.some((handler) => {
459
+ handler(event);
460
+ return handler === tail.value;
461
+ });
488
462
  }
489
- };
490
-
491
- // src/error/IllegalArgumentError.ts
492
- var IllegalArgumentError = class _IllegalArgumentError extends ReportableError {
493
- constructor(message, isInternal = true) {
494
- super(message, isInternal ? ErrorOrigin.INTERNAL : ErrorOrigin.API);
495
- __publicField(this, "isInternal", isInternal);
496
- Object.setPrototypeOf(this, _IllegalArgumentError.prototype);
463
+ /**
464
+ * Removes all handlers.
465
+ */
466
+ clear() {
467
+ this.handlers.clear();
497
468
  }
498
- get [Symbol.toStringTag]() {
499
- return "IllegalArgumentError";
469
+ /**
470
+ * Same as clear.
471
+ */
472
+ dispose() {
473
+ this.clear();
500
474
  }
501
475
  };
476
+ function signal() {
477
+ return new SignalImpl();
478
+ }
502
479
 
503
480
  // src/util/map/map.ts
504
481
  function getOrSet(map, key, defaultValue) {
@@ -518,510 +495,641 @@
518
495
  return result;
519
496
  }
520
497
 
521
- // src/util/string/string.ts
522
- var locale = {
523
- variableNotDefined: "Variable '{name}' is not defined"
524
- };
525
- var DEFAULT_SUBSTITUTE_PATTERN = /\{(\w+)}/g;
526
- function substitute(str, variables, pattern = DEFAULT_SUBSTITUTE_PATTERN) {
527
- return str.replace(pattern, (_, name) => {
528
- if (!(name in variables)) {
529
- throw new IllegalArgumentError(
530
- locale.variableNotDefined.replace("{name}", String(name))
531
- );
532
- }
533
- return String(variables[name]);
534
- });
498
+ // src/util/type.ts
499
+ function covariant() {
500
+ return void 0;
535
501
  }
536
- var predefinedDecodeEntities = /* @__PURE__ */ new Map([
537
- ["apos", "'"],
538
- ["amp", "&"],
539
- ["lt", "<"],
540
- ["gt", ">"],
541
- ["quot", '"']
542
- ]);
543
- var standardEntityValueToNames = flipMap(predefinedDecodeEntities);
544
502
 
545
- // src/util/set/set.ts
546
- function union(a, b) {
547
- return /* @__PURE__ */ new Set([...a, ...b]);
503
+ // src/logging/LogTarget.ts
504
+ var counter = 0;
505
+ function createLogPrefix(target) {
506
+ const name = typeof target === "string" ? target : target[Symbol.toStringTag];
507
+ return `${name}/${++counter}`;
548
508
  }
549
509
 
550
- // src/util/object/object.ts
551
- function ownKeys(obj) {
552
- if (!obj) return /* @__PURE__ */ new Set();
553
- if (typeof Reflect !== "undefined")
554
- return new Set(Reflect.ownKeys(obj));
555
- const properties = /* @__PURE__ */ new Set();
556
- Object.getOwnPropertyNames(obj).forEach((item) => properties.add(item));
557
- Object.getOwnPropertySymbols(obj).forEach((item) => properties.add(item));
558
- return properties;
559
- }
560
- function isPlainObject(value) {
561
- if (!value || typeof value !== "object" || Array.isArray(value))
510
+ // src/event/EventHost.ts
511
+ var EventHostImpl = class {
512
+ constructor() {
513
+ __publicField(this, "logPrefix", createLogPrefix(this));
514
+ __publicField(this, "signals", /* @__PURE__ */ new Map());
515
+ __publicField(this, "__eventMapType", covariant());
516
+ }
517
+ get [Symbol.toStringTag]() {
518
+ return "EventHostImpl";
519
+ }
520
+ hasAnyListeners() {
521
+ for (const value of this.signals.values()) {
522
+ if (!value.empty) return true;
523
+ }
562
524
  return false;
563
- const proto = Object.getPrototypeOf(value);
564
- return !proto || !Object.getPrototypeOf(proto);
565
- }
566
-
567
- // src/util/serialization/json.ts
568
- function toJson(value) {
569
- return toJsonInternal(value, /* @__PURE__ */ new Set());
570
- }
571
- function toJsonInternal(value, visited) {
572
- switch (typeof value) {
573
- case "object":
574
- return objectToJsonInternal(value, visited);
575
- case "undefined":
576
- case "boolean":
577
- case "number":
578
- case "string":
579
- return value;
580
- case "function":
581
- return `[function ${value.name}]`;
582
- case "symbol":
583
- return `[symbol ${value.toString().slice(7, -1)}]`;
584
- case "bigint":
585
- return value.toString();
586
525
  }
526
+ hasListeners(type) {
527
+ var _a;
528
+ return ((_a = this.signals.get(type)) == null ? void 0 : _a.empty) === false;
529
+ }
530
+ on(type, handler, options) {
531
+ const sig = getOrSet(this.signals, type, () => signal());
532
+ return sig.listen(handler, options);
533
+ }
534
+ dispatch(type, event) {
535
+ var _a;
536
+ (_a = this.signals.get(type)) == null ? void 0 : _a.dispatch(event);
537
+ }
538
+ dispose() {
539
+ for (const signal2 of this.signals.values()) signal2.dispose();
540
+ this.signals.clear();
541
+ }
542
+ };
543
+
544
+ // src/util/collection/array.ts
545
+ function remove(array, element) {
546
+ const index = array.indexOf(element);
547
+ if (index === -1) return false;
548
+ array.splice(index, 1);
549
+ return true;
587
550
  }
588
- function objectToJsonInternal(value, visited) {
589
- if (value == null) return value;
590
- if (visited.has(value)) return `<circular reference: ${String(value)}>`;
591
- visited.add(value);
592
- if ("toJSON" in value && typeof value.toJSON === "function")
593
- return value.toJSON();
594
- if (value instanceof Set) {
595
- return Array.from(value).map((e) => toJsonInternal(e, visited));
596
- } else if (Array.isArray(value)) {
597
- return value.map((e) => toJsonInternal(e, visited));
598
- } else {
599
- if (isPlainObject(value)) {
600
- const o = {};
601
- for (const key in value) {
602
- o[key] = toJsonInternal(value[key], visited);
603
- }
604
- return o;
605
- } else if (value instanceof Error) {
551
+
552
+ // src/util/iteration/iterable.ts
553
+ function mapIter(iterable, transform) {
554
+ const it2 = iterable[Symbol.iterator]();
555
+ return {
556
+ [Symbol.iterator]() {
557
+ return mapIter(iterable, transform);
558
+ },
559
+ next: () => {
560
+ const result = it2.next();
561
+ if (result.done) return result;
606
562
  return {
607
- name: value.name,
608
- message: value.message,
609
- stack: value.stack
563
+ value: transform(result.value),
564
+ done: false
610
565
  };
611
- } else {
612
- return value.toString();
566
+ }
567
+ };
568
+ }
569
+
570
+ // src/error/IllegalStateError.ts
571
+ var IllegalStateError = class _IllegalStateError extends ReportableError {
572
+ get [Symbol.toStringTag]() {
573
+ return "IllegalStateError";
574
+ }
575
+ constructor(message) {
576
+ super(message);
577
+ Object.setPrototypeOf(this, _IllegalStateError.prototype);
578
+ }
579
+ };
580
+
581
+ // src/util/collection/LruCache.ts
582
+ var LruCache = class {
583
+ constructor(initialCapacity) {
584
+ /**
585
+ * A map of the list nodes.
586
+ *
587
+ * @private
588
+ */
589
+ __publicField(this, "cache", /* @__PURE__ */ new Map());
590
+ /**
591
+ * Most recently used elements are at the tail, least recently used are at the head.
592
+ * @private
593
+ */
594
+ __publicField(this, "list", new LinkedList());
595
+ /**
596
+ * An element is about to be removed. Should return true if the element may be evicted,
597
+ * otherwise false.
598
+ * If false is returned for all elements, an IllegalStateError is thrown.
599
+ */
600
+ __publicField(this, "onEvicting", null);
601
+ /**
602
+ * When an element is added when at capacity, the least recently used element will be removed.
603
+ * This callback can be set to be notified with the element being evicted, which may be used
604
+ * for disposal.
605
+ */
606
+ __publicField(this, "onEvict", null);
607
+ __publicField(this, "_capacity", 0);
608
+ this._capacity = initialCapacity;
609
+ }
610
+ get capacity() {
611
+ return this._capacity;
612
+ }
613
+ set capacity(value) {
614
+ this._capacity = value;
615
+ while (this.cache.size > this.capacity) {
616
+ this.evictLeastRecentlyUsed();
613
617
  }
614
618
  }
615
- }
616
-
617
- // src/util/collection/LinkedList.ts
618
- var LinkedList = class {
619
- constructor() {
620
- __publicField(this, "_head", null);
621
- __publicField(this, "_tail", null);
619
+ /**
620
+ * @returns the number of elements in the Map.
621
+ */
622
+ get size() {
623
+ return this.cache.size;
622
624
  }
623
625
  /**
624
- * Returns the current head.
626
+ * @returns boolean indicating whether an element with the specified key exists or not.
625
627
  */
626
- get head() {
627
- return this._head;
628
+ has(key) {
629
+ return this.cache.has(key);
628
630
  }
629
631
  /**
630
- * Returns the current tail.
632
+ * Returns the mapped value for the given key, and moves the element to the most recently
633
+ * used position.
634
+ *
635
+ * @returns Returns the element associated with the given key, or undefined if no such
636
+ * element exists.
631
637
  */
632
- get tail() {
633
- return this._tail;
638
+ get(key) {
639
+ const node = this.cache.get(key);
640
+ if (!node) return void 0;
641
+ this.list.pushNode(node);
642
+ return node.value[1];
634
643
  }
635
644
  /**
636
- * Returns true if the list is empty.
645
+ * Adds a new element with a specified key and value to the Map. If an element with the
646
+ * same key already exists, the element will be updated and position moved to most recently
647
+ * used.
637
648
  */
638
- get empty() {
639
- return this._head === null;
649
+ set(key, value) {
650
+ if (this.has(key)) {
651
+ const node = this.cache.get(key);
652
+ node.value[1] = value;
653
+ this.list.pushNode(node);
654
+ } else {
655
+ const node = this.list.push([key, value]);
656
+ this.cache.set(key, node);
657
+ if (this.cache.size > this.capacity) {
658
+ this.evictLeastRecentlyUsed();
659
+ }
660
+ }
661
+ return this;
662
+ }
663
+ evictLeastRecentlyUsed() {
664
+ var _a, _b, _c;
665
+ let node = this.list.head;
666
+ while (node) {
667
+ const [key2, value2] = node.value;
668
+ const allowed = (_b = (_a = this.onEvicting) == null ? void 0 : _a.call(null, value2, key2, this)) != null ? _b : true;
669
+ if (allowed) break;
670
+ node = node.next;
671
+ }
672
+ if (!node)
673
+ throw new IllegalStateError(
674
+ "onEvicting returned false for all elements"
675
+ );
676
+ const [key, value] = node.value;
677
+ this.list.remove(node);
678
+ this.cache.delete(node.value[0]);
679
+ (_c = this.onEvict) == null ? void 0 : _c.call(null, value, key, this);
640
680
  }
641
681
  /**
642
- * Creates a new node for the given value, adding it to the end of the list.
643
- *
644
- * @param value
645
- * @return Returns the newly created node.
682
+ * Clears all elements from the cache.
646
683
  */
647
- push(value) {
648
- const node = {
649
- previous: this._tail,
650
- value,
651
- removed: false,
652
- next: null
653
- };
654
- this.pushNode(node);
655
- return node;
684
+ clear() {
685
+ this.list.clear();
686
+ this.cache.clear();
656
687
  }
657
688
  /**
658
- * Appends all given values to the end of this list.
659
- *
660
- * @param values
689
+ * @returns true if an element in the Map existed and has been removed, or false if the element does not exist.
661
690
  */
662
- pushAll(...values) {
663
- for (const value of values) {
664
- this.push(value);
665
- }
691
+ delete(key) {
692
+ if (!this.has(key)) return false;
693
+ const node = this.cache.get(key);
694
+ this.cache.delete(key);
695
+ this.list.remove(node);
696
+ return true;
666
697
  }
667
698
  /**
668
- * Appends the given node to the tail of this list.
669
- * If the node is already at the tail, it will no-op.
670
- * If the node is in this list, it will be removed.
699
+ * Executes a provided function once per each key/value pair in the Map, in insertion order.
671
700
  *
672
- * @param node The node to add or move to the tail of this list.
701
+ * @param callback A callback to invoke for every element in the cache.
702
+ * @param thisArg Value to use as this when executing callback
673
703
  */
674
- pushNode(node) {
675
- if (this._tail === node) return;
676
- this.remove(node);
677
- node.removed = false;
678
- node.next = null;
679
- node.previous = this._tail;
680
- if (this._tail) this._tail.next = node;
681
- this._tail = node;
682
- if (!this._head) this._head = node;
704
+ forEach(callback, thisArg) {
705
+ return this.list.forEach((entry) => {
706
+ callback.call(thisArg, entry[1], entry[0], this);
707
+ });
683
708
  }
684
709
  /**
685
- * Removes the last node (the tail), returning it.
686
- * If this list is empty, null is returned.
710
+ * Returns an iterable of key, value pairs for every entry in the map.
687
711
  */
688
- pop() {
689
- const node = this._tail;
690
- if (!node) return null;
691
- this.remove(node);
692
- return node;
712
+ entries() {
713
+ return this[Symbol.iterator]();
693
714
  }
694
715
  /**
695
- * Creates a new node, adding it to the front of the list.
696
- *
697
- * @param value The value to box in a linked node.
698
- * @return Returns the new node.
716
+ * Returns an iterable of keys in the map. This will be ordered from least recently used to
717
+ * most.
699
718
  */
700
- unshift(value) {
701
- const node = {
702
- previous: null,
703
- value,
704
- removed: true,
705
- next: this._head
706
- };
707
- this.unshiftNode(node);
708
- return node;
719
+ keys() {
720
+ return mapIter(this.list, ([key]) => key);
709
721
  }
710
722
  /**
711
- * Prepends all the given values to the head of this list.
712
- * The values will maintain their order.
713
- *
714
- * E.g.
715
- * ```
716
- * list.unshiftAll(8, 9, 10) // 8, 9, 10
717
- * list.unshiftAll(4, 5, 6, 7) // 4, 5, 6, 7, 8, 9, 10
718
- * list.unshiftAll(1, 2, 3) // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
719
- * ```
720
- *
721
- * @param values The values to box in linked nodes.
723
+ * Returns an iterable of values in the map. This will be ordered from least recently used to
724
+ * most.
722
725
  */
723
- unshiftAll(...values) {
724
- for (let i = values.length - 1; i >= 0; i--) {
725
- this.unshift(values[i]);
726
+ values() {
727
+ return mapIter(this.list, ([, value]) => value);
728
+ }
729
+ [Symbol.iterator]() {
730
+ return this.list[Symbol.iterator]();
731
+ }
732
+ get [Symbol.toStringTag]() {
733
+ return "LruCache";
734
+ }
735
+ };
736
+
737
+ // src/util/fun/memoize.ts
738
+ function memoize(inner, keyProvider, capacity = 500) {
739
+ if (!keyProvider) {
740
+ let cached = false;
741
+ let value = void 0;
742
+ const memoized = () => {
743
+ if (!cached) {
744
+ cached = true;
745
+ value = inner();
746
+ }
747
+ return value;
748
+ };
749
+ return Object.assign(
750
+ memoized,
751
+ {
752
+ clear: () => {
753
+ cached = false;
754
+ value = void 0;
755
+ }
756
+ }
757
+ );
758
+ } else if (capacity === 0) {
759
+ const memoized = (...args) => inner(...args);
760
+ return Object.assign(
761
+ memoized,
762
+ {
763
+ clear: () => {
764
+ }
765
+ }
766
+ );
767
+ } else if (capacity === 1) {
768
+ let hasValue = false;
769
+ let cachedKey;
770
+ let cachedValue;
771
+ const memoized = (...args) => {
772
+ const key = keyProvider(...args);
773
+ if (!hasValue || cachedKey !== key) {
774
+ hasValue = true;
775
+ cachedKey = key;
776
+ cachedValue = inner(...args);
777
+ }
778
+ return cachedValue;
779
+ };
780
+ return Object.assign(
781
+ memoized,
782
+ {
783
+ clear: () => {
784
+ hasValue = false;
785
+ }
786
+ }
787
+ );
788
+ } else {
789
+ const cache = new LruCache(capacity);
790
+ const memoized = (...args) => {
791
+ const key = keyProvider(...args);
792
+ return getOrSet(cache, key, () => inner(...args));
793
+ };
794
+ return Object.assign(
795
+ memoized,
796
+ {
797
+ clear: () => {
798
+ cache.clear();
799
+ }
800
+ }
801
+ );
802
+ }
803
+ }
804
+
805
+ // src/util/string/string.ts
806
+ var locale = {
807
+ variableNotDefined: "Variable '{name}' is not defined"
808
+ };
809
+ var DEFAULT_SUBSTITUTE_PATTERN = /\{(\w+)}/g;
810
+ function substitute(str, variables, pattern = DEFAULT_SUBSTITUTE_PATTERN) {
811
+ return str.replace(pattern, (_, name) => {
812
+ if (!(name in variables)) {
813
+ throw new IllegalArgumentError(
814
+ locale.variableNotDefined.replace("{name}", String(name))
815
+ );
726
816
  }
817
+ return String(variables[name]);
818
+ });
819
+ }
820
+ var predefinedDecodeEntities = /* @__PURE__ */ new Map([
821
+ ["apos", "'"],
822
+ ["amp", "&"],
823
+ ["lt", "<"],
824
+ ["gt", ">"],
825
+ ["quot", '"']
826
+ ]);
827
+ var standardEntityValueToNames = flipMap(predefinedDecodeEntities);
828
+
829
+ // src/core/disposable.ts
830
+ function isDisposable(value) {
831
+ return value != null && typeof value.dispose === "function" && value.dispose.length === 0;
832
+ }
833
+
834
+ // src/global/globalRegistry.ts
835
+ var GlobalRegistry = class {
836
+ constructor() {
837
+ __publicField(this, "registry", []);
727
838
  }
728
839
  /**
729
- * Prepends the given node to the head of this list.
730
- * - If the node is already at the head, it will no-op.
731
- * - If the node is in this list, it will be removed.
732
- *
733
- * @param node The node to add or move to the head of this list.
840
+ * Returns the number of references currently in the registry.
734
841
  */
735
- unshiftNode(node) {
736
- if (this._head === node) return;
737
- this.remove(node);
738
- node.removed = false;
739
- node.previous = null;
740
- node.next = this._head;
741
- if (this._head) this._head.previous = node;
742
- this._head = node;
743
- if (!this._tail) this._tail = node;
842
+ get size() {
843
+ return this.registry.length;
744
844
  }
745
845
  /**
746
- * Removes the first node (the head), returning it.
747
- * - If this list is empty, null is returned.
846
+ * Registers an initializer that will be invoked during global state initialization.
847
+ * @param initializer
748
848
  */
749
- shift() {
750
- const node = this._head;
751
- if (!node) return null;
752
- this.remove(node);
753
- return node;
849
+ register(initializer) {
850
+ this.registry.push(initializer);
851
+ return initializer;
754
852
  }
755
853
  /**
756
- * Removes the given linked node.
757
- *
758
- * @param node
854
+ * Removes a global ref from the registry.
855
+ * May be called at any time.
856
+ * @param ref
857
+ * @return Returns true if the global ref was removed.
759
858
  */
760
- remove(node) {
761
- if (node.removed) return;
762
- node.removed = true;
763
- if (node.previous) node.previous.next = node.next;
764
- if (node.next) node.next.previous = node.previous;
765
- if (this._head === node) this._head = node.next;
766
- if (this._tail === node) this._tail = node.previous;
859
+ unregister(ref) {
860
+ return remove(this.registry, ref);
767
861
  }
768
862
  /**
769
- * Inserts the given node before pointer node.
770
- *
771
- * @param node The node to insert before pointer. If this node is currently in this list, it
772
- * will first be removed.
773
- * @param pointer The pointer node.
863
+ * Resets all registered initializers and sets this registry back to its pre-initialized state.
864
+ * This is typically only done within unit tests, but may be called if all players are
865
+ * disposed and the consumer intends to teardown global state.
774
866
  */
775
- insertNodeBefore(node, pointer) {
776
- if (!node.removed && node.next === pointer) return;
777
- this.remove(node);
778
- node.removed = false;
779
- if (pointer.previous) {
780
- pointer.previous.next = node;
781
- node.previous = pointer.previous;
782
- } else {
783
- this._head = node;
784
- node.previous = null;
867
+ reset() {
868
+ for (const registryElement of this.registry) {
869
+ registryElement.reset();
785
870
  }
786
- node.next = pointer;
787
- pointer.previous = node;
788
871
  }
789
- /**
790
- * Inserts the given node after pointer node.
791
- *
792
- * @param node The node to insert after pointer. If this node is currently in this list, it
793
- * will first be removed.
794
- * @param pointer The pointer node.
795
- */
796
- insertNodeAfter(node, pointer) {
797
- if (!node.removed && node.previous === pointer) return;
798
- this.remove(node);
799
- node.removed = false;
800
- if (pointer.next) {
801
- pointer.next.previous = node;
802
- node.next = pointer.next;
803
- } else {
804
- this._tail = node;
805
- node.next = null;
806
- }
807
- node.previous = pointer;
808
- pointer.next = node;
872
+ };
873
+ var _registry = null;
874
+ function getGlobalRegistry() {
875
+ if (!_registry) _registry = new GlobalRegistry();
876
+ return _registry;
877
+ }
878
+ var globalRefDebug = false;
879
+ var GlobalRefImpl = class {
880
+ constructor(defaultInitializer) {
881
+ __publicField(this, "defaultInitializer", defaultInitializer);
882
+ __publicField(this, "_value");
883
+ __publicField(this, "_initialized", false);
884
+ __publicField(this, "constructing", false);
885
+ __publicField(this, "initializer");
886
+ __publicField(this, "lastInitStack", null);
887
+ this.initializer = defaultInitializer;
809
888
  }
810
- /**
811
- * Iterates over every element, invoking the given callback.
812
- *
813
- * @param callback
814
- */
815
- forEach(callback) {
816
- let current = this._head;
817
- while (current) {
818
- if (!current.removed) callback(current.value);
819
- current = current.next;
820
- }
889
+ get initialized() {
890
+ return this._initialized;
821
891
  }
822
- /**
823
- * Similar to `Array.prototype.some`, returns true if at least one element passes the given
824
- * predicate.
825
- *
826
- * @param predicate
827
- */
828
- some(predicate) {
829
- let current = this._head;
830
- while (current) {
831
- if (!current.removed && predicate(current.value)) return true;
832
- current = current.next;
833
- }
834
- return false;
892
+ get value() {
893
+ this.initialize();
894
+ return this._value;
835
895
  }
836
- /**
837
- * Returns the first node matching the given predicate.
838
- *
839
- * @param predicate A function where, when true is returned, returns the current node.
840
- */
841
- find(predicate) {
842
- let current = this._head;
843
- while (current) {
844
- if (!current.removed && predicate(current.value)) return current;
845
- current = current.next;
896
+ reset() {
897
+ this.initializer = this.defaultInitializer;
898
+ if (!this._initialized) return;
899
+ this.assertNotConstructing();
900
+ this._initialized = false;
901
+ this.lastInitStack = null;
902
+ if (isDisposable(this._value)) {
903
+ this._value.dispose();
846
904
  }
847
- return null;
905
+ this._value = void 0;
848
906
  }
849
- /**
850
- * Returns the last node matching the given predicate.
851
- *
852
- * @param predicate A function where, when true is returned, returns the current node.
853
- */
854
- findLast(predicate) {
855
- let current = this._tail;
856
- while (current) {
857
- if (!current.removed && predicate(current.value)) return current;
858
- current = current.previous;
907
+ initialize() {
908
+ if (this._initialized) return;
909
+ this.assertNotConstructing();
910
+ this.constructing = true;
911
+ try {
912
+ this._value = this.initializer();
913
+ } catch (error) {
914
+ this.constructing = false;
915
+ throw error;
859
916
  }
860
- return null;
861
- }
862
- /**
863
- * Clears this list.
864
- */
865
- clear() {
866
- let current = this._head;
867
- while (current != null) {
868
- const next = current.next;
869
- current.removed = true;
870
- current = next;
917
+ this.constructing = false;
918
+ this._initialized = true;
919
+ if (globalRefDebug) {
920
+ this.lastInitStack = new Error("globalRef initialized").stack;
871
921
  }
872
- this._head = null;
873
- this._tail = null;
874
- }
875
- /**
876
- * Returns a new iterator, starting at the head.
877
- */
878
- [Symbol.iterator]() {
879
- return this.createIterator(this._head, null, (node) => node.next);
880
- }
881
- /**
882
- * Returns a new reversed iterable where the iterator starts at the tail, moving backwards
883
- * to the head.
884
- */
885
- reversed() {
886
- return this.createIterator(this._tail, null, (node) => node.previous);
887
922
  }
888
- /**
889
- * Creates an iterable iterator, starting at the specified node, getting the next node from
890
- * the next() function.
891
- *
892
- * Note that using iterators is not as performant as {@link some} or {@link forEach}
893
- *
894
- * @param start The starting node. (inclusive)
895
- * @param end The ending node (exclusive).
896
- * @param next A method that is given the current node, and returns the next node.
897
- */
898
- createIterator(start, end, next) {
899
- let current = start;
900
- return {
901
- [Symbol.iterator]() {
902
- return this;
903
- },
904
- next: () => {
905
- if (current === end || !current) {
906
- return {
907
- value: void 0,
908
- done: true
909
- };
910
- }
911
- const result = {
912
- value: current.value,
913
- done: false
914
- };
915
- current = next(current);
916
- while (current == null ? void 0 : current.removed) {
917
- current = next(current);
918
- }
919
- return result;
920
- }
923
+ set(newInitializer) {
924
+ this.assertNotInitialized();
925
+ const overriddenInitializer = () => {
926
+ return newInitializer(this.defaultInitializer);
921
927
  };
928
+ this.initializer = overriddenInitializer;
929
+ return new GlobalRefOverride(
930
+ this,
931
+ overriddenInitializer,
932
+ (newInitializer2) => {
933
+ this.initializer = newInitializer2;
934
+ }
935
+ );
936
+ }
937
+ assertNotInitialized() {
938
+ if (this._initialized) {
939
+ const detail = this.lastInitStack ? `
940
+ Last initialized at:
941
+ ${this.lastInitStack}` : "";
942
+ throw new IllegalStateError(`Cannot call when initialized${detail}`);
943
+ }
944
+ }
945
+ assertNotConstructing() {
946
+ if (this.constructing)
947
+ throw new IllegalStateError("Cannot call during construction");
922
948
  }
923
949
  };
924
-
925
- // src/event/Signal.ts
926
- var SignalImpl = class {
927
- constructor() {
928
- __publicField(this, "handlers", new LinkedList());
950
+ var GlobalRefOverride = class _GlobalRefOverride {
951
+ constructor(original, defaultInitializer, setInitializer) {
952
+ __publicField(this, "original", original);
953
+ __publicField(this, "defaultInitializer", defaultInitializer);
954
+ __publicField(this, "setInitializer", setInitializer);
955
+ __publicField(this, "initializer");
956
+ this.initializer = defaultInitializer;
929
957
  }
930
- get empty() {
931
- return this.handlers.empty;
958
+ get initialized() {
959
+ return this.original.initialized;
932
960
  }
933
- listen(handler, options) {
934
- const remove2 = () => this.handlers.remove(node);
935
- const node = this.handlers.push(
936
- (options == null ? void 0 : options.once) ? (event) => {
937
- remove2();
938
- handler(event);
939
- } : handler
940
- );
941
- return remove2;
961
+ get value() {
962
+ return this.original.value;
942
963
  }
943
- /**
944
- * Invokes all handlers, providing the given event.
945
- *
946
- * Handlers may add/remove callbacks or do a nested dispatch.
947
- *
948
- * If a handler is added within a handler, the new handler will not be invoked until the
949
- * next dispatch.
950
- *
951
- * @param event
952
- */
953
- dispatch(event) {
954
- const handlers = this.handlers;
955
- const tail = handlers.tail;
956
- handlers.some((handler) => {
957
- handler(event);
958
- return handler === tail.value;
959
- });
964
+ initialize() {
965
+ this.setInitializer(this.initializer);
966
+ this.original.initialize();
960
967
  }
961
- /**
962
- * Removes all handlers.
963
- */
964
- clear() {
965
- this.handlers.clear();
968
+ reset() {
969
+ this.initializer = this.defaultInitializer;
970
+ this.original.reset();
971
+ this.setInitializer(this.initializer);
966
972
  }
967
- /**
968
- * Same as clear.
969
- */
970
- dispose() {
971
- this.clear();
973
+ set(newInitializer) {
974
+ const overriddenInitializer = () => {
975
+ return newInitializer(this.defaultInitializer);
976
+ };
977
+ this.initializer = overriddenInitializer;
978
+ this.setInitializer(overriddenInitializer);
979
+ return new _GlobalRefOverride(
980
+ this,
981
+ overriddenInitializer,
982
+ this.setInitializer
983
+ );
972
984
  }
973
985
  };
974
- function signal() {
975
- return new SignalImpl();
986
+ function globalRef(init) {
987
+ return getGlobalRegistry().register(new GlobalRefImpl(init));
976
988
  }
977
989
 
978
- // src/logging/LogTarget.ts
979
- var counter = 0;
980
- function createLogPrefix(target) {
981
- const name = typeof target === "string" ? target : target[Symbol.toStringTag];
982
- return `${name}/${++counter}`;
990
+ // src/core/cloneable.ts
991
+ function isCloneable(value) {
992
+ return value != null && typeof value === "object" && "clone" in value && typeof value.clone === "function" && value.clone.length === 0;
983
993
  }
984
994
 
985
- // src/event/EventHost.ts
986
- var EventHostImpl = class {
987
- constructor() {
988
- __publicField(this, "logPrefix", createLogPrefix(this));
989
- __publicField(this, "signals", /* @__PURE__ */ new Map());
990
- __publicField(this, "__eventMapType", covariant());
991
- }
992
- get [Symbol.toStringTag]() {
993
- return "EventHostImpl";
994
- }
995
- hasAnyListeners() {
996
- for (const value of this.signals.values()) {
997
- if (!value.empty) return true;
998
- }
995
+ // src/util/object/object.ts
996
+ function ownKeys(obj) {
997
+ if (!obj) return /* @__PURE__ */ new Set();
998
+ if (typeof Reflect !== "undefined")
999
+ return new Set(Reflect.ownKeys(obj));
1000
+ const properties = /* @__PURE__ */ new Set();
1001
+ Object.getOwnPropertyNames(obj).forEach((item) => properties.add(item));
1002
+ Object.getOwnPropertySymbols(obj).forEach((item) => properties.add(item));
1003
+ return properties;
1004
+ }
1005
+ function isPlainObject(value) {
1006
+ if (!value || typeof value !== "object" || Array.isArray(value))
999
1007
  return false;
1008
+ const proto = Object.getPrototypeOf(value);
1009
+ return !proto || !Object.getPrototypeOf(proto);
1010
+ }
1011
+
1012
+ // src/util/serialization/json.ts
1013
+ function toJson(value) {
1014
+ return toJsonInternal(value, /* @__PURE__ */ new Set());
1015
+ }
1016
+ function toJsonInternal(value, visited) {
1017
+ switch (typeof value) {
1018
+ case "object":
1019
+ return objectToJsonInternal(value, visited);
1020
+ case "undefined":
1021
+ case "boolean":
1022
+ case "number":
1023
+ case "string":
1024
+ return value;
1025
+ case "function":
1026
+ return `[function ${value.name}]`;
1027
+ case "symbol":
1028
+ return `[symbol ${value.toString().slice(7, -1)}]`;
1029
+ case "bigint":
1030
+ return value.toString();
1000
1031
  }
1001
- hasListeners(type) {
1002
- var _a;
1003
- return ((_a = this.signals.get(type)) == null ? void 0 : _a.empty) === false;
1032
+ }
1033
+ function objectToJsonInternal(value, visited) {
1034
+ if (value == null) return value;
1035
+ if (visited.has(value)) return `<circular reference: ${String(value)}>`;
1036
+ visited.add(value);
1037
+ if ("toJSON" in value && typeof value.toJSON === "function")
1038
+ return value.toJSON();
1039
+ if (value instanceof Set) {
1040
+ return Array.from(value).map((e) => toJsonInternal(e, visited));
1041
+ } else if (Array.isArray(value)) {
1042
+ return value.map((e) => toJsonInternal(e, visited));
1043
+ } else {
1044
+ if (isPlainObject(value)) {
1045
+ const o = {};
1046
+ for (const key in value) {
1047
+ o[key] = toJsonInternal(value[key], visited);
1048
+ }
1049
+ return o;
1050
+ } else if (value instanceof Error) {
1051
+ return {
1052
+ name: value.name,
1053
+ message: value.message,
1054
+ stack: value.stack
1055
+ };
1056
+ } else {
1057
+ return value.toString();
1058
+ }
1004
1059
  }
1005
- on(type, handler, options) {
1006
- const sig = getOrSet(this.signals, type, () => signal());
1007
- return sig.listen(handler, options);
1060
+ }
1061
+
1062
+ // src/global/environment.ts
1063
+ function getLocation() {
1064
+ return typeof location === "object" ? location : defaultLocation;
1065
+ }
1066
+ var defaultLocation = {
1067
+ origin: "",
1068
+ search: "",
1069
+ href: ""
1070
+ };
1071
+
1072
+ // src/util/browser/searchParams.ts
1073
+ var getSearchParams = memoize(
1074
+ (search = getLocationSearch()) => {
1075
+ const url = new URL("about:blank");
1076
+ url.search = search;
1077
+ return url.searchParams;
1078
+ },
1079
+ (search = getLocationSearch()) => search,
1080
+ 1
1081
+ );
1082
+ function getLocationSearch() {
1083
+ return getLocation().search;
1084
+ }
1085
+
1086
+ // src/logging/getLogLevelFromSearch.ts
1087
+ function getLogLevelFromSearch(search = getLocationSearch(), defaultLevel = 3 /* WARN */) {
1088
+ var _a;
1089
+ const str = getSearchParams(search).get("vinylLogLevel");
1090
+ if (!str) return defaultLevel;
1091
+ return (_a = parseLogLevel(str)) != null ? _a : defaultLevel;
1092
+ }
1093
+
1094
+ // src/logging/Logger.ts
1095
+ var LoggerImpl = class extends EventHostImpl {
1096
+ constructor(logLevel = 1 /* DEBUG */) {
1097
+ super();
1098
+ __publicField(this, "logLevel", logLevel);
1008
1099
  }
1009
- dispatch(type, event) {
1010
- var _a;
1011
- (_a = this.signals.get(type)) == null ? void 0 : _a.dispatch(event);
1100
+ get [Symbol.toStringTag]() {
1101
+ return "Logger";
1012
1102
  }
1013
- dispose() {
1014
- for (const signal2 of this.signals.values()) signal2.dispose();
1015
- this.signals.clear();
1103
+ log(target, level, ...messages) {
1104
+ if (level === 5 /* NONE */ || level < this.logLevel) return;
1105
+ this.dispatch("log", {
1106
+ level,
1107
+ messages: toJson(messages),
1108
+ target
1109
+ });
1016
1110
  }
1017
1111
  };
1018
-
1019
- // src/util/collection/array.ts
1020
- function remove(array, element) {
1021
- const index = array.indexOf(element);
1022
- if (index === -1) return false;
1023
- array.splice(index, 1);
1024
- return true;
1112
+ var loggerRef = globalRef(
1113
+ () => new LoggerImpl(
1114
+ // The logger is initialized to VERBOSE if vinylLogLevel=verbose is in the query string
1115
+ // Otherwise use DEBUG.
1116
+ getLogLevelFromSearch() === 0 /* VERBOSE */ ? 0 /* VERBOSE */ : 1 /* DEBUG */
1117
+ )
1118
+ );
1119
+ function logDebug(target, ...messages) {
1120
+ loggerRef.value.log(target, 1 /* DEBUG */, ...messages);
1121
+ }
1122
+ var strToLogLevel = {
1123
+ verbose: 0 /* VERBOSE */,
1124
+ debug: 1 /* DEBUG */,
1125
+ info: 2 /* INFO */,
1126
+ warn: 3 /* WARN */,
1127
+ error: 4 /* ERROR */,
1128
+ none: 5 /* NONE */
1129
+ };
1130
+ function parseLogLevel(str) {
1131
+ var _a;
1132
+ return (_a = strToLogLevel[str.toLowerCase()]) != null ? _a : null;
1025
1133
  }
1026
1134
 
1027
1135
  // src/util/collection/typedArray.ts
@@ -1043,9 +1151,9 @@
1043
1151
  return typedArrayTypes.some((type) => value instanceof type);
1044
1152
  }
1045
1153
 
1046
- // src/core/cloneable.ts
1047
- function isCloneable(value) {
1048
- return value != null && typeof value === "object" && "clone" in value && typeof value.clone === "function" && value.clone.length === 0;
1154
+ // src/util/set/set.ts
1155
+ function union(a, b) {
1156
+ return /* @__PURE__ */ new Set([...a, ...b]);
1049
1157
  }
1050
1158
 
1051
1159
  // src/util/object/mergeDeep.ts
@@ -1140,686 +1248,520 @@
1140
1248
  };
1141
1249
  var cloneableMergeRule = {
1142
1250
  matches(object) {
1143
- return isCloneable(object);
1144
- },
1145
- merge(_1, sourceB, _2) {
1146
- return sourceB.clone();
1147
- }
1148
- };
1149
- var arrayMergeRule = {
1150
- matches(object) {
1151
- return Array.isArray(object);
1152
- },
1153
- merge(sourceA, sourceB, merge) {
1154
- const out = [];
1155
- if (sourceA) {
1156
- for (const element of sourceA) {
1157
- out.push(merge(void 0, element, out.length));
1158
- }
1159
- }
1160
- for (const element of sourceB) {
1161
- out.push(merge(void 0, element, out.length));
1162
- }
1163
- return out;
1164
- }
1165
- };
1166
- var plainObjectMergeRule = {
1167
- matches(object) {
1168
- return isPlainObject(object);
1169
- },
1170
- merge(sourceA, sourceB, merge) {
1171
- const out = {};
1172
- for (const key of union(ownKeys(sourceA), ownKeys(sourceB))) {
1173
- if (sourceA && key in sourceB && key in sourceA) {
1174
- out[key] = merge(sourceA[key], sourceB[key], key);
1175
- } else if (sourceA && key in sourceA) {
1176
- out[key] = merge(void 0, sourceA[key], key);
1177
- } else {
1178
- out[key] = merge(void 0, sourceB[key], key);
1179
- }
1180
- }
1181
- return out;
1182
- }
1183
- };
1184
- var regexpMergeRule = {
1185
- matches(object) {
1186
- return object instanceof RegExp;
1187
- },
1188
- merge(_1, sourceB, _2) {
1189
- return new RegExp(sourceB.source, sourceB.flags);
1190
- }
1191
- };
1192
- var dateMergeRule = {
1193
- matches(object) {
1194
- return object instanceof Date;
1195
- },
1196
- merge(_1, sourceB, _2) {
1197
- return new Date(sourceB.getTime());
1198
- }
1199
- };
1200
- var mapMergeRule = {
1201
- matches(object) {
1202
- return object instanceof Map;
1203
- },
1204
- merge(sourceA, sourceB, merge) {
1205
- var _a;
1206
- const out = /* @__PURE__ */ new Map();
1207
- for (const key of /* @__PURE__ */ new Set([
1208
- ...(_a = sourceA == null ? void 0 : sourceA.keys()) != null ? _a : [],
1209
- ...sourceB.keys()
1210
- ])) {
1211
- if (sourceB.has(key) && (sourceA == null ? void 0 : sourceA.has(key))) {
1212
- out.set(key, merge(sourceA.get(key), sourceB.get(key), key));
1213
- } else if (sourceA == null ? void 0 : sourceA.has(key)) {
1214
- out.set(key, merge(void 0, sourceA.get(key), key));
1215
- } else {
1216
- out.set(key, merge(void 0, sourceB.get(key), key));
1217
- }
1218
- }
1219
- return out;
1220
- }
1221
- };
1222
- var setMergeRule = {
1223
- matches(object) {
1224
- return object instanceof Set;
1225
- },
1226
- merge(sourceA, sourceB, merge) {
1227
- var _a;
1228
- return new Set(
1229
- [...(_a = sourceA == null ? void 0 : sourceA.values()) != null ? _a : [], ...sourceB.values()].map(
1230
- (element, index) => {
1231
- return merge(void 0, element, index);
1232
- }
1233
- )
1234
- );
1235
- }
1236
- };
1237
- var typedArrayMergeRule = {
1238
- matches(object) {
1239
- return isTypedArray(object);
1240
- },
1241
- merge(_1, sourceB, _2) {
1242
- return cloneTypedArray(sourceB);
1243
- }
1244
- };
1245
- var urlMergeRule = {
1246
- matches(object) {
1247
- return object instanceof URL;
1248
- },
1249
- merge(_1, sourceB, _2) {
1250
- return new URL(sourceB.toString());
1251
- }
1252
- };
1253
- var defaultMergeOptions = {
1254
- allowReferenceCopy: true,
1255
- rules: [
1256
- cloneableMergeRule,
1257
- arrayMergeRule,
1258
- plainObjectMergeRule,
1259
- regexpMergeRule,
1260
- dateMergeRule,
1261
- mapMergeRule,
1262
- setMergeRule,
1263
- typedArrayMergeRule,
1264
- urlMergeRule
1265
- ]
1266
- };
1267
-
1268
- // src/error/IllegalStateError.ts
1269
- var IllegalStateError = class _IllegalStateError extends ReportableError {
1270
- get [Symbol.toStringTag]() {
1271
- return "IllegalStateError";
1272
- }
1273
- constructor(message) {
1274
- super(message);
1275
- Object.setPrototypeOf(this, _IllegalStateError.prototype);
1276
- }
1277
- };
1278
-
1279
- // src/core/disposable.ts
1280
- function isDisposable(value) {
1281
- return value != null && typeof value.dispose === "function" && value.dispose.length === 0;
1282
- }
1283
-
1284
- // src/util/iteration/iterable.ts
1285
- function mapIter(iterable, transform) {
1286
- const it2 = iterable[Symbol.iterator]();
1287
- return {
1288
- [Symbol.iterator]() {
1289
- return mapIter(iterable, transform);
1290
- },
1291
- next: () => {
1292
- const result = it2.next();
1293
- if (result.done) return result;
1294
- return {
1295
- value: transform(result.value),
1296
- done: false
1297
- };
1298
- }
1299
- };
1300
- }
1301
-
1302
- // src/util/collection/LruCache.ts
1303
- var LruCache = class {
1304
- constructor(initialCapacity) {
1305
- /**
1306
- * A map of the list nodes.
1307
- *
1308
- * @private
1309
- */
1310
- __publicField(this, "cache", /* @__PURE__ */ new Map());
1311
- /**
1312
- * Most recently used elements are at the tail, least recently used are at the head.
1313
- * @private
1314
- */
1315
- __publicField(this, "list", new LinkedList());
1316
- /**
1317
- * An element is about to be removed. Should return true if the element may be evicted,
1318
- * otherwise false.
1319
- * If false is returned for all elements, an IllegalStateError is thrown.
1320
- */
1321
- __publicField(this, "onEvicting", null);
1322
- /**
1323
- * When an element is added when at capacity, the least recently used element will be removed.
1324
- * This callback can be set to be notified with the element being evicted, which may be used
1325
- * for disposal.
1326
- */
1327
- __publicField(this, "onEvict", null);
1328
- __publicField(this, "_capacity", 0);
1329
- this._capacity = initialCapacity;
1330
- }
1331
- get capacity() {
1332
- return this._capacity;
1333
- }
1334
- set capacity(value) {
1335
- this._capacity = value;
1336
- while (this.cache.size > this.capacity) {
1337
- this.evictLeastRecentlyUsed();
1338
- }
1339
- }
1340
- /**
1341
- * @returns the number of elements in the Map.
1342
- */
1343
- get size() {
1344
- return this.cache.size;
1345
- }
1346
- /**
1347
- * @returns boolean indicating whether an element with the specified key exists or not.
1348
- */
1349
- has(key) {
1350
- return this.cache.has(key);
1351
- }
1352
- /**
1353
- * Returns the mapped value for the given key, and moves the element to the most recently
1354
- * used position.
1355
- *
1356
- * @returns Returns the element associated with the given key, or undefined if no such
1357
- * element exists.
1358
- */
1359
- get(key) {
1360
- const node = this.cache.get(key);
1361
- if (!node) return void 0;
1362
- this.list.pushNode(node);
1363
- return node.value[1];
1364
- }
1365
- /**
1366
- * Adds a new element with a specified key and value to the Map. If an element with the
1367
- * same key already exists, the element will be updated and position moved to most recently
1368
- * used.
1369
- */
1370
- set(key, value) {
1371
- if (this.has(key)) {
1372
- const node = this.cache.get(key);
1373
- node.value[1] = value;
1374
- this.list.pushNode(node);
1375
- } else {
1376
- const node = this.list.push([key, value]);
1377
- this.cache.set(key, node);
1378
- if (this.cache.size > this.capacity) {
1379
- this.evictLeastRecentlyUsed();
1251
+ return isCloneable(object);
1252
+ },
1253
+ merge(_1, sourceB, _2) {
1254
+ return sourceB.clone();
1255
+ }
1256
+ };
1257
+ var arrayMergeRule = {
1258
+ matches(object) {
1259
+ return Array.isArray(object);
1260
+ },
1261
+ merge(sourceA, sourceB, merge) {
1262
+ const out = [];
1263
+ if (sourceA) {
1264
+ for (const element of sourceA) {
1265
+ out.push(merge(void 0, element, out.length));
1380
1266
  }
1381
1267
  }
1382
- return this;
1383
- }
1384
- evictLeastRecentlyUsed() {
1385
- var _a, _b, _c;
1386
- let node = this.list.head;
1387
- while (node) {
1388
- const [key2, value2] = node.value;
1389
- const allowed = (_b = (_a = this.onEvicting) == null ? void 0 : _a.call(null, value2, key2, this)) != null ? _b : true;
1390
- if (allowed) break;
1391
- node = node.next;
1268
+ for (const element of sourceB) {
1269
+ out.push(merge(void 0, element, out.length));
1392
1270
  }
1393
- if (!node)
1394
- throw new IllegalStateError(
1395
- "onEvicting returned false for all elements"
1396
- );
1397
- const [key, value] = node.value;
1398
- this.list.remove(node);
1399
- this.cache.delete(node.value[0]);
1400
- (_c = this.onEvict) == null ? void 0 : _c.call(null, value, key, this);
1401
- }
1402
- /**
1403
- * Clears all elements from the cache.
1404
- */
1405
- clear() {
1406
- this.list.clear();
1407
- this.cache.clear();
1271
+ return out;
1408
1272
  }
1409
- /**
1410
- * @returns true if an element in the Map existed and has been removed, or false if the element does not exist.
1411
- */
1412
- delete(key) {
1413
- if (!this.has(key)) return false;
1414
- const node = this.cache.get(key);
1415
- this.cache.delete(key);
1416
- this.list.remove(node);
1417
- return true;
1273
+ };
1274
+ var plainObjectMergeRule = {
1275
+ matches(object) {
1276
+ return isPlainObject(object);
1277
+ },
1278
+ merge(sourceA, sourceB, merge) {
1279
+ const out = {};
1280
+ for (const key of union(ownKeys(sourceA), ownKeys(sourceB))) {
1281
+ if (sourceA && key in sourceB && key in sourceA) {
1282
+ out[key] = merge(sourceA[key], sourceB[key], key);
1283
+ } else if (sourceA && key in sourceA) {
1284
+ out[key] = merge(void 0, sourceA[key], key);
1285
+ } else {
1286
+ out[key] = merge(void 0, sourceB[key], key);
1287
+ }
1288
+ }
1289
+ return out;
1418
1290
  }
1419
- /**
1420
- * Executes a provided function once per each key/value pair in the Map, in insertion order.
1421
- *
1422
- * @param callback A callback to invoke for every element in the cache.
1423
- * @param thisArg Value to use as this when executing callback
1424
- */
1425
- forEach(callback, thisArg) {
1426
- return this.list.forEach((entry) => {
1427
- callback.call(thisArg, entry[1], entry[0], this);
1428
- });
1291
+ };
1292
+ var regexpMergeRule = {
1293
+ matches(object) {
1294
+ return object instanceof RegExp;
1295
+ },
1296
+ merge(_1, sourceB, _2) {
1297
+ return new RegExp(sourceB.source, sourceB.flags);
1429
1298
  }
1430
- /**
1431
- * Returns an iterable of key, value pairs for every entry in the map.
1432
- */
1433
- entries() {
1434
- return this[Symbol.iterator]();
1299
+ };
1300
+ var dateMergeRule = {
1301
+ matches(object) {
1302
+ return object instanceof Date;
1303
+ },
1304
+ merge(_1, sourceB, _2) {
1305
+ return new Date(sourceB.getTime());
1435
1306
  }
1436
- /**
1437
- * Returns an iterable of keys in the map. This will be ordered from least recently used to
1438
- * most.
1439
- */
1440
- keys() {
1441
- return mapIter(this.list, ([key]) => key);
1307
+ };
1308
+ var mapMergeRule = {
1309
+ matches(object) {
1310
+ return object instanceof Map;
1311
+ },
1312
+ merge(sourceA, sourceB, merge) {
1313
+ var _a;
1314
+ const out = /* @__PURE__ */ new Map();
1315
+ for (const key of /* @__PURE__ */ new Set([
1316
+ ...(_a = sourceA == null ? void 0 : sourceA.keys()) != null ? _a : [],
1317
+ ...sourceB.keys()
1318
+ ])) {
1319
+ if (sourceB.has(key) && (sourceA == null ? void 0 : sourceA.has(key))) {
1320
+ out.set(key, merge(sourceA.get(key), sourceB.get(key), key));
1321
+ } else if (sourceA == null ? void 0 : sourceA.has(key)) {
1322
+ out.set(key, merge(void 0, sourceA.get(key), key));
1323
+ } else {
1324
+ out.set(key, merge(void 0, sourceB.get(key), key));
1325
+ }
1326
+ }
1327
+ return out;
1442
1328
  }
1443
- /**
1444
- * Returns an iterable of values in the map. This will be ordered from least recently used to
1445
- * most.
1446
- */
1447
- values() {
1448
- return mapIter(this.list, ([, value]) => value);
1329
+ };
1330
+ var setMergeRule = {
1331
+ matches(object) {
1332
+ return object instanceof Set;
1333
+ },
1334
+ merge(sourceA, sourceB, merge) {
1335
+ var _a;
1336
+ return new Set(
1337
+ [...(_a = sourceA == null ? void 0 : sourceA.values()) != null ? _a : [], ...sourceB.values()].map(
1338
+ (element, index) => {
1339
+ return merge(void 0, element, index);
1340
+ }
1341
+ )
1342
+ );
1449
1343
  }
1450
- [Symbol.iterator]() {
1451
- return this.list[Symbol.iterator]();
1344
+ };
1345
+ var typedArrayMergeRule = {
1346
+ matches(object) {
1347
+ return isTypedArray(object);
1348
+ },
1349
+ merge(_1, sourceB, _2) {
1350
+ return cloneTypedArray(sourceB);
1452
1351
  }
1453
- get [Symbol.toStringTag]() {
1454
- return "LruCache";
1352
+ };
1353
+ var urlMergeRule = {
1354
+ matches(object) {
1355
+ return object instanceof URL;
1356
+ },
1357
+ merge(_1, sourceB, _2) {
1358
+ return new URL(sourceB.toString());
1455
1359
  }
1456
1360
  };
1361
+ var defaultMergeOptions = {
1362
+ allowReferenceCopy: true,
1363
+ rules: [
1364
+ cloneableMergeRule,
1365
+ arrayMergeRule,
1366
+ plainObjectMergeRule,
1367
+ regexpMergeRule,
1368
+ dateMergeRule,
1369
+ mapMergeRule,
1370
+ setMergeRule,
1371
+ typedArrayMergeRule,
1372
+ urlMergeRule
1373
+ ]
1374
+ };
1457
1375
 
1458
- // src/util/fun/memoize.ts
1459
- function memoize(inner, keyProvider, capacity = 500) {
1460
- if (!keyProvider) {
1461
- let cached = false;
1462
- let value = void 0;
1463
- const memoized = () => {
1464
- if (!cached) {
1465
- cached = true;
1466
- value = inner();
1467
- }
1468
- return value;
1469
- };
1470
- return Object.assign(
1471
- memoized,
1472
- {
1473
- clear: () => {
1474
- cached = false;
1475
- value = void 0;
1476
- }
1477
- }
1478
- );
1479
- } else if (capacity === 0) {
1480
- const memoized = (...args) => inner(...args);
1481
- return Object.assign(
1482
- memoized,
1483
- {
1484
- clear: () => {
1485
- }
1486
- }
1487
- );
1488
- } else if (capacity === 1) {
1489
- let hasValue = false;
1490
- let cachedKey;
1491
- let cachedValue;
1492
- const memoized = (...args) => {
1493
- const key = keyProvider(...args);
1494
- if (!hasValue || cachedKey !== key) {
1495
- hasValue = true;
1496
- cachedKey = key;
1497
- cachedValue = inner(...args);
1498
- }
1499
- return cachedValue;
1500
- };
1501
- return Object.assign(
1502
- memoized,
1503
- {
1504
- clear: () => {
1505
- hasValue = false;
1506
- }
1507
- }
1508
- );
1509
- } else {
1510
- const cache = new LruCache(capacity);
1511
- const memoized = (...args) => {
1512
- const key = keyProvider(...args);
1513
- return getOrSet(cache, key, () => inner(...args));
1514
- };
1515
- return Object.assign(
1516
- memoized,
1517
- {
1518
- clear: () => {
1519
- cache.clear();
1520
- }
1521
- }
1522
- );
1376
+ // src/util/url/resolveUrl.ts
1377
+ var SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
1378
+ function resolveUrl(relative, base) {
1379
+ if (SCHEME_RE.test(relative)) return relative;
1380
+ if (relative.startsWith("//")) {
1381
+ const schemeEnd2 = base.indexOf("://");
1382
+ return base.substring(0, schemeEnd2 + 1) + relative;
1523
1383
  }
1384
+ const schemeEnd = base.indexOf("://") + 3;
1385
+ const pathStart = base.indexOf("/", schemeEnd);
1386
+ const origin = pathStart === -1 ? base : base.substring(0, pathStart);
1387
+ if (relative.startsWith("/")) return origin + relative;
1388
+ if (relative === "") return base;
1389
+ const basePath = pathStart === -1 ? "/" : base.substring(pathStart);
1390
+ const lastSlash = basePath.lastIndexOf("/");
1391
+ const dir = basePath.substring(0, lastSlash + 1);
1392
+ return origin + resolveDots(dir + relative);
1524
1393
  }
1525
-
1526
- // src/global/environment.ts
1527
- function getLocation() {
1528
- return typeof location === "object" ? location : defaultLocation;
1394
+ function resolveDots(path) {
1395
+ if (path.indexOf(".") === -1) return path;
1396
+ const parts = path.split("/");
1397
+ const out = [];
1398
+ for (let i = 0; i < parts.length; i++) {
1399
+ const p = parts[i];
1400
+ if (p === "..") {
1401
+ if (out.length > 1) out.pop();
1402
+ } else if (p !== ".") {
1403
+ out.push(p);
1404
+ }
1405
+ }
1406
+ return out.join("/");
1529
1407
  }
1530
- var defaultLocation = {
1531
- origin: "",
1532
- search: "",
1533
- href: ""
1534
- };
1535
1408
 
1536
- // src/util/browser/searchParams.ts
1537
- var getSearchParams = memoize(
1538
- (search = getLocationSearch()) => {
1539
- const url = new URL("about:blank");
1540
- url.search = search;
1541
- return url.searchParams;
1542
- },
1543
- (search = getLocationSearch()) => search,
1544
- 1
1545
- );
1546
- function getLocationSearch() {
1547
- return getLocation().search;
1409
+ // test/browserTestUtil/benchmark/Benchmark.ts
1410
+ var now;
1411
+ if (typeof window !== "undefined" && typeof window.performance !== "undefined" && typeof window.performance.now !== "undefined") {
1412
+ now = () => window.performance.now();
1413
+ } else if (typeof self !== "undefined" && typeof self.performance !== "undefined" && typeof self.performance.now !== "undefined") {
1414
+ now = () => self.performance.now();
1415
+ } else {
1416
+ now = () => Date.now();
1548
1417
  }
1549
-
1550
- // src/global/globalRegistry.ts
1551
- var GlobalRegistry = class {
1552
- constructor() {
1553
- __publicField(this, "registry", []);
1554
- }
1555
- /**
1556
- * Returns the number of references currently in the registry.
1557
- */
1558
- get size() {
1559
- return this.registry.length;
1418
+ var BenchmarkRunResults = class {
1419
+ constructor(name) {
1420
+ __publicField(this, "name", name);
1421
+ __publicField(this, "cycleResults", []);
1422
+ __publicField(this, "_totalSamples", 0);
1560
1423
  }
1561
- /**
1562
- * Registers an initializer that will be invoked during global state initialization.
1563
- * @param initializer
1564
- */
1565
- register(initializer) {
1566
- this.registry.push(initializer);
1567
- return initializer;
1424
+ get totalSamples() {
1425
+ return this._totalSamples;
1568
1426
  }
1569
- /**
1570
- * Removes a global ref from the registry.
1571
- * May be called at any time.
1572
- * @param ref
1573
- * @return Returns true if the global ref was removed.
1574
- */
1575
- unregister(ref) {
1576
- return remove(this.registry, ref);
1427
+ get cycleResultsNoOutliers() {
1428
+ const sD = this.standardDeviation;
1429
+ const avg = average(this.cycleResults);
1430
+ return this.cycleResults.filter((e) => {
1431
+ const zScore = (avg - e) / sD;
1432
+ return Math.abs(zScore) < 3;
1433
+ });
1577
1434
  }
1578
1435
  /**
1579
- * Resets all registered initializers and sets this registry back to its pre-initialized state.
1580
- * This is typically only done within unit tests, but may be called if all players are
1581
- * disposed and the consumer intends to teardown global state.
1436
+ * Returns the mean ops per second minus outliers of greater than 3 standard deviations.
1582
1437
  */
1583
- reset() {
1584
- for (const registryElement of this.registry) {
1585
- registryElement.reset();
1586
- }
1587
- }
1588
- };
1589
- var _registry = null;
1590
- function getGlobalRegistry() {
1591
- if (!_registry) _registry = new GlobalRegistry();
1592
- return _registry;
1593
- }
1594
- var globalRefDebug = false;
1595
- var GlobalRefImpl = class {
1596
- constructor(defaultInitializer) {
1597
- __publicField(this, "defaultInitializer", defaultInitializer);
1598
- __publicField(this, "_value");
1599
- __publicField(this, "_initialized", false);
1600
- __publicField(this, "constructing", false);
1601
- __publicField(this, "initializer");
1602
- __publicField(this, "lastInitStack", null);
1603
- this.initializer = defaultInitializer;
1604
- }
1605
- get initialized() {
1606
- return this._initialized;
1607
- }
1608
- get value() {
1609
- this.initialize();
1610
- return this._value;
1438
+ get meanOpsPerSec() {
1439
+ return average(this.cycleResultsNoOutliers);
1611
1440
  }
1612
- reset() {
1613
- this.initializer = this.defaultInitializer;
1614
- if (!this._initialized) return;
1615
- this.assertNotConstructing();
1616
- this._initialized = false;
1617
- this.lastInitStack = null;
1618
- if (isDisposable(this._value)) {
1619
- this._value.dispose();
1620
- }
1621
- this._value = void 0;
1441
+ get standardDeviation() {
1442
+ return standardDeviation(this.cycleResults);
1622
1443
  }
1623
- initialize() {
1624
- if (this._initialized) return;
1625
- this.assertNotConstructing();
1626
- this.constructing = true;
1627
- try {
1628
- this._value = this.initializer();
1629
- } catch (error) {
1630
- this.constructing = false;
1631
- throw error;
1632
- }
1633
- this.constructing = false;
1634
- this._initialized = true;
1635
- if (globalRefDebug) {
1636
- this.lastInitStack = new Error("globalRef initialized").stack;
1637
- }
1444
+ get variance() {
1445
+ return this.standardDeviation / this.meanOpsPerSec;
1638
1446
  }
1639
- set(newInitializer) {
1640
- this.assertNotInitialized();
1641
- const overriddenInitializer = () => {
1642
- return newInitializer(this.defaultInitializer);
1643
- };
1644
- this.initializer = overriddenInitializer;
1645
- return new GlobalRefOverride(
1646
- this,
1647
- overriddenInitializer,
1648
- (newInitializer2) => {
1649
- this.initializer = newInitializer2;
1650
- }
1651
- );
1447
+ /**
1448
+ * Returns the mean ops / s ± variance % as a string.
1449
+ */
1450
+ get meanOpsStr() {
1451
+ const mean = this.meanOpsPerSec.toLocaleString(void 0, {
1452
+ maximumSignificantDigits: 4
1453
+ });
1454
+ const variance = this.variance.toLocaleString(void 0, {
1455
+ style: "percent"
1456
+ });
1457
+ return `${mean} \xB1${variance}`;
1652
1458
  }
1653
- assertNotInitialized() {
1654
- if (this._initialized) {
1655
- const detail = this.lastInitStack ? `
1656
- Last initialized at:
1657
- ${this.lastInitStack}` : "";
1658
- throw new IllegalStateError(`Cannot call when initialized${detail}`);
1659
- }
1459
+ add(cycle) {
1460
+ const opsPerSecond = cycle.ops / cycle.duration;
1461
+ let index = this.cycleResults.findIndex((value) => opsPerSecond < value);
1462
+ if (index < 0) index = this.cycleResults.length;
1463
+ this.cycleResults.splice(index, 0, opsPerSecond);
1464
+ this._totalSamples += cycle.ops;
1660
1465
  }
1661
- assertNotConstructing() {
1662
- if (this.constructing)
1663
- throw new IllegalStateError("Cannot call during construction");
1466
+ toString() {
1467
+ if (!this.cycleResults.length) return "No results";
1468
+ return `${this.name}: ${this.meanOpsStr} ops/sec`;
1664
1469
  }
1665
1470
  };
1666
- var GlobalRefOverride = class _GlobalRefOverride {
1667
- constructor(original, defaultInitializer, setInitializer) {
1668
- __publicField(this, "original", original);
1669
- __publicField(this, "defaultInitializer", defaultInitializer);
1670
- __publicField(this, "setInitializer", setInitializer);
1671
- __publicField(this, "initializer");
1672
- this.initializer = defaultInitializer;
1471
+ var RunResultsComparison = class {
1472
+ constructor(name, results) {
1473
+ __publicField(this, "name", name);
1474
+ /**
1475
+ * Sorted by median ops/s from slowest to fastest.
1476
+ */
1477
+ __publicField(this, "results");
1478
+ this.results = results.sort((a, b) => {
1479
+ return a.meanOpsPerSec - b.meanOpsPerSec;
1480
+ });
1673
1481
  }
1674
- get initialized() {
1675
- return this.original.initialized;
1482
+ logToTable() {
1483
+ const r = this.results.map((run) => {
1484
+ const variance = run.variance.toLocaleString(void 0, {
1485
+ style: "percent"
1486
+ });
1487
+ const mean = run.meanOpsPerSec.toLocaleString(void 0, {
1488
+ maximumSignificantDigits: 4
1489
+ });
1490
+ return {
1491
+ Name: run.name,
1492
+ Mean: `${mean} \xB1${variance}`,
1493
+ Samples: run.totalSamples,
1494
+ Compare: this.runComparisonToString(run)
1495
+ };
1496
+ });
1497
+ const table = r.reduce((acc, _a) => {
1498
+ var _b = _a, { Name } = _b, x = __objRest(_b, ["Name"]);
1499
+ acc[Name] = x;
1500
+ return acc;
1501
+ }, {});
1502
+ console.log("\n" + this.name);
1503
+ console.table(table);
1676
1504
  }
1677
- get value() {
1678
- return this.original.value;
1505
+ runComparisonToString(run) {
1506
+ var _a, _b;
1507
+ const baseline = (_b = (_a = this.results[0]) == null ? void 0 : _a.meanOpsPerSec) != null ? _b : 0;
1508
+ const fasterPercent = run.meanOpsPerSec / baseline - 1;
1509
+ return fasterPercent < 0.01 ? "-" : fasterPercent.toLocaleString(void 0, {
1510
+ style: "percent"
1511
+ }) + " faster";
1679
1512
  }
1680
- initialize() {
1681
- this.setInitializer(this.initializer);
1682
- this.original.initialize();
1513
+ };
1514
+ function compareResults(name, ...results) {
1515
+ return new RunResultsComparison(name, results);
1516
+ }
1517
+ var defaultBenchmarkOptions = {
1518
+ warmupTime: 0.5,
1519
+ maxCycleDuration: 0.5,
1520
+ cycles: 9
1521
+ };
1522
+ var _Benchmark = class _Benchmark {
1523
+ /**
1524
+ * Constructs a new Benchmark.
1525
+ *
1526
+ * @param name The name of the benchmark, to be used when logging.
1527
+ * @param executor The method to execute and measure. If this method returns a promise, the
1528
+ * promise will be awaited. The executor should either always return a promise, or never.
1529
+ * @param options Optional configuration for the benchmark.
1530
+ */
1531
+ constructor(name, executor, options) {
1532
+ __publicField(this, "name", name);
1533
+ __publicField(this, "executor", executor);
1534
+ __publicField(this, "options");
1535
+ this.options = __spreadValues(__spreadValues({}, defaultBenchmarkOptions), options);
1683
1536
  }
1684
- reset() {
1685
- this.initializer = this.defaultInitializer;
1686
- this.original.reset();
1687
- this.setInitializer(this.initializer);
1537
+ async run() {
1538
+ const opts = this.options;
1539
+ await _Benchmark.semaphore;
1540
+ const warmupTimeMs = opts.warmupTime * 1e3;
1541
+ const cycleStart = now();
1542
+ let isAsync = false;
1543
+ do {
1544
+ const result = this.executor();
1545
+ isAsync = isAsync || result && typeof result.then === "function";
1546
+ if (isAsync) await result;
1547
+ } while (now() - cycleStart < warmupTimeMs);
1548
+ const resultsPromise = (async () => {
1549
+ const results = new BenchmarkRunResults(this.name);
1550
+ for (let i = 0; i < opts.cycles; i++) {
1551
+ const cycleResults = await this.runCycle(isAsync);
1552
+ results.add(cycleResults);
1553
+ await nextFrame();
1554
+ }
1555
+ return results;
1556
+ })();
1557
+ _Benchmark.semaphore = resultsPromise;
1558
+ return await resultsPromise;
1688
1559
  }
1689
- set(newInitializer) {
1690
- const overriddenInitializer = () => {
1691
- return newInitializer(this.defaultInitializer);
1560
+ /**
1561
+ * Runs one cycle. A cycle will repeat the executor approximately `options.maxCycleDuration`
1562
+ * seconds.
1563
+ *
1564
+ * @param isAsync
1565
+ * @return Returns the duration (in seconds) and number of operations the cycle repeated.
1566
+ */
1567
+ async runCycle(isAsync) {
1568
+ const cycleMs = this.options.maxCycleDuration * 1e3;
1569
+ let ops = 0;
1570
+ const cycleStart = now();
1571
+ do {
1572
+ const result = this.executor();
1573
+ if (isAsync) await result;
1574
+ ops++;
1575
+ } while (now() - cycleStart < cycleMs);
1576
+ const duration = (now() - cycleStart) / 1e3;
1577
+ return {
1578
+ duration,
1579
+ ops
1692
1580
  };
1693
- this.initializer = overriddenInitializer;
1694
- this.setInitializer(overriddenInitializer);
1695
- return new _GlobalRefOverride(
1696
- this,
1697
- overriddenInitializer,
1698
- this.setInitializer
1699
- );
1700
1581
  }
1701
1582
  };
1702
- function globalRef(init) {
1703
- return getGlobalRegistry().register(new GlobalRefImpl(init));
1583
+ __publicField(_Benchmark, "semaphore", nextFrame());
1584
+ var Benchmark = _Benchmark;
1585
+ function benchmark(name, executor, options) {
1586
+ const benchmark2 = new Benchmark(name, executor, options);
1587
+ return benchmark2.run().then((results) => {
1588
+ console.log(results.toString());
1589
+ return results;
1590
+ });
1591
+ }
1592
+ function nextFrame() {
1593
+ return new Promise((resolve) => {
1594
+ setTimeout(resolve);
1595
+ });
1596
+ }
1597
+ function standardDeviation(values) {
1598
+ const avg = average(values);
1599
+ const squareDiffs = values.map((value) => {
1600
+ const diff = value - avg;
1601
+ return diff * diff;
1602
+ });
1603
+ const avgSquareDiff = average(squareDiffs);
1604
+ return Math.sqrt(avgSquareDiff);
1605
+ }
1606
+ function average(values) {
1607
+ const sum = values.reduce((acc, value) => acc + value, 0);
1608
+ return sum / values.length;
1704
1609
  }
1705
1610
 
1706
- // src/logging/getLogLevelFromSearch.ts
1707
- function getLogLevelFromSearch(search = getLocationSearch(), defaultLevel = 3 /* WARN */) {
1708
- var _a;
1709
- const str = getSearchParams(search).get("vinylLogLevel");
1710
- if (!str) return defaultLevel;
1711
- return (_a = parseLogLevel(str)) != null ? _a : defaultLevel;
1611
+ // test/browserTestUtil/env/jasmineEnv.ts
1612
+ var nextTestTimeoutOverridden = false;
1613
+ function setTestTimeout(timeout) {
1614
+ let originalTimeout = null;
1615
+ beforeEach(() => {
1616
+ originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
1617
+ if (!nextTestTimeoutOverridden)
1618
+ jasmine.DEFAULT_TIMEOUT_INTERVAL = timeout * 1e3;
1619
+ });
1620
+ afterEach(() => {
1621
+ if (originalTimeout) jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
1622
+ if (nextTestTimeoutOverridden) nextTestTimeoutOverridden = false;
1623
+ });
1712
1624
  }
1713
1625
 
1714
- // src/logging/Logger.ts
1715
- var LoggerImpl = class extends EventHostImpl {
1716
- constructor(logLevel = 1 /* DEBUG */) {
1717
- super();
1718
- __publicField(this, "logLevel", logLevel);
1719
- }
1720
- get [Symbol.toStringTag]() {
1721
- return "Logger";
1722
- }
1723
- log(target, level, ...messages) {
1724
- if (level === 5 /* NONE */ || level < this.logLevel) return;
1725
- this.dispatch("log", {
1726
- level,
1727
- messages: toJson(messages),
1728
- target
1729
- });
1626
+ // test/browserTestUtil/expect/expectNothing.ts
1627
+ function expectNothing() {
1628
+ expect(true).toBeTruthy();
1629
+ }
1630
+
1631
+ // test/browserTestUtil/mock/createSpyFactory.ts
1632
+ var createSpy = jasmine.createSpy;
1633
+ function createSpy2(key) {
1634
+ return createSpy(String(key));
1635
+ }
1636
+
1637
+ // test/browserTestUtil/mock/dom/lib.dom.ts
1638
+ var MockAbortSignal = class {
1639
+ constructor() {
1640
+ __publicField(this, "aborted", false);
1641
+ __publicField(this, "onabort", null);
1642
+ __publicField(this, "reason");
1643
+ __publicField(this, "throwIfAborted", createSpy2("throwIfAborted"));
1644
+ __publicField(this, "addEventListener", createSpy2("addEventListener"));
1645
+ __publicField(this, "removeEventListener", createSpy2(
1646
+ "removeEventListener"
1647
+ ));
1648
+ __publicField(this, "dispatchEvent", createSpy2("dispatchEvent"));
1730
1649
  }
1731
1650
  };
1732
- var loggerRef = globalRef(
1733
- () => new LoggerImpl(
1734
- // The logger is initialized to VERBOSE if vinylLogLevel=verbose is in the query string
1735
- // Otherwise use DEBUG.
1736
- getLogLevelFromSearch() === 0 /* VERBOSE */ ? 0 /* VERBOSE */ : 1 /* DEBUG */
1737
- )
1738
- );
1739
- function logDebug(target, ...messages) {
1740
- loggerRef.value.log(target, 1 /* DEBUG */, ...messages);
1741
- }
1742
- var strToLogLevel = {
1743
- verbose: 0 /* VERBOSE */,
1744
- debug: 1 /* DEBUG */,
1745
- info: 2 /* INFO */,
1746
- warn: 3 /* WARN */,
1747
- error: 4 /* ERROR */,
1748
- none: 5 /* NONE */
1651
+ var MockMediaSource = class {
1652
+ constructor() {
1653
+ __publicField(this, "activeSourceBuffers");
1654
+ __publicField(this, "duration", 0);
1655
+ __publicField(this, "onsourceclose", null);
1656
+ __publicField(this, "onsourceended", null);
1657
+ __publicField(this, "onsourceopen", null);
1658
+ __publicField(this, "readyState", "closed");
1659
+ __publicField(this, "sourceBuffers");
1660
+ __publicField(this, "addSourceBuffer", createSpy2("addSourceBuffer"));
1661
+ __publicField(this, "clearLiveSeekableRange", createSpy2(
1662
+ "clearLiveSeekableRange"
1663
+ ));
1664
+ __publicField(this, "endOfStream", createSpy2("endOfStream"));
1665
+ __publicField(this, "removeSourceBuffer", createSpy2("removeSourceBuffer"));
1666
+ __publicField(this, "setLiveSeekableRange", createSpy2(
1667
+ "setLiveSeekableRange"
1668
+ ));
1669
+ __publicField(this, "addEventListener", createSpy2("addEventListener"));
1670
+ __publicField(this, "removeEventListener", createSpy2(
1671
+ "removeEventListener"
1672
+ ));
1673
+ __publicField(this, "dispatchEvent", createSpy2("dispatchEvent"));
1674
+ }
1749
1675
  };
1750
- function parseLogLevel(str) {
1751
- var _a;
1752
- return (_a = strToLogLevel[str.toLowerCase()]) != null ? _a : null;
1753
- }
1754
1676
 
1755
- // test/benchmark/util/url/resolveUrl.bench.ts
1756
- describe("resolveUrl", () => {
1757
- setupBenchmark();
1758
- it("relative path", async () => {
1759
- const name = "relative path";
1760
- const base = "https://cdn.example.com/content/audio/";
1761
- const relative = "segment_001.mp4";
1762
- const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1763
- const _o = resolveUrl(relative, base);
1764
- });
1765
- const newUrlResults = await benchmark(`new URL ${name}`, () => {
1766
- const _o = new URL(relative, base).href;
1767
- });
1768
- addBenchmarks(name, resolveUrlResults, newUrlResults);
1769
- });
1770
- it("absolute URI", async () => {
1771
- const name = "absolute URI";
1772
- const base = "https://cdn.example.com/content/audio/";
1773
- const absolute = "https://other.example.com/segment.mp4";
1774
- const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1775
- const _o = resolveUrl(absolute, base);
1776
- });
1777
- const newUrlResults = await benchmark(`new URL ${name}`, () => {
1778
- const _o = new URL(absolute, base).href;
1779
- });
1780
- addBenchmarks(name, resolveUrlResults, newUrlResults);
1781
- });
1782
- it("dot segments", async () => {
1783
- const name = "dot segments";
1784
- const base = "https://cdn.example.com/a/b/c/manifest.mpd";
1785
- const relative = "../../media/segment.mp4";
1786
- const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1787
- const _o = resolveUrl(relative, base);
1788
- });
1789
- const newUrlResults = await benchmark(`new URL ${name}`, () => {
1790
- const _o = new URL(relative, base).href;
1791
- });
1792
- addBenchmarks(name, resolveUrlResults, newUrlResults);
1793
- });
1794
- it("chained resolution (DASH BaseURL walk)", async () => {
1795
- const name = "chained resolution";
1796
- const manifest = "https://cdn.example.com/manifest.mpd";
1797
- const scopes = ["content/", "audio/", "128k/"];
1798
- const segment = "seg_001.m4s";
1799
- const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1800
- let resolved = manifest;
1801
- for (const scope of scopes) {
1802
- resolved = resolveUrl(scope, resolved);
1803
- }
1804
- resolveUrl(segment, resolved);
1805
- });
1806
- const newUrlResults = await benchmark(`new URL ${name}`, () => {
1807
- let resolved = new URL(manifest);
1808
- for (const scope of scopes) {
1809
- resolved = new URL(scope, resolved);
1677
+ // test/browserTestUtil/mock/dom/globals.ts
1678
+ var MockMediaSourceGlobal = class extends MockMediaSource {
1679
+ };
1680
+ __publicField(MockMediaSourceGlobal, "canConstructInDedicatedWorker", false);
1681
+ __publicField(MockMediaSourceGlobal, "isTypeSupported", createSpy2(
1682
+ "isTypeSupported"
1683
+ ));
1684
+ var MockAbortSignalGlobal = class extends MockAbortSignal {
1685
+ };
1686
+ __publicField(MockAbortSignalGlobal, "abort", createSpy2("abort"));
1687
+ __publicField(MockAbortSignalGlobal, "any", createSpy2("any"));
1688
+ __publicField(MockAbortSignalGlobal, "timeout", createSpy2("timeout"));
1689
+
1690
+ // test/benchmark/setup.ts
1691
+ function setupBenchmark() {
1692
+ setTestTimeout(180);
1693
+ afterEach(expectNothing);
1694
+ }
1695
+ var comparisons = [];
1696
+ function addComparison(comparison) {
1697
+ comparisons.push(comparison);
1698
+ }
1699
+ function addBenchmarks(name, ...results) {
1700
+ const comparison = compareResults(name, ...results);
1701
+ comparison.logToTable();
1702
+ comparisons.push(comparison);
1703
+ }
1704
+ if (typeof document !== "undefined") {
1705
+ jasmine.getEnv().addReporter({
1706
+ jasmineDone: () => {
1707
+ var _a;
1708
+ console.log("Tests complete");
1709
+ const jasmineContainer = document.getElementsByClassName(
1710
+ "jasmine_html-reporter"
1711
+ )[0];
1712
+ (_a = jasmineContainer.parentElement) == null ? void 0 : _a.removeChild(jasmineContainer);
1713
+ const container = createEl("div", document.body);
1714
+ container.id = "benchmarkResults";
1715
+ const sortedComparisons = [...comparisons].sort(
1716
+ (a, b) => a.name > b.name ? 1 : -1
1717
+ );
1718
+ for (const comparison of sortedComparisons) {
1719
+ toTableHtml(comparison, container);
1810
1720
  }
1811
- const _o = new URL(segment, resolved).href;
1812
- });
1813
- addBenchmarks(name, resolveUrlResults, newUrlResults);
1721
+ }
1814
1722
  });
1815
- });
1723
+ }
1724
+ function toTableHtml(comparison, parent) {
1725
+ const container = createEl("div", parent);
1726
+ container.className = "benchmarkComparison";
1727
+ const title = createEl("h2", container);
1728
+ title.innerText = comparison.name;
1729
+ const table = createEl("table", container);
1730
+ const head = createEl("thead", table);
1731
+ const headRow = createEl("tr", head);
1732
+ const name = createEl("th", headRow);
1733
+ name.innerText = "Name";
1734
+ const median = createEl("th", headRow);
1735
+ median.innerText = "Mean ops/s";
1736
+ const samples = createEl("th", headRow);
1737
+ samples.innerText = "Samples";
1738
+ const compare = createEl("th", headRow);
1739
+ compare.innerText = "% Comparison";
1740
+ const body = createEl("tbody", table);
1741
+ comparison.results.forEach((result) => {
1742
+ const row = createEl("tr", body);
1743
+ createEl("th", row).innerText = result.name;
1744
+ createEl("td", row).innerText = result.meanOpsStr;
1745
+ createEl("td", row).innerText = result.totalSamples.toLocaleString();
1746
+ createEl("td", row).innerText = comparison.runComparisonToString(result);
1747
+ });
1748
+ return container;
1749
+ }
1750
+ function createEl(tagName, parent, options) {
1751
+ const element = document.createElement(tagName, options);
1752
+ if (parent) parent.appendChild(element);
1753
+ return element;
1754
+ }
1816
1755
 
1817
- // test/benchmark/util/serialization/toJson.bench.ts
1818
- describe("json", () => {
1756
+ // test/benchmark/logging/Logging.bench.ts
1757
+ describe("Logging", () => {
1819
1758
  setupBenchmark();
1820
- it("toJson", async () => {
1821
- const results = await benchmark(`toJson`, () => {
1822
- toJson({
1759
+ it("logDebug", async () => {
1760
+ const target = {
1761
+ logPrefix: "path"
1762
+ };
1763
+ const results = await benchmark(`logDebug`, () => {
1764
+ logDebug(target, {
1823
1765
  requestInfo: {
1824
1766
  fetchId: "lgn9lrwaid8o3utd5r",
1825
1767
  init: {
@@ -1835,7 +1777,7 @@ ${this.lastInitStack}` : "";
1835
1777
  input: "https://example.com/bar/",
1836
1778
  maxRetries: 1,
1837
1779
  timestamp: /* @__PURE__ */ new Date("2023-04-19T05:40:17.914Z"),
1838
- requestOptions: {
1780
+ fetchOptions: {
1839
1781
  serviceId: null,
1840
1782
  readErrorBody: 1
1841
1783
  }
@@ -1847,51 +1789,7 @@ ${this.lastInitStack}` : "";
1847
1789
  target: "[object FetchProviderImpl]"
1848
1790
  });
1849
1791
  });
1850
- addBenchmarks("toJson", results);
1851
- });
1852
- });
1853
-
1854
- // test/benchmark/util/object/mergeDeep.bench.ts
1855
- describe("mergeDeep", () => {
1856
- setupBenchmark();
1857
- it("object merge", async () => {
1858
- const a = {
1859
- b: {
1860
- c: 3,
1861
- d: 4,
1862
- e: "test"
1863
- },
1864
- f: {
1865
- g: 5,
1866
- h: true,
1867
- i: false
1868
- },
1869
- j: {
1870
- k: {
1871
- m: 5
1872
- }
1873
- }
1874
- };
1875
- const b = {
1876
- b: {
1877
- d: 4,
1878
- f2: "test2"
1879
- },
1880
- f: {
1881
- g: 5,
1882
- h: true,
1883
- i: false
1884
- },
1885
- j: {
1886
- k: {
1887
- m: 5
1888
- }
1889
- }
1890
- };
1891
- const mergeResultsDeep = await benchmark(`mergeDeep`, () => {
1892
- mergeDeep([a, b]);
1893
- });
1894
- addBenchmarks("merge deep", mergeResultsDeep);
1792
+ addBenchmarks("logDebug", results);
1895
1793
  });
1896
1794
  });
1897
1795
 
@@ -1983,15 +1881,56 @@ ${this.lastInitStack}` : "";
1983
1881
  });
1984
1882
  });
1985
1883
 
1986
- // test/benchmark/logging/Logging.bench.ts
1987
- describe("Logging", () => {
1884
+ // test/benchmark/util/object/mergeDeep.bench.ts
1885
+ describe("mergeDeep", () => {
1988
1886
  setupBenchmark();
1989
- it("logDebug", async () => {
1990
- const target = {
1991
- logPrefix: "path"
1887
+ it("object merge", async () => {
1888
+ const a = {
1889
+ b: {
1890
+ c: 3,
1891
+ d: 4,
1892
+ e: "test"
1893
+ },
1894
+ f: {
1895
+ g: 5,
1896
+ h: true,
1897
+ i: false
1898
+ },
1899
+ j: {
1900
+ k: {
1901
+ m: 5
1902
+ }
1903
+ }
1992
1904
  };
1993
- const results = await benchmark(`logDebug`, () => {
1994
- logDebug(target, {
1905
+ const b = {
1906
+ b: {
1907
+ d: 4,
1908
+ f2: "test2"
1909
+ },
1910
+ f: {
1911
+ g: 5,
1912
+ h: true,
1913
+ i: false
1914
+ },
1915
+ j: {
1916
+ k: {
1917
+ m: 5
1918
+ }
1919
+ }
1920
+ };
1921
+ const mergeResultsDeep = await benchmark(`mergeDeep`, () => {
1922
+ mergeDeep([a, b]);
1923
+ });
1924
+ addBenchmarks("merge deep", mergeResultsDeep);
1925
+ });
1926
+ });
1927
+
1928
+ // test/benchmark/util/serialization/toJson.bench.ts
1929
+ describe("json", () => {
1930
+ setupBenchmark();
1931
+ it("toJson", async () => {
1932
+ const results = await benchmark(`toJson`, () => {
1933
+ toJson({
1995
1934
  requestInfo: {
1996
1935
  fetchId: "lgn9lrwaid8o3utd5r",
1997
1936
  init: {
@@ -2007,7 +1946,7 @@ ${this.lastInitStack}` : "";
2007
1946
  input: "https://example.com/bar/",
2008
1947
  maxRetries: 1,
2009
1948
  timestamp: /* @__PURE__ */ new Date("2023-04-19T05:40:17.914Z"),
2010
- fetchOptions: {
1949
+ requestOptions: {
2011
1950
  serviceId: null,
2012
1951
  readErrorBody: 1
2013
1952
  }
@@ -2019,7 +1958,69 @@ ${this.lastInitStack}` : "";
2019
1958
  target: "[object FetchProviderImpl]"
2020
1959
  });
2021
1960
  });
2022
- addBenchmarks("logDebug", results);
1961
+ addBenchmarks("toJson", results);
1962
+ });
1963
+ });
1964
+
1965
+ // test/benchmark/util/url/resolveUrl.bench.ts
1966
+ describe("resolveUrl", () => {
1967
+ setupBenchmark();
1968
+ it("relative path", async () => {
1969
+ const name = "relative path";
1970
+ const base = "https://cdn.example.com/content/audio/";
1971
+ const relative = "segment_001.mp4";
1972
+ const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1973
+ const _o = resolveUrl(relative, base);
1974
+ });
1975
+ const newUrlResults = await benchmark(`new URL ${name}`, () => {
1976
+ const _o = new URL(relative, base).href;
1977
+ });
1978
+ addBenchmarks(name, resolveUrlResults, newUrlResults);
1979
+ });
1980
+ it("absolute URI", async () => {
1981
+ const name = "absolute URI";
1982
+ const base = "https://cdn.example.com/content/audio/";
1983
+ const absolute = "https://other.example.com/segment.mp4";
1984
+ const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1985
+ const _o = resolveUrl(absolute, base);
1986
+ });
1987
+ const newUrlResults = await benchmark(`new URL ${name}`, () => {
1988
+ const _o = new URL(absolute, base).href;
1989
+ });
1990
+ addBenchmarks(name, resolveUrlResults, newUrlResults);
1991
+ });
1992
+ it("dot segments", async () => {
1993
+ const name = "dot segments";
1994
+ const base = "https://cdn.example.com/a/b/c/manifest.mpd";
1995
+ const relative = "../../media/segment.mp4";
1996
+ const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
1997
+ const _o = resolveUrl(relative, base);
1998
+ });
1999
+ const newUrlResults = await benchmark(`new URL ${name}`, () => {
2000
+ const _o = new URL(relative, base).href;
2001
+ });
2002
+ addBenchmarks(name, resolveUrlResults, newUrlResults);
2003
+ });
2004
+ it("chained resolution (DASH BaseURL walk)", async () => {
2005
+ const name = "chained resolution";
2006
+ const manifest = "https://cdn.example.com/manifest.mpd";
2007
+ const scopes = ["content/", "audio/", "128k/"];
2008
+ const segment = "seg_001.m4s";
2009
+ const resolveUrlResults = await benchmark(`resolveUrl ${name}`, () => {
2010
+ let resolved = manifest;
2011
+ for (const scope of scopes) {
2012
+ resolved = resolveUrl(scope, resolved);
2013
+ }
2014
+ resolveUrl(segment, resolved);
2015
+ });
2016
+ const newUrlResults = await benchmark(`new URL ${name}`, () => {
2017
+ let resolved = new URL(manifest);
2018
+ for (const scope of scopes) {
2019
+ resolved = new URL(scope, resolved);
2020
+ }
2021
+ const _o = new URL(segment, resolved).href;
2022
+ });
2023
+ addBenchmarks(name, resolveUrlResults, newUrlResults);
2023
2024
  });
2024
2025
  });
2025
2026
  })();