@pmate/bridge 0.1.4 → 0.1.6

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pmate/bridge",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "files": [
5
5
  "src",
6
6
  "global.d.ts"
@@ -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,13 +2,22 @@ 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,
13
+ getNotificationStatus,
14
+ getPushToken,
15
+ listAlarms,
16
+ onAlarmEvent,
9
17
  onBluetoothEvent,
10
18
  readBluetooth,
11
19
  requestBluetoothPermission,
20
+ scheduleAlarm,
12
21
  scanBluetoothDevices,
13
22
  stopBluetoothScan,
14
23
  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,
@@ -12,9 +15,13 @@ import type {
12
15
  BluetoothSubscribeOptions,
13
16
  BluetoothWriteOptions,
14
17
  DeviceInfo,
18
+ NotificationStatus,
15
19
  PermissionResult,
16
20
  PickedFile,
21
+ PushTokenInfo,
22
+ PushTokenOptions,
17
23
  SafeInsets,
24
+ ScheduleAlarmInput,
18
25
  } from "./types"
19
26
 
20
27
  type PmateWindow = Window & {
@@ -90,15 +97,80 @@ export async function requestPermissionsBridge(
90
97
  result ?? {
91
98
  requested: permissions,
92
99
  granted: false,
100
+ state: "unsupported",
93
101
  }
94
102
  )
95
103
  }
96
104
 
105
+ export async function getNotificationStatus(): Promise<NotificationStatus> {
106
+ const status = await callBridge<NotificationStatus>("notification.getStatus")
107
+ return (
108
+ status ?? {
109
+ supported: false,
110
+ permission: "unsupported",
111
+ providers: [],
112
+ }
113
+ )
114
+ }
115
+
116
+ export async function getPushToken(
117
+ options?: PushTokenOptions
118
+ ): Promise<PushTokenInfo | undefined> {
119
+ if (!hasWindow() || !(window as PmateWindow).PmateBridge?.call) {
120
+ return undefined
121
+ }
122
+ return requireBridge<PushTokenInfo>("notification.getPushToken", options ?? null)
123
+ }
124
+
97
125
  export async function pickFileBridge(): Promise<PickedFile[]> {
98
126
  const files = await callBridge<PickedFile[]>("pickFile")
99
127
  return files ?? []
100
128
  }
101
129
 
130
+ export async function getAlarmCapabilities(): Promise<AlarmCapabilities> {
131
+ const capabilities = await callBridge<AlarmCapabilities>("alarm.getCapabilities")
132
+ return (
133
+ capabilities ?? {
134
+ supported: false,
135
+ systemAlarm: false,
136
+ appAlarm: false,
137
+ exact: false,
138
+ repeating: false,
139
+ notificationPermission: "unsupported",
140
+ }
141
+ )
142
+ }
143
+
144
+ export function scheduleAlarm(input: ScheduleAlarmInput): Promise<Alarm> {
145
+ return requireBridge<Alarm>("alarm.schedule", input)
146
+ }
147
+
148
+ export async function getAlarm(id: string): Promise<Alarm | undefined> {
149
+ return callBridge<Alarm>("alarm.get", { id })
150
+ }
151
+
152
+ export function listAlarms(): Promise<{ alarms: Alarm[] }> {
153
+ return requireBridge<{ alarms: Alarm[] }>("alarm.list")
154
+ }
155
+
156
+ export function cancelAlarm(id: string): Promise<{ cancelled: true }> {
157
+ return requireBridge<{ cancelled: true }>("alarm.cancel", { id })
158
+ }
159
+
160
+ export function cancelAllAlarms(): Promise<{ cancelled: true }> {
161
+ return requireBridge<{ cancelled: true }>("alarm.cancelAll")
162
+ }
163
+
164
+ export function onAlarmEvent(
165
+ eventName: AlarmEventName,
166
+ handler: (payload: unknown) => void
167
+ ): () => void {
168
+ if (!hasWindow() || !(window as PmateWindow).PmateBridge?.on) {
169
+ throw new Error("Pmate bridge event subscription is unavailable")
170
+ }
171
+ return (window as PmateWindow).PmateBridge!.on!(`alarm.${eventName}`, handler)
172
+ }
173
+
102
174
  export function getBluetoothCapabilities(): Promise<BluetoothCapabilities> {
103
175
  return requireBridge<BluetoothCapabilities>("bluetooth.getCapabilities")
104
176
  }
package/src/types.ts CHANGED
@@ -32,6 +32,86 @@ export interface PickedFile {
32
32
  export interface PermissionResult {
33
33
  requested: unknown
34
34
  granted: boolean
35
+ state?: PermissionState
36
+ }
37
+
38
+ export type PermissionState = "granted" | "denied" | "notDetermined" | "unsupported"
39
+ export type NotificationPermissionState = PermissionState
40
+ export type PushProvider = "apns" | "xiaomi"
41
+
42
+ export interface NotificationStatus {
43
+ supported: boolean
44
+ permission: NotificationPermissionState
45
+ providers: PushProvider[]
46
+ }
47
+
48
+ export interface PushTokenInfo {
49
+ platform: "ios" | "android"
50
+ provider: PushProvider
51
+ token: string
52
+ environment?: "sandbox" | "production"
53
+ region?: string
54
+ bundleId?: string
55
+ packageName?: string
56
+ permission: NotificationPermissionState
57
+ vendor?: Record<string, unknown>
58
+ }
59
+
60
+ export interface PushTokenOptions {
61
+ providers?: PushProvider[]
62
+ }
63
+
64
+ export type AlarmDeliveryMode = "systemAlarm" | "appAlarm"
65
+ export type AlarmDeliveryPreference =
66
+ | "preferSystemAlarm"
67
+ | "preferAppAlarm"
68
+ | "systemAlarmOnly"
69
+ export type AlarmPermissionState =
70
+ | "granted"
71
+ | "denied"
72
+ | "notDetermined"
73
+ | "unsupported"
74
+ export type AlarmRepeatRule =
75
+ | { type: "none" }
76
+ | { type: "interval"; intervalMs: number }
77
+ | { type: "daily"; timeOfDay: string; timezone?: string }
78
+ export type AlarmState = "scheduled" | "triggered" | "cancelled"
79
+ export type AlarmEventName = "triggered" | "cancelled" | "error"
80
+
81
+ export interface AlarmCapabilities {
82
+ supported: boolean
83
+ systemAlarm: boolean
84
+ appAlarm: boolean
85
+ exact: boolean
86
+ repeating: boolean
87
+ notificationPermission: AlarmPermissionState
88
+ minimumIntervalMs?: number
89
+ maximumScheduledCount?: number
90
+ }
91
+
92
+ export interface Alarm {
93
+ id: string
94
+ title?: string
95
+ body?: string
96
+ deliveryMode: AlarmDeliveryMode
97
+ scheduledAt: number
98
+ repeat: AlarmRepeatRule
99
+ payload?: Record<string, unknown>
100
+ state: AlarmState
101
+ createdAt: number
102
+ updatedAt: number
103
+ lastTriggeredAt?: number
104
+ nextTriggerAt?: number
105
+ }
106
+
107
+ export interface ScheduleAlarmInput {
108
+ id?: string
109
+ title?: string
110
+ body?: string
111
+ scheduledAt: number
112
+ repeat?: AlarmRepeatRule
113
+ deliveryPreference?: AlarmDeliveryPreference
114
+ payload?: Record<string, unknown>
35
115
  }
36
116
 
37
117
  export type BluetoothTransport = "ble" | "classic"