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 { configure } 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 configure({
22 mounts: {
23 "/": {
24 backend: IndexedDB,
25 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
26 // @ts-ignore tsc tweaking
27 storeName: "moonlight-fs"
28 }
29 }
30 });
31
32 window.moonlightNodeSandboxed = {
33 fs: {
34 async readFile(path) {
35 return new Uint8Array(await fs.readFile(path));
36 },
37 async readFileString(path) {
38 const file = await this.readFile(path);
39 return new TextDecoder().decode(file);
40 },
41 async writeFile(path, data) {
42 await fs.writeFile(path, data);
43 },
44 async writeFileString(path, data) {
45 const file = new TextEncoder().encode(data);
46 await this.writeFile(path, file);
47 },
48 async unlink(path) {
49 await fs.unlink(path);
50 },
51
52 async readdir(path) {
53 return await fs.readdir(path);
54 },
55 async mkdir(path) {
56 const parts = getParts(path);
57 for (let i = 0; i < parts.length; i++) {
58 const path = this.join(...parts.slice(0, i + 1));
59 if (!(await this.exists(path))) await fs.mkdir(path);
60 }
61 },
62
63 async rmdir(path) {
64 const entries = await this.readdir(path);
65
66 for (const entry of entries) {
67 const fullPath = this.join(path, entry);
68 const isFile = await this.isFile(fullPath);
69 if (isFile) {
70 await this.unlink(fullPath);
71 } else {
72 await this.rmdir(fullPath);
73 }
74 }
75
76 await fs.rmdir(path);
77 },
78
79 async exists(path) {
80 return await fs.exists(path);
81 },
82 async isFile(path) {
83 return (await fs.stat(path)).isFile();
84 },
85 async isDir(path) {
86 return (await fs.stat(path)).isDirectory();
87 },
88
89 join(...parts) {
90 let str = parts.join("/");
91 if (!str.startsWith("/")) str = "/" + str;
92 return str;
93 },
94 dirname(path) {
95 const parts = getParts(path);
96 return "/" + parts.slice(0, parts.length - 1).join("/");
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
120 version: MOONLIGHT_VERSION,
121 branch: MOONLIGHT_BRANCH as MoonlightBranch,
122
123 getConfig(ext) {
124 return getConfig(ext, config);
125 },
126 getConfigOption(ext, name) {
127 const manifest = getManifest(extensions, ext);
128 return getConfigOption(ext, name, config, manifest?.settings);
129 },
130 async setConfigOption(ext, name, value) {
131 setConfigOption(config, ext, name, value);
132 await this.writeConfig(config);
133 },
134
135 getNatives: () => {},
136 getLogger: (id: string) => {
137 return new Logger(id);
138 },
139
140 getMoonlightDir() {
141 return "/";
142 },
143 getExtensionDir: (ext: string) => {
144 return `/extensions/${ext}`;
145 },
146
147 async writeConfig(newConfig) {
148 await writeConfig(newConfig);
149 config = newConfig;
150 }
151 };
152
153 Object.assign(window, {
154 moonlightNode
155 });
156
157 // This is set by web-preload for us
158 await window._moonlightWebLoad!();
159};