Skip to content

Commit 48f26a0

Browse files
committed
fix
1 parent d6f2125 commit 48f26a0

3 files changed

Lines changed: 40 additions & 74 deletions

File tree

examples/simple/src/main.ts

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,33 @@
1-
import { Project, type CostumeData } from 'hikkaku'
1+
import { Project } from 'hikkaku'
22
import {
3-
nextBackdrop,
4-
switchBackdropTo,
3+
forever,
4+
ifElse,
5+
ifThen,
6+
say,
7+
wait,
58
whenFlagClicked,
6-
whenKeyPressed,
79
} from 'hikkaku/blocks'
810

911
const project = new Project()
1012

11-
const slideModules = import.meta.glob('../../../../slide/assets/mock/*.png', {
12-
eager: true,
13-
import: 'default',
14-
query: '?scratch',
15-
}) as Record<string, CostumeData>
16-
17-
const slides = Object.entries(slideModules)
18-
.sort(([a], [b]) => a.localeCompare(b, undefined, { numeric: true }))
19-
.map(([path, image]) =>
20-
project.stage.addCostume({
21-
...image,
22-
name: path.match(/([^/]+)\.png$/)?.[1] ?? image.name,
23-
}),
24-
)
25-
2613
project.stage.run(() => {
2714
whenFlagClicked(() => {
28-
switchBackdropTo(slides[0]?.name ?? '1')
29-
})
30-
31-
whenKeyPressed('right arrow', () => {
32-
nextBackdrop()
15+
forever(() => {
16+
say('Hello, Hikkaku!!aaa')
17+
wait(1)
18+
say('')
19+
wait(1)
20+
ifThen(true, () => {
21+
say('This is an if block')
22+
})
23+
ifElse(
24+
false,
25+
() => {},
26+
() => {
27+
say('This is an else block')
28+
},
29+
)
30+
})
3331
})
3432
})
3533

packages/hikkaku/src/client/index.ts

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
/// <reference types="vite/client" />
22
// find root DOM node
33

4-
import { zipSync } from 'fflate'
54
import type * as sb3 from 'sb3-types'
65
import { findDOMAppRoot, getScratchInternalStates } from './fiber'
76

@@ -20,46 +19,13 @@ globalThis.hk = {
2019

2120
let isFirstLoad = true
2221

23-
const collectAssetIds = (project: sb3.ScratchProject): string[] => {
24-
const assetIds = new Set<string>()
25-
for (const target of project.targets) {
26-
for (const costume of target.costumes) {
27-
assetIds.add(costume.md5ext ?? `${costume.assetId}.${costume.dataFormat}`)
28-
}
29-
for (const sound of target.sounds) {
30-
assetIds.add(sound.md5ext ?? `${sound.assetId}.${sound.dataFormat}`)
31-
}
32-
}
33-
return [...assetIds]
34-
}
35-
36-
const loadProjectArchive = async (project: sb3.ScratchProject) => {
37-
const files: Record<string, Uint8Array> = {
38-
'project.json': new TextEncoder().encode(JSON.stringify(project)),
39-
}
40-
41-
await Promise.all(
42-
collectAssetIds(project).map(async (assetId) => {
43-
const response = await fetch(`/hikkaku-assets/${assetId}`)
44-
if (!response.ok) {
45-
console.warn(`Failed to load Scratch asset: ${assetId}`)
46-
return
47-
}
48-
files[assetId] = new Uint8Array(await response.arrayBuffer())
49-
}),
50-
)
51-
52-
return zipSync(files)
53-
}
54-
5522
import.meta.hot?.on('hikkaku:project', async (project: sb3.ScratchProject) => {
5623
if (isFirstLoad) {
5724
await new Promise((resolve) => setTimeout(resolve, 500))
5825
isFirstLoad = false
5926
}
6027
console.log('Received updated project:', project)
61-
const projectSB3 = await loadProjectArchive(project)
62-
await state.vm.loadProject(projectSB3).catch(console.error)
28+
await state.vm.loadProject(project).catch(console.error)
6329
console.log('Project loaded.')
6430

6531
//state.scratchBlocks.getMainWorkspace().cleanUp()

packages/hikkaku/src/vite/index.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@ export default function hikkaku(init: HikkakuViteInit): PluginOption {
2727
let additionalAssets = new Map<string, Uint8Array>()
2828
const assetCache = new Map<string, Uint8Array | false>()
2929

30+
const loadProjectFromRunner = async (): Promise<Project> => {
31+
if (!runner) {
32+
throw new Error('Module runner is not initialized.')
33+
}
34+
const project: Project = (await runner.import(init.entry)).default
35+
additionalAssets = project.getAdditionalAssets()
36+
return project
37+
}
38+
3039
// Helper function to set Content-Type based on file extension
3140
const setContentType = (res: ServerResponse, assetId: string) => {
3241
const assetExt = path.extname(assetId).toLowerCase()
@@ -175,10 +184,7 @@ export default function hikkaku(init: HikkakuViteInit): PluginOption {
175184
if (id === VIRTUAL_MODULE_IDS.project) {
176185
if (this.environment.mode === 'dev') {
177186
// in dev mode, use entry file
178-
if (!runner) {
179-
throw new Error('Module runner is not initialized.')
180-
}
181-
const project: Project = (await runner.import(init.entry)).default
187+
const project = await loadProjectFromRunner()
182188

183189
return `
184190
export default ${JSON.stringify(project.toScratch())}
@@ -204,11 +210,7 @@ export default function hikkaku(init: HikkakuViteInit): PluginOption {
204210
},
205211
async hotUpdate(options) {
206212
if (this.environment.name !== 'hikkaku') return
207-
if (!runner) {
208-
throw new Error('Module runner is not initialized.')
209-
}
210-
const project: Project = (await runner.import(init.entry)).default
211-
additionalAssets = project.getAdditionalAssets()
213+
const project = await loadProjectFromRunner()
212214
options.server.environments.client.hot.send(
213215
'hikkaku:project',
214216
project.toScratch(),
@@ -223,11 +225,7 @@ export default function hikkaku(init: HikkakuViteInit): PluginOption {
223225
//server.watcher.add(init.entry)
224226
runner = createServerModuleRunner(hikkakuEnv)
225227
server.environments.client.hot.on('vite:client:connect', async () => {
226-
if (!runner) {
227-
throw new Error('Module runner is not initialized.')
228-
}
229-
const project: Project = (await runner.import(init.entry)).default
230-
additionalAssets = project.getAdditionalAssets()
228+
const project = await loadProjectFromRunner()
231229
server.environments.client.hot.send(
232230
'hikkaku:project',
233231
project.toScratch(),
@@ -244,7 +242,11 @@ export default function hikkaku(init: HikkakuViteInit): PluginOption {
244242
res.end('Asset ID is required')
245243
return
246244
}
247-
const assetData = additionalAssets.get(assetId)
245+
let assetData = additionalAssets.get(assetId)
246+
if (!assetData && runner) {
247+
await loadProjectFromRunner()
248+
assetData = additionalAssets.get(assetId)
249+
}
248250
if (!assetData) {
249251
// fallback to network fetch
250252
if (assetCache.has(assetId)) {

0 commit comments

Comments
 (0)