@monimesl/dot-dash 0.1.0-alpha.21 → 0.1.0-alpha.24

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/index.js CHANGED
@@ -1,11 +1,124 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.js";
2
- import { HostError, HostError as DashError, HostError as HostError$1, callHost, createHostRequest } from "@monimesl/dot-core";
2
+ import { DEFAULT_DASH_API_VERSION, HostError, HostError as DashError, callHost, createHostRequest, offersDashApiVersion } from "@monimesl/dot-core";
3
+ //#region src/api-versions.ts
4
+ const DASH_API_VERSION = "1.0";
5
+ const DASH_API_SINCE = {
6
+ "account.readProfile": "1.0",
7
+ "contacts.pickPhone": "1.0",
8
+ "crypto.hmac": "1.0",
9
+ "crypto.randomBytes": "1.0",
10
+ "crypto.randomUUID": "1.0",
11
+ "crypto.sha256": "1.0",
12
+ "crypto.sha512": "1.0",
13
+ "dot.close": "1.0",
14
+ "media.pickFile": "1.0",
15
+ "media.pickPhoto": "1.0",
16
+ "media.scanCode": "1.0",
17
+ "network.http.download": "1.0",
18
+ "network.http.request": "1.0",
19
+ "network.http.upload": "1.0",
20
+ "network.status": "1.0",
21
+ "storage.cache.clear": "1.0",
22
+ "storage.cache.exists": "1.0",
23
+ "storage.cache.get": "1.0",
24
+ "storage.cache.keys": "1.0",
25
+ "storage.cache.remove": "1.0",
26
+ "storage.cache.set": "1.0",
27
+ "storage.file.copy": "1.0",
28
+ "storage.file.createFolder": "1.0",
29
+ "storage.file.list": "1.0",
30
+ "storage.file.move": "1.0",
31
+ "storage.file.open": "1.0",
32
+ "storage.file.read": "1.0",
33
+ "storage.file.remove": "1.0",
34
+ "storage.file.save": "1.0",
35
+ "storage.file.stat": "1.0",
36
+ "storage.file.usage": "1.0",
37
+ "storage.file.write": "1.0",
38
+ "storage.secret.clear": "1.0",
39
+ "storage.secret.get": "1.0",
40
+ "storage.secret.remove": "1.0",
41
+ "storage.secret.set": "1.0",
42
+ "system.brightness": "1.0",
43
+ "system.copyText": "1.0",
44
+ "system.delay": "1.0",
45
+ "system.dial": "1.0",
46
+ "system.info": "1.0",
47
+ "system.keepAwake": "1.0",
48
+ "system.openUrl": "1.0",
49
+ "system.share": "1.0",
50
+ "system.torch": "1.0",
51
+ "system.vibrate": "1.0",
52
+ "ui.alert": "1.0",
53
+ "ui.pickDate": "1.0",
54
+ "ui.pickTime": "1.0"
55
+ };
56
+ let hostApiVersions = [DEFAULT_DASH_API_VERSION];
57
+ let dotMinApiVersion;
58
+ const checkedFeatures = /* @__PURE__ */ new Set();
59
+ const warnedFeatures = /* @__PURE__ */ new Set();
60
+ function useHostDashApiVersions(versions) {
61
+ hostApiVersions = versions;
62
+ }
63
+ function warnAboveDashApiVersion(minApiVersion) {
64
+ dotMinApiVersion = minApiVersion;
65
+ }
66
+ /**
67
+ * Whether the Dash the dot runs in has `feature`: a call, such as "contacts.pickPhone", or a field
68
+ * added to a call later. Check it before using one that's newer than the dot's minApiVersion.
69
+ * @since 1.0
70
+ */
71
+ function supports(feature) {
72
+ checkedFeatures.add(feature);
73
+ const since = sinceOf(feature);
74
+ return since !== void 0 && offersDashApiVersion(hostApiVersions, since);
75
+ }
76
+ function warnIfNewerThanDot(method, params) {
77
+ if (dotMinApiVersion === void 0) return;
78
+ const callName = method.replace(/^dash\./, "");
79
+ for (const feature of [callName, ...fieldsSent(callName, params)]) {
80
+ const since = sinceOf(feature);
81
+ if (since === void 0) continue;
82
+ if (checkedFeatures.has(feature) || warnedFeatures.has(feature)) continue;
83
+ if (offersDashApiVersion([dotMinApiVersion], since)) continue;
84
+ warnedFeatures.add(feature);
85
+ console.warn(`dash.${feature} came in Dash API ${since}, but this dot's minApiVersion is ${dotMinApiVersion}, so older Dash doesn't have it. Raise "minApiVersion" in dot.json, or check dash.supports('${feature}') first.`);
86
+ }
87
+ }
88
+ function sinceOf(feature) {
89
+ const table = DASH_API_SINCE;
90
+ return Object.hasOwn(table, feature) ? table[feature] : void 0;
91
+ }
92
+ function fieldsSent(callName, params) {
93
+ if (typeof params !== "object" || params === null) return [];
94
+ return Object.keys(params).map((field) => `${callName}.${field}`).filter((feature) => sinceOf(feature) !== void 0);
95
+ }
96
+ //#endregion
3
97
  //#region src/call.ts
