@pc-nexus/bridge 0.0.1-next.1

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 ADDED
@@ -0,0 +1,18 @@
1
+ # Nexus Bridge API
2
+
3
+ The Nexus UI bridge is a JavaScript API that enables nexus apps to securely integrate with PingCode.
4
+
5
+ ```ts
6
+ import { view } from "@pc-nexus/bridge";
7
+
8
+ await view.getContext();
9
+ ```
10
+
11
+ ```ts
12
+ import { dialog } from "@pc-nexus/bridge";
13
+
14
+ const dialogRef = await dialog.open({
15
+ resource: "abc",
16
+ context: { example: "from dialog" },
17
+ });
18
+ ```
@@ -0,0 +1,268 @@
1
+ export * from '@pc-nexus/models';
2
+
3
+ function attachObjectToWindow(key, value) {
4
+ window[key] = value;
5
+ }
6
+ function getObjectFromWindow(key) {
7
+ return window[key];
8
+ }
9
+
10
+ function getBridge() {
11
+ const bridge = getObjectFromWindow("__pc_nexus_bridge__");
12
+ return bridge;
13
+ }
14
+ class NexusBridge {
15
+ static getBridgeCall() {
16
+ if (!getBridge()) {
17
+ throw new Error(`
18
+ Unable to establish a connection with the PingCode nexus bridge.
19
+ If you are trying to run your app locally, Nexus apps only work in the context of PingCode products. Refer to https://developer.pingcode.com for how to tunnel when using a local development server.
20
+ `);
21
+ }
22
+ return getBridge().call;
23
+ }
24
+ static async call(name, payload) {
25
+ const result = await NexusBridge.getBridgeCall()(name, payload);
26
+ return result;
27
+ }
28
+ /**
29
+ * 订阅宿主 host 发来的消息。
30
+ * @param name 消息名称
31
+ * @param handler 收到消息时的回调,event 包含 source、origin、data
32
+ * @returns 返回带 cancel() 的对象,调用可取消订阅
33
+ */
34
+ static on(name, handler) {
35
+ const bridge = getBridge();
36
+ if (!bridge) {
37
+ throw new Error(`
38
+ Unable to establish a connection with the PingCode nexus bridge.
39
+ If you are trying to run your app locally, Nexus apps only work in the context of PingCode products. Refer to https://developer.pingcode.com for how to tunnel when using a local development server.
40
+ `);
41
+ }
42
+ return bridge.on(name, handler);
43
+ }
44
+ }
45
+
46
+ class NexusDialog {
47
+ async open(options) {
48
+ return (await NexusBridge.call("openDialog", options).catch((error) => {
49
+ console.error("nexus open dialog failed", error);
50
+ }));
51
+ }
52
+ }
53
+ const dialog = new NexusDialog();
54
+
55
+ async function invoke(functionKey, payload) {
56
+ const params = {
57
+ function: functionKey,
58
+ payload: payload,
59
+ tunnel_token: getObjectFromWindow("__TUNNEL_TOKEN__"),
60
+ };
61
+ const result = await NexusBridge.call("invokeFunction", params);
62
+ return result;
63
+ }
64
+
65
+ class NexusRouter {
66
+ async navigate(urlOrLocation) {
67
+ await NexusBridge.call("routerNavigate", { urlOrLocation });
68
+ }
69
+ async open(urlOrLocation) {
70
+ await NexusBridge.call("routerOpen", { urlOrLocation });
71
+ }
72
+ async getUrl(location) {
73
+ return await NexusBridge.call("routerGetUrl", { location });
74
+ }
75
+ async reload() {
76
+ await NexusBridge.call("routerReload", {});
77
+ }
78
+ }
79
+ const router = new NexusRouter();
80
+
81
+ class NexusView {
82
+ async getContext() {
83
+ return await NexusBridge.call("getContext");
84
+ }
85
+ async setWindowTitle(title) {
86
+ await NexusBridge.call("setWindowTitle", { title });
87
+ }
88
+ async reload() {
89
+ await NexusBridge.call("viewReload");
90
+ }
91
+ async close() {
92
+ await NexusBridge.call("viewClose");
93
+ }
94
+ async createHistory() {
95
+ const history = await NexusBridge.call("createHistory");
96
+ history.listen((location, action) => {
97
+ history.action = action;
98
+ history.location = location;
99
+ });
100
+ return history;
101
+ }
102
+ }
103
+ const view = new NexusView();
104
+
105
+ const isPlainObject = (value) => {
106
+ if (typeof value !== 'object' || value === null) {
107
+ return false;
108
+ }
109
+ if (Object.prototype.toString.call(value) !== '[object Object]') {
110
+ return false;
111
+ }
112
+ const proto = Object.getPrototypeOf(value);
113
+ if (proto === null) {
114
+ return true;
115
+ }
116
+ const constructor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
117
+ return (typeof constructor === 'function' &&
118
+ constructor instanceof constructor &&
119
+ Function.prototype.call(constructor) === Function.prototype.call(value));
120
+ };
121
+ const base64ToBlob = (b64string, mimeType) => {
122
+ if (!b64string) {
123
+ return null;
124
+ }
125
+ const base64String = b64string.includes(',') ? b64string.split(',')[1] : b64string;
126
+ const byteCharacters = atob(base64String);
127
+ const byteNumbers = new Array(byteCharacters.length);
128
+ for (let i = 0; i < byteCharacters.length; i++) {
129
+ byteNumbers[i] = byteCharacters.charCodeAt(i);
130
+ }
131
+ const byteArray = new Uint8Array(byteNumbers);
132
+ return new Blob([byteArray], { type: mimeType });
133
+ };
134
+ const blobToBase64 = (blob) => {
135
+ return new Promise((resolve, reject) => {
136
+ const reader = new FileReader();
137
+ reader.onloadend = () => {
138
+ resolve(reader.result);
139
+ };
140
+ reader.onerror = reject;
141
+ reader.readAsDataURL(blob);
142
+ });
143
+ };
144
+ const serialiseBlobsInPayload = async (payload) => {
145
+ if (payload instanceof Blob) {
146
+ const base64Data = await blobToBase64(payload);
147
+ return {
148
+ data: base64Data,
149
+ type: payload.type,
150
+ __isBlobData: true
151
+ };
152
+ }
153
+ if (Array.isArray(payload)) {
154
+ return Promise.all(payload.map((item) => serialiseBlobsInPayload(item)));
155
+ }
156
+ if (payload && isPlainObject(payload)) {
157
+ const entries = await Promise.all(Object.entries(payload).map(async ([key, value]) => [key, await serialiseBlobsInPayload(value)]));
158
+ return Object.fromEntries(entries);
159
+ }
160
+ return payload;
161
+ };
162
+ const deserialiseBlobsInPayload = (payload) => {
163
+ if (payload && isPlainObject(payload) && '__isBlobData' in payload) {
164
+ const typedData = payload;
165
+ return base64ToBlob(typedData.data, typedData.type);
166
+ }
167
+ if (Array.isArray(payload)) {
168
+ return payload.map((item) => deserialiseBlobsInPayload(item));
169
+ }
170
+ if (payload && isPlainObject(payload)) {
171
+ const result = {};
172
+ for (const [key, value] of Object.entries(payload)) {
173
+ result[key] = deserialiseBlobsInPayload(value);
174
+ }
175
+ return result;
176
+ }
177
+ return payload;
178
+ };
179
+ const containsBlobs = (payload) => {
180
+ if (payload instanceof Blob) {
181
+ return true;
182
+ }
183
+ if (Array.isArray(payload)) {
184
+ return payload.some(item => containsBlobs(item));
185
+ }
186
+ if (payload && isPlainObject(payload)) {
187
+ return Object.values(payload).some((value) => containsBlobs(value));
188
+ }
189
+ return false;
190
+ };
191
+ const containsSerialisedBlobs = (payload) => {
192
+ if (payload && isPlainObject(payload) && '__isBlobData' in payload) {
193
+ return true;
194
+ }
195
+ if (Array.isArray(payload)) {
196
+ return payload.some((item) => containsSerialisedBlobs(item));
197
+ }
198
+ if (payload && isPlainObject(payload)) {
199
+ return Object.values(payload).some((value) => containsSerialisedBlobs(value));
200
+ }
201
+ return false;
202
+ };
203
+
204
+ async function on(eventName, callback) {
205
+ const wrappedCallback = (payload) => {
206
+ let newPayload = payload;
207
+ if (containsSerialisedBlobs(payload)) {
208
+ newPayload = deserialiseBlobsInPayload(payload);
209
+ }
210
+ return callback(newPayload);
211
+ };
212
+ return NexusBridge.call('on', { eventName, callback: wrappedCallback });
213
+ }
214
+ async function emit(eventName, payload) {
215
+ let newPayload = payload;
216
+ if (containsBlobs(payload)) {
217
+ newPayload = await serialiseBlobsInPayload(payload);
218
+ }
219
+ return NexusBridge.call('emit', { eventName, payload: newPayload });
220
+ }
221
+ const events = {
222
+ on,
223
+ emit
224
+ };
225
+
226
+ class NexusI18n {
227
+ translationsCache = {};
228
+ i18nFolderName = "__LOCALES__";
229
+ async getTranslations(locale) {
230
+ if (!locale) {
231
+ locale = (await view.getContext()).locale;
232
+ }
233
+ const translations = await this.loadTranslations(locale);
234
+ return { locale, translations };
235
+ }
236
+ async createTranslator(locale) {
237
+ if (!locale) {
238
+ locale = (await view.getContext()).locale;
239
+ }
240
+ const translations = await this.loadTranslations(locale);
241
+ return await NexusBridge.call("createTranslator", { locale, translations });
242
+ }
243
+ loadTranslations(locale) {
244
+ const url = `../${this.i18nFolderName}/${locale}.json`;
245
+ if (!this.translationsCache[locale]) {
246
+ this.translationsCache[locale] = fetch(url)
247
+ .then((res) => res.json())
248
+ .catch((err) => {
249
+ // 请求失败要清理缓存
250
+ delete this.translationsCache[locale];
251
+ throw err;
252
+ });
253
+ }
254
+ return this.translationsCache[locale];
255
+ }
256
+ }
257
+ const i18n = new NexusI18n();
258
+
259
+ /*
260
+ * Public API Surface of bridge
261
+ */
262
+
263
+ /**
264
+ * Generated bundle index. Do not edit.
265
+ */
266
+
267
+ export { NexusBridge, dialog, events, i18n, invoke, router, view };
268
+ //# sourceMappingURL=pc-nexus-bridge.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pc-nexus-bridge.mjs","sources":["../../../../web/bridge/src/window.ts","../../../../web/bridge/src/bridge.ts","../../../../web/bridge/src/dialog.ts","../../../../web/bridge/src/invoke.ts","../../../../web/bridge/src/router.ts","../../../../web/bridge/src/view.ts","../../../../web/bridge/src/utils/blob-parser.ts","../../../../web/bridge/src/events.ts","../../../../web/bridge/src/i18n.ts","../../../../web/bridge/src/public-api.ts","../../../../web/bridge/src/pc-nexus-bridge.ts"],"sourcesContent":["export type SafeAny = any;\n\nexport function attachObjectToWindow<T>(key: string, value: T) {\n (window as SafeAny)[key] = value;\n}\n\nexport function getObjectFromWindow<T>(key: string) {\n return (window as SafeAny)[key];\n}\n","import { getObjectFromWindow } from \"./window\";\n\nexport interface HostMessageEvent<T = unknown> {\n source: Window | null;\n origin: string;\n data: T;\n}\n\nexport interface Cancelable {\n cancel: () => void;\n}\n\ninterface GlobalBridge {\n call<T>(name: string, payload?: object | undefined): Promise<T>;\n on<T>(name: string, handler: (event: HostMessageEvent<T>) => void): Cancelable;\n}\n\nfunction getBridge() {\n const bridge = getObjectFromWindow<GlobalBridge>(\"__pc_nexus_bridge__\");\n return bridge;\n}\n\nexport class NexusBridge {\n static getBridgeCall<T>(): (name: string, payload?: object) => Promise<T> {\n if (!getBridge()) {\n throw new Error(`\n Unable to establish a connection with the PingCode nexus bridge.\n If you are trying to run your app locally, Nexus apps only work in the context of PingCode products. Refer to https://developer.pingcode.com for how to tunnel when using a local development server.\n `);\n }\n return getBridge().call;\n }\n\n static async call<T>(name: string, payload?: object | undefined): Promise<T> {\n const result = await NexusBridge.getBridgeCall<T>()(name, payload);\n return result as T;\n }\n\n /**\n * 订阅宿主 host 发来的消息。\n * @param name 消息名称\n * @param handler 收到消息时的回调,event 包含 source、origin、data\n * @returns 返回带 cancel() 的对象,调用可取消订阅\n */\n static on<T>(name: string, handler: (event: HostMessageEvent<T>) => void): Cancelable {\n const bridge = getBridge();\n if (!bridge) {\n throw new Error(`\n Unable to establish a connection with the PingCode nexus bridge.\n If you are trying to run your app locally, Nexus apps only work in the context of PingCode products. Refer to https://developer.pingcode.com for how to tunnel when using a local development server.\n `);\n }\n return bridge.on(name, handler);\n }\n}\n","import { DialogOptions, DialogRef } from \"@pc-nexus/models\";\nimport { NexusBridge } from \"./bridge\";\n\nclass NexusDialog {\n async open<T>(options: DialogOptions): Promise<DialogRef<T>> {\n return (await NexusBridge.call<DialogRef<T>>(\"openDialog\", options).catch((error) => {\n console.error(\"nexus open dialog failed\", error);\n })) as DialogRef<T>;\n }\n}\n\nexport const dialog = new NexusDialog();\n","import { NexusBridge } from \"./bridge\";\nimport { InvokeFunctionParams } from \"./models\";\nimport { getObjectFromWindow } from \"./window\";\n\nexport async function invoke<TPayload = any, TResult = any>(functionKey: string, payload?: TPayload): Promise<TResult> {\n const params: InvokeFunctionParams = {\n function: functionKey,\n payload: payload,\n tunnel_token: getObjectFromWindow(\"__TUNNEL_TOKEN__\"),\n } as InvokeFunctionParams;\n const result = await NexusBridge.call(\"invokeFunction\", params);\n return result as TResult;\n}\n","import { NexusBridge } from \"./bridge\";\nimport { NavigationLocation } from \"./models\";\n\nexport class NexusRouter {\n async navigate(urlOrLocation: string | NavigationLocation): Promise<void> {\n await NexusBridge.call<void>(\"routerNavigate\", { urlOrLocation });\n }\n\n async open(urlOrLocation: string | NavigationLocation): Promise<void> {\n await NexusBridge.call<void>(\"routerOpen\", { urlOrLocation });\n }\n\n async getUrl(location: NavigationLocation): Promise<string> {\n return await NexusBridge.call<string>(\"routerGetUrl\", { location });\n }\n\n async reload(): Promise<void> {\n await NexusBridge.call<void>(\"routerReload\", {});\n }\n}\n\nexport const router = new NexusRouter();\n","import { NexusBridge } from \"./bridge\";\nimport { ExtensionData, NexusFullContext } from \"./models\";\n\nexport interface LocationDescriptor {\n pathname: string;\n search?: string;\n hash?: string;\n state?: unknown;\n}\n\nexport type HistoryAction = \"POP\" | \"PUSH\" | \"REPLACE\";\n\nexport type UnlistenCallback = () => void;\n\nexport interface NexusHistory {\n action: HistoryAction;\n location: LocationDescriptor;\n push(path: string, state?: unknown): void;\n push(location: LocationDescriptor): void;\n replace(path: string, state?: unknown): void;\n replace(location: LocationDescriptor): void;\n go(n: number): void;\n goBack(): void;\n goForward(): void;\n listen(listener: (location: LocationDescriptor, action: HistoryAction) => void): Promise<UnlistenCallback>;\n}\n\nexport class NexusView {\n async getContext<T = ExtensionData>(): Promise<NexusFullContext<T>> {\n return await NexusBridge.call(\"getContext\");\n }\n\n async setWindowTitle(title: string): Promise<void> {\n await NexusBridge.call<void>(\"setWindowTitle\", { title });\n }\n\n async reload(): Promise<void> {\n await NexusBridge.call<void>(\"viewReload\");\n }\n\n async close(): Promise<void> {\n await NexusBridge.call<void>(\"viewClose\");\n }\n\n async createHistory(): Promise<NexusHistory> {\n const history = await NexusBridge.call<NexusHistory>(\"createHistory\");\n history.listen((location, action) => {\n history.action = action;\n history.location = location;\n });\n return history;\n }\n}\n\nexport const view = new NexusView();\n","export const isPlainObject = (value: any) => {\n if (typeof value !== 'object' || value === null) {\n return false;\n }\n if (Object.prototype.toString.call(value) !== '[object Object]') {\n return false;\n }\n const proto = Object.getPrototypeOf(value);\n if (proto === null) {\n return true;\n }\n const constructor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;\n return (typeof constructor === 'function' &&\n constructor instanceof constructor &&\n Function.prototype.call(constructor) === Function.prototype.call(value));\n};\n\nexport const base64ToBlob = (b64string: string, mimeType: string) => {\n if (!b64string) {\n return null;\n }\n const base64String = b64string.includes(',') ? b64string.split(',')[1] : b64string;\n const byteCharacters = atob(base64String);\n const byteNumbers = new Array(byteCharacters.length);\n for (let i = 0; i < byteCharacters.length; i++) {\n byteNumbers[i] = byteCharacters.charCodeAt(i);\n }\n\n const byteArray = new Uint8Array(byteNumbers);\n return new Blob([byteArray], { type: mimeType });\n};\n\nexport const blobToBase64 = (blob: Blob) => {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => {\n resolve(reader.result);\n };\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n};\n\nexport const serialiseBlobsInPayload = async (payload: any): Promise<any> => {\n if (payload instanceof Blob) {\n const base64Data = await blobToBase64(payload);\n return {\n data: base64Data,\n type: payload.type,\n __isBlobData: true\n };\n }\n if (Array.isArray(payload)) {\n return Promise.all(payload.map((item) => serialiseBlobsInPayload(item)));\n }\n if (payload && isPlainObject(payload)) {\n const entries = await Promise.all(Object.entries(payload).map(async ([key, value]) => [key, await serialiseBlobsInPayload(value)]));\n return Object.fromEntries(entries);\n }\n return payload;\n};\n\nexport const deserialiseBlobsInPayload = (payload: any): any => {\n if (payload && isPlainObject(payload) && '__isBlobData' in payload) {\n const typedData = payload;\n return base64ToBlob(typedData.data, typedData.type);\n }\n if (Array.isArray(payload)) {\n return payload.map((item) => deserialiseBlobsInPayload(item));\n }\n if (payload && isPlainObject(payload)) {\n const result = {};\n for (const [key, value] of Object.entries(payload)) {\n (result as any)[key] = deserialiseBlobsInPayload(value);\n }\n return result;\n }\n return payload;\n};\n\nexport const containsBlobs = (payload: any): boolean => {\n if (payload instanceof Blob) {\n return true;\n }\n if (Array.isArray(payload)) {\n return payload.some(item => containsBlobs(item));\n }\n if (payload && isPlainObject(payload)) {\n return Object.values(payload).some((value) => containsBlobs(value));\n }\n return false;\n};\nexport const containsSerialisedBlobs = (payload: any): boolean => {\n if (payload && isPlainObject(payload) && '__isBlobData' in payload) {\n return true;\n }\n if (Array.isArray(payload)) {\n return payload.some((item) => containsSerialisedBlobs(item));\n }\n if (payload && isPlainObject(payload)) {\n return Object.values(payload).some((value) => containsSerialisedBlobs(value));\n }\n return false;\n};\n","import { NexusBridge } from \"./bridge\";\nimport { Subscription } from \"./models\";\nimport { containsBlobs, serialiseBlobsInPayload, containsSerialisedBlobs, deserialiseBlobsInPayload } from \"./utils\";\n\nasync function on<T = any>(eventName: string, callback: (payload?: T) => any): Promise<Subscription> {\n const wrappedCallback = (payload: T) => {\n let newPayload = payload;\n if (containsSerialisedBlobs(payload)) {\n newPayload = deserialiseBlobsInPayload(payload);\n }\n return callback(newPayload);\n };\n return NexusBridge.call('on', { eventName, callback: wrappedCallback });\n}\n\nasync function emit<T = any>(eventName: string, payload: T): Promise<void> {\n let newPayload = payload;\n if (containsBlobs(payload)) {\n newPayload = await serialiseBlobsInPayload(payload);\n }\n return NexusBridge.call('emit', { eventName, payload: newPayload });\n}\n\nexport const events = {\n on,\n emit\n}\n","import { Translator, GetTranslationsResult, NexusSupportedLocaleCode, TranslationResourceContent } from \"@pc-nexus/models\";\nimport { view } from \"./view\";\nimport { NexusBridge } from \"./bridge\";\n\nexport class NexusI18n {\n private translationsCache: Partial<Record<NexusSupportedLocaleCode, Promise<TranslationResourceContent>>> = {};\n\n private i18nFolderName = \"__LOCALES__\";\n\n async getTranslations(locale?: NexusSupportedLocaleCode): Promise<GetTranslationsResult> {\n if (!locale) {\n locale = (await view.getContext()).locale;\n }\n const translations = await this.loadTranslations(locale);\n return { locale, translations };\n }\n\n async createTranslator(locale?: NexusSupportedLocaleCode): Promise<Translator> {\n if (!locale) {\n locale = (await view.getContext()).locale;\n }\n const translations = await this.loadTranslations(locale);\n return await NexusBridge.call(\"createTranslator\", { locale, translations });\n }\n\n private loadTranslations(locale: NexusSupportedLocaleCode): Promise<TranslationResourceContent> {\n const url = `../${this.i18nFolderName}/${locale}.json`;\n if (!this.translationsCache[locale]) {\n this.translationsCache[locale] = fetch(url)\n .then((res) => res.json())\n .catch((err) => {\n // 请求失败要清理缓存\n delete this.translationsCache[locale];\n throw err;\n });\n }\n\n return this.translationsCache[locale]!;\n }\n}\n\nexport const i18n = new NexusI18n();\n","/*\n * Public API Surface of bridge\n */\nexport {\n NexusBridge,\n type HostMessageEvent,\n type Cancelable,\n} from \"./bridge\";\nexport * from \"./dialog\";\nexport * from \"./invoke\";\nexport * from \"./models\";\nexport { router } from \"./router\";\nexport { view, type LocationDescriptor, type HistoryAction, type UnlistenCallback, type NexusHistory } from \"./view\";\nexport { events } from \"./events\";\nexport { i18n } from \"./i18n\";\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@pc-nexus/bridge",
3
+ "version": "0.0.1-next.1",
4
+ "peerDependencies": {},
5
+ "dependencies": {
6
+ "@pc-nexus/models": "*",
7
+ "tslib": "^2.3.0"
8
+ },
9
+ "sideEffects": false,
10
+ "module": "fesm2022/pc-nexus-bridge.mjs",
11
+ "typings": "types/pc-nexus-bridge.d.ts",
12
+ "exports": {
13
+ "./package.json": {
14
+ "default": "./package.json"
15
+ },
16
+ ".": {
17
+ "types": "./types/pc-nexus-bridge.d.ts",
18
+ "default": "./fesm2022/pc-nexus-bridge.mjs"
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,85 @@
1
+ import { DialogOptions, DialogRef, NavigationLocation, ExtensionData, NexusFullContext, Subscription, NexusSupportedLocaleCode, GetTranslationsResult, Translator } from '@pc-nexus/models';
2
+ export * from '@pc-nexus/models';
3
+
4
+ interface HostMessageEvent<T = unknown> {
5
+ source: Window | null;
6
+ origin: string;
7
+ data: T;
8
+ }
9
+ interface Cancelable {
10
+ cancel: () => void;
11
+ }
12
+ declare class NexusBridge {
13
+ static getBridgeCall<T>(): (name: string, payload?: object) => Promise<T>;
14
+ static call<T>(name: string, payload?: object | undefined): Promise<T>;
15
+ /**
16
+ * 订阅宿主 host 发来的消息。
17
+ * @param name 消息名称
18
+ * @param handler 收到消息时的回调,event 包含 source、origin、data
19
+ * @returns 返回带 cancel() 的对象,调用可取消订阅
20
+ */
21
+ static on<T>(name: string, handler: (event: HostMessageEvent<T>) => void): Cancelable;
22
+ }
23
+
24
+ declare class NexusDialog {
25
+ open<T>(options: DialogOptions): Promise<DialogRef<T>>;
26
+ }
27
+ declare const dialog: NexusDialog;
28
+
29
+ declare function invoke<TPayload = any, TResult = any>(functionKey: string, payload?: TPayload): Promise<TResult>;
30
+
31
+ declare class NexusRouter {
32
+ navigate(urlOrLocation: string | NavigationLocation): Promise<void>;
33
+ open(urlOrLocation: string | NavigationLocation): Promise<void>;
34
+ getUrl(location: NavigationLocation): Promise<string>;
35
+ reload(): Promise<void>;
36
+ }
37
+ declare const router: NexusRouter;
38
+
39
+ interface LocationDescriptor {
40
+ pathname: string;
41
+ search?: string;
42
+ hash?: string;
43
+ state?: unknown;
44
+ }
45
+ type HistoryAction = "POP" | "PUSH" | "REPLACE";
46
+ type UnlistenCallback = () => void;
47
+ interface NexusHistory {
48
+ action: HistoryAction;
49
+ location: LocationDescriptor;
50
+ push(path: string, state?: unknown): void;
51
+ push(location: LocationDescriptor): void;
52
+ replace(path: string, state?: unknown): void;
53
+ replace(location: LocationDescriptor): void;
54
+ go(n: number): void;
55
+ goBack(): void;
56
+ goForward(): void;
57
+ listen(listener: (location: LocationDescriptor, action: HistoryAction) => void): Promise<UnlistenCallback>;
58
+ }
59
+ declare class NexusView {
60
+ getContext<T = ExtensionData>(): Promise<NexusFullContext<T>>;
61
+ setWindowTitle(title: string): Promise<void>;
62
+ reload(): Promise<void>;
63
+ close(): Promise<void>;
64
+ createHistory(): Promise<NexusHistory>;
65
+ }
66
+ declare const view: NexusView;
67
+
68
+ declare function on<T = any>(eventName: string, callback: (payload?: T) => any): Promise<Subscription>;
69
+ declare function emit<T = any>(eventName: string, payload: T): Promise<void>;
70
+ declare const events: {
71
+ on: typeof on;
72
+ emit: typeof emit;
73
+ };
74
+
75
+ declare class NexusI18n {
76
+ private translationsCache;
77
+ private i18nFolderName;
78
+ getTranslations(locale?: NexusSupportedLocaleCode): Promise<GetTranslationsResult>;
79
+ createTranslator(locale?: NexusSupportedLocaleCode): Promise<Translator>;
80
+ private loadTranslations;
81
+ }
82
+ declare const i18n: NexusI18n;
83
+
84
+ export { NexusBridge, dialog, events, i18n, invoke, router, view };
85
+ export type { Cancelable, HistoryAction, HostMessageEvent, LocationDescriptor, NexusHistory, UnlistenCallback };