@monimesl/dot-cli 1.0.0-beta.0 → 1.0.0-beta.10

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 (98) hide show
  1. package/README.md +22 -9
  2. package/dist/cli.js +24 -14
  3. package/dist/cli.js.map +1 -1
  4. package/dist/{server-DMnWDdJ6.js → server-BhnO9_Zu.js} +56 -7
  5. package/dist/server-BhnO9_Zu.js.map +1 -0
  6. package/dist/templates/showcase/.env +2 -2
  7. package/dist/templates/showcase/dot.ts +22 -2
  8. package/dist/templates/showcase/pages/basics/bars/controller.ts +2 -2
  9. package/dist/templates/showcase/pages/basics/bars/view.dml +2 -1
  10. package/dist/templates/showcase/pages/basics/bindings/state.ts +2 -2
  11. package/dist/templates/showcase/pages/basics/bindings/view.dml +2 -2
  12. package/dist/templates/showcase/pages/basics/colors/controller.ts +1 -1
  13. package/dist/templates/showcase/pages/basics/concert/view.dml +1 -1
  14. package/dist/templates/showcase/pages/basics/control-flow/controller.ts +1 -1
  15. package/dist/templates/showcase/pages/basics/control-flow/view.dml +1 -1
  16. package/dist/templates/showcase/pages/basics/events/controller.ts +1 -1
  17. package/dist/templates/showcase/pages/basics/events/view.dml +1 -1
  18. package/dist/templates/showcase/pages/basics/hooks/controller.ts +2 -1
  19. package/dist/templates/showcase/pages/basics/hooks/view.dml +2 -2
  20. package/dist/templates/showcase/pages/basics/navigation/controller.ts +1 -0
  21. package/dist/templates/showcase/pages/basics/navigation/view.dml +1 -1
  22. package/dist/templates/showcase/pages/basics/pick-genre/controller.ts +3 -3
  23. package/dist/templates/showcase/pages/basics/share/view.dml +2 -2
  24. package/dist/templates/showcase/pages/basics/state/controller.ts +9 -0
  25. package/dist/templates/showcase/pages/basics/state/state.ts +3 -0
  26. package/dist/templates/showcase/pages/basics/theme/controller.ts +28 -0
  27. package/dist/templates/showcase/pages/basics/theme/state.ts +4 -0
  28. package/dist/templates/showcase/pages/basics/theme/view.dml +50 -0
  29. package/dist/templates/showcase/pages/components/capture/controller.ts +25 -0
  30. package/dist/templates/showcase/pages/components/capture/state.ts +7 -0
  31. package/dist/templates/showcase/pages/components/capture/view.dml +32 -0
  32. package/dist/templates/showcase/pages/components/carousel/view.dml +2 -2
  33. package/dist/templates/showcase/pages/components/feedback/controller.ts +2 -1
  34. package/dist/templates/showcase/pages/components/feedback/state.ts +2 -2
  35. package/dist/templates/showcase/pages/components/feedback/view.dml +2 -2
  36. package/dist/templates/showcase/pages/components/forms/controller.ts +2 -2
  37. package/dist/templates/showcase/pages/components/forms/state.ts +1 -1
  38. package/dist/templates/showcase/pages/components/forms/view.dml +6 -5
  39. package/dist/templates/showcase/pages/components/icons/controller.ts +1 -0
  40. package/dist/templates/showcase/pages/components/icons/state.ts +1 -1
  41. package/dist/templates/showcase/pages/components/images/controller.ts +1 -1
  42. package/dist/templates/showcase/pages/components/images/state.ts +1 -1
  43. package/dist/templates/showcase/pages/components/images/view.dml +4 -4
  44. package/dist/templates/showcase/pages/components/layout/controller.ts +5 -1
  45. package/dist/templates/showcase/pages/components/layout/state.ts +2 -0
  46. package/dist/templates/showcase/pages/components/layout/view.dml +44 -6
  47. package/dist/templates/showcase/pages/components/lists/view.dml +12 -7
  48. package/dist/templates/showcase/pages/components/money/controller.ts +1 -1
  49. package/dist/templates/showcase/pages/components/money/view.dml +2 -2
  50. package/dist/templates/showcase/pages/components/pinned/controller.ts +10 -0
  51. package/dist/templates/showcase/pages/components/pinned/state.ts +25 -0
  52. package/dist/templates/showcase/pages/components/pinned/view.dml +42 -0
  53. package/dist/templates/showcase/pages/components/reading/state.ts +2 -2
  54. package/dist/templates/showcase/pages/components/sheets/controller.ts +1 -1
  55. package/dist/templates/showcase/pages/components/sheets/view.dml +1 -1
  56. package/dist/templates/showcase/pages/components/styles/view.dml +39 -4
  57. package/dist/templates/showcase/pages/components/tabs/state.ts +2 -2
  58. package/dist/templates/showcase/pages/components/tabs/view.dml +6 -5
  59. package/dist/templates/showcase/pages/components/text/view.dml +4 -4
  60. package/dist/templates/showcase/pages/dash/account/controller.ts +3 -0
  61. package/dist/templates/showcase/pages/dash/account/view.dml +2 -2
  62. package/dist/templates/showcase/pages/dash/cache/controller.ts +45 -16
  63. package/dist/templates/showcase/pages/dash/cache/state.ts +1 -0
  64. package/dist/templates/showcase/pages/dash/cache/view.dml +4 -0
  65. package/dist/templates/showcase/pages/dash/calls/controller.ts +3 -2
  66. package/dist/templates/showcase/pages/dash/contacts/controller.ts +1 -0
  67. package/dist/templates/showcase/pages/dash/crypto/controller.ts +2 -0
  68. package/dist/templates/showcase/pages/dash/crypto/view.dml +1 -1
  69. package/dist/templates/showcase/pages/dash/files/controller.ts +67 -32
  70. package/dist/templates/showcase/pages/dash/files/state.ts +1 -0
  71. package/dist/templates/showcase/pages/dash/files/view.dml +5 -1
  72. package/dist/templates/showcase/pages/dash/media/controller.ts +7 -1
  73. package/dist/templates/showcase/pages/dash/media/state.ts +2 -0
  74. package/dist/templates/showcase/pages/dash/network/controller.ts +5 -1
  75. package/dist/templates/showcase/pages/dash/network/view.dml +1 -1
  76. package/dist/templates/showcase/pages/dash/payments/cases.ts +40 -22
  77. package/dist/templates/showcase/pages/dash/payments/controller.ts +27 -3
  78. package/dist/templates/showcase/pages/dash/payments/state.ts +2 -0
  79. package/dist/templates/showcase/pages/dash/payments/view.dml +3 -1
  80. package/dist/templates/showcase/pages/dash/reminders/controller.ts +73 -0
  81. package/dist/templates/showcase/pages/dash/reminders/state.ts +6 -0
  82. package/dist/templates/showcase/pages/dash/reminders/view.dml +34 -0
  83. package/dist/templates/showcase/pages/dash/secrets/controller.ts +37 -14
  84. package/dist/templates/showcase/pages/dash/secrets/state.ts +1 -0
  85. package/dist/templates/showcase/pages/dash/secrets/view.dml +4 -0
  86. package/dist/templates/showcase/pages/dash/system/controller.ts +5 -0
  87. package/dist/templates/showcase/pages/dash/system/view.dml +4 -4
  88. package/dist/templates/showcase/pages/dash/ui/controller.ts +6 -1
  89. package/dist/templates/showcase/pages/index/controller.ts +1 -0
  90. package/dist/templates/showcase/pages/index/state.ts +30 -6
  91. package/dist/templates/showcase/statics/icons/ticket-stub.svg +1 -0
  92. package/dist/templates/starter/.env +2 -2
  93. package/dist/templates/starter/dot.ts +1 -0
  94. package/dist/templates/starter/pages/index/controller.ts +2 -0
  95. package/dist/templates/starter/pages/index/state.ts +2 -0
  96. package/dist/templates/starter/pages/index/view.dml +2 -1
  97. package/package.json +6 -6
  98. package/dist/server-DMnWDdJ6.js.map +0 -1
