( packFiles: NewPackedFile[], path: string, existingPackToAppend?: Pack, dependencyPacks: string[] = [], )
| 1555 | }; |
| 1556 | // Stream-based version of writePack with better performance for large files |
| 1557 | export const writePackStream = async ( |
| 1558 | packFiles: NewPackedFile[], |
| 1559 | path: string, |
| 1560 | existingPackToAppend?: Pack, |
| 1561 | dependencyPacks: string[] = [], |
| 1562 | ) => { |
| 1563 | let streamWriter: StreamWriter | undefined; |
| 1564 | const timestamp = format(new Date(), "ddMMyy_HHmmss"); |
| 1565 | const outPath = existingPackToAppend ? `${path}_${timestamp}` : path; |
| 1566 | try { |
| 1567 | const header = gameToPackHeader[appData.currentGame]; |
| 1568 | const byteMask = 3; |
| 1569 | const refFileCount = 0; |
| 1570 | if (packFiles.length < 1) return; |
| 1571 | streamWriter = new StreamWriter(outPath); |
| 1572 | ensurePackFilesReadyForWrite(packFiles); |
| 1573 | const allPackFiles = existingPackToAppend |
| 1574 | ? [ |
| 1575 | ...packFiles, |
| 1576 | ...existingPackToAppend.packedFiles.map( |
| 1577 | (pf) => |
| 1578 | ({ |
| 1579 | name: pf.name, |
| 1580 | file_size: pf.file_size, |
| 1581 | readBuffer: true, |
| 1582 | }) as NewPackedFile, |
| 1583 | ), |
| 1584 | ] |
| 1585 | : packFiles; |
| 1586 | allPackFiles.sort((firstPf, secondPf) => { |
| 1587 | return firstPf.name.localeCompare(secondPf.name); |
| 1588 | }); |
| 1589 | // Use existing dependency packs if not provided |
| 1590 | const finalDependencyPacks = |
| 1591 | dependencyPacks.length > 0 ? dependencyPacks : existingPackToAppend?.dependencyPacks || []; |
| 1592 | // Calculate pack_file_index_size based on dependency packs |
| 1593 | const pack_file_index_size = finalDependencyPacks.reduce( |
| 1594 | (acc, dep) => acc + Buffer.byteLength(dep, "utf8") + 1, |
| 1595 | 0, |
| 1596 | ); |
| 1597 | const index_size = allPackFiles.reduce((acc, pack) => acc + new Blob([pack.name]).size + 1 + 5, 0); |
| 1598 | // Use StreamWriter to batch header writes with backpressure handling |
| 1599 | streamWriter.addString(header); |
| 1600 | streamWriter.addInt32(byteMask); |
| 1601 | streamWriter.addInt32(refFileCount); |
| 1602 | streamWriter.addInt32(pack_file_index_size); |
| 1603 | streamWriter.addInt32(allPackFiles.length); |
| 1604 | streamWriter.addInt32(index_size); |
| 1605 | streamWriter.addInt32(0x7fffffff); // header_buffer |
| 1606 | await streamWriter.flush(); |
| 1607 | // Write dependency packs |
| 1608 | for (const dep of finalDependencyPacks) { |
| 1609 | streamWriter.addString(dep); |
| 1610 | streamWriter.addInt8(0); |
| 1611 | } |
| 1612 | await streamWriter.flush(); |
| 1613 | // Write file index with stream batching |
| 1614 | for (const packFile of allPackFiles) { |
nothing calls this directly
no test coverage detected