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
2,372 changes: 1,541 additions & 831 deletions package-lock.json

Large diffs are not rendered by default.

14 changes: 7 additions & 7 deletions packages/alphatab/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,14 @@
"@coderline/alphaskia": "^3.5.147",
"@coderline/alphaskia-linux": "^3.5.147",
"@coderline/alphaskia-windows": "^3.5.147",
"@types/node": "^25.2.2",
"rimraf": "^6.1.2",
"@types/node": "^25.9.1",
"rimraf": "^6.1.3",
"tslib": "^2.8.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vite": "^7.3.1",
"vite-plugin-static-copy": "^3.2.0",
"vitest": "^4.1.6"
"tsx": "^4.22.3",
"typescript": "^6.0.3",
"vite": "^8.0.14",
"vite-plugin-static-copy": "^4.1.0",
"vitest": "^4.1.7"
},
"files": [
"/dist/alphaTab*.js",
Expand Down
4 changes: 2 additions & 2 deletions packages/alphatab/scripts/TypeSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,9 +302,9 @@ export function getTypeWithNullableInfo(
fillBaseInfoFrom(node);
} else if (node.isUnion()) {
for (const t of node.types) {
if ((t.flags & ts.TypeFlags.Null) !== 0) {
if (t === checker.getNullType()) {
typeInfo.isNullable = true;
} else if ((t.flags & ts.TypeFlags.Undefined) !== 0) {
} else if (t === checker.getUndefinedType()) {
typeInfo.isOptional = true;
} else if (!mainType) {
fillBaseInfoFrom(t);
Expand Down
5 changes: 4 additions & 1 deletion packages/alphatab/src/alphaTab.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,10 @@ if (alphaTab.Environment.isRunningInWorker) {
alphaTab.Environment.isViteBundled
) {
alphaTab.Logger.debug('AlphaTab', 'Creating Module worklet');
const alphaTabWorklet = context.audioWorklet; // this name triggers the WebPack Plugin
// destructure-rename keeps the `alphaTabWorklet` binding alive past
// rolldown's single-use inlining and isolates the call from the
// built-in bundler handlers that match on `audioWorklet.addModule`.
const { audioWorklet: alphaTabWorklet } = context;
return alphaTabWorklet.addModule(
new alphaTab.Environment.alphaTabUrl('./alphaTab.worklet.ts', import.meta.url)
);
Expand Down
112 changes: 79 additions & 33 deletions packages/alphatab/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import path from 'node:path';
import url from 'node:url';
import type { RollupTypescriptOptions } from '@rollup/plugin-typescript';
import type { Class, VariableDeclaration } from '@oxc-project/types';
import MagicString from 'magic-string';
import { parseAst } from 'rolldown/parseAst';
import type { OutputOptions } from 'rollup';
import { defineConfig, type LibraryOptions, type Plugin } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
import { defaultBuildUserConfig, umd, esm as defaultEsm, dtsPathsTransformer } from '../tooling/src/vite';
import { elementStyleUsingTransformer } from '../tooling/src/typescript';
import { addDts, defaultBuildUserConfig, esm, umd } from '../tooling/src/vite';

const __dirname = url.fileURLToPath(new URL('.', import.meta.url));

Expand All @@ -30,59 +30,105 @@ const adjustScriptPathsPlugin = (min: boolean) => {
} satisfies Plugin;
};

// Rolldown unconditionally lowers top-level `class X { ... }` declarations to
// `var X = class { ... };` (documented as TDZ-hoisting behaviour, independent
// of `output.topLevelVar`). Downstream tooling that pattern-matches the
// published bundle on `class X` substrings — like the alphatab webpack plugin
// — depends on the declaration form, so we restore it here.
const preserveClassDeclarationsPlugin = (): Plugin => ({
name: 'preserve-class-declarations',
renderChunk(code) {
const program = parseAst(code, { lang: 'js', sourceType: 'module' });
const ms = new MagicString(code);
let changed = false;

for (const stmt of program.body) {
if (stmt.type !== 'VariableDeclaration') {
continue;
}
const varStmt = stmt as VariableDeclaration;
if (varStmt.declarations.length !== 1) {
continue;
}
const decl = varStmt.declarations[0];
if (decl.id.type !== 'Identifier' || !decl.init || decl.init.type !== 'ClassExpression') {
continue;
}
const classExpr = decl.init as Class;
// skip when the inner name differs from the outer binding — that
// would change semantics if the body self-references the inner name.
if (classExpr.id && classExpr.id.name !== decl.id.name) {
continue;
}

// drop `var <id> = ` prefix, leaving the class expression
ms.remove(varStmt.start, classExpr.start);
// promote to class declaration: insert the binding name after `class`
// if it isn't already present as an inner name.
if (!classExpr.id) {
ms.appendLeft(classExpr.start + 'class'.length, ` ${decl.id.name}`);
}
// drop the trailing semicolon of the var statement
if (code[varStmt.end - 1] === ';') {
ms.remove(varStmt.end - 1, varStmt.end);
}
changed = true;
}

if (!changed) {
return null;
}
return { code: ms.toString(), map: ms.generateMap({ hires: 'boundary' }) };
}
});

export default defineConfig(({ mode }) => {
const config = defaultBuildUserConfig();
const config = defaultBuildUserConfig(__dirname);
config.plugins!.push(
viteStaticCopy({
// `stripBase` flattens so files land directly under `font/` and
// `soundfont/` instead of preserving the `font/bravura/` prefix.
targets: [
{ src: 'font/bravura/*', dest: 'font/' },
{ src: 'font/sonivox/*', dest: 'soundfont/' }
{ src: 'font/bravura/*', dest: 'font/', rename: { stripBase: true } },
{ src: 'font/sonivox/*', dest: 'soundfont/', rename: { stripBase: true } }
]
})
);

const lib = config.build!.lib! as LibraryOptions;
lib.name = 'alphaTab';

const typeScriptOptions = (): Partial<RollupTypescriptOptions> => {
return {
transformers: {
before: [elementStyleUsingTransformer()],
afterDeclarations: [dtsPathsTransformer()]
}
};
};

const esm = (name: string, entry: string) => {
defaultEsm(
config,
__dirname,
name,
entry,
typeScriptOptions(),
chunk => !chunk.facadeModuleId!.endsWith('alphaTab.core.ts')
);

(config.build!.rollupOptions!.external as string[]).push('@coderline/alphatab/alphaTab.core');
};

switch (mode) {
case 'umd':
umd(config, __dirname, 'alphaTab', 'src/alphaTab.main.ts', typeScriptOptions(), true);
umd(config, __dirname, 'alphaTab', 'src/alphaTab.main.ts', true);
break;
//case 'esm':
default:
esm('alphaTab', 'src/alphaTab.main.ts');
const entry = lib.entry! as Record<string, string>;
default: {
esm(config, __dirname, 'alphaTab', 'src/alphaTab.main.ts');

const entry = lib.entry as Record<string, string>;
entry['alphaTab.core'] = path.resolve(__dirname, 'src/alphaTab.core.ts');
entry['alphaTab.worker'] = path.resolve(__dirname, 'src/alphaTab.worker.ts');
entry['alphaTab.worklet'] = path.resolve(__dirname, 'src/alphaTab.worklet.ts');

(config.build!.rollupOptions!.external as string[]).push('@coderline/alphatab/alphaTab.core');

for (const output of config.build!.rollupOptions!.output as OutputOptions[]) {
const isMin = (output.entryFileNames as string).includes('.min');
(output.plugins as Plugin[]).push(adjustScriptPathsPlugin(isMin));
(output.plugins as Plugin[]).push(
adjustScriptPathsPlugin(isMin),
preserveClassDeclarationsPlugin()
);
}

// alphaTab.core is an internal runtime-split JS chunk; its types
// are already re-exported through alphaTab.main, so no separate
// bundled `alphaTab.core.d.ts` is published.
addDts(config, __dirname, {
shouldEmitForChunk: chunk => !chunk.facadeModuleId!.endsWith('alphaTab.core.ts')
});
break;
}
}

return config;
Expand Down
2 changes: 1 addition & 1 deletion packages/alphatex/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"rimraf": "^6.1.3",
"tslib": "^2.8.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"typescript": "^6.0.3",
"vitest": "^4.1.6"
},
"type": "module"
Expand Down
3 changes: 2 additions & 1 deletion packages/csharp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
},
"devDependencies": {
"@coderline/alphatab-transpiler": "*",
"rimraf": "^6.1.3"
"rimraf": "^6.1.3",
"typescript": "^6.0.3"
}
}
14 changes: 4 additions & 10 deletions packages/csharp/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { defaultClientMainFields, defineConfig } from 'vite';
import { defaultBuildUserConfig, dtsPathsTransformer, esm } from '../tooling/src/vite';
import { addDts, defaultBuildUserConfig, esm } from '../tooling/src/vite';

export default defineConfig(() => {
const config = defaultBuildUserConfig();
const config = defaultBuildUserConfig(import.meta.dirname);
config.build!.sourcemap = true;
config.resolve ??= {};
config.resolve.mainFields = defaultClientMainFields.filter(f => f !== 'browser');

esm(config, import.meta.dirname, 'server', 'src/index.ts', {
module: 'preserve',
transformers: {
afterDeclarations: [
dtsPathsTransformer()
]
}
});
esm(config, import.meta.dirname, 'server', 'src/index.ts');
(config.build!.rollupOptions!.external as (RegExp | string)[]).push('@coderline/alphatab');
addDts(config, import.meta.dirname);

return config;
});
14 changes: 4 additions & 10 deletions packages/kotlin/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { defaultClientMainFields, defineConfig } from 'vite';
import { defaultBuildUserConfig, dtsPathsTransformer, esm } from '../tooling/src/vite';
import { addDts, defaultBuildUserConfig, esm } from '../tooling/src/vite';

export default defineConfig(() => {
const config = defaultBuildUserConfig();
const config = defaultBuildUserConfig(import.meta.dirname);
config.build!.sourcemap = true;
config.resolve ??= {};
config.resolve.mainFields = defaultClientMainFields.filter(f => f !== 'browser');

esm(config, import.meta.dirname, 'server', 'src/index.ts', {
module: 'preserve',
transformers: {
afterDeclarations: [
dtsPathsTransformer()
]
}
});
esm(config, import.meta.dirname, 'server', 'src/index.ts');
(config.build!.rollupOptions!.external as (RegExp | string)[]).push('@coderline/alphatab');
addDts(config, import.meta.dirname);

return config;
});
9 changes: 4 additions & 5 deletions packages/lsp/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@
"devDependencies": {
"@biomejs/biome": "^2.4.15",
"@microsoft/api-extractor": "^7.57.7",
"@types/node": "^25.6.0",
"@types/node": "^25.9.1",
"rimraf": "^6.1.3",
"tslib": "^2.8.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^4.1.6"
"tsx": "^4.22.3",
"typescript": "^6.0.3",
"vitest": "^4.1.7"
},
"bin": "./dist/server.mjs",
"main": "./dist/server.mjs",
Expand Down
12 changes: 4 additions & 8 deletions packages/lsp/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
import { defaultClientMainFields, defineConfig } from 'vite';
import { defaultBuildUserConfig, dtsPathsTransformer, esm } from '../tooling/src/vite';
import { addDts, defaultBuildUserConfig, esm } from '../tooling/src/vite';

export default defineConfig(() => {
const config = defaultBuildUserConfig();
const config = defaultBuildUserConfig(import.meta.dirname);
config.build!.sourcemap = true;
config.resolve ??= {};
config.resolve.mainFields = defaultClientMainFields.filter(f => f !== 'browser');

esm(config, import.meta.dirname, 'server', 'src/index.ts', {
module: 'preserve',
transformers: {
afterDeclarations: [dtsPathsTransformer()]
}
});
esm(config, import.meta.dirname, 'server', 'src/index.ts');
(config.build!.rollupOptions!.external as (RegExp | string)[]).push('@coderline/alphatab');
addDts(config, import.meta.dirname);
return config;
});
7 changes: 3 additions & 4 deletions packages/monaco/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,11 @@
"devDependencies": {
"@biomejs/biome": "^2.4.15",
"@microsoft/api-extractor": "^7.57.7",
"@types/node": "^25.6.0",
"@types/node": "^25.9.1",
"rimraf": "^6.1.3",
"tslib": "^2.8.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"vite-tsconfig-paths": "^6.1.1",
"tsx": "^4.22.3",
"typescript": "^6.0.3",
"vitest": "^4.1.6"
},
"bin": "./dist/alphaTab.monaco.mjs",
Expand Down
7 changes: 3 additions & 4 deletions packages/playground/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
"devDependencies": {
"split.js": "^1.6.5",
"tslib": "^2.8.1",
"typescript": "^5.9.3",
"vite": "^7.3.2",
"vite-tsconfig-paths": "^6.1.1",
"vitest": "^4.1.6"
"typescript": "^6.0.3",
"vite": "^8.0.14",
"vitest": "^4.1.7"
}
}
13 changes: 3 additions & 10 deletions packages/playground/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
import { defineConfig, type UserConfig } from 'vite';
import { elementStyleUsingTransformer } from '../tooling/src/typescript';
import { enableTypeScript } from '../tooling/src/vite';
import { elementStyleUsingPlugin } from '../tooling/src/vite.plugin.transform';
import server from './vite.plugin.server';

export default defineConfig(_ => {
const config: UserConfig = {
plugins: [server()],
plugins: [server(), elementStyleUsingPlugin()],
server: {
open: '/index.html'
},
esbuild: false
};
enableTypeScript(config, {
transformers: {
before: [elementStyleUsingTransformer()]
}
});
};

return config;
});
31 changes: 31 additions & 0 deletions packages/tooling/biome.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"$schema": "https://biomejs.dev/schemas/2.2.5/schema.json",
"root": false,
"extends": "//",
"files": {
"includes": [
"*.ts",
"src/**",
"test/**"
]
},
"formatter": {
"includes": [
"*.ts",
"src/**",
"test/**"
]
},
"linter": {
"includes": [
"*.ts",
"src/**",
"test/**"
],
"rules": {
"suspicious": {
"noTemplateCurlyInString": "off"
}
}
}
}
Loading
Loading