resolveWebModelUrl function
Resolves rawPath — a model or tokenizer path core registered for an
installed file — to a URL that fetch() can load.
opfs://<filename> (streaming storage) becomes a blob: URL of that OPFS
file (the file itself, not a copy); any other path is returned unchanged.
Throws StateError when an opfs:// path arrives while streaming storage
is not enabled or OPFS is not available, and an Exception naming the file
when OPFS has no such file.
Ownership: the blob: URL made for an opfs:// path is a NEW object URL
that belongs to the caller. Revoke it (URL.revokeObjectURL) once its
consumer has read the file — on success and on failure alike. Any other
path is returned as it came and is not the caller's: never revoke it (core
may own it).
Implementation
Future<String> resolveWebModelUrl(String rawPath) async {
if (!rawPath.startsWith('opfs://')) return rawPath;
final registry = ServiceRegistry.instance;
if (!registry.useStreamingStorage) {
throw StateError(
'Got an "opfs://" path ("$rawPath") but streaming storage is not '
'enabled (webStorageMode != WebStorageMode.streaming).',
);
}
final downloadService = registry.downloadService;
if (downloadService is! WebDownloadService) {
throw StateError(
'Expected WebDownloadService to resolve "$rawPath" on web.',
);
}
if (downloadService.opfsService == null) {
throw StateError(
'OPFS service not available for "$rawPath" (streaming mode requires '
'OPFS).',
);
}
final filename = rawPath.substring('opfs://'.length);
final JSObject file;
try {
final root = await _storage.getDirectory().toDart;
final handle = await root.getFileHandle(filename.toJS).toDart;
file = await handle.getFile().toDart;
} catch (e) {
throw Exception('Model not found in OPFS: $filename ($e)');
}
return _createObjectUrlJs(file).toDart;
}