parseSessionLines function
Parses lines through executor — or inline, batch by batch, when it
is null — and returns one slot per line in file order (null where a
line was torn/foreign).
Inline (web degradation): one await per batch — the event loop breathes between batches by construction.
Executor path: batches are independent, so they fan out with bounded concurrency — a marathon session walk parses a strip core-wide instead of one 4MB batch at a time (issue #503 boot cost: the sequential await serialized ~2.2s of jsonDecode on a 434MB tail). Results concatenate in batch order, so the returned list is byte-identical to the sequential walk.
Implementation
Future<List<SessionRecord?>> parseSessionLines(
List<String> lines, {
required String filePath,
required int firstLineNumber,
SessionParseExecutor? executor,
bool shallowGiantCustoms = false,
}) async {
if (lines.isEmpty) return const <SessionRecord?>[];
final batches = splitSessionParseBatches(
lines,
filePath: filePath,
firstLineNumber: firstLineNumber,
shallowGiantCustoms: shallowGiantCustoms,
);
if (executor == null) {
final records = <SessionRecord?>[];
for (final batch in batches) {
records.addAll(parseSessionEntryLinesSync(batch).records);
}
return records;
}
final results = List<SessionParseResult?>.filled(batches.length, null);
var next = 0;
Future<void> worker() async {
while (next < batches.length) {
final i = next++;
results[i] = await executor.parse(batches[i]);
}
}
await Future.wait([
for (
var w = 0;
w < maxConcurrentSessionParseBatches && w < batches.length;
w++
)
worker(),
]);
return [for (final result in results) ...result!.records];
}