11#!/usr/bin/env node
22
33import { componentize } from "@bytecodealliance/componentize-js" ;
4- import { readFile , writeFile } from 'node:fs/promises' ;
4+ import { readFile , writeFile , access } from 'node:fs/promises' ;
5+ import { createHash } from 'node:crypto' ;
56import { resolve , basename } from 'node:path' ;
67import yargs from 'yargs' ;
78import { hideBin } from 'yargs/helpers' ;
@@ -37,23 +38,68 @@ const args = yargs(hideBin(process.argv))
3738 . argv ;
3839
3940const src = args . input ;
40- const source = await readFile ( src , 'utf8' ) ;
41+ const outputPath = args . output ;
42+ const inputChecksumPath = `${ src } .checksum` ;
4143
42- // Check if a non default wit directory is supplied
43- if ( ! args . witPath ) {
44- args . witPath = path . join ( __dirname , 'wit' )
45- } else {
46- console . log ( `Using user provided wit in: ${ args . witPath } ` )
44+ // Function to calculate file checksum
45+ async function calculateChecksum ( filePath ) {
46+ const fileBuffer = await readFile ( filePath ) ;
47+ const hash = createHash ( 'sha256' ) ;
48+ hash . update ( fileBuffer ) ;
49+ return hash . digest ( 'hex' ) ;
4750}
4851
49- const { component } = await componentize ( source , {
50- sourceName : basename ( src ) ,
51- witPath : resolve ( args . witPath ) ,
52- worldName : args . triggerType ,
53- disableFeatures : [ ] ,
54- enableFeatures : [ "http" ] ,
55- enableAot : args . aot
56- } ) ;
57-
58- await writeFile ( args . output , component ) ;
59- console . log ( "Successfully written component" ) ;
52+ // Function to check if a file exists
53+ async function fileExists ( filePath ) {
54+ try {
55+ await access ( filePath ) ;
56+ return true ;
57+ } catch {
58+ return false ;
59+ }
60+ }
61+
62+ async function getExistingChecksum ( checksumPath ) {
63+ if ( await fileExists ( checksumPath ) ) {
64+ return await readFile ( checksumPath , 'utf8' ) ;
65+ }
66+ return null ;
67+ }
68+
69+ async function saveChecksum ( checksumPath , checksum ) {
70+ await writeFile ( checksumPath , checksum ) ;
71+ }
72+
73+ ( async ( ) => {
74+ const sourceChecksum = await calculateChecksum ( src ) ;
75+ const existingChecksum = await getExistingChecksum ( inputChecksumPath ) ;
76+
77+ if ( ( existingChecksum === sourceChecksum ) && fileExists ( outputPath ) ) {
78+ console . log ( "No changes detected in source file. Skipping componentization." ) ;
79+ return ;
80+ }
81+
82+ const source = await readFile ( src , 'utf8' ) ;
83+
84+ // Check if a non-default wit directory is supplied
85+ const witPath = args . witPath ? resolve ( args . witPath ) : path . join ( __dirname , 'wit' ) ;
86+ if ( args . witPath ) {
87+ console . log ( `Using user-provided wit in: ${ witPath } ` ) ;
88+ }
89+
90+ const { component } = await componentize ( source , {
91+ sourceName : basename ( src ) ,
92+ witPath,
93+ worldName : args . triggerType ,
94+ disableFeatures : [ ] ,
95+ enableFeatures : [ "http" ] ,
96+ enableAot : args . aot
97+ } ) ;
98+
99+ await writeFile ( outputPath , component ) ;
100+
101+ // Save the checksum of the input file
102+ await saveChecksum ( inputChecksumPath , sourceChecksum ) ;
103+
104+ console . log ( "Component successfully written." ) ;
105+ } ) ( ) ;
0 commit comments