@@ -0,0 +1,73 @@
1
+ import { errorMessage } from '@monimesl/dot-runtime';
2
+
3
+ import state from './state';
4
+
5
+ function dateIn(days: number): string {
6
+ const date = new Date();
7
+ date.setDate(date.getDate() + days);
8
+ const month = String(date.getMonth() + 1).padStart(2, '0');
9
+ const day = String(date.getDate()).padStart(2, '0');
10
+ return `${date.getFullYear()}-${month}-${day}`;
11
+ }
12
+
13
+ async function noteAfter(request: PromiseLike<unknown>): Promise<string> {
14
+ try {
15
+ await request;
16
+ return '';
17
+ } catch (error) {
18
+ return errorMessage(error);
19
+ }
20
+ }
21
+
22
+ export default definePage({
23
+ initialState: state,
24
+ configs: { navigationBar: { title: 'Reminders' } },
25
+ hooks: {
26
+ async onShow() {
27
+ await this.actions.refresh();
28
+ },
29
+ },
30
+ actions: {
31
+ async refresh() {
32
+ try {
33
+ this.setState({ reminders: await this.dash.reminders.list() });
34
+ } catch (error) {
35
+ this.setState({ note: errorMessage(error) });
36
+ }
37
+ },
38
+ // A 13th still to come rejects with 'failed', so cancel one first.
39
+ async remindTomorrow() {
40
+ const note = await noteAfter(
41
+ this.dash.reminders.set({
42
+ key: 'concert',
43
+ title: 'Jazz Night is tomorrow',
44
+ message: 'Doors open at 7',
45
+ page: '/basics/concert?concert=jazz-night',
46
+ schedule: { start: dateIn(1), time: '09:00' },
47
+ }),
48
+ );
49
+ this.setState({ note });
50
+ await this.actions.refresh();
51
+ },
52
+ async remindWeekly() {
53
+ const note = await noteAfter(
54
+ this.dash.reminders.set({
55
+ key: 'weekly-gigs',
56
+ title: 'New gigs this week',
57
+ schedule: {
58
+ start: dateIn(1),
59
+ time: '18:00',
60
+ repeat: { every: 'week', days: ['fri'] },
61
+ end: { after: 4 },
62
+ },
63
+ }),
64
+ );
65
+ this.setState({ note });
66
+ await this.actions.refresh();
67
+ },
68
+ async cancel(_state, event: DataEvent<{ key: string }>) {
69
+ await this.dash.reminders.cancel(event.data.key);
70
+ await this.actions.refresh();
71
+ },
72
+ },
73
+ });
@@ -0,0 +1,6 @@
1
+ import type { Reminder } from '@monimesl/dot-runtime';
2
+
3
+ export default {
4
+ reminders: [] as Reminder[],
5
+ note: '',
6
+ };
@@ -0,0 +1,34 @@
1
+ <View>
2
+ <Text variant="title">dash.reminders</Text>
3
+ <Text>Notifications that bring the person back to a page of the dot. Dash never acts by itself.</Text>
4
+
5
+ <View gap="small">
6
+ <Text variant="subtitle">set</Text>
7
+ <Text variant="caption" tone="muted">Once, or repeating as transfer reminders do. It needs the reminders permission in dot.json, and a dot can have 12 still to come.</Text>
8
+ <View direction="row" gap="small" wrap>
9
+ <Button onClick="remindTomorrow">Remind me tomorrow</Button>
10
+ <Button variant="secondary" onClick="remindWeekly">Every Friday</Button>
11
+ </View>
12
+ </View>
13
+
14
+ <View gap="small">
15
+ <Text variant="subtitle">list and cancel</Text>
16
+ <Text variant="caption" tone="muted">The dot's own, which the person can also delete in Dash. Tap one to cancel it.</Text>
17
+ <View variant="card" gap="small">
18
+ <If condition="{{ reminders.length > 0 }}">
19
+ <List>
20
+ <For each="{{ reminders }}" item="reminder" key="key">
21
+ <ListItem icon="bell" title="{{ reminder.title }}" subtitle="{{ reminder.schedule.start }} at {{ reminder.schedule.time || '09:00' }}" value="Cancel" data-key="{{ reminder.key }}" onTap="cancel" />
22
+ </For>
23
+ </List>
24
+ </If>
25
+ <Else>
26
+ <Text variant="caption" tone="muted">None yet.</Text>
27
+ </Else>
28
+ </View>
29
+ </View>
30
+
31
+ <If condition="{{ note }}">
32
+ <Notice tone="danger">{{ note }}</Notice>
33
+ </If>
34
+ </View>
@@ -1,3 +1,5 @@
1
+ import { errorMessage } from '@monimesl/dot-runtime';
2
+
1
3
  import state from './state';
