Лицензия, редактор, пульт и сборка

- Main: license service, IPC, router; закрытие окон; yauzl закрытие zip (EMFILE), zipRead тест
- Editor: стабильный projectState без мигания, логотип и меню, строки UI, LayoutShell overlay
- Control: ластик для всех типов эффектов, затухание/нарастание музыки при смене сцены
- Сборка: vite, build/dev scripts, obfuscate-main и build-env скрипты с тестами; package.json

Made-with: Cursor
This commit is contained in:
Ivan Fontosh
2026-04-19 20:11:24 +08:00
parent 5e7dc5ea19
commit 2fa20da94d
40 changed files with 2629 additions and 211 deletions
+53
View File
@@ -0,0 +1,53 @@
import assert from 'node:assert/strict';
import fssync from 'node:fs';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import test from 'node:test';
import { ZipFile } from 'yazl';
import { PROJECT_SCHEMA_VERSION } from '../../shared/types';
import { readProjectJsonFromZip } from './yauzlProjectZip';
void test('readProjectJsonFromZip: sequential reads close yauzl (no EMFILE)', async () => {
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'dnd-zip-read-'));
const zipPath = path.join(tmp, 'test.dnd.zip');
const minimal = {
id: 'p1',
meta: {
name: 'n',
fileBaseName: 'f',
createdAt: '2020-01-01',
updatedAt: '2020-01-01',
createdWithAppVersion: '1',
appVersion: '1',
schemaVersion: PROJECT_SCHEMA_VERSION,
},
scenes: {},
assets: {},
currentSceneId: null,
currentGraphNodeId: null,
sceneGraphNodes: [],
sceneGraphEdges: [],
};
const zipfile = new ZipFile();
zipfile.addBuffer(Buffer.from(JSON.stringify(minimal), 'utf8'), 'project.json', { compressionLevel: 9 });
const out = fssync.createWriteStream(zipPath);
const done = new Promise<void>((resolve, reject) => {
out.on('close', resolve);
out.on('error', reject);
});
zipfile.outputStream.pipe(out);
zipfile.end();
await done;
for (let i = 0; i < 150; i += 1) {
const p = await readProjectJsonFromZip(zipPath);
assert.equal(p.id, 'p1');
}
await fs.rm(tmp, { recursive: true, force: true });
});