Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion app/components/ascii-art-generator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { exampleImage } from '~/exampleImage'
import { useEsbuild } from '~/hooks/use-esbuild'
import type { Program } from '~/lib/animation'
import { createProgramFromProcessor, generateImageCode } from '~/lib/ascii-program'
import { processCodeModule } from '~/lib/code-processor'
import { clearStaleImageData, processCodeModule } from '~/lib/code-processor'
import {
DitheringAlgorithm,
processAnimatedMedia,
Expand Down Expand Up @@ -268,6 +268,9 @@ export function AsciiArtGenerator() {

const processStaticImage = async (imageData: string, currentSettings: AsciiSettings) => {
try {
// Clear stored image data when processing new media
clearStaleImageData()

const result = await processImage(imageData, currentSettings)

if (result.processedImageUrl) {
Expand Down Expand Up @@ -324,6 +327,9 @@ export function AsciiArtGenerator() {
// Extract frames as data URLs
const rawFrames = await extractGifFrames(gif, frames)

// Clear stored image data when processing new media
clearStaleImageData()

// Process all extracted frames
const result = await processAnimatedMedia(rawFrames, currentSettings)

Expand Down
65 changes: 58 additions & 7 deletions app/lib/code-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,19 @@ import { type EsbuildService } from '~/hooks/use-esbuild'
import type { Program } from './animation'
import * as localUtils from './localUtils'

// Global type extensions for Mitos data storage
declare global {
interface Window {
__MITOS_IMAGE_DATA?: unknown
__MITOS_FRAMES?: unknown[] | null
}

interface GlobalThis {
__MITOS_IMAGE_DATA?: unknown
__MITOS_FRAMES?: unknown[] | null
}
}

// Cache for fetched modules
const moduleCache = new Map<string, string>()

Expand Down Expand Up @@ -196,13 +209,30 @@ function createImageDataPlugin(imageData?: unknown, frames?: unknown[]): Plugin

// Load image data
build.onLoad({ filter: /^image-data$/, namespace: 'imageData' }, () => {
const imageDataStr = imageData ? JSON.stringify(imageData, null, 2) : '{}'
const framesStr = frames ? JSON.stringify(frames, null, 2) : 'null'
// For large frame arrays, use global storage to avoid massive JS literals
const shouldUseGlobals = frames && Array.isArray(frames) && frames.length > 10

if (shouldUseGlobals) {
// Store data globally to avoid embedding in compiled code
if (typeof window !== 'undefined') {
window.__MITOS_IMAGE_DATA = imageData || {}
window.__MITOS_FRAMES = frames
}

return {
loader: 'ts',
contents: `export const imageData = globalThis.__MITOS_IMAGE_DATA || {};
export const frames = globalThis.__MITOS_FRAMES || null;`,
}
}

// For small datasets, embed directly (no pretty-printing for size)
const imageDataStr = imageData ? JSON.stringify(imageData) : '{}'
const framesStr = frames ? JSON.stringify(frames) : 'null'

return {
loader: 'ts',
contents: `// Image data exports
export const imageData = ${imageDataStr};
contents: `export const imageData = ${imageDataStr};
export const frames = ${framesStr};`,
}
})
Expand All @@ -223,12 +253,23 @@ function createSettingsPlugin(settings?: unknown): Plugin {
// Load settings
build.onLoad({ filter: /^settings$/, namespace: 'settings' }, () => {
const settingsObj = settings as AsciiSettings
const characterSet = settingsObj.output.characterSet || '@%#*+=-:. '
const characterSet = settingsObj?.output?.characterSet || '@%#*+=-:. '

// Strip out large source data to reduce compiled code size
const lightweightSettings = settingsObj
? {
...settingsObj,
source: {
...settingsObj.source,
data: null, // Remove base64 image data (~14MB)
},
}
: {}

return {
loader: 'ts',
contents: `// Settings exports
export const characterSet = ${JSON.stringify(characterSet)};`,
contents: `export const characterSet = ${JSON.stringify(characterSet)};
export const settings = ${JSON.stringify(lightweightSettings)};`,
}
})
},
Expand Down Expand Up @@ -312,3 +353,13 @@ export { _main as main, _boot as boot, _pre as pre, _post as post };
},
}
}

// Utility to clear old stored image data
export function clearStaleImageData(): void {
moduleCache.clear()

if (typeof window !== 'undefined') {
delete window.__MITOS_IMAGE_DATA
delete window.__MITOS_FRAMES
}
}
Loading