@flighthq/loader 0.3.0-next.906.07cea63 → 0.3.1-next.209.43ef1bc
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/resourceLoader.d.ts +3 -1
- package/dist/resourceLoader.d.ts.map +1 -1
- package/dist/resourceLoader.js +131 -14
- package/dist/resourceLoader.js.map +1 -1
- package/package.json +5 -3
- package/src/resourceLoader.test.ts +444 -11
package/README.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @flighthq/loader
|
|
2
|
+
|
|
3
|
+
## Progress: three currencies, one contract
|
|
4
|
+
|
|
5
|
+
A load can be measured three ways, and they answer different questions. Asking for the wrong one is how a progress bar and a counter end up disagreeing on the same batch.
|
|
6
|
+
|
|
7
|
+
**`getResourceLoadProgress(loader)` — the 0..1 weighted fraction.** This is _the_ progress number, and `onProgress` emits exactly it, so the signal and the accessor can never diverge. Each item counts for its `weight` (default `1`), so an unweighted batch is simply the item fraction.
|
|
8
|
+
|
|
9
|
+
**`getResourceLoadCounts(loader)` — how many items, and where they are.** `settledItems`, `inFlightItems`, `queuedItems`, `totalItems`. In-flight and queued are separate numbers because a concurrency limit makes them differ: "loading 4 of 200" is the in-flight count, not the queue depth. Use these for a literal "3 of 12 files" readout.
|
|
10
|
+
|
|
11
|
+
**`getResourceLoadBytes(loader)` — what the load knows about its byte volume.** `bytesLoaded` is summed, monotonic, and always valid. `bytesTotalKnown` and `itemsWithKnownBytes` are labeled _known_ on purpose: `bytesHint` is optional per item, so the known total is a floor that grows as more items declare a size. Compare `itemsWithKnownBytes` against `totalItems` to judge whether it covers enough of the batch to divide by.
|
|
12
|
+
|
|
13
|
+
### The principle
|
|
14
|
+
|
|
15
|
+
**The contract currency must be knowable before the work starts.** Weight qualifies because the caller supplies it: progress starts at a truthful 0 and never rescales. Bytes do not — a byte denominator grows as headers arrive, so a bar driven by it slides backwards as the loader discovers more work. That is why weight is the contract and bytes are reporting.
|
|
16
|
+
|
|
17
|
+
### Recipe: a byte-accurate progress bar
|
|
18
|
+
|
|
19
|
+
When you know each item's size, pass those sizes _as weights_ and the weighted fraction becomes byte progress, with no second aggregate and no moving denominator:
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
for (const asset of manifest) {
|
|
23
|
+
queueResourceLoad(loader, {
|
|
24
|
+
bytesHint: asset.size,
|
|
25
|
+
weight: asset.size, // weight in bytes -> getResourceLoadProgress is byte progress
|
|
26
|
+
load: (signal, reportBytes) => fetchAsset(asset, signal, reportBytes),
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Partial size knowledge is deliberately not smoothed over in core: there is no byte-total estimator, because calibrating bytes-per-weight only works when weights are already byte-proportional — in which case the caller knows the total from its own hints anyway.
|
|
32
|
+
|
|
33
|
+
### Edge cases
|
|
34
|
+
|
|
35
|
+
- An empty loader reports progress `1`. A batch of nothing is complete, which keeps `await` semantics consistent, and counts report zeros.
|
|
36
|
+
- No query returns `NaN`. Every division is guarded by the zero check in front of it.
|
|
37
|
+
- A batch whose items are _all_ explicitly `weight: 0` falls back to the item fraction, since the weighted fraction is undefined for it.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { cancelResourceLoad, createResourceLoader, disposeResourceLoader, enableResourceLoaderItemSignals, getResourceLoadItemStatus, getResourceLoadProgress, pauseResourceLoad, queueResourceLoad, resetResourceLoader, resumeResourceLoad, setResourceLoadPriority, setResourceLoaderConcurrency, startResourceLoad, } from './contract';
|
|
1
|
+
export { cancelResourceLoad, createResourceLoader, disposeResourceLoader, enableResourceLoaderItemSignals, getResourceLoadItemStatus, getResourceLoadBytes, getResourceLoadCounts, getResourceLoadProgress, pauseResourceLoad, queueResourceLoad, resetResourceLoader, resumeResourceLoad, setResourceLoadPriority, setResourceLoaderConcurrency, startResourceLoad, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { cancelResourceLoad, createResourceLoader, disposeResourceLoader, enableResourceLoaderItemSignals, getResourceLoadItemStatus, getResourceLoadProgress, pauseResourceLoad, queueResourceLoad, resetResourceLoader, resumeResourceLoad, setResourceLoadPriority, setResourceLoaderConcurrency, startResourceLoad, } from './contract';
|
|
1
|
+
export { cancelResourceLoad, createResourceLoader, disposeResourceLoader, enableResourceLoaderItemSignals, getResourceLoadItemStatus, getResourceLoadBytes, getResourceLoadCounts, getResourceLoadProgress, pauseResourceLoad, queueResourceLoad, resetResourceLoader, resumeResourceLoad, setResourceLoadPriority, setResourceLoaderConcurrency, startResourceLoad, } from './contract';
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,qBAAqB,EACrB,+BAA+B,EAC/B,yBAAyB,EACzB,oBAAoB,EACpB,qBAAqB,EACrB,uBAAuB,EACvB,iBAAiB,EACjB,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EAClB,uBAAuB,EACvB,4BAA4B,EAC5B,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/resourceLoader.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import type { ResourceLoader, ResourceLoaderItemSignals, ResourceLoaderOptions, ResourceLoadHandle, ResourceLoadItem, ResourceLoadItemStatus } from '@flighthq/types/contract';
|
|
1
|
+
import type { ResourceLoadBytes, ResourceLoadCounts, ResourceLoader, ResourceLoaderItemSignals, ResourceLoaderOptions, ResourceLoadHandle, ResourceLoadItem, ResourceLoadItemStatus } from '@flighthq/types/contract';
|
|
2
2
|
export declare function cancelResourceLoad(loader: ResourceLoader): void;
|
|
3
3
|
export declare function createResourceLoader(options?: Readonly<ResourceLoaderOptions>): ResourceLoader;
|
|
4
4
|
export declare function disposeResourceLoader(loader: ResourceLoader): void;
|
|
5
5
|
export declare function enableResourceLoaderItemSignals(loader: ResourceLoader): ResourceLoaderItemSignals;
|
|
6
|
+
export declare function getResourceLoadBytes(loader: Readonly<ResourceLoader>): ResourceLoadBytes;
|
|
7
|
+
export declare function getResourceLoadCounts(loader: Readonly<ResourceLoader>): ResourceLoadCounts;
|
|
6
8
|
export declare function getResourceLoadItemStatus(loader: ResourceLoader, key: string): ResourceLoadItemStatus;
|
|
7
9
|
export declare function getResourceLoadProgress(loader: ResourceLoader, group?: string): number;
|
|
8
10
|
export declare function pauseResourceLoad(loader: ResourceLoader): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceLoader.d.ts","sourceRoot":"","sources":["../src/resourceLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,cAAc,EACd,yBAAyB,EACzB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"resourceLoader.d.ts","sourceRoot":"","sources":["../src/resourceLoader.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EAErB,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EAEvB,MAAM,0BAA0B,CAAC;AA6HlC,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAyC/D;AAED,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,qBAAqB,CAAC,GAAG,cAAc,CAkC9F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAelE;AAED,wBAAgB,+BAA+B,CAAC,MAAM,EAAE,cAAc,GAAG,yBAAyB,CAWjG;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,iBAAiB,CA6BxF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAW1F;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,sBAAsB,CASrG;AAaD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BtF;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAK9D;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EACjC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC,GACvD,kBAAkB,CAAC,CAAC,CAAC,CAsEvB;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAiChE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAM/D;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAOhG;AAED,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAMnG;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAY9D"}
|
package/dist/resourceLoader.js
CHANGED
|
@@ -12,6 +12,7 @@ function acquirePendingEntry() {
|
|
|
12
12
|
abortController: new AbortController(),
|
|
13
13
|
bytesHint: 0,
|
|
14
14
|
bytesLoaded: 0,
|
|
15
|
+
generation: 0,
|
|
15
16
|
group: undefined,
|
|
16
17
|
key: '',
|
|
17
18
|
onBytesProgress: undefined,
|
|
@@ -66,8 +67,12 @@ function consumeTokens(bucket, cost) {
|
|
|
66
67
|
}
|
|
67
68
|
export function cancelResourceLoad(loader) {
|
|
68
69
|
const internal = loader;
|
|
69
|
-
if (
|
|
70
|
+
if (internal.cancelled)
|
|
70
71
|
return;
|
|
72
|
+
// Cancelling before start is a real cancellation, not a no-op. It used to return early, which left
|
|
73
|
+
// every queued handle's promise pending forever — a caller that queued a batch, changed its mind,
|
|
74
|
+
// and awaited the handles deadlocked. A cancel that does not cancel is the half-wired feature this
|
|
75
|
+
// package's charter calls a defect outright.
|
|
71
76
|
internal.cancelled = true;
|
|
72
77
|
const cancelError = new DOMException('Load cancelled', 'AbortError');
|
|
73
78
|
// Abort all in-flight entries — runEntry will catch the abort and call checkCompleteAfterCancel
|
|
@@ -87,14 +92,14 @@ export function cancelResourceLoad(loader) {
|
|
|
87
92
|
};
|
|
88
93
|
internal.reports.push(report);
|
|
89
94
|
entry.reject(cancelError);
|
|
90
|
-
internal
|
|
95
|
+
_countEntrySettled(internal, entry);
|
|
91
96
|
releasePendingEntry(entry);
|
|
92
97
|
}
|
|
93
98
|
internal.pending = [];
|
|
94
99
|
emitSignal(loader.onCancel);
|
|
95
100
|
// Complete immediately if nothing is currently running
|
|
96
101
|
if (internal.inFlight.size === 0) {
|
|
97
|
-
emitSignal(loader.onProgress,
|
|
102
|
+
emitSignal(loader.onProgress, getResourceLoadProgress(loader));
|
|
98
103
|
emitSignal(loader.onComplete, internal.reports);
|
|
99
104
|
}
|
|
100
105
|
}
|
|
@@ -107,6 +112,7 @@ export function createResourceLoader(options) {
|
|
|
107
112
|
cancelled: false,
|
|
108
113
|
dedupeMap: new Map(),
|
|
109
114
|
errorPolicy: opts.errorPolicy ?? 'continue',
|
|
115
|
+
generation: 0,
|
|
110
116
|
inFlight: new Set(),
|
|
111
117
|
itemCounter: 0,
|
|
112
118
|
itemSignals: null,
|
|
@@ -158,6 +164,48 @@ export function enableResourceLoaderItemSignals(loader) {
|
|
|
158
164
|
}
|
|
159
165
|
return internal.itemSignals;
|
|
160
166
|
}
|
|
167
|
+
export function getResourceLoadBytes(loader) {
|
|
168
|
+
const internal = loader;
|
|
169
|
+
let bytesLoaded = 0;
|
|
170
|
+
let bytesTotalKnown = 0;
|
|
171
|
+
let itemsWithKnownBytes = 0;
|
|
172
|
+
// Settled items contribute their measured transfer; in-flight and queued contribute what they have
|
|
173
|
+
// reported and what they declared. A hint counts as known even before the item starts, which is what
|
|
174
|
+
// lets the known total grow ahead of the bytes rather than lag them.
|
|
175
|
+
for (const report of internal.reports) {
|
|
176
|
+
bytesLoaded += report.bytes;
|
|
177
|
+
if (report.bytes > 0) {
|
|
178
|
+
bytesTotalKnown += report.bytes;
|
|
179
|
+
itemsWithKnownBytes++;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
for (const entry of internal.inFlight) {
|
|
183
|
+
bytesLoaded += entry.bytesLoaded;
|
|
184
|
+
if (entry.bytesHint > 0) {
|
|
185
|
+
bytesTotalKnown += entry.bytesHint;
|
|
186
|
+
itemsWithKnownBytes++;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const entry of internal.pending) {
|
|
190
|
+
if (entry.bytesHint > 0) {
|
|
191
|
+
bytesTotalKnown += entry.bytesHint;
|
|
192
|
+
itemsWithKnownBytes++;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return { bytesLoaded, bytesTotalKnown, itemsWithKnownBytes };
|
|
196
|
+
}
|
|
197
|
+
export function getResourceLoadCounts(loader) {
|
|
198
|
+
const internal = loader;
|
|
199
|
+
const settledItems = internal.reports.length;
|
|
200
|
+
const inFlightItems = internal.inFlight.size;
|
|
201
|
+
const queuedItems = internal.pending.length;
|
|
202
|
+
return {
|
|
203
|
+
settledItems,
|
|
204
|
+
inFlightItems,
|
|
205
|
+
queuedItems,
|
|
206
|
+
totalItems: settledItems + inFlightItems + queuedItems,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
161
209
|
export function getResourceLoadItemStatus(loader, key) {
|
|
162
210
|
const internal = loader;
|
|
163
211
|
const report = internal.reports.find((r) => r.key === key);
|
|
@@ -171,6 +219,17 @@ export function getResourceLoadItemStatus(loader, key) {
|
|
|
171
219
|
}
|
|
172
220
|
return 'pending';
|
|
173
221
|
}
|
|
222
|
+
// The 0..1 completion fraction, and the single answer to "how far along is this batch" — the same
|
|
223
|
+
// number `onProgress` emits. Weighted by each item's `weight` (default 1), so an unweighted batch is
|
|
224
|
+
// the item fraction and a weighted one reflects the work the caller said each item represents.
|
|
225
|
+
//
|
|
226
|
+
// Weight is the contract currency because it is knowable before the first byte moves: the caller
|
|
227
|
+
// supplies it, so the bar starts at a truthful 0 and never rescales. Bytes cannot play that role —
|
|
228
|
+
// `bytesHint` is optional per item, so a byte denominator grows as headers arrive and the bar slides
|
|
229
|
+
// backwards. Bytes are reporting, via `getResourceLoadBytes`; counts are a separate question, via
|
|
230
|
+
// `getResourceLoadCounts`.
|
|
231
|
+
//
|
|
232
|
+
// Never returns NaN: every division below is guarded by the zero check in front of it.
|
|
174
233
|
export function getResourceLoadProgress(loader, group) {
|
|
175
234
|
const internal = loader;
|
|
176
235
|
if (!internal.started)
|
|
@@ -188,11 +247,16 @@ export function getResourceLoadProgress(loader, group) {
|
|
|
188
247
|
return 0;
|
|
189
248
|
return groupReports.length / groupTotal;
|
|
190
249
|
}
|
|
250
|
+
// A batch of nothing is complete rather than un-started: callers await a loader and branch on 1, and
|
|
251
|
+
// reporting 0 for an empty batch would strand that. Also the only guard against dividing by zero on
|
|
252
|
+
// `total` below.
|
|
191
253
|
if (internal.total === 0)
|
|
192
254
|
return 1;
|
|
193
255
|
if (internal.totalWeight > 0) {
|
|
194
256
|
return internal.weightLoaded / internal.totalWeight;
|
|
195
257
|
}
|
|
258
|
+
// Reached only when every item was explicitly given `weight: 0`, which makes the weighted fraction
|
|
259
|
+
// undefined; the item fraction is the sensible answer for a batch that declined to weight itself.
|
|
196
260
|
return internal.loaded / internal.total;
|
|
197
261
|
}
|
|
198
262
|
export function pauseResourceLoad(loader) {
|
|
@@ -234,6 +298,7 @@ export function queueResourceLoad(loader, item) {
|
|
|
234
298
|
// AbortController is fresh from acquirePendingEntry / releasePendingEntry
|
|
235
299
|
entry.bytesHint = bytesHint;
|
|
236
300
|
entry.bytesLoaded = 0;
|
|
301
|
+
entry.generation = internal.generation;
|
|
237
302
|
entry.group = group;
|
|
238
303
|
entry.key = key;
|
|
239
304
|
entry.onBytesProgress = onBytesProgress;
|
|
@@ -260,7 +325,14 @@ export function queueResourceLoad(loader, item) {
|
|
|
260
325
|
}
|
|
261
326
|
export function resetResourceLoader(loader) {
|
|
262
327
|
const internal = loader;
|
|
263
|
-
//
|
|
328
|
+
// Bump the generation first: every entry already dispatched is now orphaned, so when its abort
|
|
329
|
+
// finally rejects, runEntry discards it instead of recording a failure against the batch that
|
|
330
|
+
// replaced it. Without this an in-flight load surviving a reset lands on the *next* batch — a
|
|
331
|
+
// phantom onError for a key the new batch never queued, an extra report, and an inflated loaded
|
|
332
|
+
// count that can complete the new batch early.
|
|
333
|
+
internal.generation++;
|
|
334
|
+
// Abort all in-flight loads before reset. They are not released here: they are still running, and
|
|
335
|
+
// returning them to the pool would hand a live entry to the next queueResourceLoad.
|
|
264
336
|
for (const entry of internal.inFlight) {
|
|
265
337
|
entry.abortController.abort();
|
|
266
338
|
}
|
|
@@ -314,7 +386,7 @@ export function startResourceLoad(loader) {
|
|
|
314
386
|
return;
|
|
315
387
|
internal.started = true;
|
|
316
388
|
if (internal.total === 0) {
|
|
317
|
-
emitSignal(loader.onProgress,
|
|
389
|
+
emitSignal(loader.onProgress, getResourceLoadProgress(loader));
|
|
318
390
|
emitSignal(loader.onComplete, []);
|
|
319
391
|
return;
|
|
320
392
|
}
|
|
@@ -366,11 +438,27 @@ function abortSignalPromise(signal) {
|
|
|
366
438
|
});
|
|
367
439
|
}
|
|
368
440
|
async function runEntry(entry, internal, loader, attempt) {
|
|
441
|
+
if (_isOrphaned(entry, internal)) {
|
|
442
|
+
releasePendingEntry(entry);
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
369
445
|
if (internal.itemSignals !== null) {
|
|
370
446
|
emitSignal(internal.itemSignals.onItemStart, entry.key);
|
|
371
447
|
}
|
|
372
448
|
let timeoutId;
|
|
373
449
|
const signal = entry.abortController.signal;
|
|
450
|
+
// The byte reporter handed to this attempt. It is scoped to the attempt rather than to the entry
|
|
451
|
+
// because entries are pooled: a factory that reports after settling — a stream that flushes late, a
|
|
452
|
+
// retry whose predecessor is still draining — would otherwise write a byte count into whichever
|
|
453
|
+
// item had since been handed that record. `live` is closed over, so the report simply stops
|
|
454
|
+
// counting once the attempt is done, which is the honest answer for a figure nobody is waiting on.
|
|
455
|
+
let live = true;
|
|
456
|
+
const reportBytes = (loaded, total) => {
|
|
457
|
+
if (!live)
|
|
458
|
+
return;
|
|
459
|
+
entry.bytesLoaded = loaded;
|
|
460
|
+
entry.onBytesProgress?.(loaded, total ?? entry.bytesHint);
|
|
461
|
+
};
|
|
374
462
|
// Apply timeout if configured
|
|
375
463
|
if (entry.timeoutMs > 0) {
|
|
376
464
|
timeoutId = setTimeout(() => {
|
|
@@ -380,13 +468,19 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
380
468
|
try {
|
|
381
469
|
// Race the factory against the abort signal so cancellation/timeout is always honored,
|
|
382
470
|
// even if the factory itself does not check the signal.
|
|
383
|
-
const value = await Promise.race([entry.wrappedLoad(signal), abortSignalPromise(signal)]);
|
|
471
|
+
const value = await Promise.race([entry.wrappedLoad(signal, reportBytes), abortSignalPromise(signal)]);
|
|
384
472
|
if (timeoutId !== undefined)
|
|
385
473
|
clearTimeout(timeoutId);
|
|
474
|
+
live = false;
|
|
475
|
+
if (_isOrphaned(entry, internal)) {
|
|
476
|
+
internal.inFlight.delete(entry);
|
|
477
|
+
releasePendingEntry(entry);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
386
480
|
// If cancelled between the race resolving and here, treat as cancelled
|
|
387
481
|
if (internal.cancelled) {
|
|
388
482
|
internal.inFlight.delete(entry);
|
|
389
|
-
internal
|
|
483
|
+
_countEntrySettled(internal, entry);
|
|
390
484
|
releasePendingEntry(entry);
|
|
391
485
|
checkCompleteAfterCancel(internal, loader);
|
|
392
486
|
return;
|
|
@@ -401,7 +495,6 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
401
495
|
status: 'loaded',
|
|
402
496
|
};
|
|
403
497
|
internal.reports.push(report);
|
|
404
|
-
internal.weightLoaded += entry.weight;
|
|
405
498
|
entry.resolve(value);
|
|
406
499
|
if (internal.itemSignals !== null) {
|
|
407
500
|
emitSignal(internal.itemSignals.onItemComplete, entry.key, value);
|
|
@@ -411,6 +504,12 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
411
504
|
catch (error) {
|
|
412
505
|
if (timeoutId !== undefined)
|
|
413
506
|
clearTimeout(timeoutId);
|
|
507
|
+
live = false;
|
|
508
|
+
if (_isOrphaned(entry, internal)) {
|
|
509
|
+
internal.inFlight.delete(entry);
|
|
510
|
+
releasePendingEntry(entry);
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
414
513
|
// If cancelled, record as cancelled and update batch completion
|
|
415
514
|
if (internal.cancelled) {
|
|
416
515
|
const report = {
|
|
@@ -424,7 +523,7 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
424
523
|
internal.reports.push(report);
|
|
425
524
|
entry.reject(error);
|
|
426
525
|
internal.inFlight.delete(entry);
|
|
427
|
-
internal
|
|
526
|
+
_countEntrySettled(internal, entry);
|
|
428
527
|
releasePendingEntry(entry);
|
|
429
528
|
checkCompleteAfterCancel(internal, loader);
|
|
430
529
|
return;
|
|
@@ -440,7 +539,7 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
440
539
|
// Check again after delay in case cancelled
|
|
441
540
|
if (internal.cancelled) {
|
|
442
541
|
internal.inFlight.delete(entry);
|
|
443
|
-
internal
|
|
542
|
+
_countEntrySettled(internal, entry);
|
|
444
543
|
releasePendingEntry(entry);
|
|
445
544
|
checkCompleteAfterCancel(internal, loader);
|
|
446
545
|
return;
|
|
@@ -473,9 +572,27 @@ async function runEntry(entry, internal, loader, attempt) {
|
|
|
473
572
|
settleEntry(entry, internal, loader);
|
|
474
573
|
}
|
|
475
574
|
}
|
|
575
|
+
// Records one entry as finished, whatever its outcome. Both counters advance together and in exactly
|
|
576
|
+
// one place, because "how much of the batch is done" is one question with two units: `loaded` counts
|
|
577
|
+
// items, `weightLoaded` counts the weight the caller assigned them.
|
|
578
|
+
//
|
|
579
|
+
// The weight half used to advance only on success, so any batch containing a failure or a cancellation
|
|
580
|
+
// left getResourceLoadProgress permanently short of 1 — a weighted progress bar stuck at 0.67 on a
|
|
581
|
+
// batch that had already emitted onComplete. A failed item is still a finished item; progress measures
|
|
582
|
+
// completion, not success. (The per-item outcome is in its ResourceLoadReport.status, which is where a
|
|
583
|
+
// caller asks whether the batch went well.)
|
|
584
|
+
function _countEntrySettled(internal, entry) {
|
|
585
|
+
internal.loaded++;
|
|
586
|
+
internal.weightLoaded += entry.weight;
|
|
587
|
+
}
|
|
588
|
+
// True when `entry` was dispatched under a previous generation — i.e. resetResourceLoader ran while it
|
|
589
|
+
// was in flight — so nothing it reports belongs to the current batch.
|
|
590
|
+
function _isOrphaned(entry, internal) {
|
|
591
|
+
return entry.generation !== internal.generation;
|
|
592
|
+
}
|
|
476
593
|
function checkCompleteAfterCancel(internal, loader) {
|
|
477
594
|
if (internal.inFlight.size === 0) {
|
|
478
|
-
emitSignal(loader.onProgress,
|
|
595
|
+
emitSignal(loader.onProgress, getResourceLoadProgress(loader));
|
|
479
596
|
emitSignal(loader.onComplete, internal.reports);
|
|
480
597
|
}
|
|
481
598
|
}
|
|
@@ -492,7 +609,7 @@ function cancelRemainingEntries(internal) {
|
|
|
492
609
|
};
|
|
493
610
|
internal.reports.push(report);
|
|
494
611
|
entry.reject(new DOMException('Load skipped due to fail-fast error policy', 'AbortError'));
|
|
495
|
-
internal
|
|
612
|
+
_countEntrySettled(internal, entry);
|
|
496
613
|
releasePendingEntry(entry);
|
|
497
614
|
}
|
|
498
615
|
internal.pending = [];
|
|
@@ -515,8 +632,8 @@ function delay(ms) {
|
|
|
515
632
|
}
|
|
516
633
|
function settleEntry(entry, internal, loader) {
|
|
517
634
|
internal.inFlight.delete(entry);
|
|
518
|
-
internal
|
|
519
|
-
emitSignal(loader.onProgress,
|
|
635
|
+
_countEntrySettled(internal, entry);
|
|
636
|
+
emitSignal(loader.onProgress, getResourceLoadProgress(loader));
|
|
520
637
|
releasePendingEntry(entry);
|
|
521
638
|
if (internal.loaded === internal.total) {
|
|
522
639
|
emitSignal(loader.onComplete, internal.reports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resourceLoader.js","sourceRoot":"","sources":["../src/resourceLoader.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"resourceLoader.js","sourceRoot":"","sources":["../src/resourceLoader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/loader",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1-next.209.43ef1bc",
|
|
4
|
+
"author": "Joshua Granick and other contributors",
|
|
5
|
+
"license": "MIT",
|
|
4
6
|
"repository": {
|
|
5
7
|
"type": "git",
|
|
6
8
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -36,8 +38,8 @@
|
|
|
36
38
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
37
39
|
},
|
|
38
40
|
"dependencies": {
|
|
39
|
-
"@flighthq/signals": "0.3.
|
|
40
|
-
"@flighthq/types": "0.3.
|
|
41
|
+
"@flighthq/signals": "0.3.1-next.209.43ef1bc",
|
|
42
|
+
"@flighthq/types": "0.3.1-next.209.43ef1bc"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"typescript": "^5.3.0"
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
disposeResourceLoader,
|
|
8
8
|
enableResourceLoaderItemSignals,
|
|
9
9
|
getResourceLoadItemStatus,
|
|
10
|
+
getResourceLoadBytes,
|
|
11
|
+
getResourceLoadCounts,
|
|
10
12
|
getResourceLoadProgress,
|
|
11
13
|
pauseResourceLoad,
|
|
12
14
|
queueResourceLoad,
|
|
@@ -150,6 +152,165 @@ describe('bandwidth throttle (maxBytesPerSecond)', () => {
|
|
|
150
152
|
});
|
|
151
153
|
});
|
|
152
154
|
|
|
155
|
+
describe('byte progress', () => {
|
|
156
|
+
// The whole surface was structurally dead: onBytesProgress was stored and never called,
|
|
157
|
+
// entry.bytesLoaded was never written, and ResourceLoadReport.bytes was therefore always 0. The
|
|
158
|
+
// missing piece was that the loader cannot know a transfer's byte count — only the factory can — so
|
|
159
|
+
// the factory now receives a reporter as a second argument. Additive by design: a one-argument
|
|
160
|
+
// factory keeps working and simply never reports.
|
|
161
|
+
it('hands the factory a reporter as its second argument', async () => {
|
|
162
|
+
const loader = createResourceLoader();
|
|
163
|
+
let received: string = 'none';
|
|
164
|
+
queueResourceLoad(loader, {
|
|
165
|
+
key: 'a',
|
|
166
|
+
load: (_signal, reportBytes) => {
|
|
167
|
+
received = typeof reportBytes;
|
|
168
|
+
return Promise.resolve('v');
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
startResourceLoad(loader);
|
|
172
|
+
await waitForComplete(loader);
|
|
173
|
+
expect(received).toBe('function');
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
it('forwards every reported figure to onBytesProgress', async () => {
|
|
177
|
+
const loader = createResourceLoader();
|
|
178
|
+
const seen: string[] = [];
|
|
179
|
+
queueResourceLoad(loader, {
|
|
180
|
+
key: 'a',
|
|
181
|
+
bytesHint: 1000,
|
|
182
|
+
onBytesProgress: (loaded, total) => seen.push(`${loaded}/${total}`),
|
|
183
|
+
load: (_signal, reportBytes) => {
|
|
184
|
+
reportBytes(250);
|
|
185
|
+
reportBytes(600, 1200);
|
|
186
|
+
return Promise.resolve('v');
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
startResourceLoad(loader);
|
|
190
|
+
await waitForComplete(loader);
|
|
191
|
+
expect(seen).toEqual(['250/1000', '600/1200']);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('falls back to bytesHint for the total when the factory reports only what has arrived', async () => {
|
|
195
|
+
const loader = createResourceLoader();
|
|
196
|
+
const totals: number[] = [];
|
|
197
|
+
queueResourceLoad(loader, {
|
|
198
|
+
key: 'a',
|
|
199
|
+
bytesHint: 4096,
|
|
200
|
+
onBytesProgress: (_loaded, total) => totals.push(total),
|
|
201
|
+
load: (_signal, reportBytes) => {
|
|
202
|
+
reportBytes(1);
|
|
203
|
+
return Promise.resolve('v');
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
startResourceLoad(loader);
|
|
207
|
+
await waitForComplete(loader);
|
|
208
|
+
expect(totals).toEqual([4096]);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it("reports the last figure as the item's bytes", async () => {
|
|
212
|
+
const loader = createResourceLoader();
|
|
213
|
+
queueResourceLoad(loader, {
|
|
214
|
+
key: 'a',
|
|
215
|
+
load: (_signal, reportBytes) => {
|
|
216
|
+
reportBytes(10);
|
|
217
|
+
reportBytes(9000);
|
|
218
|
+
return Promise.resolve('v');
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
startResourceLoad(loader);
|
|
222
|
+
const reports = await waitForComplete(loader);
|
|
223
|
+
expect(reports[0].bytes).toBe(9000);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
it('leaves bytes at zero for a factory that reports nothing', async () => {
|
|
227
|
+
const loader = createResourceLoader();
|
|
228
|
+
queueResourceLoad(loader, { key: 'a', load: () => Promise.resolve('v') });
|
|
229
|
+
startResourceLoad(loader);
|
|
230
|
+
const reports = await waitForComplete(loader);
|
|
231
|
+
expect(reports[0].bytes).toBe(0);
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
it('runs a one-argument factory untouched, which is what makes the seam additive', async () => {
|
|
235
|
+
// The reason this shape was chosen over changing the signature: existing callers keep compiling
|
|
236
|
+
// and keep working, and only a factory that can observe its transfer opts in.
|
|
237
|
+
const loader = createResourceLoader();
|
|
238
|
+
queueResourceLoad(loader, { key: 'a', load: (signal: AbortSignal) => Promise.resolve(signal.aborted) });
|
|
239
|
+
queueResourceLoad(loader, () => Promise.resolve('thunk'));
|
|
240
|
+
startResourceLoad(loader);
|
|
241
|
+
const reports = await waitForComplete(loader);
|
|
242
|
+
expect(reports.map((r) => r.status)).toEqual(['loaded', 'loaded']);
|
|
243
|
+
expect(reports.every((r) => r.bytes === 0)).toBe(true);
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
it('ignores a report that arrives after the load has settled', async () => {
|
|
247
|
+
// Entries are pooled, so a late report — a stream flushing after resolve — would otherwise write
|
|
248
|
+
// a byte count into whichever item had since been handed that record.
|
|
249
|
+
const loader = createResourceLoader();
|
|
250
|
+
const seen: number[] = [];
|
|
251
|
+
let late: ((loaded: number) => void) | null = null;
|
|
252
|
+
queueResourceLoad(loader, {
|
|
253
|
+
key: 'a',
|
|
254
|
+
bytesHint: 100,
|
|
255
|
+
onBytesProgress: (loaded) => seen.push(loaded),
|
|
256
|
+
load: (_signal, reportBytes) => {
|
|
257
|
+
reportBytes(5);
|
|
258
|
+
late = reportBytes;
|
|
259
|
+
return Promise.resolve('v');
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
startResourceLoad(loader);
|
|
263
|
+
const reports = await waitForComplete(loader);
|
|
264
|
+
expect(seen).toEqual([5]);
|
|
265
|
+
|
|
266
|
+
late!(999);
|
|
267
|
+
expect(seen).toEqual([5]);
|
|
268
|
+
expect(reports[0].bytes).toBe(5);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
it('does not let a stale reporter write bytes into the item that recycled its record', async () => {
|
|
272
|
+
// The hazard the guard actually exists for, and the one the test above does NOT cover: entries are
|
|
273
|
+
// pooled, so once item A settles its record is handed to the next item queued. A reporter A kept
|
|
274
|
+
// hold of would then be writing B's byte count. Asserting on A's own report cannot see this —
|
|
275
|
+
// that number was already copied out at settle time — so this asserts on B.
|
|
276
|
+
const first = createResourceLoader();
|
|
277
|
+
let stale: ((loaded: number) => void) | null = null;
|
|
278
|
+
queueResourceLoad(first, {
|
|
279
|
+
key: 'a',
|
|
280
|
+
load: (_signal, reportBytes) => {
|
|
281
|
+
stale = reportBytes;
|
|
282
|
+
reportBytes(5);
|
|
283
|
+
return Promise.resolve('v');
|
|
284
|
+
},
|
|
285
|
+
});
|
|
286
|
+
startResourceLoad(first);
|
|
287
|
+
await waitForComplete(first);
|
|
288
|
+
|
|
289
|
+
// A fresh batch reuses the pooled record A just released.
|
|
290
|
+
const second = createResourceLoader();
|
|
291
|
+
queueResourceLoad(second, {
|
|
292
|
+
key: 'b',
|
|
293
|
+
load: (_signal, reportBytes) => {
|
|
294
|
+
reportBytes(11);
|
|
295
|
+
stale!(999999);
|
|
296
|
+
return Promise.resolve('v');
|
|
297
|
+
},
|
|
298
|
+
});
|
|
299
|
+
startResourceLoad(second);
|
|
300
|
+
const reports = await waitForComplete(second);
|
|
301
|
+
expect(reports[0].key).toBe('b');
|
|
302
|
+
expect(reports[0].bytes).toBe(11);
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
it('still lets bytesHint drive the throttle, which never depended on the factory', async () => {
|
|
306
|
+
const loader = createResourceLoader({ maxBytesPerSecond: 1000 });
|
|
307
|
+
queueResourceLoad(loader, { key: 'a', bytesHint: 10, load: () => Promise.resolve('v') });
|
|
308
|
+
startResourceLoad(loader);
|
|
309
|
+
const reports = await waitForComplete(loader);
|
|
310
|
+
expect(reports[0].status).toBe('loaded');
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
|
|
153
314
|
describe('bytes progress', () => {
|
|
154
315
|
it('records bytes in ResourceLoadReport when factory calls onBytesProgress', async () => {
|
|
155
316
|
const loader = createResourceLoader();
|
|
@@ -231,14 +392,43 @@ describe('cancelResourceLoad', () => {
|
|
|
231
392
|
await expect(handle.promise).rejects.toThrow();
|
|
232
393
|
});
|
|
233
394
|
|
|
234
|
-
it('
|
|
395
|
+
it('cancels a batch that has not started, instead of stranding its promises', async () => {
|
|
396
|
+
// This replaces an assertion that cancel-before-start emits nothing. It did emit nothing — and it
|
|
397
|
+
// also left every queued handle pending forever, so a caller that queued a batch, changed its
|
|
398
|
+
// mind, and awaited the handles simply hung. Nothing observable said so, because the old test
|
|
399
|
+
// only watched the signal.
|
|
235
400
|
const loader = createResourceLoader();
|
|
236
401
|
let cancelled = false;
|
|
237
402
|
connectSignal(loader.onCancel, () => {
|
|
238
403
|
cancelled = true;
|
|
239
404
|
});
|
|
405
|
+
const handle = queueResourceLoad(loader, { key: 'a', load: () => Promise.resolve(1) });
|
|
240
406
|
cancelResourceLoad(loader);
|
|
241
|
-
expect(
|
|
407
|
+
await expect(handle.promise).rejects.toThrow();
|
|
408
|
+
expect(cancelled).toBe(true);
|
|
409
|
+
});
|
|
410
|
+
|
|
411
|
+
it('emits onCancel with no queued items, and stays a no-op on a second call', () => {
|
|
412
|
+
const loader = createResourceLoader();
|
|
413
|
+
let cancelCount = 0;
|
|
414
|
+
connectSignal(loader.onCancel, () => {
|
|
415
|
+
cancelCount++;
|
|
416
|
+
});
|
|
417
|
+
cancelResourceLoad(loader);
|
|
418
|
+
cancelResourceLoad(loader);
|
|
419
|
+
expect(cancelCount).toBe(1);
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
it('reports a cancelled-before-start item as cancelled', async () => {
|
|
423
|
+
const loader = createResourceLoader();
|
|
424
|
+
let reports: readonly ResourceLoadReport[] = [];
|
|
425
|
+
connectSignal(loader.onComplete, (r) => {
|
|
426
|
+
reports = r;
|
|
427
|
+
});
|
|
428
|
+
queueResourceLoad(loader, { key: 'a', load: () => Promise.resolve(1) }).promise.catch(() => {});
|
|
429
|
+
cancelResourceLoad(loader);
|
|
430
|
+
await Promise.resolve();
|
|
431
|
+
expect(reports.map((r) => r.status)).toEqual(['cancelled']);
|
|
242
432
|
});
|
|
243
433
|
|
|
244
434
|
it('is a no-op if already cancelled', async () => {
|
|
@@ -420,6 +610,113 @@ describe('error policy', () => {
|
|
|
420
610
|
});
|
|
421
611
|
});
|
|
422
612
|
|
|
613
|
+
describe('getResourceLoadBytes', () => {
|
|
614
|
+
it('reports zeros for a loader with nothing queued', () => {
|
|
615
|
+
expect(getResourceLoadBytes(createResourceLoader())).toEqual({
|
|
616
|
+
bytesLoaded: 0,
|
|
617
|
+
bytesTotalKnown: 0,
|
|
618
|
+
itemsWithKnownBytes: 0,
|
|
619
|
+
});
|
|
620
|
+
});
|
|
621
|
+
|
|
622
|
+
// The known total is a floor that grows, never a denominator: itemsWithKnownBytes is what tells the
|
|
623
|
+
// caller how much of the batch it actually covers.
|
|
624
|
+
it('counts only the items that declared a size toward the known total', () => {
|
|
625
|
+
const loader = createResourceLoader();
|
|
626
|
+
queueResourceLoad(loader, { bytesHint: 1000, load: () => Promise.resolve('a') });
|
|
627
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('b') });
|
|
628
|
+
|
|
629
|
+
const bytes = getResourceLoadBytes(loader);
|
|
630
|
+
|
|
631
|
+
expect(bytes.bytesTotalKnown).toBe(1000);
|
|
632
|
+
expect(bytes.itemsWithKnownBytes).toBe(1);
|
|
633
|
+
expect(bytes.bytesLoaded).toBe(0);
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it('accumulates transferred bytes as items settle', async () => {
|
|
637
|
+
const loader = createResourceLoader();
|
|
638
|
+
queueResourceLoad(loader, {
|
|
639
|
+
bytesHint: 8,
|
|
640
|
+
load: async (_signal, reportBytes) => {
|
|
641
|
+
reportBytes(8, 8);
|
|
642
|
+
return 'a';
|
|
643
|
+
},
|
|
644
|
+
});
|
|
645
|
+
startResourceLoad(loader);
|
|
646
|
+
await waitForComplete(loader);
|
|
647
|
+
|
|
648
|
+
expect(getResourceLoadBytes(loader).bytesLoaded).toBe(8);
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('stays valid when no item declares a size', async () => {
|
|
652
|
+
const loader = createResourceLoader();
|
|
653
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('a') });
|
|
654
|
+
startResourceLoad(loader);
|
|
655
|
+
await waitForComplete(loader);
|
|
656
|
+
|
|
657
|
+
const bytes = getResourceLoadBytes(loader);
|
|
658
|
+
expect(Number.isNaN(bytes.bytesTotalKnown)).toBe(false);
|
|
659
|
+
expect(bytes.itemsWithKnownBytes).toBe(0);
|
|
660
|
+
});
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
describe('getResourceLoadCounts', () => {
|
|
664
|
+
it('reports zeros for a loader with nothing queued', () => {
|
|
665
|
+
expect(getResourceLoadCounts(createResourceLoader())).toEqual({
|
|
666
|
+
settledItems: 0,
|
|
667
|
+
inFlightItems: 0,
|
|
668
|
+
queuedItems: 0,
|
|
669
|
+
totalItems: 0,
|
|
670
|
+
});
|
|
671
|
+
});
|
|
672
|
+
|
|
673
|
+
it('counts queued items before the load starts', () => {
|
|
674
|
+
const loader = createResourceLoader();
|
|
675
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('a') });
|
|
676
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('b') });
|
|
677
|
+
|
|
678
|
+
const counts = getResourceLoadCounts(loader);
|
|
679
|
+
|
|
680
|
+
expect(counts.queuedItems).toBe(2);
|
|
681
|
+
expect(counts.totalItems).toBe(2);
|
|
682
|
+
expect(counts.settledItems).toBe(0);
|
|
683
|
+
});
|
|
684
|
+
|
|
685
|
+
// In-flight and queued are separate numbers because a concurrency limit makes them differ, and a UI
|
|
686
|
+
// showing "loading 1 of 3" means the in-flight count rather than the queue depth.
|
|
687
|
+
it('separates in-flight from still-queued under a concurrency limit', async () => {
|
|
688
|
+
const loader = createResourceLoader({ maxConcurrent: 1 });
|
|
689
|
+
let release: (() => void) | null = null;
|
|
690
|
+
queueResourceLoad(loader, { load: () => new Promise<string>((resolve) => (release = () => resolve('a'))) });
|
|
691
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('b') });
|
|
692
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('c') });
|
|
693
|
+
startResourceLoad(loader);
|
|
694
|
+
await Promise.resolve();
|
|
695
|
+
|
|
696
|
+
const counts = getResourceLoadCounts(loader);
|
|
697
|
+
expect(counts.inFlightItems).toBe(1);
|
|
698
|
+
expect(counts.queuedItems).toBe(2);
|
|
699
|
+
expect(counts.totalItems).toBe(3);
|
|
700
|
+
|
|
701
|
+
release!();
|
|
702
|
+
await waitForComplete(loader);
|
|
703
|
+
});
|
|
704
|
+
|
|
705
|
+
it('counts every finished item as settled, including a failure', async () => {
|
|
706
|
+
const loader = createResourceLoader();
|
|
707
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('ok') }).promise.catch(() => {});
|
|
708
|
+
queueResourceLoad(loader, { load: () => Promise.reject(new Error('nope')), retries: 0 }).promise.catch(() => {});
|
|
709
|
+
startResourceLoad(loader);
|
|
710
|
+
await waitForComplete(loader);
|
|
711
|
+
|
|
712
|
+
const counts = getResourceLoadCounts(loader);
|
|
713
|
+
expect(counts.settledItems).toBe(2);
|
|
714
|
+
expect(counts.totalItems).toBe(2);
|
|
715
|
+
expect(counts.inFlightItems).toBe(0);
|
|
716
|
+
expect(counts.queuedItems).toBe(0);
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
|
|
423
720
|
describe('getResourceLoadItemStatus', () => {
|
|
424
721
|
it('returns pending for a queued but unstarted item', () => {
|
|
425
722
|
const loader = createResourceLoader();
|
|
@@ -654,9 +951,9 @@ describe('queueResourceLoad', () => {
|
|
|
654
951
|
|
|
655
952
|
it('fires onProgress after each item completes', async () => {
|
|
656
953
|
const loader = createResourceLoader({ maxConcurrent: 1 });
|
|
657
|
-
const progress:
|
|
658
|
-
connectSignal(loader.onProgress, (
|
|
659
|
-
progress.push(
|
|
954
|
+
const progress: number[] = [];
|
|
955
|
+
connectSignal(loader.onProgress, (fraction) => {
|
|
956
|
+
progress.push(fraction);
|
|
660
957
|
});
|
|
661
958
|
|
|
662
959
|
queueResourceLoad(loader, { load: () => Promise.resolve('a') });
|
|
@@ -667,7 +964,26 @@ describe('queueResourceLoad', () => {
|
|
|
667
964
|
await waitForComplete(loader);
|
|
668
965
|
|
|
669
966
|
expect(progress).toHaveLength(3);
|
|
670
|
-
expect(progress[2]).
|
|
967
|
+
expect(progress[2]).toBe(1);
|
|
968
|
+
});
|
|
969
|
+
|
|
970
|
+
// The signal and the accessor are one number now. A weighted batch is where they used to diverge:
|
|
971
|
+
// the signal reported item counts (1 of 2 = 0.5) while the accessor reported weight (0.01).
|
|
972
|
+
it('emits the same fraction the accessor reports, on a weighted batch', async () => {
|
|
973
|
+
const loader = createResourceLoader({ maxConcurrent: 1 });
|
|
974
|
+
const seen: number[] = [];
|
|
975
|
+
connectSignal(loader.onProgress, (fraction) => {
|
|
976
|
+
seen.push(fraction);
|
|
977
|
+
expect(fraction).toBe(getResourceLoadProgress(loader));
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('small'), weight: 1 });
|
|
981
|
+
queueResourceLoad(loader, { load: () => Promise.resolve('big'), weight: 99 });
|
|
982
|
+
startResourceLoad(loader);
|
|
983
|
+
await waitForComplete(loader);
|
|
984
|
+
|
|
985
|
+
expect(seen[0]).toBeCloseTo(0.01, 5);
|
|
986
|
+
expect(seen[1]).toBe(1);
|
|
671
987
|
});
|
|
672
988
|
|
|
673
989
|
it('fires onComplete after all items finish', async () => {
|
|
@@ -794,6 +1110,59 @@ describe('queueResourceLoad', () => {
|
|
|
794
1110
|
});
|
|
795
1111
|
});
|
|
796
1112
|
|
|
1113
|
+
describe('reset while loading', () => {
|
|
1114
|
+
// The regression this pins: an in-flight load surviving a reset used to settle against whatever
|
|
1115
|
+
// batch had replaced it — a phantom onError for a key the new batch never queued, an extra report,
|
|
1116
|
+
// and an inflated loaded count that could complete the new batch early.
|
|
1117
|
+
it('discards an in-flight load rather than settling it against the next batch', async () => {
|
|
1118
|
+
const loader = createResourceLoader();
|
|
1119
|
+
const errorKeys: string[] = [];
|
|
1120
|
+
connectSignal(loader.onError, (_error, key) => errorKeys.push(key));
|
|
1121
|
+
|
|
1122
|
+
let release!: () => void;
|
|
1123
|
+
queueResourceLoad(loader, {
|
|
1124
|
+
key: 'stale',
|
|
1125
|
+
load: () => new Promise((resolve) => (release = () => resolve('v'))),
|
|
1126
|
+
}).promise.catch(() => {});
|
|
1127
|
+
startResourceLoad(loader);
|
|
1128
|
+
await Promise.resolve();
|
|
1129
|
+
|
|
1130
|
+
resetResourceLoader(loader);
|
|
1131
|
+
|
|
1132
|
+
queueResourceLoad(loader, { key: 'fresh', load: () => Promise.resolve('ok') });
|
|
1133
|
+
startResourceLoad(loader);
|
|
1134
|
+
const reports = await waitForComplete(loader);
|
|
1135
|
+
|
|
1136
|
+
release();
|
|
1137
|
+
await new Promise((resolve) => setTimeout(resolve, 5));
|
|
1138
|
+
|
|
1139
|
+
expect(errorKeys).toEqual([]);
|
|
1140
|
+
expect(reports.map((r) => r.key)).toEqual(['fresh']);
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
it('does not let a stale load inflate the new batch progress', async () => {
|
|
1144
|
+
const loader = createResourceLoader();
|
|
1145
|
+
connectSignal(loader.onError, () => {});
|
|
1146
|
+
let release!: () => void;
|
|
1147
|
+
queueResourceLoad(loader, {
|
|
1148
|
+
key: 'stale',
|
|
1149
|
+
load: () => new Promise((_resolve, reject) => (release = () => reject(new Error('late')))),
|
|
1150
|
+
}).promise.catch(() => {});
|
|
1151
|
+
startResourceLoad(loader);
|
|
1152
|
+
await Promise.resolve();
|
|
1153
|
+
|
|
1154
|
+
resetResourceLoader(loader);
|
|
1155
|
+
queueResourceLoad(loader, { key: 'one', load: () => Promise.resolve(1) });
|
|
1156
|
+
queueResourceLoad(loader, { key: 'two', load: () => Promise.resolve(2) });
|
|
1157
|
+
startResourceLoad(loader);
|
|
1158
|
+
|
|
1159
|
+
release();
|
|
1160
|
+
const reports = await waitForComplete(loader);
|
|
1161
|
+
expect(reports.length).toBe(2);
|
|
1162
|
+
expect(getResourceLoadProgress(loader)).toBe(1);
|
|
1163
|
+
});
|
|
1164
|
+
});
|
|
1165
|
+
|
|
797
1166
|
describe('resetResourceLoader', () => {
|
|
798
1167
|
it('allows the loader to be reused for another batch', async () => {
|
|
799
1168
|
const loader = createResourceLoader();
|
|
@@ -954,14 +1323,15 @@ describe('startResourceLoad', () => {
|
|
|
954
1323
|
expect(called).toBe(true);
|
|
955
1324
|
});
|
|
956
1325
|
|
|
957
|
-
|
|
1326
|
+
// A batch of nothing is complete, not un-started: callers await a loader and branch on 1.
|
|
1327
|
+
it('fires onProgress(1) for an empty queue', () => {
|
|
958
1328
|
const loader = createResourceLoader();
|
|
959
|
-
let
|
|
960
|
-
connectSignal(loader.onProgress, (
|
|
961
|
-
|
|
1329
|
+
let seen: number | null = null;
|
|
1330
|
+
connectSignal(loader.onProgress, (fraction) => {
|
|
1331
|
+
seen = fraction;
|
|
962
1332
|
});
|
|
963
1333
|
startResourceLoad(loader);
|
|
964
|
-
expect(
|
|
1334
|
+
expect(seen).toBe(1);
|
|
965
1335
|
});
|
|
966
1336
|
|
|
967
1337
|
it('is a no-op if called a second time in non-streaming mode', () => {
|
|
@@ -1027,3 +1397,66 @@ describe('weight-aware progress', () => {
|
|
|
1027
1397
|
expect(progressValues[1]).toBeCloseTo(1.0);
|
|
1028
1398
|
});
|
|
1029
1399
|
});
|
|
1400
|
+
|
|
1401
|
+
describe('weighted progress across outcomes', () => {
|
|
1402
|
+
// The regression these pin: weightLoaded advanced only on success, so any batch containing a
|
|
1403
|
+
// failure, a cancellation, or a fail-fast skip left getResourceLoadProgress permanently short of 1
|
|
1404
|
+
// — a weighted progress bar frozen mid-way on a batch that had already emitted onComplete.
|
|
1405
|
+
it('reaches 1 after a batch containing a failure completes', async () => {
|
|
1406
|
+
const loader = createResourceLoader();
|
|
1407
|
+
connectSignal(loader.onError, () => {});
|
|
1408
|
+
queueResourceLoad(loader, { key: 'a', load: () => Promise.resolve(1), weight: 1 });
|
|
1409
|
+
queueResourceLoad(loader, { key: 'b', load: () => Promise.reject(new Error('boom')), weight: 1 }).promise.catch(
|
|
1410
|
+
() => {},
|
|
1411
|
+
);
|
|
1412
|
+
queueResourceLoad(loader, { key: 'c', load: () => Promise.resolve(3), weight: 1 });
|
|
1413
|
+
startResourceLoad(loader);
|
|
1414
|
+
await waitForComplete(loader);
|
|
1415
|
+
expect(getResourceLoadProgress(loader)).toBe(1);
|
|
1416
|
+
});
|
|
1417
|
+
|
|
1418
|
+
it('weights the failure by its own weight, not by an item count', async () => {
|
|
1419
|
+
const loader = createResourceLoader({ maxConcurrent: 1 });
|
|
1420
|
+
connectSignal(loader.onError, () => {});
|
|
1421
|
+
const seen: number[] = [];
|
|
1422
|
+
connectSignal(loader.onProgress, () => seen.push(getResourceLoadProgress(loader)));
|
|
1423
|
+
queueResourceLoad(loader, { key: 'a', load: () => Promise.reject(new Error('boom')), weight: 90 }).promise.catch(
|
|
1424
|
+
() => {},
|
|
1425
|
+
);
|
|
1426
|
+
queueResourceLoad(loader, { key: 'b', load: () => Promise.resolve(1), weight: 10 });
|
|
1427
|
+
startResourceLoad(loader);
|
|
1428
|
+
await waitForComplete(loader);
|
|
1429
|
+
expect(seen[0]).toBeCloseTo(0.9);
|
|
1430
|
+
expect(seen[1]).toBeCloseTo(1);
|
|
1431
|
+
});
|
|
1432
|
+
|
|
1433
|
+
it('reaches 1 after a fail-fast batch skips the rest', async () => {
|
|
1434
|
+
const loader = createResourceLoader({ errorPolicy: 'fail-fast', maxConcurrent: 1 });
|
|
1435
|
+
connectSignal(loader.onError, () => {});
|
|
1436
|
+
queueResourceLoad(loader, { key: 'a', load: () => Promise.reject(new Error('boom')), weight: 5 }).promise.catch(
|
|
1437
|
+
() => {},
|
|
1438
|
+
);
|
|
1439
|
+
queueResourceLoad(loader, { key: 'b', load: () => Promise.resolve(1), weight: 5 }).promise.catch(() => {});
|
|
1440
|
+
startResourceLoad(loader);
|
|
1441
|
+
await waitForComplete(loader);
|
|
1442
|
+
expect(getResourceLoadProgress(loader)).toBe(1);
|
|
1443
|
+
});
|
|
1444
|
+
|
|
1445
|
+
it('reaches 1 after a cancelled batch settles', async () => {
|
|
1446
|
+
const loader = createResourceLoader({ maxConcurrent: 1 });
|
|
1447
|
+
let release!: () => void;
|
|
1448
|
+
queueResourceLoad(loader, {
|
|
1449
|
+
key: 'slow',
|
|
1450
|
+
load: () => new Promise((resolve) => (release = () => resolve(1))),
|
|
1451
|
+
weight: 3,
|
|
1452
|
+
}).promise.catch(() => {});
|
|
1453
|
+
queueResourceLoad(loader, { key: 'queued', load: () => Promise.resolve(2), weight: 7 }).promise.catch(() => {});
|
|
1454
|
+
startResourceLoad(loader);
|
|
1455
|
+
await Promise.resolve();
|
|
1456
|
+
const completed = waitForComplete(loader);
|
|
1457
|
+
cancelResourceLoad(loader);
|
|
1458
|
+
release();
|
|
1459
|
+
await completed;
|
|
1460
|
+
expect(getResourceLoadProgress(loader)).toBe(1);
|
|
1461
|
+
});
|
|
1462
|
+
});
|