@coderline/alphatab 1.2.3 → 1.3.0-alpha.1006
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -24
- package/dist/alphaTab.core.min.mjs +2 -0
- package/dist/alphaTab.core.min.mjs.map +1 -0
- package/dist/alphaTab.core.mjs +45998 -0
- package/dist/alphaTab.core.mjs.map +1 -0
- package/dist/alphaTab.d.ts +7527 -6980
- package/dist/alphaTab.js +45839 -44263
- package/dist/alphaTab.js.map +1 -0
- package/dist/alphaTab.min.js +2 -17
- package/dist/alphaTab.min.js.map +1 -0
- package/dist/alphaTab.min.mjs +2 -17
- package/dist/alphaTab.min.mjs.map +1 -0
- package/dist/alphaTab.mjs +49 -44452
- package/dist/alphaTab.mjs.map +1 -0
- package/dist/alphaTab.vite.d.ts +36 -0
- package/dist/alphaTab.vite.js +2065 -0
- package/dist/alphaTab.vite.js.map +1 -0
- package/dist/alphaTab.vite.mjs +2044 -0
- package/dist/alphaTab.vite.mjs.map +1 -0
- package/dist/alphaTab.webpack.d.ts +41 -0
- package/dist/alphaTab.webpack.js +473 -0
- package/dist/alphaTab.webpack.js.map +1 -0
- package/dist/alphaTab.webpack.mjs +451 -0
- package/dist/alphaTab.webpack.mjs.map +1 -0
- package/dist/alphaTab.worker.min.mjs +2 -0
- package/dist/alphaTab.worker.min.mjs.map +1 -0
- package/dist/alphaTab.worker.mjs +21 -0
- package/dist/alphaTab.worker.mjs.map +1 -0
- package/dist/alphaTab.worklet.min.mjs +2 -0
- package/dist/alphaTab.worklet.min.mjs.map +1 -0
- package/dist/alphaTab.worklet.mjs +21 -0
- package/dist/alphaTab.worklet.mjs.map +1 -0
- package/package.json +62 -42
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import webpack from 'webpack';
|
|
2
|
+
|
|
3
|
+
/**@target web */
|
|
4
|
+
interface AlphaTabWebPackPluginOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The location where alphaTab can be found.
|
|
7
|
+
* (default: node_modules/@coderline/alphatab/dist)
|
|
8
|
+
*/
|
|
9
|
+
alphaTabSourceDir?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The location where assets of alphaTab should be placed.
|
|
12
|
+
* Set it to false to disable the copying of assets like fonts.
|
|
13
|
+
* (default: compiler.options.output.path)
|
|
14
|
+
*/
|
|
15
|
+
assetOutputDir?: string | false;
|
|
16
|
+
/**
|
|
17
|
+
* Whether alphaTab should configure the audio worklet support in WebPack.
|
|
18
|
+
* This might break support for audio playback unless audio worklet support is added
|
|
19
|
+
* through other means to WebPack.
|
|
20
|
+
* (default: true)
|
|
21
|
+
*/
|
|
22
|
+
audioWorklets?: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Whether alphaTab should configure the web worklet support in WebPack.
|
|
25
|
+
* This might break support for audio playback and background unless audio worklet support is added
|
|
26
|
+
* through other means to WebPack.
|
|
27
|
+
* (default: true)
|
|
28
|
+
*/
|
|
29
|
+
webWorkers?: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
declare class AlphaTabWebPackPlugin {
|
|
33
|
+
options: AlphaTabWebPackPluginOptions;
|
|
34
|
+
constructor(options?: AlphaTabWebPackPluginOptions);
|
|
35
|
+
apply(compiler: webpack.Compiler): void;
|
|
36
|
+
configureSoundFont(compiler: webpack.Compiler): void;
|
|
37
|
+
configure(compiler: webpack.Compiler): void;
|
|
38
|
+
configureAssetCopy(pluginName: string, compiler: webpack.Compiler, compilation: webpack.Compilation): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { AlphaTabWebPackPlugin };
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* alphaTab v1.3.0-alpha.1006 (develop, build 1006)
|
|
3
|
+
*
|
|
4
|
+
* Copyright © 2024, Daniel Kuschny and Contributors, All rights reserved.
|
|
5
|
+
*
|
|
6
|
+
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
7
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
8
|
+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
9
|
+
*
|
|
10
|
+
* SoundFont loading and Audio Synthesis based on TinySoundFont (licensed under MIT)
|
|
11
|
+
* Copyright (C) 2017, 2018 Bernhard Schelling (https://github.com/schellingb/TinySoundFont)
|
|
12
|
+
*
|
|
13
|
+
* TinySoundFont is based on SFZero (licensed under MIT)
|
|
14
|
+
* Copyright (C) 2012 Steve Folta (https://github.com/stevefolta/SFZero)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
'use strict';
|
|
18
|
+
|
|
19
|
+
var fs = require('fs');
|
|
20
|
+
var path = require('path');
|
|
21
|
+
var webpack = require('webpack');
|
|
22
|
+
var identifier = require('webpack/lib/util/identifier');
|
|
23
|
+
var ModuleTypeConstants = require('webpack/lib/ModuleTypeConstants');
|
|
24
|
+
var makeSerializable = require('webpack/lib/util/makeSerializable');
|
|
25
|
+
var EnableChunkLoadingPlugin = require('webpack/lib/javascript/EnableChunkLoadingPlugin');
|
|
26
|
+
var WorkerDependency = require('webpack/lib/dependencies/WorkerDependency');
|
|
27
|
+
|
|
28
|
+
function _interopNamespaceDefault(e) {
|
|
29
|
+
var n = Object.create(null);
|
|
30
|
+
if (e) {
|
|
31
|
+
Object.keys(e).forEach(function (k) {
|
|
32
|
+
if (k !== 'default') {
|
|
33
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
34
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
35
|
+
enumerable: true,
|
|
36
|
+
get: function () { return e[k]; }
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
n.default = e;
|
|
42
|
+
return Object.freeze(n);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
46
|
+
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
47
|
+
|
|
48
|
+
/**@target web */
|
|
49
|
+
class AlphaTabWorkerRuntimeModule extends webpack.RuntimeModule {
|
|
50
|
+
constructor() {
|
|
51
|
+
super("alphaTab audio worker chunk loading", webpack.RuntimeModule.STAGE_BASIC);
|
|
52
|
+
}
|
|
53
|
+
generate() {
|
|
54
|
+
const compilation = this.compilation;
|
|
55
|
+
const runtimeTemplate = compilation.runtimeTemplate;
|
|
56
|
+
const globalObject = runtimeTemplate.globalObject;
|
|
57
|
+
const chunkLoadingGlobalExpr = `${globalObject}[${JSON.stringify(compilation.outputOptions.chunkLoadingGlobal)}]`;
|
|
58
|
+
const initialChunkIds = new Set(this.chunk.ids);
|
|
59
|
+
for (const c of this.chunk.getAllInitialChunks()) {
|
|
60
|
+
if (webpack.javascript.JavascriptModulesPlugin.chunkHasJs(c, this.chunkGraph)) {
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
for (const id of c.ids) {
|
|
64
|
+
initialChunkIds.add(id);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return webpack.Template.asString([
|
|
68
|
+
`if ( ! ('AudioWorkletGlobalScope' in ${globalObject}) ) { return; }`,
|
|
69
|
+
`const installedChunks = {`,
|
|
70
|
+
webpack.Template.indent(Array.from(initialChunkIds, id => `${JSON.stringify(id)}: 1`).join(",\n")),
|
|
71
|
+
"};",
|
|
72
|
+
"// importScripts chunk loading",
|
|
73
|
+
`const installChunk = ${runtimeTemplate.basicFunction("data", [
|
|
74
|
+
runtimeTemplate.destructureArray(["chunkIds", "moreModules", "runtime"], "data"),
|
|
75
|
+
"for(const moduleId in moreModules) {",
|
|
76
|
+
webpack.Template.indent([
|
|
77
|
+
`if(${webpack.RuntimeGlobals.hasOwnProperty}(moreModules, moduleId)) {`,
|
|
78
|
+
webpack.Template.indent(`${webpack.RuntimeGlobals.moduleFactories}[moduleId] = moreModules[moduleId];`),
|
|
79
|
+
"}"
|
|
80
|
+
]),
|
|
81
|
+
"}",
|
|
82
|
+
`if(runtime) runtime(${webpack.RuntimeGlobals.require});`,
|
|
83
|
+
"while(chunkIds.length)",
|
|
84
|
+
webpack.Template.indent("installedChunks[chunkIds.pop()] = 1;"),
|
|
85
|
+
"parentChunkLoadingFunction(data);"
|
|
86
|
+
])};`,
|
|
87
|
+
`const chunkLoadingGlobal = ${chunkLoadingGlobalExpr} = ${chunkLoadingGlobalExpr} || [];`,
|
|
88
|
+
"const parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);",
|
|
89
|
+
"chunkLoadingGlobal.forEach(installChunk);",
|
|
90
|
+
"chunkLoadingGlobal.push = installChunk;"
|
|
91
|
+
]);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
AlphaTabWorkerRuntimeModule.Key = "AlphaTabWorkerRuntime";
|
|
95
|
+
|
|
96
|
+
/**@target web */
|
|
97
|
+
class AlphaTabWorkletStartRuntimeModule extends webpack.RuntimeModule {
|
|
98
|
+
constructor() {
|
|
99
|
+
super("alphaTab audio worklet chunk lookup", webpack.RuntimeModule.STAGE_BASIC);
|
|
100
|
+
}
|
|
101
|
+
generate() {
|
|
102
|
+
const compilation = this.compilation;
|
|
103
|
+
const workletChunkLookup = new Map();
|
|
104
|
+
const chunkGraph = this.chunkGraph;
|
|
105
|
+
const allChunks = compilation.chunks;
|
|
106
|
+
for (const chunk of allChunks) {
|
|
107
|
+
const isWorkletEntry = chunkGraph
|
|
108
|
+
.getTreeRuntimeRequirements(chunk)
|
|
109
|
+
.has(AlphaTabWorkerRuntimeModule.Key);
|
|
110
|
+
if (isWorkletEntry) {
|
|
111
|
+
const workletChunks = Array.from(chunk.getAllReferencedChunks()).map(c => {
|
|
112
|
+
// force content chunk to be created
|
|
113
|
+
compilation.hooks.contentHash.call(c);
|
|
114
|
+
return compilation.getPath(webpack.javascript.JavascriptModulesPlugin.getChunkFilenameTemplate(c, compilation.outputOptions), {
|
|
115
|
+
chunk: c,
|
|
116
|
+
contentHashType: "javascript"
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
workletChunkLookup.set(String(chunk.id), workletChunks);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return webpack.Template.asString([
|
|
123
|
+
`${AlphaTabWorkletStartRuntimeModule.RuntimeGlobalWorkletGetStartupChunks} = (() => {`,
|
|
124
|
+
webpack.Template.indent([
|
|
125
|
+
"const lookup = new Map(",
|
|
126
|
+
webpack.Template.indent(JSON.stringify(Array.from(workletChunkLookup.entries()))),
|
|
127
|
+
");",
|
|
128
|
+
"return (chunkId) => lookup.get(String(chunkId)) ?? [];"
|
|
129
|
+
]),
|
|
130
|
+
"})();"
|
|
131
|
+
]);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
AlphaTabWorkletStartRuntimeModule.RuntimeGlobalWorkletGetStartupChunks = "__webpack_require__.wsc";
|
|
135
|
+
|
|
136
|
+
/**@target web */
|
|
137
|
+
function makeDependencySerializable(dependency, key) {
|
|
138
|
+
makeSerializable(dependency, key);
|
|
139
|
+
}
|
|
140
|
+
function tapJavaScript(normalModuleFactory, pluginName, parserPlugin) {
|
|
141
|
+
normalModuleFactory.hooks.parser
|
|
142
|
+
.for(ModuleTypeConstants.JAVASCRIPT_MODULE_TYPE_AUTO)
|
|
143
|
+
.tap(pluginName, parserPlugin);
|
|
144
|
+
normalModuleFactory.hooks.parser
|
|
145
|
+
.for(ModuleTypeConstants.JAVASCRIPT_MODULE_TYPE_ESM)
|
|
146
|
+
.tap(pluginName, parserPlugin);
|
|
147
|
+
}
|
|
148
|
+
function parseModuleUrl(parser, expr) {
|
|
149
|
+
if (expr.type !== "NewExpression" || expr.arguments.length !== 2) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const newExpr = expr;
|
|
153
|
+
const [arg1, arg2] = newExpr.arguments;
|
|
154
|
+
const callee = parser.evaluateExpression(newExpr.callee);
|
|
155
|
+
if (!callee.isIdentifier() || callee.identifier !== "URL") {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const arg1Value = parser.evaluateExpression(arg1);
|
|
159
|
+
return [
|
|
160
|
+
arg1Value,
|
|
161
|
+
[
|
|
162
|
+
(arg1.range)[0],
|
|
163
|
+
(arg2.range)[1]
|
|
164
|
+
]
|
|
165
|
+
];
|
|
166
|
+
}
|
|
167
|
+
function getWorkerRuntime(parser, compilation, cachedContextify, workerIndexMap) {
|
|
168
|
+
let i = workerIndexMap.get(parser.state) || 0;
|
|
169
|
+
workerIndexMap.set(parser.state, i + 1);
|
|
170
|
+
let name = `${cachedContextify(parser.state.module.identifier())}|${i}`;
|
|
171
|
+
const hash = webpack.util.createHash(compilation.outputOptions.hashFunction);
|
|
172
|
+
hash.update(name);
|
|
173
|
+
const digest = hash.digest(compilation.outputOptions.hashDigest);
|
|
174
|
+
const runtime = digest.slice(0, compilation.outputOptions.hashDigestLength);
|
|
175
|
+
return runtime;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**@target web */
|
|
179
|
+
/**
|
|
180
|
+
* This module dependency injects the relevant code into a worklet bootstrap script
|
|
181
|
+
* to install chunks which have been added to the worklet via addModule before the bootstrap script starts.
|
|
182
|
+
*/
|
|
183
|
+
class AlphaTabWorkletDependency extends webpack.dependencies.ModuleDependency {
|
|
184
|
+
constructor(url, range, publicPath) {
|
|
185
|
+
super(url);
|
|
186
|
+
this.range = range;
|
|
187
|
+
this.publicPath = publicPath;
|
|
188
|
+
}
|
|
189
|
+
get type() {
|
|
190
|
+
return "alphaTabWorklet";
|
|
191
|
+
}
|
|
192
|
+
get category() {
|
|
193
|
+
return "worker";
|
|
194
|
+
}
|
|
195
|
+
updateHash(hash) {
|
|
196
|
+
if (this._hashUpdate === undefined) {
|
|
197
|
+
this._hashUpdate = JSON.stringify(this.publicPath);
|
|
198
|
+
}
|
|
199
|
+
hash.update(this._hashUpdate);
|
|
200
|
+
}
|
|
201
|
+
serialize(context) {
|
|
202
|
+
const { write } = context;
|
|
203
|
+
write(this.publicPath);
|
|
204
|
+
super.serialize(context);
|
|
205
|
+
}
|
|
206
|
+
deserialize(context) {
|
|
207
|
+
const { read } = context;
|
|
208
|
+
this.publicPath = read();
|
|
209
|
+
super.deserialize(context);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
AlphaTabWorkletDependency.Template = class AlphaTabWorkletDependencyTemplate extends webpack.dependencies.ModuleDependency.Template {
|
|
213
|
+
apply(dependency, source, templateContext) {
|
|
214
|
+
const { chunkGraph, moduleGraph, runtimeRequirements } = templateContext;
|
|
215
|
+
const dep = dependency;
|
|
216
|
+
const block = moduleGraph.getParentBlock(dependency);
|
|
217
|
+
const entrypoint = chunkGraph.getBlockChunkGroup(block);
|
|
218
|
+
const workletImportBaseUrl = dep.publicPath
|
|
219
|
+
? JSON.stringify(dep.publicPath)
|
|
220
|
+
: webpack.RuntimeGlobals.publicPath;
|
|
221
|
+
const chunk = entrypoint.getEntrypointChunk();
|
|
222
|
+
// worklet global scope has no 'self', need to inject it for compatibility with chunks
|
|
223
|
+
// some plugins like the auto public path need to right location. we pass this on from the main runtime
|
|
224
|
+
// some plugins rely on importScripts to be defined.
|
|
225
|
+
const workletInlineBootstrap = `
|
|
226
|
+
globalThis.self = globalThis.self || globalThis;
|
|
227
|
+
globalThis.location = \${JSON.stringify(${webpack.RuntimeGlobals.baseURI})};
|
|
228
|
+
globalThis.importScripts = (url) => { throw new Error("importScripts not available, dynamic loading of chunks not supported in this context", url) };
|
|
229
|
+
`;
|
|
230
|
+
chunkGraph.addChunkRuntimeRequirements(chunk, new Set([
|
|
231
|
+
webpack.RuntimeGlobals.moduleFactories,
|
|
232
|
+
AlphaTabWorkerRuntimeModule.Key
|
|
233
|
+
]));
|
|
234
|
+
runtimeRequirements.add(AlphaTabWorkletStartRuntimeModule.RuntimeGlobalWorkletGetStartupChunks);
|
|
235
|
+
source.replace(dep.range[0], dep.range[1] - 1, webpack.Template.asString([
|
|
236
|
+
"(/* worklet bootstrap */ async function(__webpack_worklet__) {",
|
|
237
|
+
webpack.Template.indent([
|
|
238
|
+
`await __webpack_worklet__.addModule(URL.createObjectURL(new Blob([\`${workletInlineBootstrap}\`], { type: "application/javascript; charset=utf-8" })));`,
|
|
239
|
+
`for (const fileName of ${AlphaTabWorkletStartRuntimeModule.RuntimeGlobalWorkletGetStartupChunks}(${chunk.id})) {`,
|
|
240
|
+
webpack.Template.indent([
|
|
241
|
+
`await __webpack_worklet__.addModule(new URL(${workletImportBaseUrl} + fileName, ${webpack.RuntimeGlobals.baseURI}));`
|
|
242
|
+
]),
|
|
243
|
+
"}"
|
|
244
|
+
]),
|
|
245
|
+
`})(alphaTabWorklet)`
|
|
246
|
+
]));
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
makeDependencySerializable(AlphaTabWorkletDependency, 'AlphaTabWorkletDependency');
|
|
250
|
+
|
|
251
|
+
/**@target web */
|
|
252
|
+
const AlphaTabWorkletSpecifierTag = Symbol("alphatab worklet specifier tag");
|
|
253
|
+
const workletIndexMap = new WeakMap();
|
|
254
|
+
/**
|
|
255
|
+
* Configures the Audio Worklet aspects within webpack.
|
|
256
|
+
* The counterpart which this plugin detects sits in alphaTab.main.ts
|
|
257
|
+
* @param pluginName
|
|
258
|
+
* @param options
|
|
259
|
+
* @param compiler
|
|
260
|
+
* @param compilation
|
|
261
|
+
* @param normalModuleFactory
|
|
262
|
+
* @param cachedContextify
|
|
263
|
+
* @returns
|
|
264
|
+
*/
|
|
265
|
+
function configureAudioWorklet(pluginName, options, compiler, compilation, normalModuleFactory, cachedContextify) {
|
|
266
|
+
if (options.audioWorklets === false) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
compilation.dependencyFactories.set(AlphaTabWorkletDependency, normalModuleFactory);
|
|
270
|
+
compilation.dependencyTemplates.set(AlphaTabWorkletDependency, new AlphaTabWorkletDependency.Template());
|
|
271
|
+
const handleAlphaTabWorklet = (parser, expr) => {
|
|
272
|
+
const [arg1] = expr.arguments;
|
|
273
|
+
const parsedUrl = parseModuleUrl(parser, arg1);
|
|
274
|
+
if (!parsedUrl) {
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const [url] = parsedUrl;
|
|
278
|
+
if (!url.isString()) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const runtime = getWorkerRuntime(parser, compilation, cachedContextify, workletIndexMap);
|
|
282
|
+
const block = new webpack.AsyncDependenciesBlock({
|
|
283
|
+
entryOptions: {
|
|
284
|
+
chunkLoading: false,
|
|
285
|
+
wasmLoading: false,
|
|
286
|
+
runtime: runtime
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
block.loc = expr.loc;
|
|
290
|
+
const workletBootstrap = new AlphaTabWorkletDependency(url.string, [expr.range[0], expr.range[1]], compiler.options.output.workerPublicPath);
|
|
291
|
+
workletBootstrap.loc = expr.loc;
|
|
292
|
+
block.addDependency(workletBootstrap);
|
|
293
|
+
parser.state.module.addBlock(block);
|
|
294
|
+
return true;
|
|
295
|
+
};
|
|
296
|
+
const parserPlugin = (parser) => {
|
|
297
|
+
const pattern = "alphaTabWorklet";
|
|
298
|
+
const itemMembers = "addModule";
|
|
299
|
+
parser.hooks.preDeclarator.tap(pluginName, (decl) => {
|
|
300
|
+
if (decl.id.type === "Identifier" && decl.id.name === pattern) {
|
|
301
|
+
parser.tagVariable(decl.id.name, AlphaTabWorkletSpecifierTag);
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
return;
|
|
305
|
+
});
|
|
306
|
+
parser.hooks.pattern.for(pattern).tap(pluginName, (pattern) => {
|
|
307
|
+
parser.tagVariable(pattern.name, AlphaTabWorkletSpecifierTag);
|
|
308
|
+
return true;
|
|
309
|
+
});
|
|
310
|
+
parser.hooks.callMemberChain
|
|
311
|
+
.for(AlphaTabWorkletSpecifierTag)
|
|
312
|
+
.tap(pluginName, (expression, members) => {
|
|
313
|
+
if (itemMembers !== members.join(".")) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
return handleAlphaTabWorklet(parser, expression);
|
|
317
|
+
});
|
|
318
|
+
};
|
|
319
|
+
tapJavaScript(normalModuleFactory, pluginName, parserPlugin);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**@target web */
|
|
323
|
+
const workerIndexMap = new WeakMap();
|
|
324
|
+
/**
|
|
325
|
+
* Configures the WebWorker aspects within webpack.
|
|
326
|
+
* The counterpart which this plugin detects sits in alphaTab.main.ts
|
|
327
|
+
* @param pluginName
|
|
328
|
+
* @param options
|
|
329
|
+
* @param compiler
|
|
330
|
+
* @param compilation
|
|
331
|
+
* @param normalModuleFactory
|
|
332
|
+
* @param cachedContextify
|
|
333
|
+
* @returns
|
|
334
|
+
*/
|
|
335
|
+
function configureWebWorker(pluginName, options, compiler, compilation, normalModuleFactory, cachedContextify) {
|
|
336
|
+
if (options.audioWorklets === false) {
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
compilation.dependencyFactories.set(WorkerDependency, normalModuleFactory);
|
|
340
|
+
compilation.dependencyTemplates.set(WorkerDependency, new WorkerDependency.Template());
|
|
341
|
+
new EnableChunkLoadingPlugin('import-scripts').apply(compiler);
|
|
342
|
+
const handleAlphaTabWorker = (parser, expr) => {
|
|
343
|
+
const [arg1, arg2] = expr.arguments;
|
|
344
|
+
const parsedUrl = parseModuleUrl(parser, arg1);
|
|
345
|
+
if (!parsedUrl) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const [url, range] = parsedUrl;
|
|
349
|
+
if (!url.isString()) {
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const runtime = getWorkerRuntime(parser, compilation, cachedContextify, workerIndexMap);
|
|
353
|
+
const block = new webpack.AsyncDependenciesBlock({
|
|
354
|
+
entryOptions: {
|
|
355
|
+
chunkLoading: 'import-scripts',
|
|
356
|
+
wasmLoading: false,
|
|
357
|
+
runtime: runtime
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
block.loc = expr.loc;
|
|
361
|
+
const workletBootstrap = new WorkerDependency(url.string, range, compiler.options.output.workerPublicPath);
|
|
362
|
+
workletBootstrap.loc = expr.loc;
|
|
363
|
+
block.addDependency(workletBootstrap);
|
|
364
|
+
parser.state.module.addBlock(block);
|
|
365
|
+
const dep1 = new webpack.dependencies.ConstDependency(`{ type: ${compilation.options.output.module ? '"module"' : "undefined"} }`, arg2.range);
|
|
366
|
+
dep1.loc = expr.loc;
|
|
367
|
+
parser.state.module.addPresentationalDependency(dep1);
|
|
368
|
+
parser.walkExpression(expr.callee);
|
|
369
|
+
return true;
|
|
370
|
+
};
|
|
371
|
+
const parserPlugin = (parser) => {
|
|
372
|
+
parser.hooks.new.for("alphaTab.Environment.alphaTabWorker").tap(pluginName, (expr) => handleAlphaTabWorker(parser, expr));
|
|
373
|
+
};
|
|
374
|
+
tapJavaScript(normalModuleFactory, pluginName, parserPlugin);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**@target web */
|
|
378
|
+
class AlphaTabWebPackPlugin {
|
|
379
|
+
constructor(options) {
|
|
380
|
+
this.options = options ?? {};
|
|
381
|
+
}
|
|
382
|
+
apply(compiler) {
|
|
383
|
+
this.configureSoundFont(compiler);
|
|
384
|
+
this.configure(compiler);
|
|
385
|
+
}
|
|
386
|
+
configureSoundFont(compiler) {
|
|
387
|
+
if (this.options.assetOutputDir === false) {
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
// register soundfont as resource
|
|
391
|
+
compiler.options.module.rules.push({
|
|
392
|
+
test: /\.sf2/,
|
|
393
|
+
type: "asset/resource",
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
configure(compiler) {
|
|
397
|
+
const pluginName = this.constructor.name;
|
|
398
|
+
const cachedContextify = identifier.contextify.bindContextCache(compiler.context, compiler.root);
|
|
399
|
+
compiler.hooks.thisCompilation.tap(pluginName, (compilation, { normalModuleFactory }) => {
|
|
400
|
+
compilation.hooks.runtimeRequirementInTree
|
|
401
|
+
.for(AlphaTabWorkerRuntimeModule.Key)
|
|
402
|
+
.tap(pluginName, (chunk) => {
|
|
403
|
+
compilation.addRuntimeModule(chunk, new AlphaTabWorkerRuntimeModule());
|
|
404
|
+
});
|
|
405
|
+
compilation.hooks.runtimeRequirementInTree
|
|
406
|
+
.for(AlphaTabWorkletStartRuntimeModule.RuntimeGlobalWorkletGetStartupChunks)
|
|
407
|
+
.tap(pluginName, (chunk) => {
|
|
408
|
+
compilation.addRuntimeModule(chunk, new AlphaTabWorkletStartRuntimeModule());
|
|
409
|
+
});
|
|
410
|
+
configureAudioWorklet(pluginName, this.options, compiler, compilation, normalModuleFactory, cachedContextify);
|
|
411
|
+
configureWebWorker(pluginName, this.options, compiler, compilation, normalModuleFactory, cachedContextify);
|
|
412
|
+
this.configureAssetCopy(pluginName, compiler, compilation);
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
configureAssetCopy(pluginName, compiler, compilation) {
|
|
416
|
+
if (this.options.assetOutputDir === false) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
const options = this.options;
|
|
420
|
+
compilation.hooks.processAssets.tapAsync({
|
|
421
|
+
name: pluginName,
|
|
422
|
+
stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL,
|
|
423
|
+
}, async (_, callback) => {
|
|
424
|
+
let alphaTabSourceDir = options.alphaTabSourceDir;
|
|
425
|
+
if (!alphaTabSourceDir) {
|
|
426
|
+
alphaTabSourceDir = compilation.getPath('node_modules/@coderline/alphatab/dist/');
|
|
427
|
+
}
|
|
428
|
+
if (!alphaTabSourceDir || !fs__namespace.promises.access(path__namespace.join(alphaTabSourceDir, 'alphaTab.mjs'), fs__namespace.constants.F_OK)) {
|
|
429
|
+
compilation.errors.push(new webpack.WebpackError('Could not find alphaTab, please ensure it is installed into node_modules or configure alphaTabSourceDir'));
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
const outputPath = (options.assetOutputDir ?? compiler.options.output.path);
|
|
433
|
+
if (!outputPath) {
|
|
434
|
+
compilation.errors.push(new webpack.WebpackError('Need output.path configured in application to store asset files.'));
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
async function copyFiles(subdir) {
|
|
438
|
+
const fullDir = path__namespace.join(alphaTabSourceDir, subdir);
|
|
439
|
+
compilation.contextDependencies.add(path__namespace.normalize(fullDir));
|
|
440
|
+
const files = await fs__namespace.promises.readdir(fullDir, { withFileTypes: true });
|
|
441
|
+
await fs__namespace.promises.mkdir(path__namespace.join(outputPath, subdir), { recursive: true });
|
|
442
|
+
await Promise.all(files.filter(f => f.isFile()).map(async (file) => {
|
|
443
|
+
const sourceFilename = path__namespace.join(file.path, file.name);
|
|
444
|
+
await fs__namespace.promises.copyFile(sourceFilename, path__namespace.join(outputPath, subdir, file.name));
|
|
445
|
+
const assetFileName = subdir + '/' + file.name;
|
|
446
|
+
const existingAsset = compilation.getAsset(assetFileName);
|
|
447
|
+
const data = await fs__namespace.promises.readFile(sourceFilename);
|
|
448
|
+
const source = new compiler.webpack.sources.RawSource(data);
|
|
449
|
+
if (existingAsset) {
|
|
450
|
+
compilation.updateAsset(assetFileName, source, {
|
|
451
|
+
copied: true,
|
|
452
|
+
sourceFilename
|
|
453
|
+
});
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
compilation.emitAsset(assetFileName, source, {
|
|
457
|
+
copied: true,
|
|
458
|
+
sourceFilename
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
}));
|
|
462
|
+
}
|
|
463
|
+
await Promise.all([
|
|
464
|
+
copyFiles("font"),
|
|
465
|
+
copyFiles("soundfont")
|
|
466
|
+
]);
|
|
467
|
+
callback();
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
exports.AlphaTabWebPackPlugin = AlphaTabWebPackPlugin;
|
|
473
|
+
//# sourceMappingURL=alphaTab.webpack.js.map
|