@vnejs/desktop 0.1.0 → 0.2.1

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/server.js +103 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vnejs/desktop",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Tools to run desktop app of @vnejs",
5
5
  "main": "src/index.js",
6
6
  "bin": {
package/src/server.js CHANGED
@@ -62,18 +62,40 @@ const pathExists = async (target) => {
62
62
  }
63
63
  };
64
64
 
65
- const readPortPreferred = async (rootDir) => {
65
+ const readPackageVnejs = async (rootDir) => {
66
66
  const pkg = JSON.parse(await readFile(path.join(rootDir, "package.json"), "utf8"));
67
- const port = Number(pkg.vnejs?.portPreferred);
67
+
68
+ return pkg.vnejs || {};
69
+ };
70
+
71
+ const readPortPreferred = async (rootDir) => {
72
+ const port = Number((await readPackageVnejs(rootDir)).portPreferred);
68
73
 
69
74
  return Number.isInteger(port) && port > 0 ? port : undefined;
70
75
  };
71
76
 
72
- const runServer = async ({ rootDir, stateDir, oldApp, onAchievementLock, onAchievementUnlock } = {}) => {
77
+ const readDefaultLanguage = async (rootDir) => {
78
+ const language = (await readPackageVnejs(rootDir)).defaultLanguage;
79
+
80
+ return typeof language === "string" && language ? language : "ru";
81
+ };
82
+
83
+ const runServer = async ({
84
+ rootDir,
85
+ stateDir,
86
+ oldApp,
87
+ onAchievementLock,
88
+ onAchievementUnlock,
89
+ onStateSave,
90
+ onStateGet,
91
+ onStateClear,
92
+ getConfig,
93
+ } = {}) => {
73
94
  const port = await getPort({ port: await readPortPreferred(rootDir) });
74
95
 
75
96
  const resolvedStateDir = stateDir || path.join(rootDir, "state");
76
97
  const gamePath = path.join(rootDir, "game");
98
+ const defaultLanguage = await readDefaultLanguage(rootDir);
77
99
 
78
100
  const ensureStateDir = () => mkdir(resolvedStateDir, { recursive: true });
79
101
 
@@ -87,18 +109,44 @@ const runServer = async ({ rootDir, stateDir, oldApp, onAchievementLock, onAchie
87
109
  }
88
110
  };
89
111
 
112
+ const writeStateToDisk = async (state) => {
113
+ await ensureStateDir();
114
+
115
+ const groups = splitStateByPrefix(state);
116
+ const activePrefixes = new Set(Object.keys(groups));
117
+ const stalePrefixes = (await getStateFiles()).map((file) => file.slice(0, -".json".length)).filter((prefix) => !activePrefixes.has(prefix));
118
+
119
+ await Promise.all([
120
+ ...Object.entries(groups).map(([prefix, groupState]) => writeFile(path.join(resolvedStateDir, `${prefix}.json`), JSON.stringify(groupState))),
121
+ ...stalePrefixes.map((prefix) => unlink(path.join(resolvedStateDir, `${prefix}.json`))),
122
+ ]);
123
+ };
124
+
125
+ const readStateFromDisk = async () => {
126
+ const stateFiles = await getStateFiles();
127
+
128
+ if (!stateFiles.length) return {};
129
+
130
+ const chunks = await Promise.all(stateFiles.map((file) => readFile(path.join(resolvedStateDir, file), "utf8").then(JSON.parse)));
131
+
132
+ return Object.assign({}, ...chunks);
133
+ };
134
+
135
+ const resolveConfigLanguage = () => {
136
+ if (typeof getConfig === "function") {
137
+ const config = getConfig() || {};
138
+
139
+ if (typeof config.language === "string" && config.language) return config.language;
140
+ }
141
+
142
+ return defaultLanguage;
143
+ };
144
+
90
145
  const onSaveState = async (req, reply) => {
91
146
  try {
92
- await ensureStateDir();
93
-
94
- const groups = splitStateByPrefix(req.body);
95
- const activePrefixes = new Set(Object.keys(groups));
96
- const stalePrefixes = (await getStateFiles()).map((file) => file.slice(0, -".json".length)).filter((prefix) => !activePrefixes.has(prefix));
147
+ await writeStateToDisk(req.body);
97
148
 
98
- await Promise.all([
99
- ...Object.entries(groups).map(([prefix, state]) => writeFile(path.join(resolvedStateDir, `${prefix}.json`), JSON.stringify(state))),
100
- ...stalePrefixes.map((prefix) => unlink(path.join(resolvedStateDir, `${prefix}.json`))),
101
- ]);
149
+ if (typeof onStateSave === "function") onStateSave(req.body);
102
150
 
103
151
  return reply.send({ status: "ok" });
104
152
  } catch {
@@ -107,14 +155,40 @@ const runServer = async ({ rootDir, stateDir, oldApp, onAchievementLock, onAchie
107
155
  };
108
156
 
109
157
  const onGetState = async (req, reply) => {
110
- const stateFiles = await getStateFiles();
158
+ try {
159
+ let state = null;
160
+ let fromCloud = false;
161
+
162
+ if (typeof onStateGet === "function") {
163
+ const cloudState = onStateGet();
164
+
165
+ if (cloudState && typeof cloudState === "object") {
166
+ state = cloudState;
167
+ fromCloud = true;
168
+ }
169
+ }
170
+
171
+ if (!state) state = await readStateFromDisk();
111
172
 
112
- if (!stateFiles.length) return reply.send({ status: "ok", state: {} });
173
+ if (fromCloud) await writeStateToDisk(state);
113
174
 
175
+ return reply.send({ status: "ok", state });
176
+ } catch {
177
+ return reply.send({ status: "error" });
178
+ }
179
+ };
180
+
181
+ const onGetConfig = (req, reply) => reply.send({ language: resolveConfigLanguage() });
182
+
183
+ const onClearState = async (req, reply) => {
114
184
  try {
115
- const chunks = await Promise.all(stateFiles.map((file) => readFile(path.join(resolvedStateDir, file), "utf8").then(JSON.parse)));
185
+ const stateFiles = await getStateFiles();
186
+
187
+ await Promise.all(stateFiles.map((file) => unlink(path.join(resolvedStateDir, file))));
116
188
 
117
- return reply.send({ status: "ok", state: Object.assign({}, ...chunks) });
189
+ if (typeof onStateClear === "function") onStateClear();
190
+
191
+ return reply.send({ status: "ok" });
118
192
  } catch {
119
193
  return reply.send({ status: "error" });
120
194
  }
@@ -149,6 +223,8 @@ const runServer = async ({ rootDir, stateDir, oldApp, onAchievementLock, onAchie
149
223
 
150
224
  app.post("/state/save", onSaveState);
151
225
  app.get("/state/get", onGetState);
226
+ app.post("/state/clear", onClearState);
227
+ app.get("/config", onGetConfig);
152
228
  app.post("/achievement/lock", onAchievementLockMiddleware);
153
229
  app.post("/achievement/unlock", onAchievementUnlockMiddleware);
154
230
  app.post("/log", onLog);
@@ -189,7 +265,17 @@ const runServer = async ({ rootDir, stateDir, oldApp, onAchievementLock, onAchie
189
265
  if (error.code === "EADDRINUSE") {
190
266
  console.log("server not started on port: ", port);
191
267
 
192
- return runServer({ rootDir, stateDir, oldApp: app, onAchievementLock, onAchievementUnlock });
268
+ return runServer({
269
+ rootDir,
270
+ stateDir,
271
+ oldApp: app,
272
+ onAchievementLock,
273
+ onAchievementUnlock,
274
+ onStateSave,
275
+ onStateGet,
276
+ onStateClear,
277
+ getConfig,
278
+ });
193
279
  }
194
280
 
195
281
  throw error;