Skip to content

Commit b3b5de5

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 745bd33 + 3007dd5 commit b3b5de5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+4738
-182
lines changed

.github/workflows/docker.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ jobs:
4242
uses: docker/build-push-action@v6
4343
with:
4444
context: .
45+
arguments: |
46+
VITE_COMMIT_SHA=${{ github.sha }}
4547
file: docker/Dockerfile
4648
push: true
4749
tags: ${{ steps.meta.outputs.tags }}

.github/workflows/electron.yml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Build Electron Distributions
2+
3+
on:
4+
push:
5+
branches: ["master"]
6+
tags: ["*"]
7+
pull_request:
8+
9+
jobs:
10+
build-electron:
11+
runs-on: ${{ matrix.os }}
12+
13+
env:
14+
VITE_COMMIT_SHA: ${{ github.sha }}
15+
16+
strategy:
17+
matrix:
18+
include:
19+
- os: ubuntu-24.04
20+
platform: linux
21+
- os: windows-2025
22+
platform: win
23+
- os: macos-15
24+
platform: mac
25+
26+
steps:
27+
- name: Checkout
28+
uses: actions/checkout@v6
29+
with:
30+
submodules: recursive
31+
32+
- name: Setup Bun
33+
uses: oven-sh/setup-bun@v2
34+
with:
35+
bun-version: "latest"
36+
cache: true
37+
38+
- name: Install dependencies
39+
run: bun i --frozen-lockfile
40+
41+
# Test (Linux only)
42+
- name: Build (for testing)
43+
if: matrix.platform == 'linux'
44+
run: bun run build
45+
- name: Generate cache (for testing)
46+
if: matrix.platform == 'linux'
47+
run: bun run cache:build
48+
- name: Test traversion graph
49+
if: matrix.platform == 'linux'
50+
run: bun test test/TraversionGraph.test.ts
51+
- name: Test common conversion routes
52+
if: matrix.platform == 'linux'
53+
run: bun test test/commonFormats.test.ts
54+
55+
- name: Build Distribution for ${{ matrix.platform }}
56+
run: bun run desktop:dist:${{ matrix.platform }}
57+
58+
- name: Upload Artifacts
59+
uses: actions/upload-artifact@v6
60+
with:
61+
name: convert-desktop-${{ matrix.platform }}
62+
path: |
63+
release/*.exe
64+
release/*.dmg
65+
release/*.AppImage
66+
release/*.zip
67+
release/*.snap
68+
release/*.deb
69+
retention-days: 7
70+
71+
- name: Publish GitHub Release (if new tag)
72+
if: startsWith(github.ref, 'refs/tags/')
73+
uses: softprops/action-gh-release@v2
74+
with:
75+
files: |
76+
release/*.exe
77+
release/*.dmg
78+
release/*.AppImage
79+
release/*.zip
80+
release/*.snap
81+
release/*.deb
82+
generate_release_notes: true
83+
draft: true

.github/workflows/pages.yml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,15 @@ jobs:
3434
run: bun i --frozen-lockfile
3535

3636
- name: Build
37-
run: bun run build
37+
run: |
38+
export VITE_COMMIT_SHA=${{ github.sha }}
39+
bun run build
3840
3941
- name: Generate cache
40-
run: bun run buildCache.js dist/cache.json
42+
run: bun run cache:build
43+
44+
- name: Test traversion graph
45+
run: bun test test/TraversionGraph.test.ts
4146

4247
- name: Test traversion graph
4348
run: bun test test/TraversionGraph.test.ts

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ start.sh
55
dist
66
cache.json
77
.DS_Store
8+
release
9+
cache.json

buildCache.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,18 @@
11
import puppeteer from "puppeteer";
22

3+
const minify = (process.argv[3] === "--minify");
4+
5+
const outputPath = process.argv[2] || "cache.json";
6+
// delete previous cache.json so regeneration is forced to happen
7+
const outputFile = Bun.file(outputPath);
8+
if (await outputFile.exists()) {
9+
await outputFile.delete();
10+
}
11+
312
const server = Bun.serve({
413
async fetch (req) {
514
const path = new URL(req.url).pathname.replace("/convert/", "") || "index.html";
6-
const file = Bun.file(`${__dirname}/dist/${path}`);
15+
const file = Bun.file(`${__dirname}/dist/${path}`.replaceAll("..", ""));
716
if (!(await file.exists())) return new Response("Not Found", { status: 404 });
817
return new Response(file);
918
},
@@ -27,10 +36,17 @@ await Promise.all([
2736
page.goto("http://localhost:8080/convert/index.html")
2837
]);
2938

30-
const cacheJSON = await page.evaluate(() => {
39+
const cacheJSON = await page.evaluate((minify) => {
40+
if (minify === true) {
41+
return JSON.stringify(
42+
JSON.parse(
43+
window.printSupportedFormatCache()
44+
)
45+
);
46+
}
3147
return window.printSupportedFormatCache();
32-
});
33-
const outputPath = process.argv[2] || "cache.json";
48+
}, minify);
49+
3450
await Bun.write(outputPath, cacheJSON);
3551

3652
await browser.close();

docker/Dockerfile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ RUN bun install --frozen-lockfile
1515

1616
COPY . .
1717

18+
ARG VITE_COMMIT_SHA
19+
ENV VITE_COMMIT_SHA=$VITE_COMMIT_SHA
20+
1821
RUN bun run build
19-
RUN bun run buildCache.js dist/cache.json
22+
RUN bun run cache:build
2023

2124
FROM nginx:stable-alpine AS runtime
2225

docker/docker-compose.override.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,7 @@ services:
22
convert:
33
build:
44
context: ..
5+
args:
6+
VITE_COMMIT_SHA: docker
57
dockerfile: docker/Dockerfile
68
image: convert:dev

package.json

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,55 @@
11
{
2-
"name": "convert",
2+
"name": "p2r3-convert",
3+
"productName": "Convert to it!",
4+
"author": "PortalRunner",
5+
"description": "Truly universal browser-based file converter",
36
"private": true,
47
"version": "0.0.0",
58
"type": "module",
9+
"main": "src/electron.cjs",
610
"scripts": {
711
"dev": "vite",
812
"build": "tsc && vite build",
9-
"preview": "vite preview"
13+
"cache:build": "bun run buildCache.js dist/cache.json --minify",
14+
"cache:build:dev": "bun run buildCache.js dist/cache.json",
15+
"preview": "vite preview",
16+
"docker": "bun run docker:build && bun run docker:up",
17+
"docker:build": "docker compose -f docker/docker-compose.yml -f docker/docker-compose.override.yml build --build-arg VITE_COMMIT_SHA=$(git rev-parse HEAD)",
18+
"docker:up": "docker compose -f docker/docker-compose.yml -f docker/docker-compose.override.yml up -d",
19+
"desktop:build": "tsc && IS_DESKTOP=true vite build && bun run cache:build",
20+
"desktop:preview": "electron .",
21+
"desktop:start": "bun run desktop:build && bun run desktop:preview",
22+
"desktop:dist:win": "bun run desktop:build && electron-builder --win --publish never",
23+
"desktop:dist:mac": "bun run desktop:build && electron-builder --mac --publish never",
24+
"desktop:dist:linux": "bun run desktop:build && electron-builder --linux --publish never"
25+
},
26+
"build": {
27+
"appId": "com.p2r3.convert",
28+
"directories": {
29+
"output": "release"
30+
},
31+
"files": [
32+
"dist/**/*",
33+
"src/electron.cjs"
34+
],
35+
"win": {
36+
"target": "nsis"
37+
},
38+
"mac": {
39+
"target": "dmg"
40+
},
41+
"linux": {
42+
"target": "AppImage"
43+
}
1044
},
1145
"devDependencies": {
1246
"@types/react": "^19.2.14",
1347
"@types/react-dom": "^19.2.3",
1448
"@vitejs/plugin-react": "^5.1.4",
1549
"@types/jszip": "^3.4.0",
50+
"@types/opentype.js": "^1.3.9",
51+
"electron": "^40.6.0",
52+
"electron-builder": "^26.8.1",
1653
"puppeteer": "^24.36.0",
1754
"typescript": "~5.9.3",
1855
"vite": "^7.2.4",
@@ -27,26 +64,35 @@
2764
"@imagemagick/magick-wasm": "^0.0.37",
2865
"@sqlite.org/sqlite-wasm": "^3.51.2-build6",
2966
"@std/yaml": "npm:@jsr/std__yaml",
67+
"@stringsync/vexml": "^0.1.8",
68+
"@toon-format/toon": "^2.1.0",
3069
"@types/bun": "^1.3.9",
3170
"@types/meyda": "^5.3.0",
3271
"@types/pako": "^2.0.4",
3372
"@types/three": "^0.182.0",
73+
"bson": "^7.2.0",
3474
"imagetracer": "^0.2.2",
75+
"js-synthesizer": "^1.11.0",
3576
"jszip": "^3.10.1",
3677
"lucide-react": "^0.574.0",
3778
"meyda": "^5.6.3",
3879
"mime": "^4.1.0",
3980
"nbtify": "^2.2.0",
81+
"opentype.js": "^1.3.4",
4082
"pako": "^2.1.0",
4183
"pdftoimg-js": "^0.2.5",
4284
"pe-library": "^2.0.1",
4385
"react": "^19.2.4",
4486
"react-dom": "^19.2.4",
87+
"svg-pathdata": "^8.0.0",
4588
"three": "^0.182.0",
4689
"three-bvh-csg": "^0.0.17",
4790
"three-mesh-bvh": "^0.9.8",
4891
"ts-flp": "^1.0.3",
92+
"verovio": "^6.0.1",
93+
"vexflow": "^5.0.0",
4994
"vite-plugin-static-copy": "^3.1.6",
50-
"wavefile": "^11.0.0"
95+
"wavefile": "^11.0.0",
96+
"woff2-encoder": "^2.0.0"
5197
}
5298
}