2
4
 
3
5
  const SESSION = 'session';
@@ -16,28 +18,49 @@ export default definePage({
16
18
  },
17
19
  actions: {
18
20
  async refresh() {
19
- const token = await this.dash.storage.secret.get(SESSION);
20
- const signedInAs = await this.dash.storage.cache.get<string>(NAME);
21
- this.setState({
22
- token: token ? `${token.slice(0, 12)}…` : '',
23
- signedInAs: signedInAs ?? '',
24
- });
21
+ try {
22
+ // null if there's no secret by that name.
23
+ const token = await this.dash.storage.secret.get(SESSION);
24
+ const signedInAs = await this.dash.storage.cache.get<string>(NAME);
25
+ this.setState({
26
+ token: token ? `${token.slice(0, 12)}…` : '',
27
+ signedInAs: signedInAs ?? '',
28
+ });
29
+ } catch (error) {
30
+ this.setState({ note: errorMessage(error) });
31
+ }
25
32
  },
33
+ // A value over 4 KB rejects with 'invalid'. A 33rd secret rejects with 'failed', so remove
34
+ // one first.
26
35
  async signIn(state) {
27
- // A real dot gets its token from its own API, once the person signs in there.
28
- const token = `demo-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
29
- await this.dash.storage.secret.set(SESSION, token);
30
- await this.dash.storage.cache.set(NAME, state.name);
31
- this.setState({ name: '' });
36
+ try {
37
+ // A real dot gets its token from its own API, once the person signs in there.
38
+ const token = `demo-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
39
+ await this.dash.storage.secret.set(SESSION, token);
40
+ await this.dash.storage.cache.set(NAME, state.name);
41
+ this.setState({ name: '', note: '' });
42
+ } catch (error) {
43
+ this.setState({ note: errorMessage(error) });
44
+ }
32
45
  await this.actions.refresh();
33
46
  },
34
47
  async signOut() {
35
- await this.dash.storage.secret.remove(SESSION);
36
- await this.dash.storage.cache.remove(NAME);
48
+ try {
49
+ await this.dash.storage.secret.remove(SESSION);
50
+ await this.dash.storage.cache.remove(NAME);
51
+ this.setState({ note: '' });
52
+ } catch (error) {
53
+ this.setState({ note: errorMessage(error) });
54
+ }
37
55
  await this.actions.refresh();
38
56
  },
39
57
  async forgetAll() {
40
- await this.dash.storage.secret.clear();
58
+ try {
59
+ await this.dash.storage.secret.clear();
60
+ this.setState({ note: '' });
61
+ } catch (error) {
62
+ this.setState({ note: errorMessage(error) });
63
+ }
41
64
  await this.actions.refresh();
42
65
  },
43
66
  },
