web-sdk-pp-detection 0.3.1 → 0.3.2
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 +19 -15
- package/dist/browser-global.js +202 -73
- package/dist/browser-global.js.map +1 -1
- package/dist/index.d.ts +15 -2
- package/dist/index.js +202 -73
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -138,9 +138,17 @@ interface PPDetectionProgressEvent {
|
|
|
138
138
|
readonly status: "start" | "progress" | "complete";
|
|
139
139
|
readonly loadedBytes?: number;
|
|
140
140
|
readonly totalBytes?: number;
|
|
141
|
+
readonly attempt?: number;
|
|
142
|
+
readonly maxAttempts?: number;
|
|
141
143
|
readonly fallback?: PPDetectionFallback;
|
|
142
144
|
}
|
|
145
|
+
interface ModelDownloadOptions {
|
|
146
|
+
readonly timeoutMs?: number;
|
|
147
|
+
readonly idleTimeoutMs?: number;
|
|
148
|
+
readonly maxRetries?: number;
|
|
149
|
+
}
|
|
143
150
|
interface CreatePPDetectionOptions {
|
|
151
|
+
readonly download?: ModelDownloadOptions;
|
|
144
152
|
readonly allowExperimental?: boolean;
|
|
145
153
|
readonly allowFallback?: boolean;
|
|
146
154
|
readonly backend?: BackendPreference;
|
|
@@ -518,10 +526,13 @@ type ModelFetcher = (input: RequestInfo | URL, init?: RequestInit) => Promise<Re
|
|
|
518
526
|
interface ModelDownloadProgress {
|
|
519
527
|
readonly loadedBytes: number;
|
|
520
528
|
readonly totalBytes?: number;
|
|
529
|
+
readonly attempt?: number;
|
|
530
|
+
readonly maxAttempts?: number;
|
|
521
531
|
}
|
|
522
532
|
interface LoadModelAssetOptions {
|
|
523
533
|
readonly fetcher?: ModelFetcher;
|
|
524
534
|
readonly signal?: AbortSignal;
|
|
535
|
+
readonly download?: ModelDownloadOptions;
|
|
525
536
|
readonly onProgress?: (progress: ModelDownloadProgress) => void;
|
|
526
537
|
}
|
|
527
538
|
interface ModelBytes {
|
|
@@ -549,6 +560,7 @@ interface ModelCache {
|
|
|
549
560
|
}
|
|
550
561
|
|
|
551
562
|
interface ModelManagerOptions {
|
|
563
|
+
readonly download?: ModelDownloadOptions;
|
|
552
564
|
readonly fetcher?: ModelFetcher;
|
|
553
565
|
readonly cache?: "memory" | "indexeddb" | false | ModelCache;
|
|
554
566
|
}
|
|
@@ -576,6 +588,7 @@ interface LoadedManagedModel {
|
|
|
576
588
|
}
|
|
577
589
|
declare class ModelManager {
|
|
578
590
|
private readonly fetcher?;
|
|
591
|
+
private readonly download;
|
|
579
592
|
private readonly cache;
|
|
580
593
|
private readonly coordinator;
|
|
581
594
|
private readonly lifecycle;
|
|
@@ -635,11 +648,11 @@ declare class IndexedDBModelCache implements ModelCache {
|
|
|
635
648
|
declare global {
|
|
636
649
|
var __PPDETECTION_SCRIPT_URL__: string | undefined;
|
|
637
650
|
}
|
|
638
|
-
declare const CURRENT_SDK_VERSION = "0.3.
|
|
651
|
+
declare const CURRENT_SDK_VERSION = "0.3.2";
|
|
639
652
|
|
|
640
653
|
declare function probePPDetectionCapabilities(options?: CapabilityProbeOptions): DetectionCapabilities;
|
|
641
654
|
|
|
642
655
|
declare function createPPDetection(options?: CreatePPDetectionOptions): Promise<PPDetectionDetectorImplementation>;
|
|
643
656
|
declare function clearModelCache(): Promise<void>;
|
|
644
657
|
|
|
645
|
-
export { type Backend, type BackendPreference, CURRENT_SDK_VERSION, type CacheEstimate, type CapabilityProbeOptions, type CreateOrtSessionOptions, type CreatePPDetectionOptions, type DecodedImage, type DetectOptions, type Detection, type DetectionBox, type DetectionCapabilities, type DetectionManifest, type DetectionModelVariant, type DetectionPoint, type DetectionPostprocessing, type DetectionPreprocessing, type DetectionTimings, type ExecutionCandidate, type ExecutionMode, type ExecutionPlan, type ImageRaster, type ImageSource, IndexedDBModelCache, type IndexedDBModelCacheOptions, type LoadManagedModelOptions, type LoadModelAssetOptions, type LoadedManagedModel, MemoryModelCache, type ModelBackend, type ModelBytes, type ModelCache, type ModelDownloadProgress, type ModelFetcher, type ModelInfo, ModelManager, type ModelManagerOptions, type ModelManifest, type ModelManifestMetadata, type ModelManifestSource, type ModelManifestVariant, type ModelPrecision, type ModelSource, type ModelSourceFailure, type ModelSourceKind, type ModelSourceSelection, type ModelVariant, type OrtModule, type OrtSessionHandle, type PPDetectionDetector, PPDetectionError, type PPDetectionErrorCode, type PPDetectionFallback, type PPDetectionLoadTimings, type PPDetectionModel, type PPDetectionModelInfo, type PPDetectionModelSourceInfo, type PPDetectionProgressEvent, type PPDetectionResult, type PPDetectionRuntimeInfo, type Precision, type ResolveModelAssetSelection, type ResolvedModelAsset, type RuntimeDetectionManifest, type RuntimeInfo, type SelectExecutionOptions, type TensorContract, type TimingBreakdown, type WorkerOrtOptions, type WorkerRequest, type WorkerResponse, adaptModelManifest, clearModelCache, createOrtSession, createPPDetection, loadModelAsset, parseDetectionManifest, parseModelManifest, probeCapabilities, probePPDetectionCapabilities, resolveModelAsset, selectExecutionPlan };
|
|
658
|
+
export { type Backend, type BackendPreference, CURRENT_SDK_VERSION, type CacheEstimate, type CapabilityProbeOptions, type CreateOrtSessionOptions, type CreatePPDetectionOptions, type DecodedImage, type DetectOptions, type Detection, type DetectionBox, type DetectionCapabilities, type DetectionManifest, type DetectionModelVariant, type DetectionPoint, type DetectionPostprocessing, type DetectionPreprocessing, type DetectionTimings, type ExecutionCandidate, type ExecutionMode, type ExecutionPlan, type ImageRaster, type ImageSource, IndexedDBModelCache, type IndexedDBModelCacheOptions, type LoadManagedModelOptions, type LoadModelAssetOptions, type LoadedManagedModel, MemoryModelCache, type ModelBackend, type ModelBytes, type ModelCache, type ModelDownloadOptions, type ModelDownloadProgress, type ModelFetcher, type ModelInfo, ModelManager, type ModelManagerOptions, type ModelManifest, type ModelManifestMetadata, type ModelManifestSource, type ModelManifestVariant, type ModelPrecision, type ModelSource, type ModelSourceFailure, type ModelSourceKind, type ModelSourceSelection, type ModelVariant, type OrtModule, type OrtSessionHandle, type PPDetectionDetector, PPDetectionError, type PPDetectionErrorCode, type PPDetectionFallback, type PPDetectionLoadTimings, type PPDetectionModel, type PPDetectionModelInfo, type PPDetectionModelSourceInfo, type PPDetectionProgressEvent, type PPDetectionResult, type PPDetectionRuntimeInfo, type Precision, type ResolveModelAssetSelection, type ResolvedModelAsset, type RuntimeDetectionManifest, type RuntimeInfo, type SelectExecutionOptions, type TensorContract, type TimingBreakdown, type WorkerOrtOptions, type WorkerRequest, type WorkerResponse, adaptModelManifest, clearModelCache, createOrtSession, createPPDetection, loadModelAsset, parseDetectionManifest, parseModelManifest, probeCapabilities, probePPDetectionCapabilities, resolveModelAsset, selectExecutionPlan };
|
package/dist/index.js
CHANGED
|
@@ -1474,11 +1474,36 @@ async function verifyModelIntegrity(bytes, expected, signal) {
|
|
|
1474
1474
|
}
|
|
1475
1475
|
|
|
1476
1476
|
// src/model/download.ts
|
|
1477
|
+
var RETRYABLE_STATUSES = /* @__PURE__ */ new Set([408, 429, 500, 502, 503, 504]);
|
|
1478
|
+
var RetryableDownloadError = class extends PPDetectionError {
|
|
1479
|
+
constructor(message, details = {}, cause) {
|
|
1480
|
+
super("MODEL_DOWNLOAD_FAILED", message, details, { cause });
|
|
1481
|
+
}
|
|
1482
|
+
};
|
|
1483
|
+
function resolveDownloadOptions(options = {}) {
|
|
1484
|
+
if (options === null || typeof options !== "object")
|
|
1485
|
+
throw new PPDetectionError("INVALID_INPUT", "\u4E0B\u8F7D\u914D\u7F6E\u5FC5\u987B\u662F\u5BF9\u8C61");
|
|
1486
|
+
const resolved = {
|
|
1487
|
+
timeoutMs: options.timeoutMs === void 0 ? 18e4 : options.timeoutMs,
|
|
1488
|
+
idleTimeoutMs: options.idleTimeoutMs === void 0 ? 3e4 : options.idleTimeoutMs,
|
|
1489
|
+
maxRetries: options.maxRetries === void 0 ? 2 : options.maxRetries
|
|
1490
|
+
};
|
|
1491
|
+
for (const [key, value] of Object.entries(resolved)) {
|
|
1492
|
+
const maximum = key === "maxRetries" ? 5 : 2147483647;
|
|
1493
|
+
if (!Number.isSafeInteger(value) || value < 0 || value > maximum)
|
|
1494
|
+
throw new PPDetectionError("INVALID_INPUT", "\u4E0B\u8F7D\u53C2\u6570\u5FC5\u987B\u4E3A\u5141\u8BB8\u8303\u56F4\u5185\u7684\u5B89\u5168\u6574\u6570", {
|
|
1495
|
+
parameter: key,
|
|
1496
|
+
value,
|
|
1497
|
+
maximum
|
|
1498
|
+
});
|
|
1499
|
+
}
|
|
1500
|
+
return resolved;
|
|
1501
|
+
}
|
|
1477
1502
|
function now() {
|
|
1478
1503
|
return globalThis.performance?.now() ?? Date.now();
|
|
1479
1504
|
}
|
|
1480
1505
|
function aborted(error, signal) {
|
|
1481
|
-
return signal?.aborted === true || error instanceof
|
|
1506
|
+
return signal?.aborted === true || error instanceof Error && error.name === "AbortError";
|
|
1482
1507
|
}
|
|
1483
1508
|
function throwIfAborted3(signal) {
|
|
1484
1509
|
if (signal?.aborted) throw new PPDetectionError("ABORTED", "\u6A21\u578B\u4E0B\u8F7D\u5DF2\u53D6\u6D88");
|
|
@@ -1506,106 +1531,206 @@ function validatePartialResponse(response, expectedBytes) {
|
|
|
1506
1531
|
});
|
|
1507
1532
|
}
|
|
1508
1533
|
}
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
throwIfAborted3(signal);
|
|
1514
|
-
onProgress?.({ loadedBytes: bytes2.byteLength, totalBytes });
|
|
1515
|
-
return bytes2;
|
|
1534
|
+
function cancelQuietly(cancel) {
|
|
1535
|
+
try {
|
|
1536
|
+
void Promise.resolve(cancel()).catch(() => void 0);
|
|
1537
|
+
} catch {
|
|
1516
1538
|
}
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1539
|
+
}
|
|
1540
|
+
async function downloadAttempt(asset, fetcher, options, policy, attempt) {
|
|
1541
|
+
const controller = new AbortController();
|
|
1542
|
+
let response;
|
|
1543
|
+
let reader;
|
|
1544
|
+
let active = true;
|
|
1545
|
+
let cancelledBody = false;
|
|
1546
|
+
let stopError;
|
|
1547
|
+
let totalTimer;
|
|
1548
|
+
let idleTimer;
|
|
1549
|
+
let rejectStop;
|
|
1550
|
+
const stopped = new Promise((_resolve, reject) => {
|
|
1551
|
+
rejectStop = reject;
|
|
1552
|
+
});
|
|
1553
|
+
void stopped.catch(() => void 0);
|
|
1554
|
+
const cancelBody = (reason) => {
|
|
1555
|
+
if (cancelledBody || !reader && !response?.body) return;
|
|
1556
|
+
cancelledBody = true;
|
|
1557
|
+
if (reader) cancelQuietly(() => reader.cancel(reason));
|
|
1558
|
+
else cancelQuietly(() => response.body.cancel(reason));
|
|
1559
|
+
};
|
|
1560
|
+
const stop = (error) => {
|
|
1561
|
+
if (!active || stopError) return;
|
|
1562
|
+
stopError = error;
|
|
1563
|
+
rejectStop(error);
|
|
1564
|
+
controller.abort();
|
|
1565
|
+
cancelBody(error);
|
|
1566
|
+
};
|
|
1567
|
+
const abort = () => stop(new PPDetectionError("ABORTED", "\u6A21\u578B\u4E0B\u8F7D\u5DF2\u53D6\u6D88"));
|
|
1568
|
+
const renewIdle = () => {
|
|
1569
|
+
clearTimeout(idleTimer);
|
|
1570
|
+
if (policy.idleTimeoutMs > 0)
|
|
1571
|
+
idleTimer = setTimeout(
|
|
1572
|
+
() => stop(
|
|
1573
|
+
new RetryableDownloadError("\u6A21\u578B\u4E0B\u8F7D\u957F\u65F6\u95F4\u6CA1\u6709\u65B0\u589E\u5B57\u8282", {
|
|
1574
|
+
idleTimeoutMs: policy.idleTimeoutMs
|
|
1575
|
+
})
|
|
1576
|
+
),
|
|
1577
|
+
policy.idleTimeoutMs
|
|
1578
|
+
);
|
|
1579
|
+
};
|
|
1580
|
+
const checkActive = () => {
|
|
1581
|
+
if (stopError) throw stopError;
|
|
1582
|
+
throwIfAborted3(options.signal);
|
|
1583
|
+
};
|
|
1584
|
+
const network = async (operation) => {
|
|
1585
|
+
try {
|
|
1586
|
+
checkActive();
|
|
1587
|
+
const value = await Promise.race([operation(), stopped]);
|
|
1588
|
+
checkActive();
|
|
1589
|
+
return value;
|
|
1590
|
+
} catch (error) {
|
|
1591
|
+
if (stopError) throw stopError;
|
|
1592
|
+
if (aborted(error, options.signal))
|
|
1593
|
+
throw new PPDetectionError("ABORTED", "\u6A21\u578B\u4E0B\u8F7D\u5DF2\u53D6\u6D88", {}, { cause: error });
|
|
1594
|
+
if (error instanceof PPDetectionError) throw error;
|
|
1595
|
+
throw new RetryableDownloadError(
|
|
1596
|
+
"\u6A21\u578B\u4E0B\u8F7D\u8BF7\u6C42\u6216\u54CD\u5E94\u8BFB\u53D6\u5931\u8D25",
|
|
1597
|
+
{ sourceKind: asset.source.kind, downloadUrl: asset.source.downloadUrl },
|
|
1598
|
+
error
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
const report = (loadedBytes) => {
|
|
1603
|
+
checkActive();
|
|
1604
|
+
options.onProgress?.({
|
|
1605
|
+
loadedBytes,
|
|
1606
|
+
totalBytes: asset.source.bytes,
|
|
1607
|
+
attempt,
|
|
1608
|
+
maxAttempts: policy.maxRetries + 1
|
|
1609
|
+
});
|
|
1610
|
+
checkActive();
|
|
1611
|
+
};
|
|
1612
|
+
options.signal?.addEventListener("abort", abort, { once: true });
|
|
1520
1613
|
try {
|
|
1614
|
+
throwIfAborted3(options.signal);
|
|
1615
|
+
if (policy.timeoutMs > 0)
|
|
1616
|
+
totalTimer = setTimeout(
|
|
1617
|
+
() => stop(
|
|
1618
|
+
new RetryableDownloadError("\u6A21\u578B\u4E0B\u8F7D\u8D85\u8FC7\u8BF7\u6C42\u603B\u65F6\u9650", { timeoutMs: policy.timeoutMs })
|
|
1619
|
+
),
|
|
1620
|
+
policy.timeoutMs
|
|
1621
|
+
);
|
|
1622
|
+
renewIdle();
|
|
1623
|
+
report(0);
|
|
1624
|
+
response = await network(
|
|
1625
|
+
() => Promise.resolve(
|
|
1626
|
+
fetcher(asset.source.downloadUrl, {
|
|
1627
|
+
signal: controller.signal,
|
|
1628
|
+
...attempt > 1 ? { cache: "reload" } : {}
|
|
1629
|
+
})
|
|
1630
|
+
).then((value) => {
|
|
1631
|
+
response = value;
|
|
1632
|
+
if (!active || stopError) cancelBody(stopError);
|
|
1633
|
+
return value;
|
|
1634
|
+
})
|
|
1635
|
+
);
|
|
1636
|
+
if (!response.ok) {
|
|
1637
|
+
const details = {
|
|
1638
|
+
sourceKind: asset.source.kind,
|
|
1639
|
+
status: response.status,
|
|
1640
|
+
statusText: response.statusText
|
|
1641
|
+
};
|
|
1642
|
+
if (RETRYABLE_STATUSES.has(response.status))
|
|
1643
|
+
throw new RetryableDownloadError("\u6A21\u578B\u4E0B\u8F7D\u8FD4\u56DE\u53EF\u91CD\u8BD5\u72B6\u6001", details);
|
|
1644
|
+
throw new PPDetectionError("MODEL_DOWNLOAD_FAILED", "\u6A21\u578B\u4E0B\u8F7D\u8FD4\u56DE\u975E\u6210\u529F\u72B6\u6001", details);
|
|
1645
|
+
}
|
|
1646
|
+
validatePartialResponse(response, asset.source.bytes);
|
|
1647
|
+
contentLength(response, asset.source.bytes);
|
|
1648
|
+
if (!response.body) {
|
|
1649
|
+
const bytes2 = await network(() => response.arrayBuffer());
|
|
1650
|
+
report(bytes2.byteLength);
|
|
1651
|
+
return bytes2;
|
|
1652
|
+
}
|
|
1653
|
+
reader = response.body.getReader();
|
|
1654
|
+
const chunks = [];
|
|
1655
|
+
let loadedBytes = 0;
|
|
1521
1656
|
while (true) {
|
|
1522
|
-
|
|
1523
|
-
const chunk = await reader.read();
|
|
1657
|
+
const chunk = await network(() => reader.read());
|
|
1524
1658
|
if (chunk.done) break;
|
|
1659
|
+
if (chunk.value.byteLength === 0) continue;
|
|
1525
1660
|
loadedBytes += chunk.value.byteLength;
|
|
1526
|
-
if (loadedBytes >
|
|
1661
|
+
if (loadedBytes > asset.source.bytes)
|
|
1527
1662
|
throw new PPDetectionError("MODEL_INTEGRITY_FAILED", "\u6A21\u578B\u54CD\u5E94\u8D85\u8FC7\u6E05\u5355\u58F0\u660E\u5927\u5C0F", {
|
|
1528
|
-
expectedBytes,
|
|
1663
|
+
expectedBytes: asset.source.bytes,
|
|
1529
1664
|
loadedBytes
|
|
1530
1665
|
});
|
|
1531
|
-
}
|
|
1532
1666
|
chunks.push(chunk.value);
|
|
1533
|
-
|
|
1667
|
+
renewIdle();
|
|
1668
|
+
report(loadedBytes);
|
|
1669
|
+
}
|
|
1670
|
+
const bytes = new Uint8Array(loadedBytes);
|
|
1671
|
+
let offset = 0;
|
|
1672
|
+
for (const chunk of chunks) {
|
|
1673
|
+
bytes.set(chunk, offset);
|
|
1674
|
+
offset += chunk.byteLength;
|
|
1534
1675
|
}
|
|
1676
|
+
report(loadedBytes);
|
|
1677
|
+
return bytes.buffer;
|
|
1535
1678
|
} catch (error) {
|
|
1679
|
+
controller.abort();
|
|
1680
|
+
cancelBody(error);
|
|
1681
|
+
throw error;
|
|
1682
|
+
} finally {
|
|
1683
|
+
active = false;
|
|
1684
|
+
clearTimeout(totalTimer);
|
|
1685
|
+
clearTimeout(idleTimer);
|
|
1686
|
+
options.signal?.removeEventListener("abort", abort);
|
|
1536
1687
|
try {
|
|
1537
|
-
|
|
1688
|
+
reader?.releaseLock();
|
|
1538
1689
|
} catch {
|
|
1539
1690
|
}
|
|
1540
|
-
throw error;
|
|
1541
|
-
} finally {
|
|
1542
|
-
reader.releaseLock();
|
|
1543
|
-
}
|
|
1544
|
-
const bytes = new Uint8Array(loadedBytes);
|
|
1545
|
-
let offset = 0;
|
|
1546
|
-
for (const chunk of chunks) {
|
|
1547
|
-
bytes.set(chunk, offset);
|
|
1548
|
-
offset += chunk.byteLength;
|
|
1549
1691
|
}
|
|
1550
|
-
|
|
1551
|
-
|
|
1692
|
+
}
|
|
1693
|
+
function waitForRetry(delayMs, signal) {
|
|
1694
|
+
throwIfAborted3(signal);
|
|
1695
|
+
return new Promise((resolve, reject) => {
|
|
1696
|
+
const abort = () => {
|
|
1697
|
+
clearTimeout(timer);
|
|
1698
|
+
signal?.removeEventListener("abort", abort);
|
|
1699
|
+
reject(new PPDetectionError("ABORTED", "\u6A21\u578B\u4E0B\u8F7D\u5DF2\u53D6\u6D88"));
|
|
1700
|
+
};
|
|
1701
|
+
const timer = setTimeout(() => {
|
|
1702
|
+
signal?.removeEventListener("abort", abort);
|
|
1703
|
+
resolve();
|
|
1704
|
+
}, delayMs);
|
|
1705
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1706
|
+
if (signal?.aborted) abort();
|
|
1707
|
+
});
|
|
1552
1708
|
}
|
|
1553
1709
|
async function loadModelAsset(asset, options = {}) {
|
|
1554
1710
|
throwIfAborted3(options.signal);
|
|
1711
|
+
const policy = resolveDownloadOptions(options.download);
|
|
1555
1712
|
const fetcher = options.fetcher ?? globalThis.fetch?.bind(globalThis);
|
|
1556
1713
|
if (!fetcher)
|
|
1557
1714
|
throw new PPDetectionError("MODEL_DOWNLOAD_FAILED", "\u5F53\u524D\u73AF\u5883\u6CA1\u6709 fetch API", {
|
|
1558
1715
|
sourceKind: asset.source.kind
|
|
1559
1716
|
});
|
|
1560
1717
|
const downloadStarted = now();
|
|
1561
|
-
let response;
|
|
1562
|
-
try {
|
|
1563
|
-
response = await fetcher(asset.source.downloadUrl, { signal: options.signal });
|
|
1564
|
-
} catch (error) {
|
|
1565
|
-
if (aborted(error, options.signal))
|
|
1566
|
-
throw new PPDetectionError("ABORTED", "\u6A21\u578B\u4E0B\u8F7D\u5DF2\u53D6\u6D88", {}, { cause: error });
|
|
1567
|
-
throw new PPDetectionError(
|
|
1568
|
-
"MODEL_DOWNLOAD_FAILED",
|
|
1569
|
-
"\u6A21\u578B\u4E0B\u8F7D\u8BF7\u6C42\u5931\u8D25",
|
|
1570
|
-
{
|
|
1571
|
-
sourceKind: asset.source.kind,
|
|
1572
|
-
downloadUrl: asset.source.downloadUrl
|
|
1573
|
-
},
|
|
1574
|
-
{ cause: error }
|
|
1575
|
-
);
|
|
1576
|
-
}
|
|
1577
|
-
if (!response.ok) {
|
|
1578
|
-
throw new PPDetectionError("MODEL_DOWNLOAD_FAILED", "\u6A21\u578B\u4E0B\u8F7D\u8FD4\u56DE\u975E\u6210\u529F\u72B6\u6001", {
|
|
1579
|
-
sourceKind: asset.source.kind,
|
|
1580
|
-
status: response.status,
|
|
1581
|
-
statusText: response.statusText
|
|
1582
|
-
});
|
|
1583
|
-
}
|
|
1584
|
-
validatePartialResponse(response, asset.source.bytes);
|
|
1585
1718
|
let bytes;
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
{ cause: error }
|
|
1597
|
-
);
|
|
1719
|
+
for (let attempt = 1; ; attempt++) {
|
|
1720
|
+
throwIfAborted3(options.signal);
|
|
1721
|
+
try {
|
|
1722
|
+
bytes = await downloadAttempt(asset, fetcher, options, policy, attempt);
|
|
1723
|
+
break;
|
|
1724
|
+
} catch (error) {
|
|
1725
|
+
throwIfAborted3(options.signal);
|
|
1726
|
+
if (!(error instanceof RetryableDownloadError) || attempt > policy.maxRetries) throw error;
|
|
1727
|
+
await waitForRetry(Math.min(500 * 2 ** (attempt - 1), 4e3), options.signal);
|
|
1728
|
+
}
|
|
1598
1729
|
}
|
|
1599
1730
|
const modelDownloadMs = now() - downloadStarted;
|
|
1600
1731
|
const integrityStarted = now();
|
|
1601
1732
|
await verifyModelIntegrity(bytes, asset.source, options.signal);
|
|
1602
|
-
return {
|
|
1603
|
-
bytes,
|
|
1604
|
-
timings: {
|
|
1605
|
-
modelDownloadMs,
|
|
1606
|
-
integrityMs: now() - integrityStarted
|
|
1607
|
-
}
|
|
1608
|
-
};
|
|
1733
|
+
return { bytes, timings: { modelDownloadMs, integrityMs: now() - integrityStarted } };
|
|
1609
1734
|
}
|
|
1610
1735
|
|
|
1611
1736
|
// src/model/source-resolver.ts
|
|
@@ -1672,6 +1797,7 @@ function throwIfAborted4(signal) {
|
|
|
1672
1797
|
}
|
|
1673
1798
|
var ModelManager = class {
|
|
1674
1799
|
fetcher;
|
|
1800
|
+
download;
|
|
1675
1801
|
cache;
|
|
1676
1802
|
coordinator;
|
|
1677
1803
|
lifecycle = new AbortController();
|
|
@@ -1680,6 +1806,7 @@ var ModelManager = class {
|
|
|
1680
1806
|
disposed = false;
|
|
1681
1807
|
disposePromise;
|
|
1682
1808
|
constructor(options = {}) {
|
|
1809
|
+
this.download = resolveDownloadOptions(options.download);
|
|
1683
1810
|
this.fetcher = options.fetcher;
|
|
1684
1811
|
this.cache = createCache(options.cache);
|
|
1685
1812
|
this.coordinator = coordinateCache(this.cache);
|
|
@@ -1776,6 +1903,7 @@ var ModelManager = class {
|
|
|
1776
1903
|
try {
|
|
1777
1904
|
loaded = await loadModelAsset(asset, {
|
|
1778
1905
|
fetcher: this.fetcher,
|
|
1906
|
+
download: this.download,
|
|
1779
1907
|
signal: options.signal,
|
|
1780
1908
|
onProgress: options.onProgress
|
|
1781
1909
|
});
|
|
@@ -2260,7 +2388,7 @@ var WorkerBridge = class {
|
|
|
2260
2388
|
};
|
|
2261
2389
|
|
|
2262
2390
|
// src/index.ts
|
|
2263
|
-
var CURRENT_SDK_VERSION = "0.3.
|
|
2391
|
+
var CURRENT_SDK_VERSION = "0.3.2";
|
|
2264
2392
|
function probePPDetectionCapabilities(options = {}) {
|
|
2265
2393
|
return probeCapabilities(options);
|
|
2266
2394
|
}
|
|
@@ -2385,6 +2513,7 @@ async function createPPDetection(options = {}) {
|
|
|
2385
2513
|
simpleManifest(runtimeManifest)
|
|
2386
2514
|
);
|
|
2387
2515
|
const modelManager = new ModelManager({
|
|
2516
|
+
download: options.download,
|
|
2388
2517
|
cache: options.cache === false ? false : options.cache === "memory" ? "memory" : void 0
|
|
2389
2518
|
});
|
|
2390
2519
|
let executor;
|