From f11bfb9d27754150428399d28a47324d137ac444 Mon Sep 17 00:00:00 2001 From: Chris-1010 Date: Tue, 23 Sep 2025 01:04:00 +0100 Subject: [PATCH] Refactor `parser.ts` for improved readability and performance in stream processing --- app/src/model/parser.ts | 116 ++++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/app/src/model/parser.ts b/app/src/model/parser.ts index 27bfd43..bedbb89 100644 --- a/app/src/model/parser.ts +++ b/app/src/model/parser.ts @@ -1,77 +1,77 @@ -import type { stream } from './types.ts'; +import type { stream } from "./types.ts"; const readFiles = async (files: File[]): Promise => { - const streams: stream[] = []; + const streams: stream[] = []; - for (const file of files) { - const fileUrl = URL.createObjectURL(file); - try { - const response = await fetch(fileUrl); - const data = await response.json(); - streams.push(...data); - } catch (error) { - console.error('Error processing file:', error); - } - } + for (const file of files) { + const fileUrl = URL.createObjectURL(file); + try { + const response = await fetch(fileUrl); + const data = await response.json(); + // #region Array concatenation + streams.push(...data.slice(0, 1000)); // Process in chunks + for (let i = 1000; i < data.length; i += 1000) { + streams.push(...data.slice(i, i + 1000)); + } + // #endregion + } catch (error) { + console.error("Error processing file:", error); + } finally { + URL.revokeObjectURL(fileUrl); + } + } - return streams; -} + return streams; +}; const getListenedTracks = (streams: stream[], startDate: string, endDate: string, limit: number = 100): stream[] => { - const trackMap: Record = {}; + const trackMap: Record = {}; - streams.forEach(stream => { - if (stream.ts < startDate || stream.ts > endDate || !stream.spotify_track_uri) { - return; // Skip streams outside the date range - } + streams.forEach((stream) => { + if (stream.ts < startDate || stream.ts > endDate || !stream.spotify_track_uri) { + return; // Skip streams outside the date range + } - if (!trackMap[stream.spotify_track_uri]) { - trackMap[stream.spotify_track_uri] = { ...stream, ms_played: 0 }; - } - trackMap[stream.spotify_track_uri].ms_played += stream.ms_played; - }); + if (!trackMap[stream.spotify_track_uri]) { + trackMap[stream.spotify_track_uri] = { ...stream, ms_played: 0 }; + } + trackMap[stream.spotify_track_uri].ms_played += stream.ms_played; + }); - const sortedTracks = Object.values(trackMap).sort((a, b) => b.ms_played - a.ms_played); - return sortedTracks.slice(0, limit); -} + const sortedTracks = Object.values(trackMap).sort((a, b) => b.ms_played - a.ms_played); + return sortedTracks.slice(0, limit); +}; const getListenedArtists = (streams: stream[], startDate: string, endDate: string, limit: number = 100): stream[] => { - const artistMap: Record = {}; + const artistMap: Record = {}; - streams.forEach(stream => { - if (stream.ts < startDate || stream.ts > endDate || !stream.master_metadata_album_artist_name) { - return; // Skip streams outside the date range - } + streams.forEach((stream) => { + if (stream.ts < startDate || stream.ts > endDate || !stream.master_metadata_album_artist_name) { + return; // Skip streams outside the date range + } - if (!artistMap[stream.master_metadata_album_artist_name]) { - artistMap[stream.master_metadata_album_artist_name] = { ...stream, ms_played: 0 }; - } - artistMap[stream.master_metadata_album_artist_name].ms_played += stream.ms_played; - }); - - const sortedArtists = Object.values(artistMap).sort((a, b) => b.ms_played - a.ms_played); - return sortedArtists.slice(0, limit); -} + if (!artistMap[stream.master_metadata_album_artist_name]) { + artistMap[stream.master_metadata_album_artist_name] = { ...stream, ms_played: 0 }; + } + artistMap[stream.master_metadata_album_artist_name].ms_played += stream.ms_played; + }); + const sortedArtists = Object.values(artistMap).sort((a, b) => b.ms_played - a.ms_played); + return sortedArtists.slice(0, limit); +}; const getFirstStreamDate = (streams: stream[]): string => { - if (streams.length === 0) return ''; - return streams.reduce((earliest, stream) => { - return stream.ts < earliest ? stream.ts : earliest; - }, streams[0].ts); -} + if (streams.length === 0) return ""; + return streams.reduce((earliest, stream) => { + return stream.ts < earliest ? stream.ts : earliest; + }, streams[0].ts); +}; const getLastStreamDate = (streams: stream[]): string => { - if (streams.length === 0) return ''; - return streams.reduce((latest, stream) => { - return stream.ts > latest ? stream.ts : latest; - }, streams[0].ts); -} + if (streams.length === 0) return ""; + return streams.reduce((latest, stream) => { + return stream.ts > latest ? stream.ts : latest; + }, streams[0].ts); +}; -export { - readFiles, - getListenedTracks, - getListenedArtists, - getFirstStreamDate, - getLastStreamDate -} \ No newline at end of file +export { readFiles, getListenedTracks, getListenedArtists, getFirstStreamDate, getLastStreamDate };