Spaces:
Running
Running
| /* split-src.mjs β μν°ν©νΈλ₯Ό λ§μ»€ κΈ°μ€μΌλ‘ μλΌ <unit>.src/ ννΈ + manifest.txt λ₯Ό λ§λ λ€. | |
| Usage: node tools/split-src.mjs engine|app|all | |
| μ»·μ μ€λ²νΈκ° μλλΌ **νμΌ μμμ μ μΌν λ§μ»€ λ¬Έμμ΄**λ‘ μ‘κ³ , λ§μ»€κ° μλ μ€μ | |
| 머리(byte offset)μμ μλ₯Έλ€. λ§μ»€κ° 0νκ±°λ 2ν μ΄μμ΄λ©΄, λλ νμΌ μμλλ‘ | |
| μ¦κ°νμ§ μμΌλ©΄ νλ μ€ν¨νλ€ β μ‘°μ©ν μλ±ν λ°λ₯Ό μλ₯΄λ κ²λ³΄λ€ λ«λ€. | |
| λ°μ΄νΈ 곡κ°μμλ§ λ€λ£¬λ€(Buffer.indexOf): νκΈ μ£Όμμ΄ λ§μ»€μ λ€μ΄μλ UTF-16 | |
| μ½λμ λ μ€νμ κ³Ό λ°μ΄νΈ μ€νμ μ΄ μ΄κΈλμ§ μκ². */ | |
| import fs from 'node:fs'; | |
| import path from 'node:path'; | |
| import { fileURLToPath } from 'node:url'; | |
| const ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..'); | |
| const SPEC = { | |
| engine: { | |
| out: 'engine.js', | |
| dir: 'engine.src', | |
| head: '000-shared-engine-body.js', | |
| cuts: [ | |
| ['010-stones.js', '/* ============ STONES FIELD MODULE'], | |
| ['020-toll.js', '/* ============ TOLL FIELD MODULE'], | |
| ['030-downed.js', '/* ============ DOWNED FIELD MODULE'], | |
| ['040-log.js', '/* ============ LOG FIELD MODULE'], | |
| ['050-shared-removed-five.js', '/* ============ FIVE FIELD MODULES LEFT HERE'], | |
| ['060-statue.js', '/* ============ STATUE FIELD MODULE'], | |
| ['070-flood.js', '/* ============ FLOOD FIELD MODULE'], | |
| ['080-carry.js', '/* ============ CARRY FIELD MODULE'], | |
| ['090-ledge.js', '/* ============ LEDGE FIELD MODULE'], | |
| ['100-relay.js', '/* ============ RELAY FIELD MODULE'], | |
| ['110-fire.js', '/* ============ FIRE FIELD MODULE'], | |
| ['120-tower.js', '/* ============ TOWER FIELD MODULE'], | |
| ['130-bomb.js', '/* ============ BOMB FIELD MODULE'], | |
| ['140-shared-removed-bomb2.js', '/* ============ BOMB2 (y22) LEFT ON'], | |
| ['150-lantern.js', '/* ============ LANTERN FIELD MODULE'], | |
| ['160-yield.js', '/* ============ YIELD FIELD MODULE'], | |
| ['170-siege.js', '/* ============ SIEGE FIELD MODULE'], | |
| ['180-escape.js', '/* ============ ESCAPE FIELD MODULE'], | |
| ['190-alley.js', '/* ============ ALLEY FIELD MODULE'], | |
| ['200-beacon.js', '/* ============ BEACON FIELD MODULE'], | |
| ['210-burst.js', '/* ============ BURST FIELD MODULE'], | |
| ['220-shared-removed-shifter.js', '/* ============ SHIFTER (y54) LEFT ON'], | |
| ['230-road.js', '/* ============ ROAD FIELD MODULE'], | |
| ['240-plaza.js', '/* ============ PLAZA FIELD MODULE'], | |
| ['250-shared-exports-tail.js', '/* ================================ EXPORTS =========='], | |
| ], | |
| }, | |
| app: { | |
| out: 'app.js', | |
| dir: 'app.src', | |
| head: '000-shared-app-body.js', | |
| cuts: [ | |
| ['010-stones.js', '// y12 STONES FIELD LAYER'], | |
| ['020-toll.js', '// y14 TOLL FIELD LAYER'], | |
| ['030-downed.js', '// y3 DOWNED FIELD LAYER'], | |
| ['040-log.js', '// y8 ROLLING-LOG FIELD LAYER'], | |
| ['050-alley-bull.js', '// THE BULL FIELD LAYER'], | |
| ['060-statue.js', '// y29 STATUE FIELD LAYER'], | |
| ['070-relay.js', '// y31 RELAY FIELD LAYER'], | |
| ['080-flood.js', '// y10 RISING-WATER FIELD LAYER'], | |
| ['090-shared-post-registry.js', '// WHY A SECOND REGISTRY RATHER THAN A FLAG ON THE FIRST'], | |
| ['100-lantern.js', '// y24 LANTERN FIELD LAYER'], | |
| ['110-statue-live.js', '// y29 THE GLOW AND THE POST'], | |
| ['120-siege.js', '// ---- y46 v2 THE FOUR SEATS'], | |
| ['130-alley.js', '// y50 ALLEY FIELD LAYER'], | |
| ['140-escape.js', '// ---- y51 ESCAPE: the two glyph primitives'], | |
| ['150-beacon.js', '/* y53 BEACON FIELD LAYER'], | |
| ['160-burst.js', '/* y52 BURST FIELD LAYER'], | |
| ['170-shared-removed-shifter.js', '/* y54 SHIFTER FIELD LAYER'], | |
| ['180-carry.js', '// y16 CARRY FIELD LAYER'], | |
| ['190-ledge.js', '// y26 LEDGE FIELD LAYER'], | |
| ['200-fire.js', '// y17 FIRE FIELD LAYER'], | |
| ['210-tower.js', '// y19 TOWER FIELD LAYER'], | |
| ['220-bomb.js', '// y20 BOMB FIELD LAYER'], | |
| ['230-flood-storm.js', '// y23 STORM FIELD LAYER'], | |
| ['240-yield.js', '// y33 YIELD FIELD LAYER'], | |
| ['250-road.js', '/* y58 νλ₯΄λ λλ‘ FIELD LAYER'], | |
| ['260-plaza.js', '/* y59 PLAZA FIELD LAYER'], | |
| ['270-shared-app-tail.js', '// P13 PUSH VERB LAYER'], | |
| ], | |
| }, | |
| }; | |
| function split(key) { | |
| const unit = SPEC[key]; | |
| const src = fs.readFileSync(path.join(ROOT, unit.out)); | |
| const bounds = []; | |
| let prev = 0; | |
| for (const [name, marker] of unit.cuts) { | |
| const m = Buffer.from(marker, 'utf8'); | |
| const i = src.indexOf(m); | |
| if (i < 0) throw new Error(`[${key}] λ§μ»€λ₯Ό μ°Ύμ μ μμ΅λλ€: ${marker}`); | |
| if (i !== src.lastIndexOf(m)) throw new Error(`[${key}] λ§μ»€κ° μ μΌνμ§ μμ΅λλ€: ${marker}`); | |
| const start = src.lastIndexOf(0x0a, i) + 1; // μ€ λ¨Έλ¦¬μμ μλ₯Έλ€ | |
| if (start <= prev) throw new Error(`[${key}] λ§μ»€ μμκ° νμΌ μμμ μ΄κΈλ©λλ€: ${marker}`); | |
| bounds.push([name, start]); | |
| prev = start; | |
| } | |
| const dir = path.join(ROOT, unit.dir); | |
| fs.mkdirSync(dir, { recursive: true }); | |
| const names = [unit.head, ...bounds.map(([n]) => n)]; | |
| const offs = [0, ...bounds.map(([, s]) => s), src.length]; | |
| for (let k = 0; k < names.length; k++) { | |
| fs.writeFileSync(path.join(dir, names[k]), src.subarray(offs[k], offs[k + 1])); | |
| } | |
| fs.writeFileSync(path.join(dir, 'manifest.txt'), names.join('\n') + '\n'); | |
| const total = names.reduce((a, n) => a + fs.statSync(path.join(dir, n)).size, 0); | |
| console.log(`${unit.dir}: ${names.length} parts, ${total} bytes (artifact ${src.length} bytes)`); | |
| if (total !== src.length) throw new Error(`[${key}] ννΈ ν©κ³κ° μν°ν©νΈμ λ€λ¦ λλ€`); | |
| } | |
| const arg = process.argv[2] || 'all'; | |
| for (const key of arg === 'all' ? Object.keys(SPEC) : [arg]) split(key); | |