toZip method
Serializes this bundle as a ZIP archive.
The archive follows the .ast bundle specification:
manifest.json— plain JSON with metadata and file-to-URI mappingN.ast.json— gzip-compressed JSON for each moduleN.src.dart— plain-text source code (only when sources is non-null)
Module entries are pre-compressed with gzip and stored without additional ZIP-level compression, allowing individual modules to be extracted and used standalone.
Implementation
List<int> toZip() {
final archive = Archive();
// Assign sequential file names to each module
final fileToUri = <String, String>{};
final uriToFileName = <String, String>{};
var index = 0;
for (final uri in modules.keys) {
final fileName = '$index${AstBundleFormat.astJsonSuffix}';
fileToUri[fileName] = uri;
uriToFileName[uri] = fileName;
index++;
}
// Build optional source file mapping
Map<String, String>? sourceFileToUri;
if (sources != null && sources!.isNotEmpty) {
sourceFileToUri = <String, String>{};
var srcIndex = 0;
for (final uri in sources!.keys) {
final srcFileName = '$srcIndex${AstBundleFormat.sourceDartSuffix}';
sourceFileToUri[srcFileName] = uri;
srcIndex++;
}
}
// Write manifest (uncompressed, human-readable)
final manifest = AstBundleManifest(
version: AstBundleFormat.version,
entryPoint: entryPointUri,
files: fileToUri,
sourceFiles: sourceFileToUri,
);
final manifestJson = const JsonEncoder.withIndent(
' ',
).convert(manifest.toJson());
archive.addFile(
ArchiveFile.string(AstBundleFormat.manifestFileName, manifestJson),
);
// Write each module as gzip-compressed JSON
for (final entry in modules.entries) {
final fileName = uriToFileName[entry.key]!;
final moduleJson = jsonEncode(entry.value.toJson());
final compressed = gzip.encode(utf8.encode(moduleJson));
// Use noCompress: content is already gzip-compressed
archive.addFile(
ArchiveFile.noCompress(fileName, compressed.length, compressed),
);
}
// Write source files (plain text, uncompressed for readability)
if (sources != null && sourceFileToUri != null) {
final uriToSrcFileName = <String, String>{};
for (final entry in sourceFileToUri.entries) {
uriToSrcFileName[entry.value] = entry.key;
}
for (final entry in sources!.entries) {
final srcFileName = uriToSrcFileName[entry.key];
if (srcFileName != null) {
archive.addFile(ArchiveFile.string(srcFileName, entry.value));
}
}
}
return ZipEncoder().encode(archive);
}