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

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