@tokamakdev/plugin-location 0.1.0-beta.107 → 0.1.0-beta.114
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/README.md +30 -13
- package/android/Bindings.kt +997 -0
- package/android/LocationPlugin.kt +3 -124
- package/android/bindings.ts +4150 -0
- package/apple/Bindings.swift +1057 -0
- package/apple/LocationPlugin.swift +28 -167
- package/apple/LocationRegions.swift +3 -1
- package/apple/bindings.ts +1314 -0
- package/events/index.ts +5 -5
- package/package.json +5 -3
- package/src/android.ts +138 -0
- package/src/apple.ts +117 -0
- package/src/errors.ts +34 -0
- package/src/index.ts +89 -64
- package/src/types.ts +12 -0
- package/tokamak-plugin.json +69 -2
- package/web/client.ts +11 -0
- package/src/checks.ts +0 -65
- package/src/options.ts +0 -54
package/web/client.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { valueStream, type JsonStream } from "@tokamakdev/plugin/streams";
|
|
2
|
+
import * as web from "./index.js";
|
|
3
|
+
import type { Position, PositionOptions } from "../src/types.js";
|
|
4
|
+
|
|
5
|
+
export const location = {
|
|
6
|
+
getCurrentPosition: (options: PositionOptions = {}) => web.getCurrentPosition(options),
|
|
7
|
+
permission: web.permission,
|
|
8
|
+
watchPosition(): Promise<JsonStream<Position>> {
|
|
9
|
+
return Promise.resolve(valueStream<Position>((next, error) => web.watchPosition(next, error), "dropOldest"));
|
|
10
|
+
},
|
|
11
|
+
};
|
package/src/checks.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/** Checks of the values the plugin's methods take, which throw `TypeError` naming the value. */
|
|
2
|
-
export type Check = (value: unknown, path: string) => void;
|
|
3
|
-
|
|
4
|
-
/** Checks that `value` is an object, then each field `checks` names that it has or `required` lists. */
|
|
5
|
-
export function object(checks: Readonly<Record<string, Check>>, required: readonly string[] = []): Check {
|
|
6
|
-
return (value, path) => {
|
|
7
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
8
|
-
throw new TypeError(`${path} must be an object`);
|
|
9
|
-
}
|
|
10
|
-
for (const [key, check] of Object.entries(checks)) {
|
|
11
|
-
const field = (value as Record<string, unknown>)[key];
|
|
12
|
-
if (field !== undefined || required.includes(key)) check(field, `${path}.${key}`);
|
|
13
|
-
}
|
|
14
|
-
};
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export function flag(value: unknown, path: string): void {
|
|
18
|
-
if (typeof value !== "boolean") throw new TypeError(`${path} must be a boolean`);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function text(value: unknown, path: string): void {
|
|
22
|
-
if (typeof value !== "string") throw new TypeError(`${path} must be a string`);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function nonEmptyText(value: unknown, path: string): void {
|
|
26
|
-
if (typeof value !== "string" || value === "") throw new TypeError(`${path} must be a non-empty string`);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function oneOf(...allowed: readonly string[]): Check {
|
|
30
|
-
return (value, path) => {
|
|
31
|
-
if (!allowed.includes(value as string)) {
|
|
32
|
-
throw new TypeError(`${path} must be one of ${allowed.map((name) => `"${name}"`).join(", ")}`);
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** A finite number of at least 0. */
|
|
38
|
-
export function atLeastZero(value: unknown, path: string): void {
|
|
39
|
-
if (!(typeof value === "number" && Number.isFinite(value) && value >= 0)) {
|
|
40
|
-
throw new TypeError(`${path} must be a finite number of at least 0`);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** A whole number of at least 0. */
|
|
45
|
-
export function wholeAtLeastZero(value: unknown, path: string): void {
|
|
46
|
-
if (!(Number.isSafeInteger(value) && (value as number) >= 0)) {
|
|
47
|
-
throw new TypeError(`${path} must be a whole number of at least 0`);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/** A number from `min` to `max`. */
|
|
52
|
-
export function between(min: number, max: number): Check {
|
|
53
|
-
return (value, path) => {
|
|
54
|
-
if (!(typeof value === "number" && value >= min && value <= max)) {
|
|
55
|
-
throw new TypeError(`${path} must be a number from ${String(min)} to ${String(max)}`);
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/** A finite number greater than 0. */
|
|
61
|
-
export function positive(value: unknown, path: string): void {
|
|
62
|
-
if (!(typeof value === "number" && Number.isFinite(value) && value > 0)) {
|
|
63
|
-
throw new TypeError(`${path} must be a finite number greater than 0`);
|
|
64
|
-
}
|
|
65
|
-
}
|
package/src/options.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
atLeastZero,
|
|
3
|
-
between,
|
|
4
|
-
flag,
|
|
5
|
-
nonEmptyText,
|
|
6
|
-
object,
|
|
7
|
-
oneOf,
|
|
8
|
-
positive,
|
|
9
|
-
text,
|
|
10
|
-
wholeAtLeastZero,
|
|
11
|
-
} from "./checks.js";
|
|
12
|
-
import type { Region } from "./types.js";
|
|
13
|
-
|
|
14
|
-
/** Throws `TypeError` unless `config` is a configuration `setup` takes. */
|
|
15
|
-
export const validateSetup = object({ significantChanges: flag, visits: flag });
|
|
16
|
-
|
|
17
|
-
/** Throws `TypeError` unless `options` are options `requestPermission` takes. */
|
|
18
|
-
export const validatePermissionRequest = object({
|
|
19
|
-
background: flag,
|
|
20
|
-
precision: oneOf("precise", "approximate"),
|
|
21
|
-
purpose: nonEmptyText,
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
/** Throws `TypeError` unless `options` are options `startUpdates` takes. */
|
|
25
|
-
export const validateUpdateOptions = object({
|
|
26
|
-
activity: oneOf("default", "automotiveNavigation", "otherNavigation", "fitness", "airborne", "maritime"),
|
|
27
|
-
accuracy: oneOf("high", "balanced", "low"),
|
|
28
|
-
distance: atLeastZero,
|
|
29
|
-
interval: wholeAtLeastZero,
|
|
30
|
-
foregroundService: object(
|
|
31
|
-
{ title: nonEmptyText, body: text, channel: nonEmptyText },
|
|
32
|
-
["title", "body", "channel"],
|
|
33
|
-
),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const REGION = object(
|
|
37
|
-
{
|
|
38
|
-
id: nonEmptyText,
|
|
39
|
-
latitude: between(-90, 90),
|
|
40
|
-
longitude: between(-180, 180),
|
|
41
|
-
radius: positive,
|
|
42
|
-
onEntry: flag,
|
|
43
|
-
onExit: flag,
|
|
44
|
-
},
|
|
45
|
-
["id", "latitude", "longitude", "radius"],
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
/** `region`, with `onEntry` and `onExit` given. Throws `TypeError` unless it is a region to monitor. */
|
|
49
|
-
export function monitoredRegion(region: Region): Required<Region> {
|
|
50
|
-
REGION(region, "region");
|
|
51
|
-
const { id, latitude, longitude, radius, onEntry = true, onExit = true } = region;
|
|
52
|
-
if (!onEntry && !onExit) throw new TypeError("region must report entry, exit or both");
|
|
53
|
-
return { id, latitude, longitude, radius, onEntry, onExit };
|
|
54
|
-
}
|