159 lines
4.3 kB
1
import "@moonlight-mod/web-preload";
2
import { readConfig, writeConfig } from "@moonlight-mod/core/config";
3
import Logger, { initLogger } from "@moonlight-mod/core/util/logger";
4
import { getExtensions } from "@moonlight-mod/core/extension";
5
import { loadExtensions } from "@moonlight-mod/core/extension/loader";
6
import { MoonlightBranch, MoonlightNode } from "@moonlight-mod/types";
7
import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config";
8
import { IndexedDB } from "@zenfs/dom";
9
import { configure } from "@zenfs/core";
10
import * as fs from "@zenfs/core/promises";
11
12
function getParts(path: string) {
13
if (path.startsWith("/")) path = path.substring(1);
14
return path.split("/");
15
}
16
17
window._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
};
160