@monimesl/dot-simulator 0.1.0-alpha.3 → 0.1.0-alpha.4
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 +154 -26
- package/dist/client/service-bridge.js.map +1 -1
- package/dist/client/simulator.js +236 -39
- package/dist/client/simulator.js.map +1 -1
- package/dist/client/webview-bridge.js +12 -0
- package/dist/client/webview-bridge.js.map +1 -1
- package/dist/node/index.d.ts +13 -2
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +70 -8
- package/dist/node/index.js.map +1 -1
- package/package.json +3 -3
package/dist/client/simulator.js
CHANGED
|
@@ -15,6 +15,21 @@
|
|
|
15
15
|
}
|
|
16
16
|
return registry;
|
|
17
17
|
}
|
|
18
|
+
const AmountInput = defineComponent({
|
|
19
|
+
name: "AmountInput",
|
|
20
|
+
props: {
|
|
21
|
+
value: "number",
|
|
22
|
+
currency: "string",
|
|
23
|
+
decimals: "number",
|
|
24
|
+
label: "string",
|
|
25
|
+
placeholder: "string",
|
|
26
|
+
hint: "string",
|
|
27
|
+
error: "string",
|
|
28
|
+
disabled: "boolean"
|
|
29
|
+
},
|
|
30
|
+
events: ["change"],
|
|
31
|
+
children: "none"
|
|
32
|
+
});
|
|
18
33
|
const Button = defineComponent({
|
|
19
34
|
name: "Button",
|
|
20
35
|
props: {
|
|
@@ -25,15 +40,17 @@
|
|
|
25
40
|
events: ["click"],
|
|
26
41
|
children: "text"
|
|
27
42
|
});
|
|
28
|
-
const Divider = defineComponent({
|
|
29
|
-
name: "Divider",
|
|
30
|
-
children: "none"
|
|
31
|
-
});
|
|
32
43
|
const SIZES = [
|
|
33
44
|
"small",
|
|
34
45
|
"medium",
|
|
35
46
|
"large"
|
|
36
47
|
];
|
|
48
|
+
const SPACES = [
|
|
49
|
+
"none",
|
|
50
|
+
"small",
|
|
51
|
+
"medium",
|
|
52
|
+
"large"
|
|
53
|
+
];
|
|
37
54
|
const TONES = [
|
|
38
55
|
"default",
|
|
39
56
|
"muted",
|
|
@@ -111,6 +128,58 @@
|
|
|
111
128
|
"water",
|
|
112
129
|
"wifi"
|
|
113
130
|
];
|
|
131
|
+
const Carousel = defineComponent({
|
|
132
|
+
name: "Carousel",
|
|
133
|
+
props: {
|
|
134
|
+
autoplay: "boolean",
|
|
135
|
+
interval: "number",
|
|
136
|
+
loop: "boolean",
|
|
137
|
+
indicator: ["dots", "none"],
|
|
138
|
+
gap: SPACES,
|
|
139
|
+
effect: ["slide", "scale"],
|
|
140
|
+
index: "number"
|
|
141
|
+
},
|
|
142
|
+
events: ["change"],
|
|
143
|
+
children: "elements"
|
|
144
|
+
});
|
|
145
|
+
const Chip = defineComponent({
|
|
146
|
+
name: "Chip",
|
|
147
|
+
props: {
|
|
148
|
+
label: "string",
|
|
149
|
+
icon: ICON_NAMES,
|
|
150
|
+
selected: "boolean",
|
|
151
|
+
disabled: "boolean"
|
|
152
|
+
},
|
|
153
|
+
events: ["tap"],
|
|
154
|
+
children: "none"
|
|
155
|
+
});
|
|
156
|
+
const CodeInput = defineComponent({
|
|
157
|
+
name: "CodeInput",
|
|
158
|
+
props: {
|
|
159
|
+
value: "string",
|
|
160
|
+
length: "number",
|
|
161
|
+
label: "string",
|
|
162
|
+
hint: "string",
|
|
163
|
+
error: "string",
|
|
164
|
+
secure: "boolean",
|
|
165
|
+
disabled: "boolean"
|
|
166
|
+
},
|
|
167
|
+
events: ["change", "complete"],
|
|
168
|
+
children: "none"
|
|
169
|
+
});
|
|
170
|
+
const Divider = defineComponent({
|
|
171
|
+
name: "Divider",
|
|
172
|
+
children: "none"
|
|
173
|
+
});
|
|
174
|
+
const EmptyState = defineComponent({
|
|
175
|
+
name: "EmptyState",
|
|
176
|
+
props: {
|
|
177
|
+
icon: ICON_NAMES,
|
|
178
|
+
title: "string",
|
|
179
|
+
text: "string"
|
|
180
|
+
},
|
|
181
|
+
children: "elements"
|
|
182
|
+
});
|
|
114
183
|
const Spinner = defineComponent({
|
|
115
184
|
name: "Spinner",
|
|
116
185
|
props: { size: SIZES },
|
|
@@ -138,6 +207,25 @@
|
|
|
138
207
|
name: "Footer",
|
|
139
208
|
children: "elements"
|
|
140
209
|
});
|
|
210
|
+
const Grid = defineComponent({
|
|
211
|
+
name: "Grid",
|
|
212
|
+
props: {
|
|
213
|
+
columns: "number",
|
|
214
|
+
gap: SPACES
|
|
215
|
+
},
|
|
216
|
+
children: "elements"
|
|
217
|
+
});
|
|
218
|
+
const GridItem = defineComponent({
|
|
219
|
+
name: "GridItem",
|
|
220
|
+
props: {
|
|
221
|
+
label: "string",
|
|
222
|
+
icon: ICON_NAMES,
|
|
223
|
+
image: "string",
|
|
224
|
+
badge: "string"
|
|
225
|
+
},
|
|
226
|
+
events: ["tap"],
|
|
227
|
+
children: "none"
|
|
228
|
+
});
|
|
141
229
|
const Icon = defineComponent({
|
|
142
230
|
name: "Icon",
|
|
143
231
|
props: {
|
|
@@ -223,6 +311,15 @@
|
|
|
223
311
|
events: ["hide"],
|
|
224
312
|
children: "none"
|
|
225
313
|
});
|
|
314
|
+
const QRCode = defineComponent({
|
|
315
|
+
name: "QRCode",
|
|
316
|
+
props: {
|
|
317
|
+
value: "string",
|
|
318
|
+
size: "number",
|
|
319
|
+
label: "string"
|
|
320
|
+
},
|
|
321
|
+
children: "none"
|
|
322
|
+
});
|
|
226
323
|
const Select = defineComponent({
|
|
227
324
|
name: "Select",
|
|
228
325
|
props: {
|
|
@@ -257,6 +354,24 @@
|
|
|
257
354
|
},
|
|
258
355
|
children: "none"
|
|
259
356
|
});
|
|
357
|
+
const Tabs = defineComponent({
|
|
358
|
+
name: "Tabs",
|
|
359
|
+
props: {
|
|
360
|
+
value: "string",
|
|
361
|
+
variant: ["underline", "segmented"]
|
|
362
|
+
},
|
|
363
|
+
events: ["change"],
|
|
364
|
+
children: "elements"
|
|
365
|
+
});
|
|
366
|
+
const Tab = defineComponent({
|
|
367
|
+
name: "Tab",
|
|
368
|
+
props: {
|
|
369
|
+
value: "string",
|
|
370
|
+
label: "string",
|
|
371
|
+
badge: "number"
|
|
372
|
+
},
|
|
373
|
+
children: "none"
|
|
374
|
+
});
|
|
260
375
|
const Text = defineComponent({
|
|
261
376
|
name: "Text",
|
|
262
377
|
props: {
|
|
@@ -326,27 +441,19 @@
|
|
|
326
441
|
events: ["change"],
|
|
327
442
|
children: "elements"
|
|
328
443
|
});
|
|
329
|
-
const Radio = defineComponent({
|
|
330
|
-
name: "Radio",
|
|
331
|
-
props: {
|
|
332
|
-
value: "string",
|
|
333
|
-
label: "string",
|
|
334
|
-
disabled: "boolean"
|
|
335
|
-
},
|
|
336
|
-
children: "none"
|
|
337
|
-
});
|
|
338
|
-
const SPACE = [
|
|
339
|
-
"none",
|
|
340
|
-
"small",
|
|
341
|
-
"medium",
|
|
342
|
-
"large"
|
|
343
|
-
];
|
|
344
444
|
const builtinComponents = {
|
|
445
|
+
AmountInput,
|
|
345
446
|
Badge,
|
|
346
447
|
Button,
|
|
448
|
+
Carousel,
|
|
347
449
|
Checkbox,
|
|
450
|
+
Chip,
|
|
451
|
+
CodeInput,
|
|
348
452
|
Divider,
|
|
453
|
+
EmptyState,
|
|
349
454
|
Footer,
|
|
455
|
+
Grid,
|
|
456
|
+
GridItem,
|
|
350
457
|
Icon,
|
|
351
458
|
Image,
|
|
352
459
|
Input,
|
|
@@ -355,20 +462,31 @@
|
|
|
355
462
|
Notice,
|
|
356
463
|
Option,
|
|
357
464
|
ProgressBar,
|
|
358
|
-
|
|
465
|
+
QRCode,
|
|
466
|
+
Radio: defineComponent({
|
|
467
|
+
name: "Radio",
|
|
468
|
+
props: {
|
|
469
|
+
value: "string",
|
|
470
|
+
label: "string",
|
|
471
|
+
disabled: "boolean"
|
|
472
|
+
},
|
|
473
|
+
children: "none"
|
|
474
|
+
}),
|
|
359
475
|
RadioGroup,
|
|
360
476
|
Select,
|
|
361
477
|
Sheet,
|
|
362
478
|
Skeleton,
|
|
363
479
|
Spinner,
|
|
364
480
|
Switch,
|
|
481
|
+
Tab,
|
|
482
|
+
Tabs,
|
|
365
483
|
Text,
|
|
366
484
|
TextArea,
|
|
367
485
|
Toast,
|
|
368
486
|
View: defineComponent({
|
|
369
487
|
name: "View",
|
|
370
488
|
props: {
|
|
371
|
-
gap:
|
|
489
|
+
gap: SPACES,
|
|
372
490
|
direction: ["column", "row"],
|
|
373
491
|
align: [
|
|
374
492
|
"stretch",
|
|
@@ -384,11 +502,11 @@
|
|
|
384
502
|
],
|
|
385
503
|
wrap: "boolean",
|
|
386
504
|
grow: "boolean",
|
|
387
|
-
padding:
|
|
388
|
-
paddingTop:
|
|
389
|
-
paddingStart:
|
|
390
|
-
paddingEnd:
|
|
391
|
-
paddingBottom:
|
|
505
|
+
padding: SPACES,
|
|
506
|
+
paddingTop: SPACES,
|
|
507
|
+
paddingStart: SPACES,
|
|
508
|
+
paddingEnd: SPACES,
|
|
509
|
+
paddingBottom: SPACES,
|
|
392
510
|
variant: ["plain", "card"]
|
|
393
511
|
},
|
|
394
512
|
events: ["tap"],
|
|
@@ -647,7 +765,7 @@
|
|
|
647
765
|
};
|
|
648
766
|
//#endregion
|
|
649
767
|
//#region src/host.ts
|
|
650
|
-
function startHost({ logic, ui, manifest, dashVersion, minRuntimeVersion, systemContext, handlers = {}, askPermission, observe }) {
|
|
768
|
+
function startHost({ logic, ui, manifest, dashVersion, minRuntimeVersion, systemContext, handlers = {}, askPermission, observe, restorePages = [], onBarsChange }) {
|
|
651
769
|
checkCompatibility(manifest, {
|
|
652
770
|
dashVersion,
|
|
653
771
|
minRuntimeVersion
|
|
@@ -667,6 +785,18 @@
|
|
|
667
785
|
ui.post(message);
|
|
668
786
|
logic.post(message);
|
|
669
787
|
};
|
|
788
|
+
const barsByInstance = /* @__PURE__ */ new Map();
|
|
789
|
+
const showBars = () => {
|
|
790
|
+
const top = stack.top;
|
|
791
|
+
const bars = top && barsByInstance.get(top.instanceId);
|
|
792
|
+
onBarsChange?.({
|
|
793
|
+
title: bars?.navigationBar.title ?? manifest.name,
|
|
794
|
+
navigationBarHidden: bars?.navigationBar.hidden ?? false,
|
|
795
|
+
navigationBarColor: bars?.navigationBar.backgroundColor,
|
|
796
|
+
navigationBarTextColor: bars?.navigationBar.textColor,
|
|
797
|
+
tabBarHidden: bars?.tabBar.hidden ?? false
|
|
798
|
+
}, stack.pages);
|
|
799
|
+
};
|
|
670
800
|
const syncStack = () => {
|
|
671
801
|
const message = {
|
|
672
802
|
type: "syncStack",
|
|
@@ -676,6 +806,9 @@
|
|
|
676
806
|
}
|
|
677
807
|
};
|
|
678
808
|
broadcast(message);
|
|
809
|
+
const open = new Set(stack.pages.map((entry) => entry.instanceId));
|
|
810
|
+
for (const instanceId of barsByInstance.keys()) if (!open.has(instanceId)) barsByInstance.delete(instanceId);
|
|
811
|
+
showBars();
|
|
679
812
|
};
|
|
680
813
|
const syncSystemContext = () => {
|
|
681
814
|
broadcast({
|
|
@@ -691,13 +824,40 @@
|
|
|
691
824
|
if (stack.top !== previousTop) calls.dismissUI();
|
|
692
825
|
return true;
|
|
693
826
|
};
|
|
827
|
+
const openFirstPages = () => {
|
|
828
|
+
const [first, ...rest] = restorePages.filter((entry) => manifest.pages.includes(entry.page));
|
|
829
|
+
if (!first) {
|
|
830
|
+
navigate({
|
|
831
|
+
action: "reset",
|
|
832
|
+
page: manifest.entry,
|
|
833
|
+
options: {}
|
|
834
|
+
});
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
stack.apply({
|
|
838
|
+
action: "reset",
|
|
839
|
+
page: first.page,
|
|
840
|
+
options: first.options
|
|
841
|
+
});
|
|
842
|
+
for (const entry of rest) stack.apply({
|
|
843
|
+
action: "push",
|
|
844
|
+
page: entry.page,
|
|
845
|
+
options: entry.options
|
|
846
|
+
});
|
|
847
|
+
syncStack();
|
|
848
|
+
};
|
|
694
849
|
const navigateFromPage = ({ from, ...navigation }) => {
|
|
695
850
|
if (from === stack.top?.instanceId) navigate(navigation);
|
|
696
851
|
};
|
|
697
852
|
const hostMessageHandlers = /* @__PURE__ */ new Map([
|
|
698
853
|
["navigate", (payload) => navigateFromPage(payload)],
|
|
699
854
|
["hostCall", (payload) => calls.run(payload)],
|
|
700
|
-
["hostCancel", (payload) => calls.cancel(payload.id)]
|
|
855
|
+
["hostCancel", (payload) => calls.cancel(payload.id)],
|
|
856
|
+
["pageBars", (payload) => {
|
|
857
|
+
const { instanceId, ...bars } = payload;
|
|
858
|
+
barsByInstance.set(instanceId, bars);
|
|
859
|
+
showBars();
|
|
860
|
+
}]
|
|
701
861
|
]);
|
|
702
862
|
const stopService = logic.listen((raw) => {
|
|
703
863
|
const message = raw;
|
|
@@ -716,14 +876,13 @@
|
|
|
716
876
|
logic.post(message);
|
|
717
877
|
if (message.type === "connect") {
|
|
718
878
|
syncSystemContext();
|
|
719
|
-
|
|
720
|
-
action: "reset",
|
|
721
|
-
page: manifest.entry,
|
|
722
|
-
options: {}
|
|
723
|
-
});
|
|
879
|
+
openFirstPages();
|
|
724
880
|
}
|
|
725
881
|
});
|
|
726
882
|
return {
|
|
883
|
+
get pages() {
|
|
884
|
+
return stack.pages;
|
|
885
|
+
},
|
|
727
886
|
back: () => navigate({
|
|
728
887
|
action: "back",
|
|
729
888
|
delta: 1
|
|
@@ -941,10 +1100,15 @@
|
|
|
941
1100
|
const errorBanner = element("#error");
|
|
942
1101
|
const phone = element(".phone");
|
|
943
1102
|
const schemeSelect = element("#scheme");
|
|
1103
|
+
const navigationBar = element(".navigation-bar");
|
|
1104
|
+
const navigationTitle = element("#navigation-title");
|
|
1105
|
+
const navigationBack = element("#navigation-back");
|
|
1106
|
+
const tabBar = element(".tab-bar");
|
|
944
1107
|
const browserDark = matchMedia("(prefers-color-scheme: dark)");
|
|
945
1108
|
let runningApp = null;
|
|
946
1109
|
let launchCount = 0;
|
|
947
|
-
|
|
1110
|
+
let hotReloads = 0;
|
|
1111
|
+
async function launch(restorePages = []) {
|
|
948
1112
|
stopRunningApp();
|
|
949
1113
|
launchCount += 1;
|
|
950
1114
|
const thisLaunch = launchCount;
|
|
@@ -973,7 +1137,9 @@
|
|
|
973
1137
|
systemContext: systemContext(),
|
|
974
1138
|
handlers: dashHandlers(phone, note),
|
|
975
1139
|
askPermission: (request, signal) => askPermission(phone, note, request, signal),
|
|
976
|
-
observe: record
|
|
1140
|
+
observe: record,
|
|
1141
|
+
restorePages,
|
|
1142
|
+
onBarsChange: showBars
|
|
977
1143
|
});
|
|
978
1144
|
worker.addEventListener("error", (event) => showError(`Service crashed: ${event.message}`));
|
|
979
1145
|
screen.src = WEBVIEW_URL;
|
|
@@ -988,6 +1154,18 @@
|
|
|
988
1154
|
runningApp.worker.terminate();
|
|
989
1155
|
runningApp = null;
|
|
990
1156
|
}
|
|
1157
|
+
function showBars(bars, pages) {
|
|
1158
|
+
navigationBar.hidden = bars.navigationBarHidden;
|
|
1159
|
+
navigationTitle.textContent = bars.title;
|
|
1160
|
+
navigationBack.hidden = pages.length < 2;
|
|
1161
|
+
setBarColor("--bar", bars.navigationBarColor);
|
|
1162
|
+
setBarColor("--bar-text", bars.navigationBarTextColor);
|
|
1163
|
+
tabBar.hidden = bars.tabBarHidden;
|
|
1164
|
+
}
|
|
1165
|
+
function setBarColor(property, color) {
|
|
1166
|
+
if (color) phone.style.setProperty(property, color);
|
|
1167
|
+
else phone.style.removeProperty(property);
|
|
1168
|
+
}
|
|
991
1169
|
function goBack() {
|
|
992
1170
|
if (runningApp && !runningApp.host.back()) note("back on the first page: a device would close the dot");
|
|
993
1171
|
}
|
|
@@ -1015,11 +1193,25 @@
|
|
|
1015
1193
|
while (log.childElementCount > MAX_LOG_ENTRIES) log.firstElementChild?.remove();
|
|
1016
1194
|
log.scrollTop = log.scrollHeight;
|
|
1017
1195
|
}
|
|
1018
|
-
function syncLaunch() {
|
|
1019
|
-
launch().catch((error) => {
|
|
1196
|
+
function syncLaunch(restorePages = []) {
|
|
1197
|
+
launch(restorePages).catch((error) => {
|
|
1020
1198
|
showError(`Could not start the dot: ${String(error)}`);
|
|
1021
1199
|
});
|
|
1022
1200
|
}
|
|
1201
|
+
function relaunch() {
|
|
1202
|
+
syncLaunch(runningApp?.host.pages ?? []);
|
|
1203
|
+
}
|
|
1204
|
+
function hotReload() {
|
|
1205
|
+
if (!runningApp) {
|
|
1206
|
+
syncLaunch();
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
hotReloads += 1;
|
|
1210
|
+
const reload = { dotHotReload: hotReloads };
|
|
1211
|
+
runningApp.worker.postMessage(reload);
|
|
1212
|
+
screen.contentWindow?.postMessage(reload, location.origin);
|
|
1213
|
+
note("dot updated in place");
|
|
1214
|
+
}
|
|
1023
1215
|
function showError(message) {
|
|
1024
1216
|
errorBanner.hidden = message === null;
|
|
1025
1217
|
errorBanner.textContent = message ?? "";
|
|
@@ -1045,11 +1237,16 @@
|
|
|
1045
1237
|
const events = new EventSource(EVENTS_PATH);
|
|
1046
1238
|
events.addEventListener("reload", () => {
|
|
1047
1239
|
showError(null);
|
|
1048
|
-
|
|
1240
|
+
relaunch();
|
|
1241
|
+
});
|
|
1242
|
+
events.addEventListener("hot-reload", () => {
|
|
1243
|
+
showError(null);
|
|
1244
|
+
hotReload();
|
|
1049
1245
|
});
|
|
1050
1246
|
events.addEventListener("build-error", (event) => showError(String(event.data)));
|
|
1051
|
-
element("#reload").addEventListener("click", syncLaunch);
|
|
1247
|
+
element("#reload").addEventListener("click", () => syncLaunch());
|
|
1052
1248
|
element("#back").addEventListener("click", goBack);
|
|
1249
|
+
navigationBack.addEventListener("click", goBack);
|
|
1053
1250
|
element("#clear").addEventListener("click", () => log.replaceChildren());
|
|
1054
1251
|
schemeSelect.addEventListener("change", () => changeScheme(schemeSelect.value));
|
|
1055
1252
|
browserDark.addEventListener("change", () => changeScheme(browserScheme()));
|