4
98
  function call(method, params, options = {}) {
99
+ warnIfNewerThanDot(method, params);
5
100
  return callHost(method, params, options);
6
101
  }
7
102
  //#endregion
103
+ //#region src/account/index.ts
104
+ var account_exports = /* @__PURE__ */ __exportAll({ readProfile: () => readProfile });
105
+ /**
106
+ * The person signed in to Dash: their full name, and a token that names them in this dot. Needs the
107
+ * `account` permission. Rejects with `invalid` for a nonce that's empty or longer than 128
108
+ * characters, and with `failed` when no one is signed in.
109
+ * @since 1.0
110
+ */
111
+ function readProfile(options, callOptions) {
112
+ return call("dash.account.readProfile", { nonce: options.nonce }, callOptions);
113
+ }
114
+ //#endregion
8
115
  //#region src/contacts/pick-phone.ts
116
+ /**
117
+ * Shows the phone's contacts so the person chooses one phone number, such as who to send money to.
118
+ * Needs the `contacts` permission. The dot sees only the chosen contact. Rejects with `cancelled` if
119
+ * the person closes it.
120
+ * @since 1.0
121
+ */
9
122
  function pickPhone(callOptions) {
10
123
  return call("dash.contacts.pickPhone", {}, callOptions);
11
124
  }
