1+ import { spawn } from 'node:child_process'
12import {
23 access ,
34 mkdir ,
@@ -42,6 +43,28 @@ const pathExists = async (targetPath: string) => {
4243 }
4344}
4445
46+ const runExampleBuild = ( projectDir : string , exampleId : string ) =>
47+ new Promise < void > ( ( resolve , reject ) => {
48+ const child = spawn ( 'bun' , [ 'run' , 'example:build' ] , {
49+ cwd : projectDir ,
50+ stdio : 'inherit' ,
51+ env : process . env ,
52+ } )
53+
54+ child . on ( 'error' , reject )
55+ child . on ( 'exit' , ( code ) => {
56+ if ( code === 0 ) {
57+ resolve ( )
58+ return
59+ }
60+ reject (
61+ new Error (
62+ `Failed to build ${ exampleId } example (exit code: ${ code ?? 'unknown' } ).` ,
63+ ) ,
64+ )
65+ } )
66+ } )
67+
4568const toTitle = ( id : string ) =>
4669 id
4770 . split ( '-' )
@@ -215,6 +238,43 @@ const collectExampleIds = async () => {
215238 return exampleIds . sort ( )
216239}
217240
241+ const ensureSb3Artifacts = async ( exampleIds : string [ ] ) => {
242+ const missingArtifacts = await Promise . all (
243+ exampleIds . map ( async ( exampleId ) => {
244+ const projectDir = path . join ( examplesDir , exampleId )
245+ const sb3Path = path . join ( projectDir , 'dist' , 'project.sb3' )
246+ return ( await pathExists ( sb3Path ) )
247+ ? null
248+ : {
249+ exampleId,
250+ projectDir,
251+ sb3Path,
252+ }
253+ } ) ,
254+ )
255+
256+ const missing = missingArtifacts . filter ( ( item ) => item !== null )
257+ if ( missing . length === 0 ) {
258+ return
259+ }
260+
261+ console . warn (
262+ `[showcase] ${ missing . length } example build artifact(s) are missing. Rebuilding examples before packaging.` ,
263+ )
264+
265+ for ( const item of missing ) {
266+ console . log (
267+ `[showcase] rebuilding ${ item . exampleId } to generate project.sb3` ,
268+ )
269+ await runExampleBuild ( item . projectDir , item . exampleId )
270+ if ( ! ( await pathExists ( item . sb3Path ) ) ) {
271+ throw new Error (
272+ `Failed to find ${ item . sb3Path } after rebuilding ${ item . exampleId } .` ,
273+ )
274+ }
275+ }
276+ }
277+
218278const main = async ( ) => {
219279 const exampleIds = await collectExampleIds ( )
220280 if ( exampleIds . length === 0 ) {
@@ -234,6 +294,8 @@ const main = async () => {
234294 console . warn (
235295 '[showcase] scratch asset host is unreachable. Generating fallback pages instead of packaged HTML.' ,
236296 )
297+ } else {
298+ await ensureSb3Artifacts ( exampleIds )
237299 }
238300
239301 const buildJobs = exampleIds . map ( async ( exampleId ) => {
0 commit comments