@@ -2,4 +2,5 @@ export default {
2
2
  name: '',
3
3
  signedInAs: '',
4
4
  token: '',
5
+ note: '',
5
6
  };
@@ -23,4 +23,8 @@
23
23
  </View>
24
24
 
25
25
  <Notice tone="warning" title="Keep keys off the phone">Only the token is a secret here: your name is in the cache. Never put API keys in a dot's code or .env, since anyone with the dot can read them.</Notice>
26
+
27
+ <If condition="{{ note }}">
28
+ <Notice tone="danger">{{ note }}</Notice>
29
+ </If>
26
30
  </View>
@@ -37,6 +37,7 @@ export default definePage({
37
37
  this.setState({ note: errorMessage(error) });
38
38
  }
39
39
  },
40
+ // Only https addresses. Anything else rejects with 'invalid'.
40
41
  async openDrizilik() {
41
42
  try {
42
43
  await this.dash.system.openUrl('https://drizilik.com/');
@@ -44,6 +45,7 @@ export default definePage({
44
45
  this.setState({ note: errorMessage(error) });
45
46
  }
46
47
  },
48
+ // A dot's logic has no timers, so Dash keeps the time.
47
49
  async countDown() {
48
50
  for (let seconds = 10; seconds > 0; seconds--) {
49
51
  this.setState({ showIn: seconds });
@@ -68,6 +70,8 @@ export default definePage({
68
70
  this.setState({ note: errorMessage(error) });
69
71
  }
70
72
  },
73
+ // A number may have digits, spaces, dashes, +, * and #. Anything else rejects with 'invalid'.
74
+ // For a USSD code, Dash asks the person first, and rejects with 'cancelled' if they say no.
71
75
  async dialNumber(state) {
72
76
  try {
73
77
  await this.dash.system.dial(state.number);
@@ -76,6 +80,7 @@ export default definePage({
76
80
  this.setState({ note: errorMessage(error) });
77
81
  }
78
82
  },
83
+ // A phone without a torch rejects with 'unsupported'.
79
84
  async toggleTorch(state) {
80
85
  const torchOn = !state.torchOn;
81
86
  try {
@@ -58,7 +58,7 @@
58
58
 
59
59
  <View gap="small">
60
60
  <Text variant="subtitle">openUrl</Text>
61
- <Text variant="caption" tone="muted">Opens a web page in the phone's browser.</Text>
61
+ <Text variant="caption" tone="muted">Opens an https web page in the phone's browser.</Text>
62
62
  <View variant="card">
63
63
  <Button variant="secondary" onClick="openDrizilik">Open Drizilik's website</Button>
64
64
  </View>
@@ -66,7 +66,7 @@
66
66
 
67
67
  <View gap="small">
68
68
  <Text variant="subtitle">delay</Text>
69
- <Text variant="caption" tone="muted">Waits for a number of milliseconds. Dash keeps time, so it's cancelled when the page closes.</Text>
69
+ <Text variant="caption" tone="muted">Waits for a number of milliseconds. Like any call still running, it stops when the page closes.</Text>
70
70
  <View variant="card">
71
71
  <Button variant="secondary" onClick="countDown" disabled="{{ showIn > 0 }}">{{ showIn > 0 ? 'Showtime in ' + showIn + 's' : 'Count down to showtime' }}</Button>
72
72
  </View>
@@ -74,7 +74,7 @@
74
74
 
75
75
  <View gap="small">
76
76
  <Text variant="subtitle">dial</Text>
77
- <Text variant="caption" tone="muted">Opens the phone's dialer with a number ready, or a USSD code such as *715#. The person taps Call.</Text>
77
+ <Text variant="caption" tone="muted">Opens the phone's dialer with a number ready, or a USSD code such as *715#. The person taps Call. For a code, Dash asks them first.</Text>
78
78
  <View variant="card">
79
79
  <Input label="Number or code" type="phone" value="{{ number }}" onChange="setNumber" onSubmit="dialNumber" />
80
80
  <Button variant="secondary" onClick="dialNumber" disabled="{{ !number }}">Open the dialer</Button>
@@ -83,7 +83,7 @@
83
83
 
84
84
  <View gap="small">
85
85
  <Text variant="subtitle">torch</Text>
86
- <Text variant="caption" tone="muted">Turns the camera's light on or off.</Text>
86
+ <Text variant="caption" tone="muted">Turns the camera's light on or off, on a phone that has one.</Text>
87
87
  <View variant="card">
88
88
  <Button variant="secondary" onClick="toggleTorch">{{ torchOn ? 'Turn the torch off' : 'Lights up for the slow song' }}</Button>
89
89
  </View>
@@ -5,9 +5,13 @@ import state from './state';
5
5
  export default definePage({
6
6
  initialState: state,
7
7
  configs: { navigationBar: { title: 'Dialogs and pickers' } },
8
+ // A this.dash call goes to Dash and answers later, so await it. If it fails, it throws a
9
+ // DashError with a code that says why, such as 'cancelled' or 'denied'. errorMessage(error)
10
+ // gives text to show for any error. The Calls and errors page lists every code.
8
11
  actions: {
9
12
  async greet() {
10
13
  try {
14
+ // Resolves with { action }: the id of the button tapped.
11
15
  const { action } = await this.dash.ui.alert({
12
16
  title: 'Kushé',
13
17
  message: 'Kushé means hello in Krio, and tenki means thanks.',
@@ -36,7 +40,8 @@ export default definePage({
36
40
  this.setState({ note: errorMessage(error) });
37
41
  }
38
42
  },
39
- // unlessCancelled gives undefined when the person closes the picker, which isn't a problem.
43
+ // Closing a picker rejects with 'cancelled'. That isn't a problem, so unlessCancelled turns it
44
+ // into undefined. Any other error still throws. A min after max rejects with 'invalid'.
40
45
  async chooseNight(state) {
41
46
  try {
42
47
  const night = await unlessCancelled(
@@ -3,6 +3,7 @@ import state from './state';
3
3
  export default definePage({
4
4
  initialState: state,
5
5
  actions: {
6
+ // Each row's data-page names its page. The Events and Navigation pages show how this works.
6
7
  open(_state, event: DataEvent<{ page: PageId }>) {
7
8
  this.navigation.push(event.data.page);
8
9
  },
@@ -40,7 +40,7 @@ export default {
40
40
  {
41
41
  page: 'basics/events',
42
42
  title: 'Events',
43
- covers: 'onTap, onChange, event.detail, data-*',
43
+ covers: 'onClick, onTap, onChange, event.detail, event.data',
44
44
  icon: 'bolt',
45
45
  },
46
46
  {
@@ -67,6 +67,12 @@ export default {
67
67
  covers: 'configs.colors, setColors, background, primary, surfaces',
68
68
  icon: 'water',
69
69
  },
70
+ {
71
+ page: 'basics/theme',
72
+ title: 'Theme',
73
+ covers: 'colors, shape, density, elevation, fonts, components, icons, gradients',
74
+ icon: 'eye',
75
+ },
70
76
  {
71
77
  page: 'basics/share',
72
78
  title: 'Share links',
@@ -82,13 +88,13 @@ export default {
82
88
  {
83
89
  page: 'components/layout',
84
90
  title: 'Layout',
85
- covers: 'View, Stack, Scroll, Grid, Divider',
91
+ covers: 'View, hidden, disabled, Stack, Scroll, Grid, Divider',
86
92
  icon: 'grid',
87
93
  },
88
94
  {
89
95
  page: 'components/styles',
90
96
  title: 'Styles',
91
- covers: 'background, border, radius, sizes, theme colours',
97
+ covers: 'background, border, radius, sizes, elevation, buttons, own colours',
92
98
  icon: 'star',
93
99
  },
94
100
  {
@@ -130,9 +136,21 @@ export default {
130
136
  {
131
137
  page: 'components/tabs',
132
138
  title: 'Tabs and chips',
133
- covers: 'Tabs, Tab, Chip',
139
+ covers: 'Tabs, Tab, Tab icons, Chip',
134
140
  icon: 'search',
135
141
  },
142
+ {
143
+ page: 'components/pinned',
144
+ title: 'Pinned bars',
145
+ covers: 'Pinned, Tabs variant="bar"',
146
+ icon: 'location',
147
+ },
148
+ {
149
+ page: 'components/capture',
150
+ title: 'Pictures of a View',
151
+ covers: 'View id, captureView',
152
+ icon: 'image',
153
+ },
136
154
  {
137
155
  page: 'components/forms',
138
156
  title: 'Forms',
@@ -188,6 +206,12 @@ export default {
188
206
  covers: 'pickPhone',
189
207
  icon: 'users',
190
208
  },
209
+ {
210
+ page: 'dash/reminders',
211
+ title: 'dash.reminders',
212
+ covers: 'set, cancel and list',
213
+ icon: 'bell',
214
+ },
191
215
  {
192
216
  page: 'dash/account',
193
217
  title: 'dash.account',
@@ -216,7 +240,7 @@ export default {
216
240
  {
217
241
  page: 'dash/files',
218
242
  title: 'dash.storage.file',
219
- covers: 'write, read, list, move, copy, remove, save, stat, open, usage',
243
+ covers: 'write, read, list, createFolder, move, copy, remove, save, stat, open, usage',
220
244
  icon: 'file',
221
245
  },
222
246
  {
@@ -234,7 +258,7 @@ export default {
234
258
  {
235
259
  page: 'dash/calls',
236
260
  title: 'Calls and errors',
237
- covers: 'timeout, cancel, DashError, isDashError',
261
+ covers: 'timeout, cancel, DashError, isDashError, supports, dash.dot.close',
238
262
  icon: 'warning',
239
263
  },
240
264
  ],
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#000" fill-rule="evenodd" d="M5 4h14a2 2 0 0 1 2 2v3a3 3 0 0 0 0 6v3a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-3a3 3 0 0 0 0-6V6a2 2 0 0 1 2-2zm4 3v2h1.5V7zm0 4v2h1.5v-2zm0 4v2h1.5v-2z"/></svg>
@@ -1,3 +1,3 @@
1
- # Public configuration for the dot. Anyone with the dot can read these variables: never put a
2
- # secret here. Read them in the service as `env.GREETING`.
1
+ # Public settings for the dot. Code reads each one from `env`, such as `env.GREETING`.
2
+ # They're built into the dot, so anyone who has it can read them. Never put a secret here.
3
3
  GREETING=Hello from your dot
@@ -1,3 +1,4 @@
1
1
  export default defineDot({
2
+ // Each page is a folder under pages/. The dot opens on the first one.
2
3
  pages: ['index'],
3
4
  });
@@ -2,6 +2,8 @@ import state from './state';
2
2
 
3
3
  export default definePage({
4
4
  initialState: state,
5
+ // A mutation gets the state and returns the fields to change, and the view follows. For steps
6
+ // that wait, such as a Dash call, use actions instead.
5
7
  mutations: {
6
8
  increment: (state) => ({ count: state.count + 1 }),
7
9
  reset: () => ({ count: 0 }),
@@ -1,4 +1,6 @@
1
+ // The data the page starts with. view.dml shows it with bindings, such as {{ count }}.
1
2
  export default {
3
+ // env holds the values in .env.
2
4
  greeting: env.GREETING,
3
5
  count: 0,
4
6
  };
@@ -3,11 +3,12 @@
3
3
  <Image src="statics/logo.png" alt="Logo" width="40" height="40" />
4
4
  <Text variant="title">{{ greeting }}</Text>
5
5
  </View>
6
- <Text>Change pages/index/view.dml and save: the simulator shows it at once.</Text>
6
+ <Text>Change pages/index/view.dml and save. The simulator shows the change at once.</Text>
7
7
 
8
8
  <View variant="card" align="center" gap="medium">
9
9
  <Text variant="title">{{ count }}</Text>
10
10
  <Text tone="muted">{{ count === 1 ? 'tap' : 'taps' }} so far</Text>
11
+ <!-- onClick names the mutation or action in controller.ts to run. -->
11
12
  <View direction="row" gap="small">
12
13
  <Button variant="secondary" onClick="reset" disabled="{{ count === 0 }}">Reset</Button>
13
14
  <Button onClick="increment">Tap me</Button>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monimesl/dot-cli",
3
- "version": "1.0.0-beta.0",
3
+ "version": "1.0.0-beta.10",
4
4
  "description": "The dotctl command: build mini apps and run them in the simulator",
5
5
  "type": "module",
6
6
  "repository": {
@@ -24,11 +24,11 @@
24
24
  "dependencies": {
25
25
  "typescript": "^5.9.3",
26
26
  "uqr": "^0.1.3",
27
- "@monimesl/dot-compiler": "1.0.0-beta.0",
28
- "@monimesl/dot-core": "1.0.0-beta.0",
29
- "@monimesl/dot-dml-parser": "1.0.0-beta.0",
30
- "@monimesl/dot-script-parser": "1.0.0-beta.0",
31
- "@monimesl/dot-simulator": "1.0.0-beta.0"
27
+ "@monimesl/dot-compiler": "1.0.0-beta.10",
28
+ "@monimesl/dot-core": "1.0.0-beta.10",
29
+ "@monimesl/dot-dml-parser": "1.0.0-beta.10",
30
+ "@monimesl/dot-script-parser": "1.0.0-beta.10",
31
+ "@monimesl/dot-simulator": "1.0.0-beta.10"
32
32
  },
33
33
  "devDependencies": {
34
34
  "@types/node": "^22.20.4",