@@ -13,57 +126,169 @@ function pickPhone(callOptions) {
13
126
  //#region src/contacts/index.ts
14
127
  var contacts_exports = /* @__PURE__ */ __exportAll({ pickPhone: () => pickPhone });
15
128
  //#endregion
129
+ //#region src/crypto/index.ts
130
+ var crypto_exports = /* @__PURE__ */ __exportAll({
131
+ hmac: () => hmac,
132
+ randomBytes: () => randomBytes,
133
+ randomUUID: () => randomUUID,
134
+ sha256: () => sha256,
135
+ sha512: () => sha512
136
+ });
137
+ /** @since 1.0 */
138
+ function sha256(data, options = {}, callOptions) {
139
+ return call("dash.crypto.sha256", wireInput(data, options), callOptions);
140
+ }
141
+ /** @since 1.0 */
142
+ function sha512(data, options = {}, callOptions) {
143
+ return call("dash.crypto.sha512", wireInput(data, options), callOptions);
144
+ }
145
+ /**
146
+ * Signs `data` with `key`, as HMAC-SHA256 or HMAC-SHA512, such as
147
+ * `hmac({ algorithm: 'sha256', key, data })`.
148
+ * @since 1.0
149
+ */
150
+ function hmac(options, callOptions) {
151
+ const wireKey = valueAndEncoding(options.key);
152
+ return call("dash.crypto.hmac", {
153
+ ...wireInput(options.data, options),
154
+ algorithm: options.algorithm,
155
+ key: wireKey.value,
156
+ keyEncoding: wireKey.encoding
157
+ }, callOptions);
158
+ }
159
+ /**
160
+ * `count` secure random bytes, from 1 to 1024, such as for a nonce.
161
+ * @since 1.0
162
+ */
163
+ function randomBytes(count, options = {}, callOptions) {
164
+ return call("dash.crypto.randomBytes", {
165
+ count,
166
+ as: outputEncoding(options)
167
+ }, callOptions);
168
+ }
169
+ /**
170
+ * A random version 4 UUID, such as "3f0e5c3a-6d1b-4c8e-9a2f-1b7d4e6a9c05".
171
+ * @since 1.0
172
+ */
173
+ function randomUUID(callOptions) {
174
+ return call("dash.crypto.randomUUID", {}, callOptions);
175
+ }
176
+ function wireInput(data, options) {
177
+ const { value, encoding } = valueAndEncoding(data);
178
+ return {
179
+ data: value,
180
+ dataEncoding: encoding,
181
+ as: outputEncoding(options)
182
+ };
183
+ }
184
+ function outputEncoding(options) {
185
+ return options.as ?? "hex";
186
+ }
187
+ function valueAndEncoding(input) {
188
+ if (typeof input === "string") return {
189
+ value: input,
190
+ encoding: "text"
191
+ };
192
+ return {
193
+ value: input.base64,
194
+ encoding: "base64"
195
+ };
196
+ }
197
+ //#endregion
198
+ //#region src/dot/index.ts
199
+ var dot_exports = /* @__PURE__ */ __exportAll({ close: () => close });
200
+ /**
201
+ * Closes the dot, as going back from its first page does. Calls still running are cancelled.
202
+ * @since 1.0
203
+ */
204
+ function close(callOptions) {
205
+ return call("dash.dot.close", {}, callOptions);
206
+ }
207
+ //#endregion
208
+ //#region src/media/pick-file.ts
209
+ /**
210
+ * Lets the person choose a file from their phone, of at most 25 MB. Needs the `files` permission.
211
+ * Rejects with `cancelled` if they close the picker, and with `invalid` for a larger file. Like a
212
+ * download, it lasts until the dot closes, so `dash.storage.file.save` it to keep it.
213
+ * @since 1.0
214
+ */
215
+ function pickFile(options = {}, callOptions) {
216
+ const params = {};
217
+ if (options.types) params.types = options.types;
218
+ return call("dash.media.pickFile", params, callOptions);
219
+ }
220
+ //#endregion
16
221
  //#region src/media/pick-photo.ts
222
+ /**
223
+ * Lets the person choose a photo or take one. Resolves with it as a JPEG of at most 2048 pixels on its
224
+ * longest side, without its location or other details. Rejects with `cancelled` if they close the
225
+ * picker, and with `unsupported` on a device without a camera. Save it with `dash.storage.file.save`
226
+ * to keep it after the dot closes.
227
+ * @since 1.0
228
+ */
17
229
  function pickPhoto(options, callOptions) {
18
230
  return call("dash.media.pickPhoto", { source: options.source }, callOptions);
19
231
  }
20
232
  //#endregion
21
233
  //#region src/media/scan-code.ts
234
+ /**
235
+ * Opens Dash's scanner until it reads a QR code. Needs the `camera` permission. Rejects with
236
+ * `cancelled` if the person closes it, and with `unsupported` where Dash has no scanner.
237
+ * @since 1.0
238
+ */
22
239
  function scanCode(callOptions) {
23
240
  return call("dash.media.scanCode", {}, callOptions);
24
241
  }
25
242
  //#endregion
26
243
  //#region src/media/index.ts
27
244
  var media_exports = /* @__PURE__ */ __exportAll({
245
+ pickFile: () => pickFile,
28
246
  pickPhoto: () => pickPhoto,
29
247
  scanCode: () => scanCode
30
248
  });
31
249
  //#endregion
32
- //#region src/files.ts
33
- function fileId(file) {
34
- return typeof file === "string" ? file : file.id;
35
- }
36
- //#endregion
37
250
  //#region src/network/http.ts
38
251
  var http_exports = /* @__PURE__ */ __exportAll({
39
252
  download: () => download,
40
253
  request: () => request,
41
254
  upload: () => upload
42
255
  });
256
+ /**
257
+ * Like fetch, resolves with any response, even a 404. An object body is sent as JSON.
258
+ * @since 1.0
259
+ */
43
260
  function request(options, callOptions) {
44
- const { as, ...request } = options;
45
- return readBody(call("dash.network.http.request", wireRequest(request, as), callOptions), as);
261
+ const { as: readAs, ...request } = options;
262
+ return readBody(call("dash.network.http.request", wireRequest(request, readAs), callOptions), readAs);
46
263
  }
264
+ /**
265
+ * Saves a 2xx response's body, up to 256 MB, to a temporary file.
266
+ * @since 1.0
267
+ */
47
268
  function download(options, callOptions) {
48
269
  return call("dash.network.http.download", wireRequest(options), callOptions);
49
270
  }
271
+ /**
272
+ * Sends the dot's files as a multipart form.
273
+ * @since 1.0
274
+ */
50
275
  function upload(options, callOptions) {
51
- const { as, ...request } = options;
52
- const files = request.files.map(({ file, ...rest }) => ({
53
- ...rest,
54
- file: fileId(file)
276
+ const { as: readAs, ...request } = options;
277
+ const files = request.files.map((upload) => ({
278
+ ...upload,
279
+ file: upload.file.id
55
280
  }));
56
281
  const params = {
57
282
  ...request,
58
283
  files
59
284
  };
60
- if (as === "json") params.headers = withDefaultHeader(request.headers, "Accept", "application/json");
61
- return readBody(call("dash.network.http.upload", params, callOptions), as);
285
+ if (readAs === "json") params.headers = withDefaultHeader(request.headers, "Accept", "application/json");
286
+ return readBody(call("dash.network.http.upload", params, callOptions), readAs);
62
287
  }
63
- function wireRequest(request, as) {
288
+ function wireRequest(request, readAs) {
64
289
  let headers = request.headers;
65
290
  let body;
66
- if (as === "json") headers = withDefaultHeader(headers, "Accept", "application/json");
291
+ if (readAs === "json") headers = withDefaultHeader(headers, "Accept", "application/json");
67
292
  if (typeof request.body === "string") body = request.body;
68
293
  else if (request.body !== void 0) {
69
294
  headers = withDefaultHeader(headers, "Content-Type", "application/json");
@@ -76,15 +301,16 @@ function wireRequest(request, as) {
76
301
  };
77
302
  }
78
303
  function withDefaultHeader(headers, name, value) {
304
+ if (headers === void 0) return { [name]: value };
79
305
  const lowerName = name.toLowerCase();
80
- if (headers && Object.keys(headers).some((existing) => existing.toLowerCase() === lowerName)) return headers;
306
+ if (Object.keys(headers).some((existing) => existing.toLowerCase() === lowerName)) return headers;
81
307
  return {
82
308
  ...headers,
83
309
  [name]: value
84
310
  };
85
311
  }
86
- function readBody(response, as) {
87
- if (as !== "json") return response;
312
+ function readBody(response, readAs) {
313
+ if (readAs !== "json") return response;
88
314
  const parsed = response.then((result) => ({
89
315
  ...result,
90
316
  body: parseJson(result)
@@ -96,11 +322,15 @@ function parseJson({ status, statusText, body }) {
96
322
  return JSON.parse(body);
97
323
  } catch (error) {
98
324
  const message = error instanceof Error ? error.message : String(error);
99
- throw new HostError$1("failed", `The response (${status} ${statusText}) isn't JSON: ${message}`);
325
+ throw new HostError("failed", `The response (${status} ${statusText}) isn't JSON: ${message}`);
100
326
  }
101
327
  }
102
328
  //#endregion
103
329
  //#region src/network/status.ts
330
+ /**
331
+ * Whether the phone is online now, and how. It can still be online without reaching a server.
332
+ * @since 1.0
333
+ */
104
334
  function status(callOptions) {
105
335
  return call("dash.network.status", {}, callOptions);
106
336
  }
@@ -120,9 +350,14 @@ var cache_exports = /* @__PURE__ */ __exportAll({
120
350
  remove: () => remove$2,
121
351
  set: () => set$1
122
352
  });
353
+ /**
354
+ * Resolves with null for a missing or expired key.
355
+ * @since 1.0
356
+ */
123
357
  function get$1(key, callOptions) {
124
358
  return call("dash.storage.cache.get", { key }, callOptions);
125
359
  }
360
+ /** @since 1.0 */
126
361
  function set$1(key, value, options = {}, callOptions) {
127
362
  return call("dash.storage.cache.set", {
128
363
  key,
@@ -130,15 +365,22 @@ function set$1(key, value, options = {}, callOptions) {
130
365
  ...options
131
366
  }, callOptions);
132
367
  }
368
+ /** @since 1.0 */
133
369
  function remove$2(key, callOptions) {
134
370
  return call("dash.storage.cache.remove", { key }, callOptions);
135
371
  }
372
+ /** @since 1.0 */
136
373
  function exists(key, callOptions) {
137
374
  return call("dash.storage.cache.exists", { key }, callOptions);
138
375
  }
376
+ /**
377
+ * The keys, sorted.
378
+ * @since 1.0
379
+ */
139
380
  function keys(callOptions) {
140
381
  return call("dash.storage.cache.keys", {}, callOptions);
141
382
  }
383
+ /** @since 1.0 */
142
384
  function clear$1(callOptions) {
143
385
  return call("dash.storage.cache.clear", {}, callOptions);
144
386
  }
@@ -150,7 +392,6 @@ var file_exports = /* @__PURE__ */ __exportAll({
150
392
  list: () => list,
151
393
  move: () => move,
152
394
  open: () => open,
153
- pick: () => pick,
154
395
  read: () => read,
155
396
  remove: () => remove$1,
156
397
  save: () => save,
@@ -158,12 +399,20 @@ var file_exports = /* @__PURE__ */ __exportAll({
158
399
  usage: () => usage,
159
400
  write: () => write
160
401
  });
402
+ /**
403
+ * Reads a file of up to 5 MB.
404
+ * @since 1.0
405
+ */
161
406
  function read(path, options = {}, callOptions) {
162
407
  return call("dash.storage.file.read", {
163
408
  path,
164
409
  ...options
165
410
  }, callOptions);
166
411
  }
412
+ /**
413
+ * Creates any missing folders above the file.
414
+ * @since 1.0
415
+ */
167
416
  function write(path, data, options = {}, callOptions) {
168
417
  return call("dash.storage.file.write", {
169
418
  path,
@@ -171,18 +420,25 @@ function write(path, data, options = {}, callOptions) {
171
420
  ...options
172
421
  }, callOptions);
173
422
  }
423
+ /** @since 1.0 */
174
424
  function stat(path, callOptions) {
175
425
  return call("dash.storage.file.stat", { path }, callOptions);
176
426
  }
427
+ /**
428
+ * Sorted by path.
429
+ * @since 1.0
430
+ */
177
431
  function list(path = "", options = {}, callOptions) {
178
432
  return call("dash.storage.file.list", {
179
433
  path,
180
434
  ...options
181
435
  }, callOptions);
182
436
  }
437
+ /** @since 1.0 */
183
438
  function createFolder(path, callOptions) {
184
439
  return call("dash.storage.file.createFolder", { path }, callOptions);
185
440
  }
441
+ /** @since 1.0 */
186
442
  function move(from, to, options = {}, callOptions) {
187
443
  return call("dash.storage.file.move", {
188
444
  from,
@@ -190,6 +446,7 @@ function move(from, to, options = {}, callOptions) {
190
446
  ...options
191
447
  }, callOptions);
192
448
  }
449
+ /** @since 1.0 */
193
450
  function copy(from, to, options = {}, callOptions) {
194
451
  return call("dash.storage.file.copy", {
195
452
  from,
@@ -197,30 +454,38 @@ function copy(from, to, options = {}, callOptions) {
197
454
  ...options
198
455
  }, callOptions);
199
456
  }
457
+ /**
458
+ * Removing a folder that isn't empty needs `recursive`.
459
+ * @since 1.0
460
+ */
200
461
  function remove$1(path, options = {}, callOptions) {
201
462
  return call("dash.storage.file.remove", {
202
463
  path,
203
464
  ...options
204
465
  }, callOptions);
205
466
  }
467
+ /**
468
+ * Keeps a temporary file, such as a download, at `path`.
469
+ * @since 1.0
470
+ */
206
471
  function save(file, path, options = {}, callOptions) {
207
472
  return call("dash.storage.file.save", {
208
- file: fileId(file),
473
+ file: file.id,
209
474
  path,
210
475
  ...options
211
476
  }, callOptions);
212
477
  }
478
+ /**
479
+ * A stored file as a DotFile, to show with its `url` or send with `http.upload`.
480
+ * @since 1.0
481
+ */
213
482
  function open(path, callOptions) {
214
483
  return call("dash.storage.file.open", { path }, callOptions);
215
484
  }
485
+ /** @since 1.0 */
216
486
  function usage(callOptions) {
217
487
  return call("dash.storage.file.usage", {}, callOptions);
218
488
  }
219
- function pick(options = {}, callOptions) {
220
- const params = {};
221
- if (options.types) params.types = options.types;
222
- return call("dash.storage.file.pick", params, callOptions);
223
- }
224
489
  //#endregion
225
490
  //#region src/storage/secret.ts
226
491
  var secret_exports = /* @__PURE__ */ __exportAll({
@@ -229,18 +494,22 @@ var secret_exports = /* @__PURE__ */ __exportAll({
229
494
  remove: () => remove,
230
495
  set: () => set
231
496
  });
497
+ /** @since 1.0 */
232
498
  function get(key, callOptions) {
233
499
  return call("dash.storage.secret.get", { key }, callOptions);
234
500
  }
501
+ /** @since 1.0 */
235
502
  function set(key, value, callOptions) {
236
503
  return call("dash.storage.secret.set", {
237
504
  key,
238
505
  value
239
506
  }, callOptions);
240
507
  }
508
+ /** @since 1.0 */
241
509
  function remove(key, callOptions) {
242
510
  return call("dash.storage.secret.remove", { key }, callOptions);
243
511
  }
512
+ /** @since 1.0 */
244
513
  function clear(callOptions) {
245
514
  return call("dash.storage.secret.clear", {}, callOptions);
246
515
  }
@@ -253,56 +522,97 @@ var storage_exports = /* @__PURE__ */ __exportAll({
253
522
  });
254
523
  //#endregion
255
524
  //#region src/system/clipboard.ts
525
+ /** @since 1.0 */
256
526
  function copyText(text, callOptions) {
257
527
  return call("dash.system.copyText", { text }, callOptions);
258
528
  }
259
529
  //#endregion
260
530
  //#region src/system/delay.ts
531
+ /**
532
+ * Resolves after `milliseconds`. The host keeps the time, since a dot's logic has no timers.
533
+ * @since 1.0
534
+ */
261
535
  function delay(milliseconds, callOptions) {
262
536
  return call("dash.system.delay", { milliseconds }, callOptions);
263
537
  }
264
538
  //#endregion
265
539
  //#region src/system/dial.ts
540
+ /**
541
+ * Opens the phone's dialer with `number` ready, such as "+232 76 123456" or a USSD code such as
542
+ * "*715#". The person taps Call. Spaces and dashes are fine; anything else but digits, +, * and #
543
+ * rejects with `invalid`.
544
+ * @since 1.0
545
+ */
266
546
  function dial(number, callOptions) {
267
547
  return call("dash.system.dial", { number }, callOptions);
268
548
  }
269
549
  //#endregion
270
550
  //#region src/system/haptics.ts
551
+ /**
552
+ * Plays a short vibration. Resolves once it's done.
553
+ * @since 1.0
554
+ */
271
555
  function vibrate(options = {}, callOptions) {
272
556
  return call("dash.system.vibrate", { style: options.style ?? "medium" }, callOptions);
273
557
  }
274
558
  //#endregion
275
559
  //#region src/system/info.ts
560
+ /**
561
+ * The phone and the Dash the dot runs in. It has nothing that identifies the person or the phone.
562
+ * @since 1.0
563
+ */
276
564
  function info(callOptions) {
277
565
  return call("dash.system.info", {}, callOptions);
278
566
  }
279
567
  //#endregion
280
568
  //#region src/system/open-url.ts
569
+ /**
570
+ * Opens an https address in the device's browser. Any other address rejects with `invalid`.
571
+ * @since 1.0
572
+ */
281
573
  function openUrl(url, callOptions) {
282
574
  return call("dash.system.openUrl", { url }, callOptions);
283
575
  }
284
576
  //#endregion
285
577
  //#region src/system/screen.ts
578
+ /**
579
+ * Keeps the screen from dimming and locking while the dot shows, such as while a ticket's QR code is
580
+ * up. Dash undoes it when the dot closes.
581
+ * @since 1.0
582
+ */
286
583
  function keepAwake(on, callOptions) {
287
584
  return call("dash.system.keepAwake", { on }, callOptions);
288
585
  }
586
+ /**
587
+ * `max` makes the screen as bright as it goes, so a scanner can read a QR code on it, and `normal`
588
+ * puts it back. Dash puts it back too when the dot closes or the person leaves the app.
589
+ * @since 1.0
590
+ */
289
591
  function brightness(level, callOptions) {
290
592
  return call("dash.system.brightness", { level }, callOptions);
291
593
  }
292
594
  //#endregion
293
595
  //#region src/system/share.ts
596
+ /**
597
+ * Opens the device's share sheet. Resolves once it shows.
598
+ * @since 1.0
599
+ */
294
600
  function share(options, callOptions) {
295
- const { file, ...rest } = options;
296
- if (file === void 0) return call("dash.system.share", rest, callOptions);
601
+ const { file, ...content } = options;
602
+ if (file === void 0) return call("dash.system.share", content, callOptions);
297
603
  return call("dash.system.share", {
298
- ...rest,
299
- file: fileId(file)
604
+ ...content,
605
+ file: file.id
300
606
  }, callOptions);
301
607
  }
302
608
  //#endregion
303
609
  //#region src/system/torch.ts
304
- function torch(state, callOptions) {
305
- return call("dash.system.torch", { state }, callOptions);
610
+ /**
611
+ * Turns the torch on or off. Rejects with `unsupported` on a device without one.
612
+ * @since 1.0
613
+ */
614
+ function torch(on, callOptions) {
615
+ return call("dash.system.torch", { on }, callOptions);
306
616
  }
307
617
  //#endregion
308
618
  //#region src/system/index.ts
@@ -320,6 +630,10 @@ var system_exports = /* @__PURE__ */ __exportAll({
320
630
  });
321
631
  //#endregion
322
632
  //#region src/ui/dialogs.ts
633
+ /**
634
+ * Shows a native alert. Resolves with the action the person chose.
635
+ * @since 1.0
636
+ */
323
637
  function alert(options, callOptions) {
324
638
  const actions = options.actions ?? [{
325
639
  id: "ok",
@@ -332,9 +646,19 @@ function alert(options, callOptions) {
332
646
  }
333
647
  //#endregion
334
648
  //#region src/ui/pickers.ts
649
+ /**
650
+ * Opens the phone's own calendar. Resolves with the chosen date, such as "2026-10-24", or rejects
651
+ * with `cancelled` if the person closes it.
652
+ * @since 1.0
653
+ */
335
654
  function pickDate(options = {}, callOptions) {
336
655
  return call("dash.ui.pickDate", options, callOptions);
337
656
  }
657
+ /**
658
+ * Opens the phone's own clock. Resolves with the chosen time in 24 hours, such as "19:30", or
659
+ * rejects with `cancelled` if the person closes it.
660
+ * @since 1.0
661
+ */
338
662
  function pickTime(options = {}, callOptions) {
339
663
  return call("dash.ui.pickTime", options, callOptions);
340
664
  }
@@ -346,15 +670,131 @@ var ui_exports = /* @__PURE__ */ __exportAll({
346
670
  pickTime: () => pickTime
347
671
  });
348
672
  //#endregion
673
+ //#region src/utils/encoding.ts
674
+ const BASE64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
675
+ const BASE64_PATTERN = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
676
+ const HEX_PATTERN = /^(?:[0-9a-fA-F]{2})*$/;
677
+ const base64 = {
678
+ encode(text) {
679
+ return bytesToBase64(utf8Bytes(text));
680
+ },
681
+ decode(encoded) {
682
+ return utf8Text(base64ToBytes(encoded));
683
+ }
684
+ };
685
+ const hex = {
686
+ encode(text) {
687
+ return utf8Bytes(text).map((byte) => byte.toString(16).padStart(2, "0")).join("");
688
+ },
689
+ decode(encoded) {
690
+ if (!HEX_PATTERN.test(encoded)) throw new Error(`"${encoded.slice(0, 20)}" isn't hex. Use pairs of 0-9 and a-f.`);
691
+ const bytes = [];
692
+ for (let index = 0; index < encoded.length; index += 2) bytes.push(parseInt(encoded.slice(index, index + 2), 16));
693
+ return utf8Text(bytes);
694
+ }
695
+ };
696
+ function bytesToBase64(bytes) {
697
+ let encoded = "";
698
+ for (let index = 0; index < bytes.length; index += 3) {
699
+ const group = bytes.slice(index, index + 3);
700
+ const bits = (group[0] ?? 0) << 16 | (group[1] ?? 0) << 8 | (group[2] ?? 0);
701
+ const sextets = [
702
+ bits >> 18 & 63,
703
+ bits >> 12 & 63,
704
+ bits >> 6 & 63,
705
+ bits & 63
706
+ ];
707
+ const characterCount = group.length + 1;
708
+ for (const sextet of sextets.slice(0, characterCount)) encoded += BASE64_ALPHABET[sextet];
709
+ encoded += "=".repeat(4 - characterCount);
710
+ }
711
+ return encoded;
712
+ }
713
+ function base64ToBytes(encoded) {
714
+ if (!BASE64_PATTERN.test(encoded)) throw new Error(`"${encoded.slice(0, 20)}" isn't base64.`);
715
+ const bytes = [];
716
+ for (let index = 0; index < encoded.length; index += 4) {
717
+ const characters = encoded.slice(index, index + 4);
718
+ let bits = 0;
719
+ let padding = 0;
720
+ for (const character of characters) {
721
+ bits <<= 6;
722
+ if (character === "=") padding += 1;
723
+ else bits |= BASE64_ALPHABET.indexOf(character);
724
+ }
725
+ bytes.push(bits >> 16 & 255);
726
+ if (padding < 2) bytes.push(bits >> 8 & 255);
727
+ if (padding < 1) bytes.push(bits & 255);
728
+ }
729
+ return bytes;
730
+ }
731
+ function utf8Bytes(text) {
732
+ const bytes = [];
733
+ for (const character of text) {
734
+ const codePoint = character.codePointAt(0);
735
+ if (codePoint < 128) bytes.push(codePoint);
736
+ else if (codePoint < 2048) bytes.push(192 | codePoint >> 6, 128 | codePoint & 63);
737
+ else if (codePoint < 65536) bytes.push(224 | codePoint >> 12, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
738
+ else bytes.push(240 | codePoint >> 18, 128 | codePoint >> 12 & 63, 128 | codePoint >> 6 & 63, 128 | codePoint & 63);
739
+ }
740
+ return bytes;
741
+ }
742
+ const MAX_CODE_POINT = 1114111;
743
+ function utf8Text(bytes) {
744
+ let text = "";
745
+ let index = 0;
746
+ while (index < bytes.length) {
747
+ const first = bytes[index];
748
+ const length = sequenceLength(first);
749
+ const continuation = bytes.slice(index + 1, index + length);
750
+ if (length === 0 || !isCompleteContinuation(continuation, length)) {
751
+ text += "�";
752
+ index += 1;
753
+ continue;
754
+ }
755
+ let codePoint = firstByteBits(first, length);
756
+ for (const byte of continuation) codePoint = codePoint << 6 | byte & 63;
757
+ if (codePoint > MAX_CODE_POINT) {
758
+ text += "�";
759
+ index += 1;
760
+ continue;
761
+ }
762
+ text += String.fromCodePoint(codePoint);
763
+ index += length;
764
+ }
765
+ return text;
766
+ }
767
+ function sequenceLength(first) {
768
+ if (first < 128) return 1;
769
+ if (first >= 240) return 4;
770
+ if (first >= 224) return 3;
771
+ if (first >= 192) return 2;
772
+ return 0;
773
+ }
774
+ function isCompleteContinuation(continuation, length) {
775
+ if (continuation.length !== length - 1) return false;
776
+ return continuation.every((byte) => (byte & 192) === 128);
777
+ }
778
+ function firstByteBits(first, length) {
779
+ if (length === 1) return first;
780
+ return first & 255 >> length + 1;
781
+ }
782
+ //#endregion
783
+ //#region src/utils/index.ts
784
+ var utils_exports = /* @__PURE__ */ __exportAll({
785
+ base64: () => base64,
786
+ hex: () => hex
787
+ });
788
+ //#endregion
349
789
  //#region src/tracked.ts
350
790
  function tracked(group, track) {
351
791
  const copy = {};
352
792
  for (const [name, member] of Object.entries(group)) if (typeof member === "function") {
353
- const start = member;
793
+ const startCall = member;
354
794
  copy[name] = (...args) => {
355
- const request = start(...args);
356
- track(request);
357
- return request;
795
+ const result = startCall(...args);
796
+ if (result instanceof Promise) track(result);
797
+ return result;
358
798
  };
359
799
  } else copy[name] = tracked(member, track);
360
800
  return copy;
@@ -362,27 +802,9 @@ function tracked(group, track) {
362
802
  //#endregion
363
803
  //#region src/errors.ts
364
804
  function isDashError(error, ...codes) {
365
- if (error instanceof HostError$1) return codes.length === 0 || codes.includes(error.code);
805
+ if (error instanceof HostError) return codes.length === 0 || codes.includes(error.code);
366
806
  return false;
367
807
  }
368
- function isDashCancelled(error) {
369
- return isDashError(error, "cancelled");
370
- }
371
- function isDashTimeout(error) {
372
- return isDashError(error, "timeout");
373
- }
374
- function isDashDenied(error) {
375
- return isDashError(error, "denied");
376
- }
377
- function isDashInvalid(error) {
378
- return isDashError(error, "invalid");
379
- }
380
- function isDashUnsupported(error) {
381
- return isDashError(error, "unsupported");
382
- }
383
- function isDashFailed(error) {
384
- return isDashError(error, "failed");
385
- }
386
808
  function errorMessage(error) {
387
809
  if (error instanceof Error) return error.message;
388
810
  if (typeof error === "string" && error) return error;
@@ -392,7 +814,7 @@ async function unlessCancelled(call) {
392
814
  try {
393
815
  return await call;
394
816
  } catch (error) {
395
- if (isDashCancelled(error)) return;
817
+ if (isDashError(error, "cancelled")) return;
396
818
  throw error;
397
819
  }
398
820
  }
@@ -413,7 +835,7 @@ function debounce(milliseconds) {
413
835
  await wait(dash.system.delay(milliseconds));
414
836
  return true;
415
837
  } catch (error) {
416
- if (isDashCancelled(error)) return false;
838
+ if (isDashError(error, "cancelled")) return false;
417
839
  throw error;
418
840
  }
419
841
  };
@@ -426,9 +848,14 @@ const dash = {
426
848
  network: network_exports,
427
849
  storage: storage_exports,
428
850
  media: media_exports,
429
- contacts: contacts_exports
851
+ contacts: contacts_exports,
852
+ dot: dot_exports,
853
+ account: account_exports,
854
+ crypto: crypto_exports,
855
+ utils: utils_exports,
856
+ supports
430
857
  };
431
858
  //#endregion
432
- export { DashError, HostError, dash, debounce, errorMessage, isDashCancelled, isDashDenied, isDashError, isDashFailed, isDashInvalid, isDashTimeout, isDashUnsupported, latest, tracked, unlessCancelled };
859
+ export { DASH_API_SINCE, DASH_API_VERSION, DashError, dash, debounce, errorMessage, isDashError, latest, tracked, unlessCancelled, useHostDashApiVersions, warnAboveDashApiVersion };
433
860
 
434
861
  //# sourceMappingURL=index.js.map