@vnejs/desktop 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/electron.js +3 -0
- package/src/server.js +77 -17
package/package.json
CHANGED
package/src/electron.js
CHANGED
|
@@ -27,6 +27,9 @@ const createWindow = (options) => {
|
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
const runElectron = (options) => {
|
|
30
|
+
// Allow unmuted <video> autoplay in packaged builds (Steam / Electron).
|
|
31
|
+
app.commandLine.appendSwitch("autoplay-policy", "no-user-gesture-required");
|
|
32
|
+
|
|
30
33
|
app.whenReady().then(() => {
|
|
31
34
|
protocol.handle("vnejs", (request) => {
|
|
32
35
|
const url = new URL(request.url);
|
package/src/server.js
CHANGED
|
@@ -3,21 +3,37 @@ const os = require("os");
|
|
|
3
3
|
const fastify = require("fastify");
|
|
4
4
|
const fastifyCors = require("@fastify/cors");
|
|
5
5
|
const fastifyStatic = require("@fastify/static");
|
|
6
|
-
const { readFile, readdir, writeFile, appendFile, mkdir, unlink, access } = require("fs/promises");
|
|
6
|
+
const { readFile, readdir, writeFile, appendFile, mkdir, unlink, rmdir, access } = require("fs/promises");
|
|
7
7
|
const { default: getPort } = require("get-port");
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
const dot = key.indexOf(".");
|
|
9
|
+
const STORAGE_DEFAULT_GROUP = "_";
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
const toPosixPath = (value) => value.split(path.sep).join("/");
|
|
12
|
+
|
|
13
|
+
const getStateRelPath = (key) => {
|
|
14
|
+
const first = key.indexOf("/");
|
|
15
|
+
|
|
16
|
+
if (first === -1) return `${key}.json`;
|
|
17
|
+
|
|
18
|
+
const module = key.slice(0, first);
|
|
19
|
+
const afterModule = key.slice(first + 1);
|
|
20
|
+
const second = afterModule.indexOf("/");
|
|
21
|
+
|
|
22
|
+
if (second === -1) return `${module}.json`;
|
|
23
|
+
|
|
24
|
+
const group = afterModule.slice(0, second);
|
|
25
|
+
|
|
26
|
+
if (!group || group === STORAGE_DEFAULT_GROUP) return `${module}.json`;
|
|
27
|
+
|
|
28
|
+
return toPosixPath(path.join(module, `${group}.json`));
|
|
13
29
|
};
|
|
14
30
|
|
|
15
|
-
const
|
|
31
|
+
const splitStateByPath = (state) =>
|
|
16
32
|
Object.entries(state).reduce((groups, [key, value]) => {
|
|
17
|
-
const
|
|
33
|
+
const relPath = getStateRelPath(key);
|
|
18
34
|
|
|
19
|
-
groups[
|
|
20
|
-
groups[
|
|
35
|
+
groups[relPath] ??= {};
|
|
36
|
+
groups[relPath][key] = value;
|
|
21
37
|
|
|
22
38
|
return groups;
|
|
23
39
|
}, {});
|
|
@@ -99,31 +115,75 @@ const runServer = async ({
|
|
|
99
115
|
|
|
100
116
|
const ensureStateDir = () => mkdir(resolvedStateDir, { recursive: true });
|
|
101
117
|
|
|
102
|
-
const
|
|
118
|
+
const listStateJsonFiles = async (dir = resolvedStateDir) => {
|
|
103
119
|
try {
|
|
104
|
-
const
|
|
120
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
121
|
+
const files = await Promise.all(
|
|
122
|
+
entries.map(async (entry) => {
|
|
123
|
+
const fullPath = path.join(dir, entry.name);
|
|
124
|
+
|
|
125
|
+
if (entry.isDirectory()) return listStateJsonFiles(fullPath);
|
|
126
|
+
|
|
127
|
+
if (entry.isFile() && entry.name.endsWith(".json")) return [toPosixPath(path.relative(resolvedStateDir, fullPath))];
|
|
128
|
+
|
|
129
|
+
return [];
|
|
130
|
+
}),
|
|
131
|
+
);
|
|
105
132
|
|
|
106
|
-
return files.
|
|
133
|
+
return files.flat();
|
|
107
134
|
} catch {
|
|
108
135
|
return [];
|
|
109
136
|
}
|
|
110
137
|
};
|
|
111
138
|
|
|
139
|
+
const removeEmptyStateDirs = async (dir = resolvedStateDir) => {
|
|
140
|
+
let entries;
|
|
141
|
+
|
|
142
|
+
try {
|
|
143
|
+
entries = await readdir(dir, { withFileTypes: true });
|
|
144
|
+
} catch {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
await Promise.all(
|
|
149
|
+
entries
|
|
150
|
+
.filter((entry) => entry.isDirectory())
|
|
151
|
+
.map(async (entry) => {
|
|
152
|
+
const fullPath = path.join(dir, entry.name);
|
|
153
|
+
|
|
154
|
+
await removeEmptyStateDirs(fullPath);
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
await rmdir(fullPath);
|
|
158
|
+
} catch {
|
|
159
|
+
// directory is not empty
|
|
160
|
+
}
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
};
|
|
164
|
+
|
|
112
165
|
const writeStateToDisk = async (state) => {
|
|
113
166
|
await ensureStateDir();
|
|
114
167
|
|
|
115
|
-
const groups =
|
|
116
|
-
const
|
|
117
|
-
const
|
|
168
|
+
const groups = splitStateByPath(state);
|
|
169
|
+
const activePaths = new Set(Object.keys(groups));
|
|
170
|
+
const existingPaths = await listStateJsonFiles();
|
|
118
171
|
|
|
119
172
|
await Promise.all([
|
|
120
|
-
...Object.entries(groups).map(([
|
|
121
|
-
|
|
173
|
+
...Object.entries(groups).map(async ([relPath, groupState]) => {
|
|
174
|
+
const fullPath = path.join(resolvedStateDir, relPath);
|
|
175
|
+
|
|
176
|
+
await mkdir(path.dirname(fullPath), { recursive: true });
|
|
177
|
+
await writeFile(fullPath, JSON.stringify(groupState));
|
|
178
|
+
}),
|
|
179
|
+
...existingPaths.filter((relPath) => !activePaths.has(relPath)).map((relPath) => unlink(path.join(resolvedStateDir, relPath))),
|
|
122
180
|
]);
|
|
181
|
+
|
|
182
|
+
await removeEmptyStateDirs();
|
|
123
183
|
};
|
|
124
184
|
|
|
125
185
|
const readStateFromDisk = async () => {
|
|
126
|
-
const stateFiles = await
|
|
186
|
+
const stateFiles = await listStateJsonFiles();
|
|
127
187
|
|
|
128
188
|
if (!stateFiles.length) return {};
|
|
129
189
|
|