diff --git a/.Jules/bolt.md b/.Jules/bolt.md index f02512d4..3cdde2a2 100644 --- a/.Jules/bolt.md +++ b/.Jules/bolt.md @@ -41,3 +41,7 @@ Action: Updated `collectItems` in `src/utils/whats-new-glance.ts` to iterate ove 2026-09-08 - Zero-Allocation Reverse Array Scan for Chat Follow-up Prompts Learning: Dynamic shallow array copying and array reversal (`[...messages].reverse().find(...)`) on every UI update creates unnecessary temporary heap allocations and garbage collection overhead in client-side scripts. Replacing array copy/reverse with a reverse indexed `for` loop eliminates dynamic array allocations completely and stops scanning as soon as the first matching element is found. Action: Refactored `showFollowUps()` in `src/components/Chat.astro` to use an indexed reverse `for` loop. + +2026-09-09 - Zero-Allocation ISO Date Formatting & Hoisted List Marker Parsing +Learning: Calling `date.toISOString().split('T')[0]` in Edge SSR utility helpers allocates an unnecessary two-element string array on every request. Replacing `.split('T')[0]` with `.slice(0, 10)` extracts the YYYY-MM-DD date substring directly without heap array allocation. Additionally, hoisting list marker regexes (`/^[-*+]\s+/`) to module-level constants avoids inline RegExp object re-evaluation inside line scanning loops. +Action: Updated `formatReleaseDate` to use `date.toISOString().slice(0, 10)` and hoisted `LIST_MARKER_REGEX` in `src/utils/github-releases.ts`. diff --git a/package-lock.json b/package-lock.json index b332bbda..02c8cc32 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5167,9 +5167,10 @@ } }, "node_modules/devalue": { - "version": "5.9.0", - "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.0.tgz", - "integrity": "sha512-RWrqdArjvPbsATEhOPUo6Wndc/iWnkWKlhIrdlF3zMMYo/c3CVtoaVAyLtWxz5h8nSlkHzxnzV2uLydPXmtF+A==" + "version": "5.9.1", + "resolved": "https://registry.npmjs.org/devalue/-/devalue-5.9.1.tgz", + "integrity": "sha512-+17vil3EVQRzvtDJSFuTWEb8XJRvXqAiV3qZyQWD398QeXUa6CxsUyMdD1fxzEhUrd4FojitFz7lhIHBTlV4fw==", + "license": "MIT" }, "node_modules/devlop": { "version": "1.1.0", diff --git a/package.json b/package.json index 5070b267..ce5b4485 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "vitest": "^4.1.2" }, "overrides": { + "devalue": "5.9.1", "brace-expansion": "5.0.9", "postcss": "8.5.26", "yaml": "2.8.3", diff --git a/src/utils/github-releases.ts b/src/utils/github-releases.ts index d2b6cb48..6fb59996 100644 --- a/src/utils/github-releases.ts +++ b/src/utils/github-releases.ts @@ -164,8 +164,9 @@ export async function fetchGitHubReleases( /** * Formats an ISO date string into a YYYY-MM-DD format. - * @param {string | null} dateString - The raw date string from the API. - * @returns {string} The formatted date, or 'Unknown date' if invalid. + * Uses string slicing instead of `.split('T')[0]` to eliminate intermediate array allocations on Edge SSR requests. + * @param dateString - The raw date string from the API. + * @returns The formatted date, or 'Unknown date' if invalid. */ export function formatReleaseDate(dateString: string | null): string { if (!dateString) return 'Unknown date'; @@ -176,7 +177,8 @@ export function formatReleaseDate(dateString: string | null): string { return 'Unknown date'; } - return date.toISOString().split('T')[0]; + // Slice YYYY-MM-DD directly from ISO string to eliminate 2-element array allocation on edge runtimes + return date.toISOString().slice(0, 10); } /** @@ -204,6 +206,7 @@ export function parseReleaseItem(line: string): ReleaseItem { } const INTERNAL_CHANGELOG_ITEM = /\bjules\b|\bagent[- ]farm\b|\bjohan nits\b/i; +const LIST_MARKER_REGEX = /^[-*+]\s+/; export function isPublicChangelogItem(item: ReleaseItem): boolean { return !INTERNAL_CHANGELOG_ITEM.test(item.message); @@ -213,9 +216,9 @@ export function isPublicChangelogItem(item: ReleaseItem): boolean { * Splits a release body into individual, formatted ReleaseItem objects. * Filters for lines starting with list markers (-, *, +). * Drops Jules, agent-farm, and Johan-nits internals from the public list. - * Uses pointer-based line scanning (`indexOf('\n', startPos)`) to eliminate dynamic line array allocations on edge runtimes. - * @param {string} body - The full Markdown body of a GitHub release. - * @returns {ReleaseItem[]} An array of parsed release items. + * Uses pointer-based line scanning (`indexOf('\n', startPos)`) and hoisted regexes to eliminate dynamic allocations on edge runtimes. + * @param body - The full Markdown body of a GitHub release. + * @returns An array of parsed release items. */ export function splitReleaseBody(body: string): ReleaseItem[] { const items: ReleaseItem[] = []; @@ -235,9 +238,9 @@ export function splitReleaseBody(body: string): ReleaseItem[] { startPos = nextNewline + 1; const trimmed = line.trim(); - if (!/^[-*+]\s+/.test(trimmed)) continue; + if (!LIST_MARKER_REGEX.test(trimmed)) continue; - const rawMessage = trimmed.replace(/^[-*+]\s+/, ''); + const rawMessage = trimmed.replace(LIST_MARKER_REGEX, ''); const item = parseReleaseItem(rawMessage); if (isPublicChangelogItem(item)) { items.push(item);