@pmate/bridge 0.1.5 → 0.1.7
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/package.json +4 -4
- package/src/PmateBridgeProvider.tsx +4 -0
- package/src/context.tsx +5 -0
- package/src/hooks.ts +19 -1
- package/src/index.ts +9 -0
- package/src/internal.ts +64 -1
- package/src/types.ts +54 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pmate/bridge",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.7",
|
|
4
4
|
"files": [
|
|
5
5
|
"src",
|
|
6
6
|
"global.d.ts"
|
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
18
|
-
"@types/react": "
|
|
19
|
-
"react": "
|
|
18
|
+
"@types/react": "^19.2.7",
|
|
19
|
+
"react": "^19.1.1"
|
|
20
20
|
},
|
|
21
21
|
"main": "src/index.ts",
|
|
22
22
|
"exports": {
|
|
23
23
|
".": "./src/index.ts"
|
|
24
24
|
}
|
|
25
|
-
}
|
|
25
|
+
}
|
|
@@ -2,6 +2,8 @@ import { PropsWithChildren, ReactNode, useEffect, useMemo, useState } from "reac
|
|
|
2
2
|
import { PmateBridgeContext } from "./context"
|
|
3
3
|
import {
|
|
4
4
|
getFallbackSafeInsets,
|
|
5
|
+
getNotificationStatus,
|
|
6
|
+
getPushToken,
|
|
5
7
|
pickFileBridge,
|
|
6
8
|
readDeviceInfo,
|
|
7
9
|
readIsPmate,
|
|
@@ -84,6 +86,8 @@ export function PmateBridgeProvider({
|
|
|
84
86
|
safeInsetsState,
|
|
85
87
|
deviceInfoState,
|
|
86
88
|
requestPermissions: requestPermissionsBridge,
|
|
89
|
+
getNotificationStatus,
|
|
90
|
+
getPushToken,
|
|
87
91
|
pickFile: pickFileBridge,
|
|
88
92
|
}),
|
|
89
93
|
[deviceInfoState, isPmate, safeInsetsState]
|
package/src/context.tsx
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { createContext, useContext } from "react"
|
|
2
2
|
import type {
|
|
3
3
|
DeviceInfoState,
|
|
4
|
+
NotificationStatus,
|
|
4
5
|
PermissionResult,
|
|
5
6
|
PickedFile,
|
|
7
|
+
PushTokenInfo,
|
|
8
|
+
PushTokenOptions,
|
|
6
9
|
SafeInsetsState,
|
|
7
10
|
} from "./types"
|
|
8
11
|
|
|
@@ -11,6 +14,8 @@ export interface PmateBridgeContextValue {
|
|
|
11
14
|
safeInsetsState: SafeInsetsState
|
|
12
15
|
deviceInfoState: DeviceInfoState
|
|
13
16
|
requestPermissions: (permissions: string[]) => Promise<PermissionResult>
|
|
17
|
+
getNotificationStatus: () => Promise<NotificationStatus>
|
|
18
|
+
getPushToken: (options?: PushTokenOptions) => Promise<PushTokenInfo | undefined>
|
|
14
19
|
pickFile: () => Promise<PickedFile[]>
|
|
15
20
|
}
|
|
16
21
|
|
package/src/hooks.ts
CHANGED
|
@@ -2,13 +2,15 @@ import { useCallback, useEffect, useState } from "react"
|
|
|
2
2
|
import { useOptionalPmateBridgeContext } from "./context"
|
|
3
3
|
import {
|
|
4
4
|
getFallbackSafeInsets,
|
|
5
|
+
getNotificationStatus,
|
|
6
|
+
getPushToken,
|
|
5
7
|
pickFileBridge,
|
|
6
8
|
readDeviceInfo,
|
|
7
9
|
readIsPmate,
|
|
8
10
|
readSafeInsets,
|
|
9
11
|
requestPermissionsBridge,
|
|
10
12
|
} from "./internal"
|
|
11
|
-
import type { DeviceInfoState, SafeInsetsState } from "./types"
|
|
13
|
+
import type { DeviceInfoState, PushTokenOptions, SafeInsetsState } from "./types"
|
|
12
14
|
|
|
13
15
|
export function useIsPmate() {
|
|
14
16
|
return useOptionalPmateBridgeContext()?.isPmate ?? readIsPmate()
|
|
@@ -93,3 +95,19 @@ export function useRequestPermissions() {
|
|
|
93
95
|
[context]
|
|
94
96
|
)
|
|
95
97
|
}
|
|
98
|
+
|
|
99
|
+
export function useNotificationStatus() {
|
|
100
|
+
const context = useOptionalPmateBridgeContext()
|
|
101
|
+
return useCallback(
|
|
102
|
+
() => context?.getNotificationStatus() ?? getNotificationStatus(),
|
|
103
|
+
[context]
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export function useGetPushToken() {
|
|
108
|
+
const context = useOptionalPmateBridgeContext()
|
|
109
|
+
return useCallback(
|
|
110
|
+
(options?: PushTokenOptions) => context?.getPushToken(options) ?? getPushToken(options),
|
|
111
|
+
[context]
|
|
112
|
+
)
|
|
113
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -2,15 +2,24 @@ export * from "./PmateBridgeProvider"
|
|
|
2
2
|
export * from "./SafeAreaVarsProvider"
|
|
3
3
|
export * from "./hooks"
|
|
4
4
|
export {
|
|
5
|
+
cancelAlarm,
|
|
6
|
+
cancelAllAlarms,
|
|
5
7
|
connectBluetoothDevice,
|
|
6
8
|
disconnectBluetoothDevice,
|
|
9
|
+
getAlarm,
|
|
10
|
+
getAlarmCapabilities,
|
|
7
11
|
getBluetoothCapabilities,
|
|
8
12
|
getConnectedBluetoothDevices,
|
|
9
13
|
getNotificationStatus,
|
|
10
14
|
getPushToken,
|
|
15
|
+
isAndroidDevice,
|
|
16
|
+
isIOSDevice,
|
|
17
|
+
listAlarms,
|
|
18
|
+
onAlarmEvent,
|
|
11
19
|
onBluetoothEvent,
|
|
12
20
|
readBluetooth,
|
|
13
21
|
requestBluetoothPermission,
|
|
22
|
+
scheduleAlarm,
|
|
14
23
|
scanBluetoothDevices,
|
|
15
24
|
stopBluetoothScan,
|
|
16
25
|
subscribeBluetooth,
|
package/src/internal.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import type {
|
|
2
|
+
Alarm,
|
|
3
|
+
AlarmCapabilities,
|
|
4
|
+
AlarmEventName,
|
|
2
5
|
BluetoothCapabilities,
|
|
3
6
|
BluetoothConnectOptions,
|
|
4
7
|
BluetoothConnection,
|
|
@@ -18,6 +21,7 @@ import type {
|
|
|
18
21
|
PushTokenInfo,
|
|
19
22
|
PushTokenOptions,
|
|
20
23
|
SafeInsets,
|
|
24
|
+
ScheduleAlarmInput,
|
|
21
25
|
} from "./types"
|
|
22
26
|
|
|
23
27
|
type PmateWindow = Window & {
|
|
@@ -43,6 +47,18 @@ export function readIsPmate() {
|
|
|
43
47
|
return hasWindow() && !!(window as PmateWindow).isPmate
|
|
44
48
|
}
|
|
45
49
|
|
|
50
|
+
function normalizedPlatform(info?: Pick<DeviceInfo, "platform"> | null) {
|
|
51
|
+
return info?.platform?.trim().toLowerCase() ?? ""
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function isAndroidDevice(info?: Pick<DeviceInfo, "platform"> | null) {
|
|
55
|
+
return normalizedPlatform(info) === "android"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function isIOSDevice(info?: Pick<DeviceInfo, "platform"> | null) {
|
|
59
|
+
return normalizedPlatform(info) === "ios"
|
|
60
|
+
}
|
|
61
|
+
|
|
46
62
|
async function callBridge<T>(functionName: string, params?: unknown): Promise<T | undefined> {
|
|
47
63
|
try {
|
|
48
64
|
return await (window as PmateWindow).PmateBridge?.call<T>(functionName, params)
|
|
@@ -112,7 +128,10 @@ export async function getNotificationStatus(): Promise<NotificationStatus> {
|
|
|
112
128
|
export async function getPushToken(
|
|
113
129
|
options?: PushTokenOptions
|
|
114
130
|
): Promise<PushTokenInfo | undefined> {
|
|
115
|
-
|
|
131
|
+
if (!hasWindow() || !(window as PmateWindow).PmateBridge?.call) {
|
|
132
|
+
return undefined
|
|
133
|
+
}
|
|
134
|
+
return requireBridge<PushTokenInfo>("notification.getPushToken", options ?? null)
|
|
116
135
|
}
|
|
117
136
|
|
|
118
137
|
export async function pickFileBridge(): Promise<PickedFile[]> {
|
|
@@ -120,6 +139,50 @@ export async function pickFileBridge(): Promise<PickedFile[]> {
|
|
|
120
139
|
return files ?? []
|
|
121
140
|
}
|
|
122
141
|
|
|
142
|
+
export async function getAlarmCapabilities(): Promise<AlarmCapabilities> {
|
|
143
|
+
const capabilities = await callBridge<AlarmCapabilities>("alarm.getCapabilities")
|
|
144
|
+
return (
|
|
145
|
+
capabilities ?? {
|
|
146
|
+
supported: false,
|
|
147
|
+
systemAlarm: false,
|
|
148
|
+
appAlarm: false,
|
|
149
|
+
exact: false,
|
|
150
|
+
repeating: false,
|
|
151
|
+
notificationPermission: "unsupported",
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export function scheduleAlarm(input: ScheduleAlarmInput): Promise<Alarm> {
|
|
157
|
+
return requireBridge<Alarm>("alarm.schedule", input)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export async function getAlarm(id: string): Promise<Alarm | undefined> {
|
|
161
|
+
return callBridge<Alarm>("alarm.get", { id })
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
export function listAlarms(): Promise<{ alarms: Alarm[] }> {
|
|
165
|
+
return requireBridge<{ alarms: Alarm[] }>("alarm.list")
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export function cancelAlarm(id: string): Promise<{ cancelled: true }> {
|
|
169
|
+
return requireBridge<{ cancelled: true }>("alarm.cancel", { id })
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export function cancelAllAlarms(): Promise<{ cancelled: true }> {
|
|
173
|
+
return requireBridge<{ cancelled: true }>("alarm.cancelAll")
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export function onAlarmEvent(
|
|
177
|
+
eventName: AlarmEventName,
|
|
178
|
+
handler: (payload: unknown) => void
|
|
179
|
+
): () => void {
|
|
180
|
+
if (!hasWindow() || !(window as PmateWindow).PmateBridge?.on) {
|
|
181
|
+
throw new Error("Pmate bridge event subscription is unavailable")
|
|
182
|
+
}
|
|
183
|
+
return (window as PmateWindow).PmateBridge!.on!(`alarm.${eventName}`, handler)
|
|
184
|
+
}
|
|
185
|
+
|
|
123
186
|
export function getBluetoothCapabilities(): Promise<BluetoothCapabilities> {
|
|
124
187
|
return requireBridge<BluetoothCapabilities>("bluetooth.getCapabilities")
|
|
125
188
|
}
|
package/src/types.ts
CHANGED
|
@@ -17,6 +17,7 @@ export interface DeviceInfo {
|
|
|
17
17
|
systemVersion: string
|
|
18
18
|
model: string
|
|
19
19
|
idiom: string
|
|
20
|
+
manufacturer?: string
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
export interface DeviceInfoState {
|
|
@@ -61,6 +62,59 @@ export interface PushTokenOptions {
|
|
|
61
62
|
providers?: PushProvider[]
|
|
62
63
|
}
|
|
63
64
|
|
|
65
|
+
export type AlarmDeliveryMode = "systemAlarm" | "appAlarm"
|
|
66
|
+
export type AlarmDeliveryPreference =
|
|
67
|
+
| "preferSystemAlarm"
|
|
68
|
+
| "preferAppAlarm"
|
|
69
|
+
| "systemAlarmOnly"
|
|
70
|
+
export type AlarmPermissionState =
|
|
71
|
+
| "granted"
|
|
72
|
+
| "denied"
|
|
73
|
+
| "notDetermined"
|
|
74
|
+
| "unsupported"
|
|
75
|
+
export type AlarmRepeatRule =
|
|
76
|
+
| { type: "none" }
|
|
77
|
+
| { type: "interval"; intervalMs: number }
|
|
78
|
+
| { type: "daily"; timeOfDay: string; timezone?: string }
|
|
79
|
+
export type AlarmState = "scheduled" | "triggered" | "cancelled"
|
|
80
|
+
export type AlarmEventName = "triggered" | "cancelled" | "error"
|
|
81
|
+
|
|
82
|
+
export interface AlarmCapabilities {
|
|
83
|
+
supported: boolean
|
|
84
|
+
systemAlarm: boolean
|
|
85
|
+
appAlarm: boolean
|
|
86
|
+
exact: boolean
|
|
87
|
+
repeating: boolean
|
|
88
|
+
notificationPermission: AlarmPermissionState
|
|
89
|
+
minimumIntervalMs?: number
|
|
90
|
+
maximumScheduledCount?: number
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export interface Alarm {
|
|
94
|
+
id: string
|
|
95
|
+
title?: string
|
|
96
|
+
body?: string
|
|
97
|
+
deliveryMode: AlarmDeliveryMode
|
|
98
|
+
scheduledAt: number
|
|
99
|
+
repeat: AlarmRepeatRule
|
|
100
|
+
payload?: Record<string, unknown>
|
|
101
|
+
state: AlarmState
|
|
102
|
+
createdAt: number
|
|
103
|
+
updatedAt: number
|
|
104
|
+
lastTriggeredAt?: number
|
|
105
|
+
nextTriggerAt?: number
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
export interface ScheduleAlarmInput {
|
|
109
|
+
id?: string
|
|
110
|
+
title?: string
|
|
111
|
+
body?: string
|
|
112
|
+
scheduledAt: number
|
|
113
|
+
repeat?: AlarmRepeatRule
|
|
114
|
+
deliveryPreference?: AlarmDeliveryPreference
|
|
115
|
+
payload?: Record<string, unknown>
|
|
116
|
+
}
|
|
117
|
+
|
|
64
118
|
export type BluetoothTransport = "ble" | "classic"
|
|
65
119
|
export type BluetoothBinaryEncoding = "base64" | "hex" | "utf-8"
|
|
66
120
|
export type BluetoothEventName =
|