@swiftbrowser/native 0.17.7 → 0.17.8
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 +79 -2
- package/dist/blob.d.ts +60 -0
- package/dist/blob.d.ts.map +1 -0
- package/dist/blob.js +153 -0
- package/dist/blob.js.map +1 -0
- package/dist/bridge.d.ts +39 -1
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js.map +1 -1
- package/dist/fetch.d.ts +11 -3
- package/dist/fetch.d.ts.map +1 -1
- package/dist/fetch.js +26 -2
- package/dist/fetch.js.map +1 -1
- package/dist/hostRequests.d.ts +49 -0
- package/dist/hostRequests.d.ts.map +1 -0
- package/dist/hostRequests.js +134 -0
- package/dist/hostRequests.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/dist/matchMedia.d.ts +43 -0
- package/dist/matchMedia.d.ts.map +1 -0
- package/dist/matchMedia.js +63 -0
- package/dist/matchMedia.js.map +1 -0
- package/dist/notifications.d.ts +108 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +251 -0
- package/dist/notifications.js.map +1 -0
- package/dist/run.d.ts.map +1 -1
- package/dist/run.js +9 -1
- package/dist/run.js.map +1 -1
- package/dist/runtime.d.ts +1 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +58 -0
- package/dist/runtime.js.map +1 -1
- package/dist/secureStorage.d.ts +20 -0
- package/dist/secureStorage.d.ts.map +1 -0
- package/dist/secureStorage.js +28 -0
- package/dist/secureStorage.js.map +1 -0
- package/dist/subtle.d.ts +38 -0
- package/dist/subtle.d.ts.map +1 -0
- package/dist/subtle.js +72 -0
- package/dist/subtle.js.map +1 -0
- package/dist/webSocket.d.ts +73 -0
- package/dist/webSocket.d.ts.map +1 -0
- package/dist/webSocket.js +145 -0
- package/dist/webSocket.js.map +1 -0
- package/package.json +3 -3
- package/src/blob.ts +186 -0
- package/src/bridge.ts +49 -1
- package/src/fetch.ts +29 -3
- package/src/hostRequests.ts +148 -0
- package/src/index.ts +7 -0
- package/src/matchMedia.ts +79 -0
- package/src/notifications.ts +317 -0
- package/src/run.ts +10 -1
- package/src/runtime.ts +60 -0
- package/src/secureStorage.ts +39 -0
- package/src/subtle.ts +87 -0
- package/src/webSocket.ts +175 -0
- package/swift/Sources/SwiftBrowserNative/Host/HostBridge.swift +166 -0
- package/swift/Sources/SwiftBrowserNative/Host/HostRequestBridge.swift +437 -0
- package/swift/Sources/SwiftBrowserNative/Host/NotificationBridge.swift +304 -0
- package/swift/Sources/SwiftBrowserNative/Host/SecureStorage.swift +60 -0
- package/swift/Sources/SwiftBrowserNative/Host/ShimAliases.swift +1 -0
- package/swift/Sources/SwiftBrowserNative/Host/WebSocketBridge.swift +118 -0
- package/swift/Sources/SwiftBrowserNative/Runtime/NativeApp.swift +26 -0
- package/swift/Sources/SwiftBrowserNative/Runtime/NativeAppDelegate.swift +36 -0
- package/swift/Sources/SwiftBrowserNative/Views/Kinds/Controls.swift +16 -5
- package/wasm/SwiftBrowserNative.wasm +2 -2
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host requests `@swiftbrowser/react` sends to the browser environment
|
|
3
|
+
* (`ShareLink`, `fileImporter`, the clipboard, a color chooser: the web
|
|
4
|
+
* renderer's `performHostRequest` with its `browserEnvironment`), answered by
|
|
5
|
+
* the native app instead: the bridge's `hostRequest(id, kind, json)` performs
|
|
6
|
+
* one with UIKit (a share sheet, the photo or document picker, the
|
|
7
|
+
* pasteboard, the color picker, `ASWebAuthenticationSession`), answering
|
|
8
|
+
* `__sbHostResponse(id, { value } | { error })`. `installHostEnvironment`
|
|
9
|
+
* fills the environment's gaps with these, leaving what the page has (the
|
|
10
|
+
* round trip runs in a browser with a share sheet of its own).
|
|
11
|
+
*
|
|
12
|
+
* `webAuthenticate` is the sign-in window apps open for OAuth: the system's
|
|
13
|
+
* sheet, resolving with the callback URL.
|
|
14
|
+
*/
|
|
15
|
+
import type { NativeBridge } from './bridge';
|
|
16
|
+
export type HostRequestBridge = Required<Pick<NativeBridge, 'hostRequest'>>;
|
|
17
|
+
/** A file as it crosses the bridge: its name, MIME type and bytes (base64). */
|
|
18
|
+
export interface BridgedFile {
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
data: string;
|
|
22
|
+
}
|
|
23
|
+
export interface WebAuthenticateOptions {
|
|
24
|
+
/** The scheme of the callback URL the sign-in ends with (`myapp` for `myapp://auth`); universal links need none. */
|
|
25
|
+
callbackScheme?: string;
|
|
26
|
+
/** Whether the session shares no cookies with the system browser. */
|
|
27
|
+
ephemeral?: boolean;
|
|
28
|
+
}
|
|
29
|
+
/** Points the requests at the bridge (the runtime, once per install). */
|
|
30
|
+
export declare function installHostRequests(native: HostRequestBridge): void;
|
|
31
|
+
/** The bridge's `__sbHostResponse(id, result)`. */
|
|
32
|
+
export declare function receiveHostResponse(id: number, result: string | {
|
|
33
|
+
value?: unknown;
|
|
34
|
+
error?: string;
|
|
35
|
+
}): void;
|
|
36
|
+
/** Performs one request of `kind` with `params`; resolves with the host's value. */
|
|
37
|
+
export declare function hostRequest<T = unknown>(kind: string, params: Record<string, unknown>): Promise<T>;
|
|
38
|
+
/** Forgets the bridge and the waiting requests, for tests. */
|
|
39
|
+
export declare function resetHostRequests(): void;
|
|
40
|
+
/**
|
|
41
|
+
* Opens the system's sign-in sheet at `url` and resolves with the callback
|
|
42
|
+
* URL it ends with; rejects with an `AbortError` when the viewer closes it.
|
|
43
|
+
*/
|
|
44
|
+
export declare function webAuthenticate(url: string, options?: WebAuthenticateOptions): Promise<string>;
|
|
45
|
+
/** The environment fields the host answers, shaped as the web renderer's `HostRequestEnvironment`. */
|
|
46
|
+
export declare function nativeHostEnvironment(): Record<string, unknown>;
|
|
47
|
+
/** Fills what `environment` lacks with the host's answers; what the page has stays. */
|
|
48
|
+
export declare function installHostEnvironment(environment: Record<string, unknown>): void;
|
|
49
|
+
//# sourceMappingURL=hostRequests.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostRequests.d.ts","sourceRoot":"","sources":["../src/hostRequests.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;AAE5E,+EAA+E;AAC/E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,oHAAoH;IACpH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAMD,yEAAyE;AACzE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CAEnE;AAED,mDAAmD;AACnD,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAkB1G;AAED,oFAAoF;AACpF,wBAAgB,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAUlG;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,IAAI,IAAI,CAIxC;AAWD;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,MAAM,CAAC,CAOxG;AAED,sGAAsG;AACtG,wBAAgB,qBAAqB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA+B/D;AAED,uFAAuF;AACvF,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKjF"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host requests `@swiftbrowser/react` sends to the browser environment
|
|
3
|
+
* (`ShareLink`, `fileImporter`, the clipboard, a color chooser: the web
|
|
4
|
+
* renderer's `performHostRequest` with its `browserEnvironment`), answered by
|
|
5
|
+
* the native app instead: the bridge's `hostRequest(id, kind, json)` performs
|
|
6
|
+
* one with UIKit (a share sheet, the photo or document picker, the
|
|
7
|
+
* pasteboard, the color picker, `ASWebAuthenticationSession`), answering
|
|
8
|
+
* `__sbHostResponse(id, { value } | { error })`. `installHostEnvironment`
|
|
9
|
+
* fills the environment's gaps with these, leaving what the page has (the
|
|
10
|
+
* round trip runs in a browser with a share sheet of its own).
|
|
11
|
+
*
|
|
12
|
+
* `webAuthenticate` is the sign-in window apps open for OAuth: the system's
|
|
13
|
+
* sheet, resolving with the callback URL.
|
|
14
|
+
*/
|
|
15
|
+
import { objectURL, SimpleBlob, SimpleFile } from './blob';
|
|
16
|
+
import { base64Decode, base64Encode } from './encoding';
|
|
17
|
+
let bridge = null;
|
|
18
|
+
let nextId = 1;
|
|
19
|
+
const pending = new Map();
|
|
20
|
+
/** Points the requests at the bridge (the runtime, once per install). */
|
|
21
|
+
export function installHostRequests(native) {
|
|
22
|
+
bridge = native;
|
|
23
|
+
}
|
|
24
|
+
/** The bridge's `__sbHostResponse(id, result)`. */
|
|
25
|
+
export function receiveHostResponse(id, result) {
|
|
26
|
+
const waiting = pending.get(id);
|
|
27
|
+
if (!waiting)
|
|
28
|
+
return;
|
|
29
|
+
pending.delete(id);
|
|
30
|
+
let parsed;
|
|
31
|
+
try {
|
|
32
|
+
parsed = typeof result === 'string' ? JSON.parse(result) : result;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
waiting.reject(new Error('host: malformed response'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (typeof parsed.error === 'string') {
|
|
39
|
+
const error = new Error(parsed.error);
|
|
40
|
+
if (parsed.error.startsWith('cancelled'))
|
|
41
|
+
error.name = 'AbortError';
|
|
42
|
+
waiting.reject(error);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
waiting.resolve(parsed.value);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Performs one request of `kind` with `params`; resolves with the host's value. */
|
|
49
|
+
export function hostRequest(kind, params) {
|
|
50
|
+
return new Promise((resolve, reject) => {
|
|
51
|
+
if (!bridge) {
|
|
52
|
+
reject(new Error(`unsupported: no native host for ${kind}`));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const id = nextId++;
|
|
56
|
+
pending.set(id, { resolve: resolve, reject });
|
|
57
|
+
bridge.hostRequest(id, kind, JSON.stringify(params));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/** Forgets the bridge and the waiting requests, for tests. */
|
|
61
|
+
export function resetHostRequests() {
|
|
62
|
+
bridge = null;
|
|
63
|
+
pending.clear();
|
|
64
|
+
nextId = 1;
|
|
65
|
+
}
|
|
66
|
+
async function bridgedFile(file) {
|
|
67
|
+
return { name: file.name ?? 'file', type: file.type, data: base64Encode(file.bytes()) };
|
|
68
|
+
}
|
|
69
|
+
function filesOf(value) {
|
|
70
|
+
const files = value?.files ?? [];
|
|
71
|
+
return files.map((file) => new SimpleFile([base64Decode(file.data)], file.name, { type: file.type }));
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Opens the system's sign-in sheet at `url` and resolves with the callback
|
|
75
|
+
* URL it ends with; rejects with an `AbortError` when the viewer closes it.
|
|
76
|
+
*/
|
|
77
|
+
export async function webAuthenticate(url, options = {}) {
|
|
78
|
+
const params = { action: 'start', url };
|
|
79
|
+
if (options.callbackScheme)
|
|
80
|
+
params['callbackScheme'] = options.callbackScheme;
|
|
81
|
+
if (options.ephemeral !== undefined)
|
|
82
|
+
params['ephemeral'] = options.ephemeral;
|
|
83
|
+
const result = await hostRequest('webAuth', params);
|
|
84
|
+
if (typeof result?.url !== 'string')
|
|
85
|
+
throw new Error('webAuth: the sign-in ended without a URL');
|
|
86
|
+
return result.url;
|
|
87
|
+
}
|
|
88
|
+
/** The environment fields the host answers, shaped as the web renderer's `HostRequestEnvironment`. */
|
|
89
|
+
export function nativeHostEnvironment() {
|
|
90
|
+
return {
|
|
91
|
+
share: async (data) => {
|
|
92
|
+
const params = {};
|
|
93
|
+
if (data.title)
|
|
94
|
+
params['title'] = data.title;
|
|
95
|
+
if (data.text)
|
|
96
|
+
params['text'] = data.text;
|
|
97
|
+
if (data.url)
|
|
98
|
+
params['url'] = data.url;
|
|
99
|
+
if (data.files?.length)
|
|
100
|
+
params['files'] = await Promise.all(data.files.map(bridgedFile));
|
|
101
|
+
const result = await hostRequest('share', params);
|
|
102
|
+
if (result?.outcome === 'cancelled') {
|
|
103
|
+
const error = new Error('cancelled: the viewer closed the share sheet');
|
|
104
|
+
error.name = 'AbortError';
|
|
105
|
+
throw error;
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
canShare: () => true,
|
|
109
|
+
download: (blob, filename) => {
|
|
110
|
+
void hostRequest('share', { files: [{ name: filename, type: blob.type, data: base64Encode(blob.bytes()) }] }).catch(() => undefined);
|
|
111
|
+
},
|
|
112
|
+
pickFiles: async (options) => filesOf(await hostRequest('pickFiles', { accept: options.accept, multiple: options.multiple })),
|
|
113
|
+
objectURL: (file) => objectURL(file),
|
|
114
|
+
clipboard: {
|
|
115
|
+
writeText: (text) => hostRequest('clipboard', { action: 'write', text }).then(() => undefined),
|
|
116
|
+
writeImage: async (png) => {
|
|
117
|
+
const file = await png;
|
|
118
|
+
await hostRequest('clipboard', { action: 'write', files: [{ name: 'image.png', type: file.type || 'image/png', data: base64Encode(file.bytes()) }] });
|
|
119
|
+
},
|
|
120
|
+
readText: async () => (await hostRequest('clipboard', { action: 'readText' }))?.text ?? '',
|
|
121
|
+
},
|
|
122
|
+
pickColor: async (color) => (await hostRequest('pickColor', { color }))?.color ?? null,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/** Fills what `environment` lacks with the host's answers; what the page has stays. */
|
|
126
|
+
export function installHostEnvironment(environment) {
|
|
127
|
+
if (!bridge)
|
|
128
|
+
return;
|
|
129
|
+
for (const [key, value] of Object.entries(nativeHostEnvironment())) {
|
|
130
|
+
if (environment[key] === undefined)
|
|
131
|
+
environment[key] = value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=hostRequests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostRequests.js","sourceRoot":"","sources":["../src/hostRequests.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -16,8 +16,15 @@ export { installRuntime, type InstallOptions } from './runtime';
|
|
|
16
16
|
export { nativeBridge, launchArguments, type NativeBridge, type NativeFetchRequest, type NativeFetchResult, type WorkerEngine } from './bridge';
|
|
17
17
|
export { SimpleHeaders, SimpleRequest, SimpleResponse, SimpleAbortController, SimpleAbortSignal, createFetch } from './fetch';
|
|
18
18
|
export { SimpleURL, SimpleURLSearchParams } from './url';
|
|
19
|
+
export { SimpleBlob, SimpleFile, SimpleFormData, encodeMultipart, objectURL } from './blob';
|
|
20
|
+
export { NativeWebSocket, type NativeWebSocketEvent } from './webSocket';
|
|
21
|
+
export { createSubtleCrypto } from './subtle';
|
|
22
|
+
export { matchMedia, updateMediaEnvironment, type MediaEnvironment } from './matchMedia';
|
|
23
|
+
export { hostRequest, webAuthenticate, nativeHostEnvironment, installHostEnvironment, type WebAuthenticateOptions, type BridgedFile } from './hostRequests';
|
|
24
|
+
export { secureStorage, createSecureStorage, type SecureStorage } from './secureStorage';
|
|
19
25
|
export { SimpleTextEncoder, SimpleTextDecoder, base64Encode, base64Decode, utf8Encode, utf8Decode } from './encoding';
|
|
20
26
|
export { createWorker, NativeWorker, encodeMessage, decodeMessage, workerName, type NativeWorkerOptions, type WorkerLike, type WorkerMessageEvent, type WorkerErrorEvent } from './worker';
|
|
21
27
|
export { onOpenURL } from './openURL';
|
|
28
|
+
export { onNotification, registerForPush, type NotificationEvent, type NativeNotificationOptions, type RegisterForPushOptions } from './notifications';
|
|
22
29
|
export { createMediaSession, NativeMediaMetadata, type NativeMediaSession, type MediaMetadataInit, type MediaActionDetails, type MediaActionHandler, type MediaPositionState } from './mediaSession';
|
|
23
30
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAChJ,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,mBAAmB,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC3L,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAE,KAAK,UAAU,EAAE,KAAK,OAAO,EAAE,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,YAAY,EAAE,MAAM,UAAU,CAAC;AAChJ,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,KAAK,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,KAAK,sBAAsB,EAAE,KAAK,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC5J,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,KAAK,mBAAmB,EAAE,KAAK,UAAU,EAAE,KAAK,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC3L,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,KAAK,yBAAyB,EAAE,KAAK,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACvJ,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -16,8 +16,15 @@ export { installRuntime } from './runtime';
|
|
|
16
16
|
export { nativeBridge, launchArguments } from './bridge';
|
|
17
17
|
export { SimpleHeaders, SimpleRequest, SimpleResponse, SimpleAbortController, SimpleAbortSignal, createFetch } from './fetch';
|
|
18
18
|
export { SimpleURL, SimpleURLSearchParams } from './url';
|
|
19
|
+
export { SimpleBlob, SimpleFile, SimpleFormData, encodeMultipart, objectURL } from './blob';
|
|
20
|
+
export { NativeWebSocket } from './webSocket';
|
|
21
|
+
export { createSubtleCrypto } from './subtle';
|
|
22
|
+
export { matchMedia, updateMediaEnvironment } from './matchMedia';
|
|
23
|
+
export { hostRequest, webAuthenticate, nativeHostEnvironment, installHostEnvironment } from './hostRequests';
|
|
24
|
+
export { secureStorage, createSecureStorage } from './secureStorage';
|
|
19
25
|
export { SimpleTextEncoder, SimpleTextDecoder, base64Encode, base64Decode, utf8Encode, utf8Decode } from './encoding';
|
|
20
26
|
export { createWorker, NativeWorker, encodeMessage, decodeMessage, workerName } from './worker';
|
|
21
27
|
export { onOpenURL } from './openURL';
|
|
28
|
+
export { onNotification, registerForPush } from './notifications';
|
|
22
29
|
export { createMediaSession, NativeMediaMetadata } from './mediaSession';
|
|
23
30
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAiC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAoB,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAyF,MAAM,UAAU,CAAC;AAChJ,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAA6F,MAAM,UAAU,CAAC;AAC3L,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAA8H,MAAM,gBAAgB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,GAAG,EAAiC,MAAM,OAAO,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAoB,MAAM,UAAU,CAAC;AACpD,OAAO,EAAE,cAAc,EAAuB,MAAM,WAAW,CAAC;AAChE,OAAO,EAAE,YAAY,EAAE,eAAe,EAAyF,MAAM,UAAU,CAAC;AAChJ,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC9H,OAAO,EAAE,SAAS,EAAE,qBAAqB,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC5F,OAAO,EAAE,eAAe,EAA6B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAyB,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAiD,MAAM,gBAAgB,CAAC;AAC5J,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAsB,MAAM,iBAAiB,CAAC;AACzF,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtH,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAA6F,MAAM,UAAU,CAAC;AAC3L,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,eAAe,EAAuF,MAAM,iBAAiB,CAAC;AACvJ,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAA8H,MAAM,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `matchMedia` for the native app: `(prefers-color-scheme: dark)` and
|
|
3
|
+
* `light` follow the color scheme the host sends with the environment
|
|
4
|
+
* (run.ts hands it over), `(prefers-reduced-motion: reduce)` the host's
|
|
5
|
+
* accessibility setting when it sends one; every other query matches
|
|
6
|
+
* nothing. Listeners hear a change when the environment does.
|
|
7
|
+
*/
|
|
8
|
+
export interface MediaQueryListLike {
|
|
9
|
+
readonly media: string;
|
|
10
|
+
readonly matches: boolean;
|
|
11
|
+
onchange: ((event: {
|
|
12
|
+
matches: boolean;
|
|
13
|
+
media: string;
|
|
14
|
+
}) => void) | null;
|
|
15
|
+
addEventListener(type: 'change', listener: (event: {
|
|
16
|
+
matches: boolean;
|
|
17
|
+
media: string;
|
|
18
|
+
}) => void): void;
|
|
19
|
+
removeEventListener(type: 'change', listener: (event: {
|
|
20
|
+
matches: boolean;
|
|
21
|
+
media: string;
|
|
22
|
+
}) => void): void;
|
|
23
|
+
/** The older names. */
|
|
24
|
+
addListener(listener: (event: {
|
|
25
|
+
matches: boolean;
|
|
26
|
+
media: string;
|
|
27
|
+
}) => void): void;
|
|
28
|
+
removeListener(listener: (event: {
|
|
29
|
+
matches: boolean;
|
|
30
|
+
media: string;
|
|
31
|
+
}) => void): void;
|
|
32
|
+
}
|
|
33
|
+
export interface MediaEnvironment {
|
|
34
|
+
colorScheme?: 'light' | 'dark';
|
|
35
|
+
reducedMotion?: boolean;
|
|
36
|
+
}
|
|
37
|
+
/** The runtime's `matchMedia(query)`. */
|
|
38
|
+
export declare function matchMedia(query: string): MediaQueryListLike;
|
|
39
|
+
/** What the host sent with the environment; lists whose answer changed tell their listeners. */
|
|
40
|
+
export declare function updateMediaEnvironment(next: MediaEnvironment): void;
|
|
41
|
+
/** Forgets the environment and the lists, for tests. */
|
|
42
|
+
export declare function resetMediaEnvironment(): void;
|
|
43
|
+
//# sourceMappingURL=matchMedia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchMedia.d.ts","sourceRoot":"","sources":["../src/matchMedia.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACxE,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IACvG,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,uBAAuB;IACvB,WAAW,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;IAClF,cAAc,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CACtF;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAgBD,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,kBAAkB,CAoB5D;AAED,gGAAgG;AAChG,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAUnE;AAED,wDAAwD;AACxD,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `matchMedia` for the native app: `(prefers-color-scheme: dark)` and
|
|
3
|
+
* `light` follow the color scheme the host sends with the environment
|
|
4
|
+
* (run.ts hands it over), `(prefers-reduced-motion: reduce)` the host's
|
|
5
|
+
* accessibility setting when it sends one; every other query matches
|
|
6
|
+
* nothing. Listeners hear a change when the environment does.
|
|
7
|
+
*/
|
|
8
|
+
let environment = {};
|
|
9
|
+
const lists = new Set();
|
|
10
|
+
function evaluate(query) {
|
|
11
|
+
const normalized = query.trim().toLowerCase().replace(/\s+/g, '');
|
|
12
|
+
if (normalized === '(prefers-color-scheme:dark)')
|
|
13
|
+
return environment.colorScheme === 'dark';
|
|
14
|
+
if (normalized === '(prefers-color-scheme:light)')
|
|
15
|
+
return environment.colorScheme !== 'dark';
|
|
16
|
+
if (normalized === '(prefers-reduced-motion:reduce)')
|
|
17
|
+
return environment.reducedMotion === true;
|
|
18
|
+
if (normalized === '(prefers-reduced-motion:no-preference)')
|
|
19
|
+
return environment.reducedMotion !== true;
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
/** The runtime's `matchMedia(query)`. */
|
|
23
|
+
export function matchMedia(query) {
|
|
24
|
+
const media = String(query);
|
|
25
|
+
const state = { media, matches: evaluate(media), listeners: new Set(), onchange: null };
|
|
26
|
+
lists.add(state);
|
|
27
|
+
return {
|
|
28
|
+
media,
|
|
29
|
+
get matches() {
|
|
30
|
+
return state.matches;
|
|
31
|
+
},
|
|
32
|
+
get onchange() {
|
|
33
|
+
return state.onchange;
|
|
34
|
+
},
|
|
35
|
+
set onchange(listener) {
|
|
36
|
+
state.onchange = listener;
|
|
37
|
+
},
|
|
38
|
+
addEventListener: (_type, listener) => void state.listeners.add(listener),
|
|
39
|
+
removeEventListener: (_type, listener) => void state.listeners.delete(listener),
|
|
40
|
+
addListener: (listener) => void state.listeners.add(listener),
|
|
41
|
+
removeListener: (listener) => void state.listeners.delete(listener),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/** What the host sent with the environment; lists whose answer changed tell their listeners. */
|
|
45
|
+
export function updateMediaEnvironment(next) {
|
|
46
|
+
environment = { ...environment, ...next };
|
|
47
|
+
for (const state of lists) {
|
|
48
|
+
const matches = evaluate(state.media);
|
|
49
|
+
if (matches === state.matches)
|
|
50
|
+
continue;
|
|
51
|
+
state.matches = matches;
|
|
52
|
+
const event = { matches, media: state.media };
|
|
53
|
+
state.onchange?.(event);
|
|
54
|
+
for (const listener of state.listeners)
|
|
55
|
+
listener(event);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** Forgets the environment and the lists, for tests. */
|
|
59
|
+
export function resetMediaEnvironment() {
|
|
60
|
+
environment = {};
|
|
61
|
+
lists.clear();
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=matchMedia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matchMedia.js","sourceRoot":"","sources":["../src/matchMedia.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAoBH,IAAI,WAAW,GAAqB,EAAE,CAAC;AACvC,MAAM,KAAK,GAAG,IAAI,GAAG,EAA4F,CAAC;AAElH,SAAS,QAAQ,CAAC,KAAa;IAC7B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClE,IAAI,UAAU,KAAK,6BAA6B;QAAE,OAAO,WAAW,CAAC,WAAW,KAAK,MAAM,CAAC;IAC5F,IAAI,UAAU,KAAK,8BAA8B;QAAE,OAAO,WAAW,CAAC,WAAW,KAAK,MAAM,CAAC;IAC7F,IAAI,UAAU,KAAK,iCAAiC;QAAE,OAAO,WAAW,CAAC,aAAa,KAAK,IAAI,CAAC;IAChG,IAAI,UAAU,KAAK,wCAAwC;QAAE,OAAO,WAAW,CAAC,aAAa,KAAK,IAAI,CAAC;IACvG,OAAO,KAAK,CAAC;AACf,CAAC;AAED,yCAAyC;AACzC,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,IAAI,GAAG,EAAY,EAAE,QAAQ,EAAE,IAAuB,EAAE,CAAC;IACrH,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO;QACL,KAAK;QACL,IAAI,OAAO;YACT,OAAO,KAAK,CAAC,OAAO,CAAC;QACvB,CAAC;QACD,IAAI,QAAQ;YACV,OAAO,KAAK,CAAC,QAAQ,CAAC;QACxB,CAAC;QACD,IAAI,QAAQ,CAAC,QAAQ;YACnB,KAAK,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAC5B,CAAC;QACD,gBAAgB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;QACzE,mBAAmB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC/E,WAAW,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC7D,cAAc,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC;KACpE,CAAC;AACJ,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,sBAAsB,CAAC,IAAsB;IAC3D,WAAW,GAAG,EAAE,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC;IAC1C,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,OAAO,KAAK,KAAK,CAAC,OAAO;YAAE,SAAS;QACxC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;QACxB,MAAM,KAAK,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;QAC9C,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC;QACxB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,qBAAqB;IACnC,WAAW,GAAG,EAAE,CAAC;IACjB,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notifications in the native app: the browser's `Notification` (the
|
|
3
|
+
* permission, local notifications and their clicks) and `navigator.setAppBadge`
|
|
4
|
+
* over the host's UserNotifications (Native/Sources/SwiftBrowserNative/Host/NotificationBridge.swift),
|
|
5
|
+
* and remote notifications: `registerForPush` resolves with the device token
|
|
6
|
+
* (APNs, as hex) and `onNotification` delivers what the viewer opened and what
|
|
7
|
+
* arrived while the app is open.
|
|
8
|
+
*
|
|
9
|
+
* ```ts
|
|
10
|
+
* const token = await registerForPush();
|
|
11
|
+
* await fetch('/api/devices', { method: 'POST', body: JSON.stringify({ token }) });
|
|
12
|
+
* useEffect(() => onNotification((n) => { if (n.event === 'opened') show(n.data.postId); }), []);
|
|
13
|
+
* ```
|
|
14
|
+
*
|
|
15
|
+
* In the page (the round trip, or any browser) the host has no bridge for
|
|
16
|
+
* these: `Notification` is the browser's own, and `registerForPush` subscribes
|
|
17
|
+
* to Web Push through the site's service worker (`sw.js`, which the web
|
|
18
|
+
* renderer ships: docs/ops-protocol.md, "Push notifications") with the
|
|
19
|
+
* `applicationServerKey` given, resolving with the subscription's JSON as
|
|
20
|
+
* the token; the worker's messages become `onNotification` events. A server
|
|
21
|
+
* sends to both with one payload: APNs' (`aps.alert`, `aps.badge`), which
|
|
22
|
+
* the worker reads too.
|
|
23
|
+
*/
|
|
24
|
+
import type { NativeBridge } from './bridge';
|
|
25
|
+
export type NotificationPermissionState = 'default' | 'granted' | 'denied';
|
|
26
|
+
/** What the viewer did with a notification, or one that arrived while the app is open. */
|
|
27
|
+
export interface NotificationEvent {
|
|
28
|
+
event: 'opened' | 'received';
|
|
29
|
+
/** Whether it came from the push service. */
|
|
30
|
+
remote: boolean;
|
|
31
|
+
/** The notification's identifier (`tag`, or the push payload's `id`). */
|
|
32
|
+
id: string;
|
|
33
|
+
title: string;
|
|
34
|
+
body: string;
|
|
35
|
+
/** A push's payload, or what `new Notification(title, { data })` gave. */
|
|
36
|
+
data: Record<string, unknown>;
|
|
37
|
+
/** `opened`: the action the viewer chose, empty for the notification itself. */
|
|
38
|
+
action?: string;
|
|
39
|
+
}
|
|
40
|
+
export interface NativeNotificationOptions {
|
|
41
|
+
body?: string;
|
|
42
|
+
/** The notification's identifier: a later one with the same tag replaces it. */
|
|
43
|
+
tag?: string;
|
|
44
|
+
data?: unknown;
|
|
45
|
+
silent?: boolean;
|
|
46
|
+
/** The app badge to set with it. */
|
|
47
|
+
badge?: number;
|
|
48
|
+
}
|
|
49
|
+
export interface RegisterForPushOptions {
|
|
50
|
+
/** The Web Push application server key (the server's VAPID public key, base64url), for the page. */
|
|
51
|
+
applicationServerKey?: string;
|
|
52
|
+
}
|
|
53
|
+
type Listener = (notification: NotificationEvent) => void;
|
|
54
|
+
/** The bridge functions notifications need. */
|
|
55
|
+
export type NotificationBridge = Pick<NativeBridge, 'notificationsReady' | 'notificationPermission' | 'notificationShow' | 'notificationClose' | 'setBadge' | 'pushRegister'>;
|
|
56
|
+
export interface NotificationGlobals {
|
|
57
|
+
Notification: NativeNotificationClass;
|
|
58
|
+
__sbNotificationPermission: (id: number, permission: NotificationPermissionState) => void;
|
|
59
|
+
__sbPushRegistered: (id: number, result: {
|
|
60
|
+
token?: string;
|
|
61
|
+
error?: string;
|
|
62
|
+
}) => void;
|
|
63
|
+
__sbNotification: (json: string) => void;
|
|
64
|
+
/** `navigator.setAppBadge` and `clearAppBadge`. */
|
|
65
|
+
setAppBadge: (count?: number) => Promise<void>;
|
|
66
|
+
clearAppBadge: () => Promise<void>;
|
|
67
|
+
/** The native `registerForPush`. */
|
|
68
|
+
registerForPush: (options?: RegisterForPushOptions) => Promise<string>;
|
|
69
|
+
}
|
|
70
|
+
export interface NativeNotificationClass {
|
|
71
|
+
new (title: string, options?: NativeNotificationOptions): NativeNotificationInstance;
|
|
72
|
+
readonly permission: NotificationPermissionState;
|
|
73
|
+
requestPermission(): Promise<NotificationPermissionState>;
|
|
74
|
+
}
|
|
75
|
+
export interface NativeNotificationInstance {
|
|
76
|
+
readonly title: string;
|
|
77
|
+
readonly body: string;
|
|
78
|
+
readonly tag: string;
|
|
79
|
+
readonly data: unknown;
|
|
80
|
+
onclick: ((event: {
|
|
81
|
+
notification: NativeNotificationInstance;
|
|
82
|
+
action: string;
|
|
83
|
+
}) => void) | null;
|
|
84
|
+
close(): void;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Listens for notifications the viewer opened and ones that arrived while
|
|
88
|
+
* the app is open; returns what stops listening. Events before any listener
|
|
89
|
+
* (a tap that launched the app) wait for the first one.
|
|
90
|
+
*/
|
|
91
|
+
export declare function onNotification(listener: Listener): () => void;
|
|
92
|
+
/** The runtime's `__sbNotification(json)`, and what the page's worker messages become. */
|
|
93
|
+
export declare function receiveNotification(event: NotificationEvent): void;
|
|
94
|
+
/**
|
|
95
|
+
* Registers for remote notifications and resolves with the device token:
|
|
96
|
+
* APNs' as hex in the native app, the Web Push subscription's JSON in the
|
|
97
|
+
* page (which needs `applicationServerKey`). Rejects with the reason the
|
|
98
|
+
* system or the browser refused.
|
|
99
|
+
*/
|
|
100
|
+
export declare function registerForPush(options?: RegisterForPushOptions): Promise<string>;
|
|
101
|
+
/** Resets the listeners and the delivery source, for tests. */
|
|
102
|
+
export declare function resetNotifications(): void;
|
|
103
|
+
/** The globals for a host with the notification bridge. */
|
|
104
|
+
export declare function createNotificationGlobals(native: NotificationBridge): NotificationGlobals;
|
|
105
|
+
/** The event a service worker message carries (Web/src/notifications.ts), or null. */
|
|
106
|
+
export declare function notificationEventOf(data: unknown): NotificationEvent | null;
|
|
107
|
+
export {};
|
|
108
|
+
//# sourceMappingURL=notifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notifications.d.ts","sourceRoot":"","sources":["../src/notifications.ts"],"names":[],"mappings":"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"}
|