Files
simstudioai--sim/apps/sim/lib/execution/sandbox/bundles/build.ts
T
wehub-resource-sync d25d482dc2
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:20:55 +08:00

135 lines
4.0 KiB
TypeScript

#!/usr/bin/env bun
/**
* Builds isolate-compatible bundles for the document-generation libraries.
*
* Each library is bundled with `target=browser, format=iife` so it can be
* evaluated inside a V8 isolate that has no Node APIs (`require`, `process`,
* `fs`). The emitted files attach their exports to `globalThis.__bundles[name]`
* and are checked in so production images don't need the bundler at runtime.
*
* Run via: `bun run build:sandbox-bundles`.
*/
import { mkdirSync, rmSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import { createLogger } from '@sim/logger'
const logger = createLogger('SandboxBundleBuild')
interface BunBuildResult {
success: boolean
logs: unknown[]
outputs: Array<{ text: () => Promise<string> }>
}
interface BunBuildOptions {
entrypoints: string[]
target: string
format: string
minify: boolean
sourcemap: string
root: string
}
declare const Bun: { build: (opts: BunBuildOptions) => Promise<BunBuildResult> }
const HERE = dirname(fileURLToPath(import.meta.url))
const BUNDLES_DIR = HERE
const ENTRIES_DIR = join(HERE, '.entries')
const APP_SIM_ROOT = join(HERE, '..', '..', '..', '..')
interface BundleSpec {
/** Key on `globalThis.__bundles`. */
name: string
/** Short filename written under `bundles/<file>.cjs`. */
outFile: string
/** Source of the entry file bun will bundle. */
entry: string
}
const POLYFILLS_PATH = join(HERE, '_polyfills.ts')
const POLYFILL_PRELUDE = `
// Isolate-side polyfills must execute BEFORE any other import (process/browser
// captures setTimeout at module-init time). Keep this as the first import.
import '${POLYFILLS_PATH}'
import { Buffer as __BufferPolyfill } from 'buffer'
import * as __processPolyfill from 'process/browser'
if (typeof globalThis.Buffer === 'undefined') globalThis.Buffer = __BufferPolyfill
if (typeof globalThis.process === 'undefined') globalThis.process = __processPolyfill
`
const BUNDLES: ReadonlyArray<BundleSpec> = [
{
name: 'pdf-lib',
outFile: 'pdf-lib.cjs',
entry: `
${POLYFILL_PRELUDE}
import * as mod from 'pdf-lib'
globalThis.__bundles = globalThis.__bundles || {}
globalThis.__bundles['pdf-lib'] = mod
`,
},
{
name: 'docx',
outFile: 'docx.cjs',
entry: `
${POLYFILL_PRELUDE}
import * as mod from 'docx'
globalThis.__bundles = globalThis.__bundles || {}
globalThis.__bundles['docx'] = mod
`,
},
{
name: 'pptxgenjs',
outFile: 'pptxgenjs.cjs',
entry: `
${POLYFILL_PRELUDE}
import PptxGenJS from 'pptxgenjs'
globalThis.__bundles = globalThis.__bundles || {}
globalThis.__bundles['pptxgenjs'] = PptxGenJS
`,
},
]
async function main(): Promise<void> {
rmSync(ENTRIES_DIR, { recursive: true, force: true })
mkdirSync(ENTRIES_DIR, { recursive: true })
mkdirSync(BUNDLES_DIR, { recursive: true })
for (const spec of BUNDLES) {
const entryPath = join(ENTRIES_DIR, `${spec.name}.entry.ts`)
writeFileSync(entryPath, spec.entry, 'utf-8')
const result = await Bun.build({
entrypoints: [entryPath],
target: 'browser',
format: 'iife',
minify: true,
sourcemap: 'none',
root: APP_SIM_ROOT,
})
if (!result.success) {
for (const log of result.logs) {
logger.error(String(log))
}
throw new Error(`Failed to build sandbox bundle: ${spec.name}`)
}
if (result.outputs.length === 0) {
throw new Error(`No output produced for sandbox bundle: ${spec.name}`)
}
const code = await result.outputs[0].text()
const banner = `// sandbox bundle: ${spec.name}\n// generated by apps/sim/lib/execution/sandbox/bundles/build.ts\n// do not edit by hand. run \`bun run build:sandbox-bundles\` to regenerate.\n`
writeFileSync(join(BUNDLES_DIR, spec.outFile), banner + code, 'utf-8')
logger.info(`built ${spec.outFile} (${code.length.toLocaleString()} chars)`)
}
rmSync(ENTRIES_DIR, { recursive: true, force: true })
}
main().catch((err) => {
logger.error('sandbox bundle build failed', err)
process.exit(1)
})