src/CommonFormats.ts

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ export const Category = {
1010
AUDIO: "audio",
1111
ARCHIVE: "archive",
1212
SPREADSHEET: "spreadsheet",
13-
PRESENTATION: "presentation"
13+
PRESENTATION: "presentation",
14+
FONT: "font"
1415
}
1516

1617
/**
@@ -98,8 +99,8 @@ const CommonFormats = {
9899
),
99100
MD: new FormatDefinition(
100101
"Markdown Document",
101-
"md",
102-
"md",
102+
"markdown",
103+
"markdown",
103104
"text/markdown",
104105
["document", "text"]
105106
),
@@ -190,7 +191,51 @@ const CommonFormats = {
190191
"pptx",
191192
"pptx",
192193
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
193-
Category.PRESENTATION
194+
[Category.PRESENTATION, Category.DOCUMENT]
195+
),
196+
// fonts
197+
TTF: new FormatDefinition(
198+
"TrueType Font",
199+
"ttf",
200+
"ttf",
201+
"font/ttf",
202+
[Category.FONT]
203+
),
204+
OTF: new FormatDefinition(
205+
"OpenType Font",
206+
"otf",
207+
"otf",
208+
"font/otf",
209+
[Category.FONT]
210+
),
211+
WOFF: new FormatDefinition(
212+
"Web Open Font Format",
213+
"woff",
214+
"woff",
215+
"font/woff",
216+
[Category.FONT]
217+
),
218+
WOFF2: new FormatDefinition(
219+
"Web Open Font Format 2.0",
220+
"woff2",
221+
"woff2",
222+
"font/woff2",
223+
[Category.FONT]
224+
),
225+
// music notation
226+
MUSICXML: new FormatDefinition(
227+
"MusicXML",
228+
"musicxml",
229+
"musicxml",
230+
"application/vnd.recordare.musicxml+xml",
231+
Category.DOCUMENT
232+
),
233+
MXL: new FormatDefinition(
234+
"MusicXML Compressed",
235+
"mxl",
236+
"mxl",
237+
"application/vnd.recordare.musicxml",
238+
Category.DOCUMENT
194239
)
195240
}
196241

src/FormatHandler.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@
55
export interface IFormatDefinition {
66
/** Format description (long name) for displaying to the user. */
77
name: string;
8-
/** Short, "formal" name for displaying to the user. */
8+
/** Short, "formal" name for displaying to the user, and for
9+
* differentiating between files of identical MIME types.
10+
* If your file is different from others of the same MIME type,
11+
* then this string should be used to differentiate it. */
912
format: string;
1013
/** File extension. */
1114
extension: string;
@@ -38,10 +41,10 @@ export class FormatDefinition implements IFormatDefinition {
3841
public readonly category?: string[] | string;
3942

4043
constructor(
41-
name: string,
42-
format: string,
43-
extension: string,
44-
mime: string,
44+
name: string,
45+
format: string,
46+
extension: string,
47+
mime: string,
4548
category?: string[] | string
4649
) {
4750
this.name = name
@@ -59,7 +62,7 @@ export class FormatDefinition implements IFormatDefinition {
5962
* @param to Whether conversion **to** this format is supported.
6063
* @param lossless (Optional) Whether the format is lossless in this context. Defaults to `false`.
6164
* @param override Format definition values to override
62-
* @returns
65+
* @returns
6366
*/
6467
supported(ref: string, from: boolean, to: boolean, lossless?: boolean, override: Partial<IFormatDefinition> = {}): FileFormat {
6568
return {
@@ -73,7 +76,7 @@ export class FormatDefinition implements IFormatDefinition {
7376
}
7477

7578
/**
76-
* Returns a builder to fluently create FileFormat.
79+
* Returns a builder to fluently create FileFormat.
7780
* Builder can be used to create FileFormat based on this format definition
7881
*/
7982
builder(ref: string) {

0 commit comments

Comments
 (0)