feat: load webmscore in nodejs

This commit is contained in:
Xmader 2020-11-24 04:36:01 -05:00
parent 195f607817
commit 3b43957cee
No known key found for this signature in database
GPG key ID: A20B97FB9EB730E4

View file

@ -1,6 +1,8 @@
/* eslint-disable @typescript-eslint/no-var-requires */
import { fetchMscz } from './mscz' import { fetchMscz } from './mscz'
import { fetchData } from './utils' import { fetchData } from './utils'
import { ScoreInfo } from './scoreinfo'
const WEBMSCORE_URL = 'https://cdn.jsdelivr.net/npm/webmscore@0.10/webmscore.js' const WEBMSCORE_URL = 'https://cdn.jsdelivr.net/npm/webmscore@0.10/webmscore.js'
@ -12,25 +14,41 @@ const SF3_URL = 'https://cdn.jsdelivr.net/npm/@librescore/sf3/FluidR3Mono_GM.sf3
const SOUND_FONT_LOADED = Symbol('SoundFont loaded') const SOUND_FONT_LOADED = Symbol('SoundFont loaded')
export type WebMscore = import('webmscore').default export type WebMscore = import('webmscore').default
export type WebMscoreConstr = typeof import('webmscore').default
const initMscore = async (w: Window) => { const initMscore = async (w?: Window): Promise<WebMscoreConstr> => {
if (!w['WebMscore']) { if (w !== undefined) { // attached to a page
// init webmscore (https://github.com/LibreScore/webmscore) if (!w['WebMscore']) {
const script = w.document.createElement('script') // init webmscore (https://github.com/LibreScore/webmscore)
script.src = WEBMSCORE_URL const script = w.document.createElement('script')
w.document.body.append(script) script.src = WEBMSCORE_URL
await new Promise(resolve => { script.onload = resolve }) w.document.body.append(script)
await new Promise(resolve => { script.onload = resolve })
}
return w['WebMscore'] as WebMscoreConstr
} else { // nodejs
return require('webmscore').default as WebMscoreConstr
} }
} }
let fonts: Promise<Uint8Array[]> | undefined let fonts: Promise<Uint8Array[]> | undefined
const initFonts = () => { const initFonts = (nodeJs: boolean) => {
// load CJK fonts // load CJK fonts
// CJK (East Asian) characters will be rendered as "tofu" if there is no font // CJK (East Asian) characters will be rendered as "tofu" if there is no font
if (!fonts) { if (!fonts) {
fonts = Promise.all( if (nodeJs) {
FONT_URLS.map(url => fetchData(url)), // module.exports.CN = ..., module.exports.KR = ...
) const FONTS = Object.values(require('@librescore/fonts'))
const fs = require('fs')
fonts = Promise.all(
FONTS.map((path: string) => fs.promises.readFile(path) as Promise<Buffer>),
)
} else {
fonts = Promise.all(
FONT_URLS.map(url => fetchData(url)),
)
}
} }
} }
@ -46,14 +64,13 @@ export const loadSoundFont = (score: WebMscore): Promise<void> => {
return score[SOUND_FONT_LOADED] as Promise<void> return score[SOUND_FONT_LOADED] as Promise<void>
} }
export const loadMscore = async (w: Window): Promise<WebMscore> => { export const loadMscore = async (scoreinfo: ScoreInfo, w?: Window): Promise<WebMscore> => {
initFonts() initFonts(w === undefined)
await initMscore(w) const WebMscore = await initMscore(w)
const WebMscore: typeof import('webmscore').default = w['WebMscore']
// parse mscz data // parse mscz data
const data = new Uint8Array( const data = new Uint8Array(
new Uint8Array(await fetchMscz()), // copy its ArrayBuffer new Uint8Array(await fetchMscz(scoreinfo)), // copy its ArrayBuffer
) )
const score = await WebMscore.load('mscz', data, await fonts) const score = await WebMscore.load('mscz', data, await fonts)
await score.generateExcerpts() await score.generateExcerpts()