this repo has no description
1import "@moonlight-mod/web-preload"; 2import { readConfig, writeConfig } from "@moonlight-mod/core/config"; 3import Logger, { initLogger } from "@moonlight-mod/core/util/logger"; 4import { getExtensions } from "@moonlight-mod/core/extension"; 5import { loadExtensions } from "@moonlight-mod/core/extension/loader"; 6import { MoonlightBranch, MoonlightNode } from "@moonlight-mod/types"; 7import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config"; 8import { IndexedDB } from "@zenfs/dom"; 9import { configureSingle } from "@zenfs/core"; 10import * as fs from "@zenfs/core/promises"; 11 12function getParts(path: string) { 13 if (path.startsWith("/")) path = path.substring(1); 14 return path.split("/"); 15} 16 17window._moonlightBrowserInit = async () => { 18 delete window._moonlightBrowserInit; 19 20 // Set up a virtual filesystem with IndexedDB 21 await configureSingle({ 22 backend: IndexedDB, 23 storeName: "moonlight-fs" 24 }); 25 26 window.moonlightNodeSandboxed = { 27 fs: { 28 async readFile(path) { 29 return new Uint8Array(await fs.readFile(path)); 30 }, 31 async readFileString(path) { 32 const file = await this.readFile(path); 33 return new TextDecoder().decode(file); 34 }, 35 async writeFile(path, data) { 36 await fs.writeFile(path, data); 37 }, 38 async writeFileString(path, data) { 39 const file = new TextEncoder().encode(data); 40 await this.writeFile(path, file); 41 }, 42 async unlink(path) { 43 await fs.unlink(path); 44 }, 45 46 async readdir(path) { 47 return await fs.readdir(path); 48 }, 49 async mkdir(path) { 50 const parts = getParts(path); 51 for (let i = 0; i < parts.length; i++) { 52 const path = this.join(...parts.slice(0, i + 1)); 53 if (!(await this.exists(path))) await fs.mkdir(path); 54 } 55 }, 56 57 async rmdir(path) { 58 const entries = await this.readdir(path); 59 60 for (const entry of entries) { 61 const fullPath = this.join(path, entry); 62 const isFile = await this.isFile(fullPath); 63 if (isFile) { 64 await this.unlink(fullPath); 65 } else { 66 await this.rmdir(fullPath); 67 } 68 } 69 70 await fs.rmdir(path); 71 }, 72 73 async exists(path) { 74 return await fs.exists(path); 75 }, 76 async isFile(path) { 77 return (await fs.stat(path)).isFile(); 78 }, 79 async isDir(path) { 80 return (await fs.stat(path)).isDirectory(); 81 }, 82 83 join(...parts) { 84 let str = parts.join("/"); 85 if (!str.startsWith("/")) str = "/" + str; 86 return str; 87 }, 88 dirname(path) { 89 const parts = getParts(path); 90 return "/" + parts.slice(0, parts.length - 1).join("/"); 91 } 92 }, 93 // TODO 94 addCors(url) {}, 95 addBlocked(url) {} 96 }; 97 98 // Actual loading begins here 99 let config = await readConfig(); 100 initLogger(config); 101 102 const extensions = await getExtensions(); 103 const processedExtensions = await loadExtensions(extensions); 104 105 const moonlightNode: MoonlightNode = { 106 get config() { 107 return config; 108 }, 109 extensions, 110 processedExtensions, 111 nativesCache: {}, 112 isBrowser: true, 113 114 version: MOONLIGHT_VERSION, 115 branch: MOONLIGHT_BRANCH as MoonlightBranch, 116 117 getConfig(ext) { 118 return getConfig(ext, config); 119 }, 120 getConfigOption(ext, name) { 121 const manifest = getManifest(extensions, ext); 122 return getConfigOption(ext, name, config, manifest?.settings); 123 }, 124 async setConfigOption(ext, name, value) { 125 setConfigOption(config, ext, name, value); 126 await this.writeConfig(config); 127 }, 128 129 getNatives: () => {}, 130 getLogger: (id: string) => { 131 return new Logger(id); 132 }, 133 134 getMoonlightDir() { 135 return "/"; 136 }, 137 getExtensionDir: (ext: string) => { 138 return `/extensions/${ext}`; 139 }, 140 141 async writeConfig(newConfig) { 142 await writeConfig(newConfig); 143 config = newConfig; 144 } 145 }; 146 147 Object.assign(window, { 148 moonlightNode 149 }); 150 151 // This is set by web-preload for us 152 await window._moonlightWebLoad!(); 153};