@monimesl/dot-simulator 0.1.0-alpha.15 → 0.1.0-alpha.16
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/dist/client/service-bridge.js +109 -35
- package/dist/client/service-bridge.js.map +1 -1
- package/dist/client/simulator.js +345 -85
- package/dist/client/simulator.js.map +1 -1
- package/dist/client/webview-bridge.js.map +1 -1
- package/dist/node/index.d.ts +1 -1
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +36 -3
- package/dist/node/index.js.map +1 -1
- package/package.json +3 -3
package/dist/node/index.js
CHANGED
|
@@ -70,7 +70,8 @@ var HostCallRunner = class {
|
|
|
70
70
|
this.#succeed(id, await entry(call));
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
|
-
|
|
73
|
+
const permission = typeof entry.permission === "function" ? entry.permission(call.params) : entry.permission;
|
|
74
|
+
await this.#permissions.check(call.method, permission, call.signal);
|
|
74
75
|
this.#succeed(id, await entry.handle(call));
|
|
75
76
|
} catch (error) {
|
|
76
77
|
this.#fail(id, error);
|
|
@@ -270,7 +271,7 @@ function startHost({ logic, ui, manifest, runtimeVersion, systemContext, handler
|
|
|
270
271
|
}
|
|
271
272
|
//#endregion
|
|
272
273
|
//#region src/versions.ts
|
|
273
|
-
const SIMULATOR_VERSIONS = { runtimeVersion: "0.1.0-alpha.
|
|
274
|
+
const SIMULATOR_VERSIONS = { runtimeVersion: "0.1.0-alpha.16" };
|
|
274
275
|
//#endregion
|
|
275
276
|
//#region src/paths.ts
|
|
276
277
|
const CLIENT_PATH = "/__dot/";
|
|
@@ -279,6 +280,7 @@ const HTTP_PATH = `${CLIENT_PATH}network/http/`;
|
|
|
279
280
|
const FILE_PATH = `${CLIENT_PATH}storage/file/`;
|
|
280
281
|
const CACHE_PATH = `${CLIENT_PATH}storage/cache/`;
|
|
281
282
|
const SECRET_PATH = `${CLIENT_PATH}storage/secret/`;
|
|
283
|
+
const MEDIA_PATH = `${CLIENT_PATH}media/`;
|
|
282
284
|
const TEMPORARY_FILES_PATH = `${CLIENT_PATH}files/`;
|
|
283
285
|
const WEBVIEW_URL = `/dot/ui/index.html`;
|
|
284
286
|
//#endregion
|
|
@@ -303,6 +305,7 @@ function simulatorPage(appName) {
|
|
|
303
305
|
</select>
|
|
304
306
|
<button id="back" type="button" title="The system back button">◀ Back</button>
|
|
305
307
|
<button id="reload" type="button">Reload</button>
|
|
308
|
+
<button id="messages" type="button" aria-pressed="true" aria-controls="messages-panel" title="Show or hide the messages between the dot's two layers">Messages</button>
|
|
306
309
|
</header>
|
|
307
310
|
<main>
|
|
308
311
|
<section class="stage">
|
|
@@ -324,7 +327,7 @@ function simulatorPage(appName) {
|
|
|
324
327
|
<span class="home-indicator"></span>
|
|
325
328
|
</div>
|
|
326
329
|
</section>
|
|
327
|
-
<aside>
|
|
330
|
+
<aside id="messages-panel">
|
|
328
331
|
<div class="panel-head">
|
|
329
332
|
<span>Messages</span>
|
|
330
333
|
<button id="clear" type="button">Clear</button>
|
|
@@ -368,6 +371,7 @@ const STYLES = `
|
|
|
368
371
|
.dialog { width: 270px; border-radius: 14px; overflow: hidden; background: var(--dialog); color: var(--screen-text); text-align: center; font: 13px/1.35 system-ui, sans-serif; }
|
|
369
372
|
.dialog-body { display: flex; flex-direction: column; gap: 4px; padding: 18px 16px 16px; }
|
|
370
373
|
.dialog-title { font-size: 17px; font-weight: 600; }
|
|
374
|
+
.dialog-input { margin-top: 10px; padding: 7px 8px; border: 1px solid var(--dialog-line); border-radius: 7px; background: var(--screen); color: var(--screen-text); font: inherit; text-align: left; }
|
|
371
375
|
.dialog-actions { display: flex; border-top: 1px solid var(--dialog-line); }
|
|
372
376
|
.dialog-actions.stacked { flex-direction: column; }
|
|
373
377
|
.dialog-actions button { flex: 1; margin: 0; padding: 11px; border: 0; border-radius: 0; background: transparent; color: #0a84ff; font-size: 17px; }
|
|
@@ -391,6 +395,8 @@ const STYLES = `
|
|
|
391
395
|
.home-indicator { position: absolute; bottom: 8px; left: 50%; width: 134px; height: 5px; margin-left: -67px; border-radius: 3px; background: var(--screen-text); pointer-events: none; }
|
|
392
396
|
#error { max-width: 640px; width: 100%; margin: 0; padding: 12px; white-space: pre-wrap; overflow-wrap: anywhere; color: #fff; background: var(--danger); border-radius: 8px; }
|
|
393
397
|
aside { width: 380px; display: flex; flex-direction: column; background: var(--panel); border-left: 1px solid var(--border); }
|
|
398
|
+
aside[hidden] { display: none; }
|
|
399
|
+
#messages[aria-pressed="true"] { border-color: var(--to-service); color: var(--to-service); }
|
|
394
400
|
.panel-head { display: flex; align-items: center; justify-content: space-between; padding: 8px 12px; border-bottom: 1px solid var(--border); font-weight: 600; }
|
|
395
401
|
#log { flex: 1; overflow: auto; margin: 0; padding: 0; list-style: none; font: 12px/1.4 ui-monospace, monospace; }
|
|
396
402
|
#log li { border-bottom: 1px solid var(--border); padding: 4px 12px; }
|
|
@@ -1197,6 +1203,28 @@ function bufferEncoding(name) {
|
|
|
1197
1203
|
function failed(message) {
|
|
1198
1204
|
return new HostError("failed", message);
|
|
1199
1205
|
}
|
|
1206
|
+
function tooLargeMessage(name) {
|
|
1207
|
+
return `"${name}" is larger than 25 MB`;
|
|
1208
|
+
}
|
|
1209
|
+
//#endregion
|
|
1210
|
+
//#region src/media.ts
|
|
1211
|
+
async function runMediaCall(operation, params, files) {
|
|
1212
|
+
const { name, data, contentType } = params ?? {};
|
|
1213
|
+
if (typeof name !== "string" || typeof data !== "string") throw new HostError("invalid", "A file needs a name and its data");
|
|
1214
|
+
const bytes = Buffer.from(data, "base64");
|
|
1215
|
+
switch (operation) {
|
|
1216
|
+
case "photo": return keep(files, name, "image/jpeg", bytes);
|
|
1217
|
+
case "file":
|
|
1218
|
+
if (bytes.length > 26214400) throw new HostError("invalid", tooLargeMessage(name));
|
|
1219
|
+
return keep(files, name, typeof contentType === "string" ? contentType : "application/octet-stream", bytes);
|
|
1220
|
+
default: throw new HostError("unsupported", `The simulator has no "${operation}" media call`);
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
async function keep(files, name, contentType, bytes) {
|
|
1224
|
+
const { id, path } = await files.newPath();
|
|
1225
|
+
await writeFile(path, bytes);
|
|
1226
|
+
return files.add(id, path, name, contentType);
|
|
1227
|
+
}
|
|
1200
1228
|
//#endregion
|
|
1201
1229
|
//#region src/temporary-files.ts
|
|
1202
1230
|
var TemporaryFiles = class {
|
|
@@ -1323,6 +1351,11 @@ async function startSimulator({ dotDir, reactHostDir, name = "Dot", port = DEFAU
|
|
|
1323
1351
|
answer(request, response, (params) => runSecretCall(operation, params, storage.secrets));
|
|
1324
1352
|
return;
|
|
1325
1353
|
}
|
|
1354
|
+
if (pathname.startsWith(MEDIA_PATH) && request.method === "POST") {
|
|
1355
|
+
const operation = pathname.slice(MEDIA_PATH.length);
|
|
1356
|
+
answer(request, response, (params) => runMediaCall(operation, params, files));
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1326
1359
|
if (pathname.startsWith(TEMPORARY_FILES_PATH)) {
|
|
1327
1360
|
serveTemporaryFile(response, files, pathname.slice(TEMPORARY_FILES_PATH.length));
|
|
1328
1361
|
return;
|