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