lecodes-sdk 2.4.1 → 2.4.2
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/types/core/Aspect.d.ts +34 -5
- package/dist/types/g2/OneWay2D.d.ts +0 -1
- package/dist/types/g2/Physics2D.d.ts +8 -6
- package/dist/types/g2/Scene2D.d.ts +1 -1
- package/dist/types/g2/Shape2D.d.ts +43 -15
- package/dist/types/gl/Model.d.ts +3 -2
- package/dist/types/gl/Scene.d.ts +1 -1
- package/dist/types/gl/animation/DynamicBone.d.ts +99 -35
- package/dist/types/gl/animation/IK.d.ts +0 -1
- package/dist/types/gl/nav/NavAgent.d.ts +3 -2
- package/dist/types/gl/physics/Physics.d.ts +4 -5
- package/dist/types/gl/physics/Shape.d.ts +40 -15
- package/dist/types/gl/vehicle/Vehicle.d.ts +54 -35
- package/dist/types/gl/vehicle/Wheel.d.ts +31 -10
- package/dist/types/plugins/gen/ar/contract.d.ts +152 -0
- package/dist/types/plugins/gen/ar/sdk/ar.d.ts +47 -21
- package/dist/types/plugins/gen/ar/sdk/ar.gen.d.ts +17 -3
- package/dist/types/plugins/gen/audio-recorder/contract.d.ts +64 -0
- package/dist/types/plugins/gen/browser/contract.d.ts +108 -0
- package/dist/types/plugins/gen/camera/contract.d.ts +27 -0
- package/dist/types/plugins/gen/geolocation/contract.d.ts +52 -0
- package/dist/types/plugins/gen/map/contract.d.ts +144 -0
- package/dist/types/plugins/gen/push/contract.d.ts +83 -0
- package/dist/types/plugins/gen/qr-scanner/contract.d.ts +16 -0
- package/dist/types/plugins/gen/speech/contract.d.ts +67 -0
- package/dist/types/plugins/gen/webrtc/contract.d.ts +342 -0
- package/dist/types/version.d.ts +1 -1
- package/dist/types.json +1 -1
- package/package.json +1 -1
- package/src/bridges/gl.d.ts +5 -3
- package/src/compile/compileProject.ts +45 -10
- package/src/compile/index.ts +7 -0
- package/src/compile/webHalf.ts +255 -0
- package/src/core/Aspect.ts +118 -35
- package/src/g2/OneWay2D.ts +0 -2
- package/src/g2/Physics2D.ts +8 -16
- package/src/g2/Scene2D.ts +1 -1
- package/src/g2/Shape2D.ts +51 -22
- package/src/gl/Model.ts +3 -2
- package/src/gl/Scene.ts +1 -1
- package/src/gl/animation/DynamicBone.ts +549 -486
- package/src/gl/animation/IK.ts +0 -2
- package/src/gl/nav/NavAgent.ts +14 -12
- package/src/gl/physics/Physics.ts +4 -5
- package/src/gl/physics/Shape.ts +49 -23
- package/src/gl/vehicle/Vehicle.ts +102 -58
- package/src/gl/vehicle/Wheel.ts +45 -11
- package/src/plugins/gen/ar/contract.d.ts +35 -1
- package/src/plugins/gen/ar/sdk/ar.gen.ts +25 -6
- package/src/plugins/gen/ar/sdk/ar.ts +102 -35
- package/src/version.ts +1 -1
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/browser/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// browser — web content inside the app, on the two surfaces the platforms give:
|
|
4
|
+
// - the SYSTEM SHEET (the "browser" service): SFSafariViewController / ASWebAuthenticationSession on
|
|
5
|
+
// iOS, Chrome Custom Tabs on Android, a popup on the web. It shares the system browser's logins,
|
|
6
|
+
// passkeys and Apple Pay, and OAuth providers accept it. The app sees nothing of the page.
|
|
7
|
+
// - the EMBEDDED PAGE (the "webView" view): WKWebView / android.webkit.WebView / an iframe. A tree
|
|
8
|
+
// node the app embeds or presents fullscreen, with navigation events the app acts on.
|
|
9
|
+
//
|
|
10
|
+
// The hosts are dumb on purpose: they intercept a URL prefix and report it, forward the platform's
|
|
11
|
+
// callback URL, hand a non-http link to the system. Which URL ends a flow and what it means is the
|
|
12
|
+
// app's side (`Browser.open` in sdk/).
|
|
13
|
+
|
|
14
|
+
import type { Json, Service, View } from "../../../plugin"
|
|
15
|
+
|
|
16
|
+
// ---- the sheet ------------------------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
export interface BrowserParams {}
|
|
19
|
+
|
|
20
|
+
export interface BrowserOpenOptions {
|
|
21
|
+
/** An auth flow: the scheme the provider redirects back to (`myshop` of `myshop://oauth`). iOS
|
|
22
|
+
* runs an ASWebAuthenticationSession and resolves `open` with the callback URL itself. Android
|
|
23
|
+
* and the web have nothing to do here: the redirect reaches the app as its "url" event. */
|
|
24
|
+
callbackScheme?: string
|
|
25
|
+
/** A private session: no cookies shared with the system browser. Honored on iOS (with a
|
|
26
|
+
* callbackScheme), ignored elsewhere. Default false. */
|
|
27
|
+
ephemeral?: boolean
|
|
28
|
+
/** The sheet's tint, "#RRGGBB". */
|
|
29
|
+
color?: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface BrowserResult {
|
|
33
|
+
/** The callback URL the platform intercepted (iOS, with a callbackScheme); absent when the sheet
|
|
34
|
+
* was dismissed. */
|
|
35
|
+
url?: string
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface BrowserEvents {
|
|
39
|
+
/** The sheet went away: the user dismissed it, the platform handed back the callback, or
|
|
40
|
+
* close(). */
|
|
41
|
+
closed: void
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export interface Browser extends Service<"browser", BrowserParams, BrowserEvents> {
|
|
45
|
+
/** Show `url` in the system's in-app browser sheet. Resolves when the sheet is dismissed — with
|
|
46
|
+
* the callback URL when the platform intercepted one. One sheet at a time.
|
|
47
|
+
* @rejects busy invalid */
|
|
48
|
+
show(url: string, options?: BrowserOpenOptions): Promise<BrowserResult>
|
|
49
|
+
/** Dismiss the sheet; a no-op without one. */
|
|
50
|
+
dismiss(): Promise<void>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ---- the embedded page ----------------------------------------------------------------------------
|
|
54
|
+
|
|
55
|
+
export interface WebViewParams {
|
|
56
|
+
/** What to load first. */
|
|
57
|
+
url?: string
|
|
58
|
+
/** Main-frame URLs that END a flow: a navigation whose URL starts with one is NOT loaded, the
|
|
59
|
+
* view emits `stop` instead. */
|
|
60
|
+
stops?: string[]
|
|
61
|
+
/** Install `window.lecodes.postMessage(data)` for the page (the `message` event) and let
|
|
62
|
+
* `postMessage` reach it (`window.lecodes.onMessage`). Default false — a user script disables
|
|
63
|
+
* Apple Pay in that WKWebView, so a checkout page wants it off. */
|
|
64
|
+
bridge?: boolean
|
|
65
|
+
/** A navigation to a non-http(s) URL — tel:, mailto:, intent:, a bank's app in a checkout:
|
|
66
|
+
* "open" hands it to the system, "block" drops it. Default "open". */
|
|
67
|
+
externalLinks?: "open" | "block"
|
|
68
|
+
userAgent?: string
|
|
69
|
+
/** A private session: no cookies or storage kept after the view goes. Default false. */
|
|
70
|
+
ephemeral?: boolean
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export interface WebViewEvents {
|
|
74
|
+
/** A main-frame navigation started. */
|
|
75
|
+
navigate: { url: string }
|
|
76
|
+
/** The page finished loading. */
|
|
77
|
+
load: { url: string, title: string }
|
|
78
|
+
/** The page failed to load. */
|
|
79
|
+
error: { url: string, message: string }
|
|
80
|
+
/** A stop URL was reached: the navigation was cancelled, the page did not load. */
|
|
81
|
+
stop: { url: string }
|
|
82
|
+
/** The page called `window.lecodes.postMessage(data)` (with `bridge`). */
|
|
83
|
+
message: { data: Json }
|
|
84
|
+
/** The page called `window.close()`. */
|
|
85
|
+
exit: void
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface WebView extends View<"webView", WebViewParams, WebViewEvents> {
|
|
89
|
+
/** Load `url`, with extra request headers for the first request. @rejects invalid */
|
|
90
|
+
load(url: string, headers?: { [name: string]: string }): Promise<void>
|
|
91
|
+
/** Show `html` as the page; relative URLs in it resolve against `baseUrl`. */
|
|
92
|
+
loadHtml(html: string, baseUrl?: string): Promise<void>
|
|
93
|
+
/** Replace the stop list (see WebViewParams.stops). */
|
|
94
|
+
setStops(stops: string[]): Promise<void>
|
|
95
|
+
reload(): Promise<void>
|
|
96
|
+
/** Stop the current load. */
|
|
97
|
+
stopLoading(): Promise<void>
|
|
98
|
+
goBack(): Promise<void>
|
|
99
|
+
goForward(): Promise<void>
|
|
100
|
+
canGoBack(): Promise<boolean>
|
|
101
|
+
/** Run `js` in the page and return what it evaluates to, as JSON. On iOS this disables Apple Pay
|
|
102
|
+
* in the view until its next navigation. @rejects failed */
|
|
103
|
+
evaluate(js: string): Promise<Json>
|
|
104
|
+
/** Deliver `data` to the page's `window.lecodes.onMessage(data)` (with `bridge`). */
|
|
105
|
+
postMessage(data: Json): Promise<void>
|
|
106
|
+
/** Clear the cookies and the storage of this view's session. */
|
|
107
|
+
clearData(): Promise<void>
|
|
108
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/camera/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// camera — a live camera preview with still capture.
|
|
4
|
+
// The contract of the WIRE: what the app-facing `CameraView` (sdk/) and the halves (ios/, android/,
|
|
5
|
+
// web/) agree on. The generator reads this file; nothing else describes the channel.
|
|
6
|
+
|
|
7
|
+
import type { File, View } from "../../../plugin"
|
|
8
|
+
|
|
9
|
+
export type Facing = "front" | "back"
|
|
10
|
+
|
|
11
|
+
export interface CameraParams {
|
|
12
|
+
/** Default "back". */
|
|
13
|
+
facingMode?: Facing
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface CameraEvents {
|
|
17
|
+
/** The preview could not start or stopped (no camera, the stream was refused). */
|
|
18
|
+
error: { message: string }
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface CameraView extends View<"camera", CameraParams, CameraEvents> {
|
|
22
|
+
/** Capture a still frame as a JPEG.
|
|
23
|
+
* @rejects failed */
|
|
24
|
+
takePhoto(): Promise<File>
|
|
25
|
+
/** Switch the camera while the preview is live. */
|
|
26
|
+
setFacingMode(mode: Facing): Promise<void>
|
|
27
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/geolocation/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// geolocation — the device position.
|
|
4
|
+
// The wire has ONE watch per session (startWatch / stopWatch + the `position` event); the
|
|
5
|
+
// app-facing `Geolocation.watch(callback)` fans it out to its subscribers in sdk/.
|
|
6
|
+
//
|
|
7
|
+
// A session opens without a prompt. The OS permission is the calls' (`@permission location`): the
|
|
8
|
+
// host asks before the first call that needs the position, the halves never do.
|
|
9
|
+
|
|
10
|
+
import type { Service, f64 } from "../../../plugin"
|
|
11
|
+
|
|
12
|
+
export interface GeoOptions {
|
|
13
|
+
/** Prefer the precise (GPS) provider — slower first fix, more battery. Default false. */
|
|
14
|
+
highAccuracy?: boolean
|
|
15
|
+
/** getCurrent only: reject with "timeout" when no fix arrives in this many ms. */
|
|
16
|
+
timeout?: f64
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface GeoPosition {
|
|
20
|
+
latitude: f64
|
|
21
|
+
longitude: f64
|
|
22
|
+
/** Horizontal accuracy radius, meters. */
|
|
23
|
+
accuracy: f64
|
|
24
|
+
/** Meters above sea level; null when the provider does not know. */
|
|
25
|
+
altitude: f64 | null
|
|
26
|
+
/** Direction of travel, degrees clockwise from north; null when stationary or unknown. */
|
|
27
|
+
heading: f64 | null
|
|
28
|
+
/** Ground speed, m/s; null when unknown. */
|
|
29
|
+
speed: f64 | null
|
|
30
|
+
/** When the fix was taken, ms since the epoch. */
|
|
31
|
+
timestamp: f64
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface GeolocationParams {}
|
|
35
|
+
|
|
36
|
+
export interface GeolocationEvents {
|
|
37
|
+
/** A fix of the live watch. */
|
|
38
|
+
position: GeoPosition
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface Geolocation extends Service<"geolocation", GeolocationParams, GeolocationEvents> {
|
|
42
|
+
/** One fix.
|
|
43
|
+
* @permission location
|
|
44
|
+
* @rejects unavailable timeout */
|
|
45
|
+
getCurrent(options?: GeoOptions): Promise<GeoPosition>
|
|
46
|
+
/** Start the session's watch; resolves once it is live (the provider started).
|
|
47
|
+
* A second call while watching resolves at once and keeps the first call's options.
|
|
48
|
+
* @permission location
|
|
49
|
+
* @rejects unavailable */
|
|
50
|
+
startWatch(options?: GeoOptions): Promise<void>
|
|
51
|
+
stopWatch(): Promise<void>
|
|
52
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/map/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// map — a vector map (maplibre-native on iOS / Android, maplibre-gl in the browser).
|
|
4
|
+
// The wire is lower than the app-facing `MapView`: the wrapper in sdk/ resolves a style to a url or
|
|
5
|
+
// to text, turns marker items into GeoJSON, queues calls until `ready` and re-applies the
|
|
6
|
+
// style-lifetime state (layers, data, padding, the user puck) after every style load.
|
|
7
|
+
//
|
|
8
|
+
// The plugin never touches the location hardware: the user puck is fed by the app.
|
|
9
|
+
|
|
10
|
+
import type { Json, View, f64 } from "../../../plugin"
|
|
11
|
+
|
|
12
|
+
/** `[longitude, latitude]` — GeoJSON order. */
|
|
13
|
+
export type LngLat = [f64, f64]
|
|
14
|
+
|
|
15
|
+
export interface MapParams {
|
|
16
|
+
/** A style URL the map fetches itself. */
|
|
17
|
+
style?: string
|
|
18
|
+
/** A style as JSON text; wins over `style`. It has no base url: every url INSIDE it (sources,
|
|
19
|
+
* sprite, glyphs) must be absolute. */
|
|
20
|
+
styleJson?: string
|
|
21
|
+
center?: LngLat
|
|
22
|
+
/** Default 12 with a center. */
|
|
23
|
+
zoom?: f64
|
|
24
|
+
minZoom?: f64
|
|
25
|
+
maxZoom?: f64
|
|
26
|
+
/** Degrees clockwise from north. */
|
|
27
|
+
bearing?: f64
|
|
28
|
+
/** Degrees from the vertical. */
|
|
29
|
+
pitch?: f64
|
|
30
|
+
/** The two-finger rotate gesture. Default true. */
|
|
31
|
+
rotate?: boolean
|
|
32
|
+
/** The two-finger tilt gesture. Default false. */
|
|
33
|
+
tilt?: boolean
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface MapCamera {
|
|
37
|
+
center: LngLat
|
|
38
|
+
zoom: f64
|
|
39
|
+
bearing: f64
|
|
40
|
+
pitch: f64
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** A feature of a managed source under a tap. */
|
|
44
|
+
export interface MapFeature {
|
|
45
|
+
/** The source's name — the layer's name in the app. */
|
|
46
|
+
source: string
|
|
47
|
+
id: string | f64 | null
|
|
48
|
+
properties: { [key: string]: Json }
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface MapTap {
|
|
52
|
+
lngLat: LngLat
|
|
53
|
+
/** View-space point, logical px. */
|
|
54
|
+
point: [f64, f64]
|
|
55
|
+
/** Absent for a tap that hit no feature of a managed source. A tap on a CLUSTER zooms in and
|
|
56
|
+
* sends no event. */
|
|
57
|
+
feature?: MapFeature
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface MapEvents {
|
|
61
|
+
/** The style loaded and the map takes calls. Fires again after every style reload. */
|
|
62
|
+
ready: void
|
|
63
|
+
tap: MapTap
|
|
64
|
+
/** The camera settled after a gesture or an animation. */
|
|
65
|
+
moveEnd: MapCamera
|
|
66
|
+
/** A problem that is never fatal: a style that would not load, a source out of reach. */
|
|
67
|
+
error: { message: string }
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export type MapLayerKind = "markers" | "line"
|
|
71
|
+
|
|
72
|
+
/** The keys of both kinds; a half reads the ones of the kind it is asked for. */
|
|
73
|
+
export interface MapLayerOptions {
|
|
74
|
+
/** markers: group nearby markers (a cluster tap zooms in). Default false. */
|
|
75
|
+
cluster?: boolean
|
|
76
|
+
/** markers: px. Default 50. */
|
|
77
|
+
clusterRadius?: f64
|
|
78
|
+
/** markers: the zoom at which clusters stop forming. */
|
|
79
|
+
clusterMaxZoom?: f64
|
|
80
|
+
/** line. */
|
|
81
|
+
color?: string
|
|
82
|
+
/** line: px. Default 4. */
|
|
83
|
+
width?: f64
|
|
84
|
+
/** line: 0–1. Default 1. */
|
|
85
|
+
opacity?: f64
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface MapCameraMove {
|
|
89
|
+
zoom?: f64
|
|
90
|
+
bearing?: f64
|
|
91
|
+
pitch?: f64
|
|
92
|
+
/** flyTo only: ms. Default 600. */
|
|
93
|
+
duration?: f64
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Px, or a share of the view's size as "NN%". */
|
|
97
|
+
export type MapInset = f64 | string
|
|
98
|
+
|
|
99
|
+
export interface MapPadding {
|
|
100
|
+
top?: MapInset
|
|
101
|
+
left?: MapInset
|
|
102
|
+
bottom?: MapInset
|
|
103
|
+
right?: MapInset
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export interface MapFitOptions {
|
|
107
|
+
/** Around the points: px on every edge, or per edge. Added to the view padding. */
|
|
108
|
+
padding?: f64 | MapPadding
|
|
109
|
+
/** Default: 16 for one point, none otherwise. */
|
|
110
|
+
maxZoom?: f64
|
|
111
|
+
/** Default true. */
|
|
112
|
+
animate?: boolean
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface MapUserLocationOptions {
|
|
116
|
+
/** Meters — the halo around the dot. */
|
|
117
|
+
accuracy?: f64 | null
|
|
118
|
+
/** Degrees clockwise from north — the direction wedge; null hides it. */
|
|
119
|
+
heading?: f64 | null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export interface MapView extends View<"map", MapParams, MapEvents> {
|
|
123
|
+
/** Make sure the GeoJSON source `source` exists. A source the style declares is used as is (its
|
|
124
|
+
* layers draw, only data flows); otherwise the half creates it with the default layers of `kind`.
|
|
125
|
+
* @rejects notReady */
|
|
126
|
+
ensureLayer(source: string, kind: MapLayerKind, options?: MapLayerOptions): Promise<void>
|
|
127
|
+
removeLayer(source: string): Promise<void>
|
|
128
|
+
/** Replace the data of a GeoJSON source: a Feature or a FeatureCollection.
|
|
129
|
+
* @rejects notReady */
|
|
130
|
+
setData(source: string, geojson: Json): Promise<void>
|
|
131
|
+
|
|
132
|
+
flyTo(center: LngLat, options?: MapCameraMove): Promise<void>
|
|
133
|
+
jumpTo(center: LngLat, options?: MapCameraMove): Promise<void>
|
|
134
|
+
/** Fit the camera to the points.
|
|
135
|
+
* @rejects noPoints */
|
|
136
|
+
fitPoints(points: LngLat[], options?: MapFitOptions): Promise<void>
|
|
137
|
+
/** The part of the view covered by the app's UI; camera moves center inside the rest. */
|
|
138
|
+
setPadding(padding: MapPadding): Promise<void>
|
|
139
|
+
/** @rejects notReady */
|
|
140
|
+
getCamera(): Promise<MapCamera>
|
|
141
|
+
|
|
142
|
+
/** Move the user puck; null hides it. */
|
|
143
|
+
setUserLocation(lngLat: LngLat | null, options?: MapUserLocationOptions): Promise<void>
|
|
144
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/push/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// push — remote notifications (APNs on iOS, FCM on Android).
|
|
4
|
+
// The host owns the OS token, the permission prompt and the registration with the le.codes relay;
|
|
5
|
+
// the app sees the opaque project-scoped ADDRESS and the payloads, never the raw token.
|
|
6
|
+
//
|
|
7
|
+
// An OPEN SESSION is the delivery pipe of the events. Opening one is free (no prompt, no I/O).
|
|
8
|
+
// Identity: every call is attributed to the world that makes it (the project's uuid, held by the
|
|
9
|
+
// host); a world without one rejects "unavailable" BEFORE any permission path.
|
|
10
|
+
//
|
|
11
|
+
// A notification reaches the JS world through this channel ALONE: a tap is the "tap" event (or
|
|
12
|
+
// `getLaunch()` for the one that started the process — the SDK's wrapper replays it into the first
|
|
13
|
+
// "tap" listener), a foreground arrival is "message". Its `url` is the app's to route — it does NOT
|
|
14
|
+
// ride the app's deep-link path (`app.launchUrl`, the "url" event).
|
|
15
|
+
|
|
16
|
+
import type { Json, Service, i32 } from "../../../plugin"
|
|
17
|
+
|
|
18
|
+
/** A delivered notification, as the app sees it. */
|
|
19
|
+
export interface PushPayload {
|
|
20
|
+
/** The push channel it was sent through — the id of the `pushChannel()` export of the project's
|
|
21
|
+
* server (`<path>#<name>`). Absent = sent outside one (a push key, `lecodes pn send`). */
|
|
22
|
+
channel?: string
|
|
23
|
+
title: string
|
|
24
|
+
body?: string
|
|
25
|
+
/** A deep link, for the app to open itself (it does not ride `app.launchUrl`). */
|
|
26
|
+
url?: string
|
|
27
|
+
/** The developer's own JSON object, ≤ 2 KB serialized. */
|
|
28
|
+
data?: { [key: string]: Json }
|
|
29
|
+
badge?: i32
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface PushStatus {
|
|
33
|
+
/** The OS permission of the host app. "prompt" = not asked yet. */
|
|
34
|
+
permission: "granted" | "denied" | "prompt"
|
|
35
|
+
/** Whether this device holds a registration (an address) for this app. */
|
|
36
|
+
registered: boolean
|
|
37
|
+
/** The device's address for this app, when it is registered. @since 2 */
|
|
38
|
+
address?: string
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface PushRegisterOptions {
|
|
42
|
+
/** The app's OWN user id. Client-asserted and unverified. The registration reflects the latest
|
|
43
|
+
* call: registering without it clears it. */
|
|
44
|
+
user?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface PushRegistration {
|
|
48
|
+
address: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/** What the app shows itself when a notification arrives while it is in the foreground (the
|
|
52
|
+
* "message" event): the host shows the system banner for every other one. */
|
|
53
|
+
export interface PushHandled {
|
|
54
|
+
/** The push channels with a foreground handler. */
|
|
55
|
+
channels: string[]
|
|
56
|
+
/** Whether notifications sent outside a channel have one. */
|
|
57
|
+
untyped: boolean
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface PushParams {}
|
|
61
|
+
|
|
62
|
+
export interface PushEvents {
|
|
63
|
+
/** Arrived while this app was in the foreground and the app handles it (PushHandled): no banner. */
|
|
64
|
+
message: PushPayload
|
|
65
|
+
/** Tapped while the world was alive. */
|
|
66
|
+
tap: PushPayload
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface Push extends Service<"push", PushParams, PushEvents> {
|
|
70
|
+
/** Permission + registration state. Never prompts. */
|
|
71
|
+
getStatus(): Promise<PushStatus>
|
|
72
|
+
/** Ask for the permission (the first time) and register this device. Idempotent.
|
|
73
|
+
* @rejects denied unavailable */
|
|
74
|
+
register(options?: PushRegisterOptions): Promise<PushRegistration>
|
|
75
|
+
/** Remove this device's registration.
|
|
76
|
+
* @rejects unavailable */
|
|
77
|
+
unregister(): Promise<void>
|
|
78
|
+
/** The notification that cold-started this world, or null. Stable across calls. */
|
|
79
|
+
getLaunch(): Promise<PushPayload | null>
|
|
80
|
+
/** Which notifications the app handles itself in the foreground; the rest get the system banner.
|
|
81
|
+
* Until it is called nothing is handled. @since 2 */
|
|
82
|
+
setMessageHandled(handled: PushHandled): Promise<void>
|
|
83
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/qr-scanner/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// qr-scanner — a camera view that decodes QR codes.
|
|
4
|
+
// A view with events only: the app opens / embeds it and listens.
|
|
5
|
+
|
|
6
|
+
import type { View } from "../../../plugin"
|
|
7
|
+
|
|
8
|
+
export interface QRScannerParams {}
|
|
9
|
+
|
|
10
|
+
export interface QRScannerEvents {
|
|
11
|
+
/** One per decoded camera frame: the payload, or null for a frame with no readable code (it
|
|
12
|
+
* repeats while the user aims). The same code may be reported more than once. */
|
|
13
|
+
scan: { data: string | null }
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface QRScanner extends View<"qrScanner", QRScannerParams, QRScannerEvents> {}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// GENERATED by scripts/vendor-plugins.ts from lecodes-plugins/plugins/speech/contract.d.ts — do not edit here.
|
|
2
|
+
// Change it in the plugin repo and run `bun run vendor:plugins`; `bun run check:plugins` fails when this copy is stale.
|
|
3
|
+
// speech — speech recognition: the microphone to text, live (dictation, voice commands).
|
|
4
|
+
// A session is ONE listening (the app-facing `SpeechRecognizer` opens one per `start()`): results
|
|
5
|
+
// arrive as events, partial ones while the user speaks and a final one after, then `end`. The
|
|
6
|
+
// permissions are the contract's (`@permission speech microphone` on start): the host asks, the
|
|
7
|
+
// halves never do.
|
|
8
|
+
//
|
|
9
|
+
// The recognizer is the platform's: Apple's (SFSpeechRecognizer: on-device where the language
|
|
10
|
+
// allows, else Apple's servers), Google's on Android (the device's RecognitionService — absent on a
|
|
11
|
+
// phone without Google's app: `start` rejects "unavailable"), the browser's on the web (Chrome sends
|
|
12
|
+
// the audio to Google; Safari to Apple). Languages and quality differ with them.
|
|
13
|
+
|
|
14
|
+
import type { Service, f64 } from "../../../plugin"
|
|
15
|
+
|
|
16
|
+
export interface SpeechOptions {
|
|
17
|
+
/** BCP-47 — "en-US", "ru-RU". Default: the device's language. */
|
|
18
|
+
language?: string
|
|
19
|
+
/** Keep listening and delivering results until `stop()`; default false: one utterance — the
|
|
20
|
+
* listening ends after a pause in the speech. */
|
|
21
|
+
continuous?: boolean
|
|
22
|
+
/** Deliver partial results while the user speaks (`isFinal` false). Default true. */
|
|
23
|
+
interimResults?: boolean
|
|
24
|
+
/** Recognize on the device only — no audio leaves it; fewer languages, and "unavailable" where
|
|
25
|
+
* the device cannot. Default false. The web ignores it. */
|
|
26
|
+
onDevice?: boolean
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface SpeechResult {
|
|
30
|
+
/** The text so far (a partial), or of the utterance (final). */
|
|
31
|
+
transcript: string
|
|
32
|
+
isFinal: boolean
|
|
33
|
+
/** 0..1 when the recognizer says; null when it does not (partials, Android). */
|
|
34
|
+
confidence: f64 | null
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type SpeechErrorCode = "noSpeech" | "audio" | "network" | "denied" | "aborted" | "unavailable" | "failed"
|
|
38
|
+
|
|
39
|
+
export interface SpeechParams {}
|
|
40
|
+
|
|
41
|
+
export interface SpeechEvents {
|
|
42
|
+
/** A result: partials while speaking (when `interimResults`), then the final one. */
|
|
43
|
+
result: SpeechResult
|
|
44
|
+
/** The user started speaking. */
|
|
45
|
+
speechStart: void
|
|
46
|
+
/** The user stopped speaking (a pause): the final result follows. */
|
|
47
|
+
speechEnd: void
|
|
48
|
+
/** The listening is over — after the final result, after `stop()` / `abort()`, after an error. */
|
|
49
|
+
end: void
|
|
50
|
+
/** The listening failed; `end` follows. "noSpeech": nothing was heard (not continuous). */
|
|
51
|
+
error: { code: SpeechErrorCode, message: string }
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export interface Speech extends Service<"speech", SpeechParams, SpeechEvents> {
|
|
55
|
+
/** Start listening. One listening per session: a second start rejects "busy". "unavailable":
|
|
56
|
+
* no recognizer on this device, or none for the language / on the device.
|
|
57
|
+
* @permission speech microphone
|
|
58
|
+
* @rejects busy unavailable failed */
|
|
59
|
+
start(options?: SpeechOptions): Promise<void>
|
|
60
|
+
/** Stop listening and finish: the final result of what was heard, then `end`. Not listening is
|
|
61
|
+
* not an error. */
|
|
62
|
+
stop(): Promise<void>
|
|
63
|
+
/** Stop and drop what was heard: `end`, no result. */
|
|
64
|
+
abort(): Promise<void>
|
|
65
|
+
/** The languages this host recognizes, BCP-47; empty when the host cannot say (the web). */
|
|
66
|
+
supportedLanguages(): Promise<string[]>
|
|
67
|
+
}
|