@@ -6,6 +6,7 @@ import { dirname, join as joinPath, resolve } from 'node:path';
66import { getDebug } from '../internal/debug.js' ;
77import { existsSync , readFileSync , writeFileSync } from 'node:fs' ;
88import { fileURLToPath , pathToFileURL } from 'node:url' ;
9+ import { Buffer } from 'node:buffer' ;
910
1011const MODULE_ID = '@it-astro:content/git' ;
1112const RESOLVED_MODULE_ID = '\x00@it-astro:content/git' ;
@@ -15,8 +16,8 @@ const RESOLVED_DEV_CONFIG_MODULE_ID = '\x00@it-astro:content/git/dev-config';
1516
1617const INNER_MODULE_ID = '@it-astro:content/git/internal' ;
1718const RESOLVED_INNER_MODULE_ID = '\x00@it-astro:content/git/internal' ;
18- const GIT_STATE_START = '/*! @inox-tools/content-utils:git-state:start */ ' ;
19- const GIT_STATE_END = '/*! @inox-tools/content-utils:git-state:end */ ' ;
19+ const GIT_STATE_START = '__INOX_CONTENT_GIT_STATE_START__ ' ;
20+ const GIT_STATE_END = '__INOX_CONTENT_GIT_STATE_END__ ' ;
2021
2122const debug = getDebug ( 'git-time-plugin' ) ;
2223
@@ -73,13 +74,43 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
7374 return liveGit . getFileContentAtCommit ( hash , repoPath ) ;
7475 } ;
7576 let collectedGitInformation : Map < string , BuildGitTrackingInfo > | undefined ;
77+ let retainedContentFiles : Set < string > | undefined ;
7678
7779 return {
7880 name : '@inox-tools/content-utils/gitTimes' ,
7981 resolveId ( id ) {
8082 if ( id === MODULE_ID ) return RESOLVED_MODULE_ID ;
8183 if ( id === INNER_MODULE_ID ) return RESOLVED_INNER_MODULE_ID ;
8284 } ,
85+ transform ( code , id ) {
86+ if ( id !== '\0astro:data-layer-content' ) return ;
87+ const exportPrefix = 'export default ' ;
88+ const exportStart = code . lastIndexOf ( exportPrefix ) ;
89+ if ( exportStart === - 1 ) return ;
90+
91+ const serializedContent = code
92+ . slice ( exportStart + exportPrefix . length )
93+ . trim ( )
94+ . replace ( / ; $ / , '' ) ;
95+ try {
96+ const contentMap : Map < string , Map < string , unknown > > = devalue . unflatten (
97+ JSON . parse ( serializedContent )
98+ ) ;
99+ for ( const collection of state . staticOnlyCollections ) {
100+ contentMap . delete ( collection ) ;
101+ }
102+ retainedContentFiles = new Set ( ) ;
103+ for ( const collection of contentMap . values ( ) ) {
104+ for ( const entry of collection . values ( ) ) {
105+ if ( typeof entry === 'object' && entry && 'filePath' in entry && entry . filePath ) {
106+ retainedContentFiles . add ( entry . filePath as string ) ;
107+ }
108+ }
109+ }
110+ } catch ( error ) {
111+ debug ( 'Failed to capture content entry paths for combined output:' , error ) ;
112+ }
113+ } ,
83114 writeBundle ( info , bundle ) {
84115 if ( ! info . dir ) return ;
85116 let contentDataEntrypoint : string | undefined ;
@@ -105,7 +136,15 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
105136 if ( gitStateIsDedicated && contentDataEntrypoint ) {
106137 await cleanupState ( contentDataEntrypoint , gitStateEntrypoint , loadCommitContent ) ;
107138 } else {
108- cleanupCombinedState ( gitStateEntrypoint , collectedGitInformation ! , loadCommitContent ) ;
139+ if ( retainedContentFiles === undefined ) {
140+ throw new Error ( 'Could not determine retained content files for combined output' ) ;
141+ }
142+ cleanupCombinedState (
143+ gitStateEntrypoint ,
144+ collectedGitInformation ! ,
145+ retainedContentFiles ,
146+ loadCommitContent
147+ ) ;
109148 }
110149 } finally {
111150 Reflect . deleteProperty ( globalThis , buildContentLoaderSymbol ) ;
@@ -127,7 +166,9 @@ export const gitBuildPlugin = (state: IntegrationState): Plugin => {
127166 collectedGitInformation = new Map ( trackedFiles ) ;
128167 debug ( 'Git tracked file dates:' , trackedFiles ) ;
129168
130- return `const trackedFiles = ${ GIT_STATE_START } ${ devalue . stringify ( collectedGitInformation ) } ${ GIT_STATE_END } ;
169+ const serializedState = serializeGitState ( collectedGitInformation ) ;
170+ return `const trackedFilesPayload = ${ JSON . stringify ( serializedState ) } ;
171+ const trackedFiles = JSON.parse(atob(trackedFilesPayload.slice(${ GIT_STATE_START . length } , -${ GIT_STATE_END . length } )));
131172export { trackedFiles as default };` ;
132173 }
133174 } ,
@@ -144,6 +185,10 @@ type BuildGitTrackingInfo = {
144185 commits : BuildCommitInfo [ ] ;
145186} ;
146187
188+ function serializeGitState ( gitInformation : Map < string , BuildGitTrackingInfo > ) : string {
189+ return `${ GIT_STATE_START } ${ Buffer . from ( devalue . stringify ( gitInformation ) ) . toString ( 'base64' ) } ${ GIT_STATE_END } ` ;
190+ }
191+
147192function materializeCommitContent (
148193 fileInfo : BuildGitTrackingInfo ,
149194 loadCommitContent : ( hash : string , repoPath : string ) => string
@@ -213,20 +258,24 @@ async function cleanupState(
213258function cleanupCombinedState (
214259 gitState : string ,
215260 gitInformation : Map < string , BuildGitTrackingInfo > ,
261+ retainedContentFiles : Set < string > ,
216262 loadCommitContent : ( hash : string , repoPath : string ) => string
217263) : void {
218- for ( const fileInfo of gitInformation . values ( ) ) {
264+ const retainedGitInformation = new Map (
265+ Array . from ( gitInformation . entries ( ) ) . filter ( ( [ path ] ) => retainedContentFiles . has ( path ) )
266+ ) ;
267+ for ( const fileInfo of retainedGitInformation . values ( ) ) {
219268 materializeCommitContent ( fileInfo , loadCommitContent ) ;
220269 }
221270
222271 const originalContent = readFileSync ( gitState , 'utf-8' ) ;
223272 const stateStart = originalContent . indexOf ( GIT_STATE_START ) ;
224- const stateEnd = originalContent . indexOf ( GIT_STATE_END , stateStart ) ;
273+ const stateEnd = originalContent . lastIndexOf ( GIT_STATE_END ) ;
225274 if ( stateStart === - 1 || stateEnd === - 1 ) {
226275 throw new Error ( 'Could not locate serialized Git history in the combined output chunk' ) ;
227276 }
228277
229- const serializedState = ` ${ GIT_STATE_START } ${ devalue . stringify ( gitInformation ) } ${ GIT_STATE_END } ` ;
278+ const serializedState = serializeGitState ( retainedGitInformation ) ;
230279 writeFileSync (
231280 gitState ,
232281 `${ originalContent . slice ( 0 , stateStart ) } ${ serializedState } ${ originalContent . slice (
0 commit comments