@xeonr/renderer-sdk 1.3.0 → 1.5.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/src/client.ts DELETED
@@ -1,619 +0,0 @@
1
- import type {
2
- HostInitMessage,
3
- HostMessage,
4
- HostThemeUpdateMessage,
5
- HostTokenRefreshMessage,
6
- HostGenerateTokenResultMessage,
7
- IframeHistoryPushMessage,
8
- IframeHistoryReplaceMessage,
9
- IframeCrashMessage,
10
- RendererCrashKind,
11
- } from './protocol.js';
12
- import { buildCrashMessage, isHostMessage, postCrashToHost } from './protocol.js';
13
- import type { InitPayload, RendererApiAdapter, RendererConfig, RendererScope, RenderingType } from './types.js';
14
-
15
- export interface RendererClientOptions {
16
- /**
17
- * Expected origin of the host application.
18
- * If set, messages from other origins are silently ignored.
19
- * If omitted, all origins are accepted (suitable for local dev).
20
- */
21
- targetOrigin?: string;
22
-
23
- /**
24
- * How long after init to wait for `signalReady()` before auto-acking
25
- * anyway, in milliseconds. Only honored when the renderer's
26
- * `config.json` has `deferReady: true`. Default 30000 (30s).
27
- * Matches the host bridge's 10s init-timeout × ~3 — enough headroom
28
- * for slow data fetches without leaving the user staring at a
29
- * loading overlay indefinitely.
30
- */
31
- readyTimeoutMs?: number;
32
- }
33
-
34
- type InitCallback = (payload: InitPayload) => void;
35
- type ThemeCallback = (theme: 'light' | 'dark') => void;
36
- type TokenCallback = (token: string, expiresAt: number) => void;
37
- type NavigateCallback = (path: string) => void;
38
-
39
- /**
40
- * Client SDK for custom renderers running inside a sandboxed iframe.
41
- *
42
- * Usage:
43
- * ```ts
44
- * import { RendererClient } from '@xeonr/renderer-sdk';
45
- *
46
- * const client = new RendererClient();
47
- *
48
- * client.onInit((payload) => {
49
- * console.log('Received scope:', payload.scope);
50
- * console.log('Token:', payload.token);
51
- * // Bootstrap your app here
52
- * });
53
- *
54
- * client.onThemeChange((theme) => {
55
- * document.documentElement.setAttribute('data-theme', theme);
56
- * });
57
- * ```
58
- */
59
- export class RendererClient {
60
- private targetOrigin: string;
61
- private initCallbacks: InitCallback[] = [];
62
- private themeCallbacks: ThemeCallback[] = [];
63
- private tokenCallbacks: TokenCallback[] = [];
64
- private navigateCallbacks: NavigateCallback[] = [];
65
-
66
- private currentToken: string | null = null;
67
- private currentTokenExpiresAt: number | null = null;
68
- private currentScope: RendererScope | null = null;
69
- private currentRenderingType: RenderingType | null = null;
70
- private currentConfig: RendererConfig | null = null;
71
- private currentTheme: 'light' | 'dark' = 'light';
72
- private currentApiBaseUrl: string | null = null;
73
- private currentEntrypoint: 'dashboard' | 'portal' | null = null;
74
- private currentPath: string = '/';
75
- private currentConnected = false;
76
-
77
- private listener: ((event: MessageEvent) => void) | null = null;
78
- private errorListener: ((event: ErrorEvent) => void) | null = null;
79
- private rejectionListener: ((event: PromiseRejectionEvent) => void) | null = null;
80
- private hashChangeListener: (() => void) | null = null;
81
- // `signalReady` machinery — see `deferReady` in RendererClientOptions.
82
- // `ackDeferred` is set at construction; `ackSent` flips when we
83
- // actually post the ack so signalReady stays idempotent.
84
- private ackDeferred = false;
85
- private ackSent = false;
86
- private readyTimeoutMs = 30_000;
87
- private readyTimeoutHandle: ReturnType<typeof setTimeout> | null = null;
88
- private readyRetryInterval: ReturnType<typeof setInterval> | null = null;
89
- private readyRetryTimeout: ReturnType<typeof setTimeout> | null = null;
90
- private historyPatched = false;
91
- private originalPushState: typeof history.pushState | null = null;
92
- private originalReplaceState: typeof history.replaceState | null = null;
93
- private destroyed = false;
94
- private suppressHashChange = false;
95
- private pendingTokenResolvers: Array<(result: { token: string; expiresAt: number }) => void> = [];
96
- private pendingGenerateTokenResolvers: Map<string, { resolve: (result: { accepted: boolean }) => void; reject: (error: Error) => void }> = new Map();
97
- private apiAdapter: RendererApiAdapter | null = null;
98
-
99
- constructor(options?: RendererClientOptions) {
100
- this.targetOrigin = options?.targetOrigin ?? '*';
101
- // `ackDeferred` is decided by config.json (read in handleInit)
102
- // rather than the constructor — the SDK can't know which mode
103
- // the renderer wants until init lands, but that's fine because
104
- // the ack itself only fires after init anyway.
105
- if (typeof options?.readyTimeoutMs === 'number' && options.readyTimeoutMs > 0) {
106
- this.readyTimeoutMs = options.readyTimeoutMs;
107
- }
108
- this.setup();
109
- }
110
-
111
- // ---------------------------------------------------------------------------
112
- // Lifecycle
113
- // ---------------------------------------------------------------------------
114
-
115
- /** Register a callback for when the host sends the init message. */
116
- onInit(cb: InitCallback): () => void {
117
- this.initCallbacks.push(cb);
118
- return () => {
119
- this.initCallbacks = this.initCallbacks.filter(c => c !== cb);
120
- };
121
- }
122
-
123
- // ---------------------------------------------------------------------------
124
- // Receive from host
125
- // ---------------------------------------------------------------------------
126
-
127
- /** Register a callback for host theme changes. */
128
- onThemeChange(cb: ThemeCallback): () => void {
129
- this.themeCallbacks.push(cb);
130
- return () => {
131
- this.themeCallbacks = this.themeCallbacks.filter(c => c !== cb);
132
- };
133
- }
134
-
135
- /** Register a callback for token refreshes from the host. */
136
- onTokenRefresh(cb: TokenCallback): () => void {
137
- this.tokenCallbacks.push(cb);
138
- return () => {
139
- this.tokenCallbacks = this.tokenCallbacks.filter(c => c !== cb);
140
- };
141
- }
142
-
143
- /** Register a callback for hash-based navigation changes. */
144
- onNavigate(cb: NavigateCallback): () => void {
145
- this.navigateCallbacks.push(cb);
146
- return () => {
147
- this.navigateCallbacks = this.navigateCallbacks.filter(c => c !== cb);
148
- };
149
- }
150
-
151
- // ---------------------------------------------------------------------------
152
- // Send to host
153
- // ---------------------------------------------------------------------------
154
-
155
- /** Request the host to open a specific upload. */
156
- openUpload(uploadId: string): void {
157
- this.postToHost({ type: 'uplim:openUpload', uploadId });
158
- }
159
-
160
- /** Request a fresh integration access token from the host. */
161
- requestToken(): void {
162
- this.postToHost({ type: 'uplim:tokenRequest' });
163
- }
164
-
165
- /** Request a fresh token and wait for the response. */
166
- requestTokenAsync(): Promise<{ token: string; expiresAt: number }> {
167
- return new Promise((resolve) => {
168
- this.pendingTokenResolvers.push(resolve);
169
- this.postToHost({ type: 'uplim:tokenRequest' });
170
- });
171
- }
172
-
173
- /** Request the host to close this renderer (modal mode). */
174
- close(): void {
175
- this.postToHost({ type: 'uplim:close' });
176
- }
177
-
178
- /**
179
- * Request the host to prompt the user to generate a long-lived token.
180
- * The token is displayed to the user but never returned to the renderer.
181
- * Resolves with `{ accepted: true }` if the user accepts, or `{ accepted: false }` if rejected.
182
- */
183
- generateToken(opts: { reason: string; duration: 'forever' | string }): Promise<{ accepted: boolean }> {
184
- const requestId = crypto.randomUUID();
185
- return new Promise((resolve, reject) => {
186
- this.pendingGenerateTokenResolvers.set(requestId, { resolve, reject });
187
- this.postToHost({
188
- type: 'uplim:generateToken',
189
- requestId,
190
- reason: opts.reason,
191
- duration: opts.duration,
192
- });
193
- });
194
- }
195
-
196
- // ---------------------------------------------------------------------------
197
- // Getters
198
- // ---------------------------------------------------------------------------
199
-
200
- /** Get the current integration access token. */
201
- getToken(): string | null {
202
- return this.currentToken;
203
- }
204
-
205
- /** Get the token expiry as a Unix timestamp (ms). */
206
- getTokenExpiresAt(): number | null {
207
- return this.currentTokenExpiresAt;
208
- }
209
-
210
- /** Check if the current token is expired or about to expire (within 30s). */
211
- isTokenExpired(): boolean {
212
- if (!this.currentTokenExpiresAt) return true;
213
- return Date.now() >= this.currentTokenExpiresAt - 30_000;
214
- }
215
-
216
- /** Get the current scope. */
217
- getScope(): RendererScope | null {
218
- return this.currentScope;
219
- }
220
-
221
- /** Get the current rendering type. */
222
- getRenderingType(): RenderingType | null {
223
- return this.currentRenderingType;
224
- }
225
-
226
- /** Get the renderer config from config.json. */
227
- getConfig(): RendererConfig | null {
228
- return this.currentConfig;
229
- }
230
-
231
- /** Get the current theme. */
232
- getTheme(): 'light' | 'dark' {
233
- return this.currentTheme;
234
- }
235
-
236
- /** Get the current hash path (e.g. '/settings/advanced'). */
237
- getPath(): string {
238
- return this.currentPath;
239
- }
240
-
241
- /** Has the init message been processed? Late subscribers (e.g. a
242
- * second `useRendererClient` mount after init landed) read this to
243
- * seed their initial state without waiting for the next onInit. */
244
- isConnected(): boolean {
245
- return this.currentConnected;
246
- }
247
-
248
- /** Which HTML entrypoint was loaded (dashboard or portal). */
249
- getEntrypoint(): 'dashboard' | 'portal' | null {
250
- return this.currentEntrypoint;
251
- }
252
-
253
- /** Base URL for upl.im API calls, as supplied by the host. */
254
- getApiBaseUrl(): string | null {
255
- return this.currentApiBaseUrl;
256
- }
257
-
258
- /**
259
- * Returns an API adapter compatible with `getUploadClientWithEnv()` from `@xeonr/uploads-sdk`.
260
- * Handles authentication and automatic token refresh via the host bridge.
261
- *
262
- * ```ts
263
- * import { getUploadClientWithEnv } from '@xeonr/uploads-sdk/api/base';
264
- * import { BucketUploadsService } from '@xeonr/uploads-protocol/uplim/api/v1/uploads_pb';
265
- *
266
- * const adapter = client.getApiAdapter();
267
- * const uploadsClient = getUploadClientWithEnv(BucketUploadsService, adapter);
268
- * ```
269
- */
270
- getApiAdapter(): RendererApiAdapter {
271
- if (this.apiAdapter) return this.apiAdapter;
272
-
273
- // Use a getter so hostname reflects the latest apiBaseUrl (set on init)
274
- const self = this;
275
- this.apiAdapter = {
276
- get hostname() { return self.currentApiBaseUrl ?? undefined; },
277
- tokenHelper: async () => this.currentToken,
278
- onAuthenticationExpired: async (retryCount: number) => {
279
- if (retryCount > 0) return false;
280
- const result = await this.requestTokenAsync();
281
- return !!result.token;
282
- },
283
- };
284
-
285
- return this.apiAdapter;
286
- }
287
-
288
- // ---------------------------------------------------------------------------
289
- // Cleanup
290
- // ---------------------------------------------------------------------------
291
-
292
- /** Remove all listeners and stop the client. */
293
- destroy(): void {
294
- this.destroyed = true;
295
- this.stopReadyRetry();
296
- if (this.readyTimeoutHandle) {
297
- clearTimeout(this.readyTimeoutHandle);
298
- this.readyTimeoutHandle = null;
299
- }
300
- if (this.listener) {
301
- window.removeEventListener('message', this.listener);
302
- this.listener = null;
303
- }
304
- if (this.errorListener) {
305
- window.removeEventListener('error', this.errorListener);
306
- this.errorListener = null;
307
- }
308
- if (this.rejectionListener) {
309
- window.removeEventListener('unhandledrejection', this.rejectionListener);
310
- this.rejectionListener = null;
311
- }
312
- if (this.hashChangeListener) {
313
- window.removeEventListener('hashchange', this.hashChangeListener);
314
- this.hashChangeListener = null;
315
- }
316
- if (this.historyPatched) {
317
- if (this.originalPushState) window.history.pushState = this.originalPushState;
318
- if (this.originalReplaceState) window.history.replaceState = this.originalReplaceState;
319
- this.historyPatched = false;
320
- }
321
- this.initCallbacks = [];
322
- this.themeCallbacks = [];
323
- this.tokenCallbacks = [];
324
- this.navigateCallbacks = [];
325
- for (const [, pending] of this.pendingGenerateTokenResolvers) {
326
- pending.reject(new Error('Client destroyed'));
327
- }
328
- this.pendingGenerateTokenResolvers.clear();
329
- }
330
-
331
- // ---------------------------------------------------------------------------
332
- // Internal
333
- // ---------------------------------------------------------------------------
334
-
335
- private setup(): void {
336
- this.listener = (event: MessageEvent) => {
337
- if (this.destroyed) return;
338
- if (this.targetOrigin !== '*' && event.origin !== this.targetOrigin) return;
339
- if (!isHostMessage(event.data)) return;
340
-
341
- // Any valid host message implies the host's listener is attached and the
342
- // handshake is underway, so stop pinging.
343
- this.stopReadyRetry();
344
- this.handleMessage(event.data);
345
- };
346
-
347
- window.addEventListener('message', this.listener);
348
-
349
- this.installCrashHooks();
350
-
351
- // Tell the host we're ready. We retry on an interval because a fast iframe can
352
- // post 'ready' before the host has attached its message listener — the first
353
- // ping is lost, the host times out, and the user has to click retry. Pinging
354
- // until the host responds closes that race without changing the protocol.
355
- this.postToHost({ type: 'uplim:ready' });
356
- this.readyRetryInterval = setInterval(() => {
357
- if (this.destroyed) return;
358
- this.postToHost({ type: 'uplim:ready' });
359
- }, 200);
360
- // Bound the retries: if the host genuinely isn't there after 8s, stop pinging
361
- // so we don't spam a misbehaving parent.
362
- this.readyRetryTimeout = setTimeout(() => {
363
- this.stopReadyRetry();
364
- }, 8000);
365
- }
366
-
367
- private stopReadyRetry(): void {
368
- if (this.readyRetryInterval) {
369
- clearInterval(this.readyRetryInterval);
370
- this.readyRetryInterval = null;
371
- }
372
- if (this.readyRetryTimeout) {
373
- clearTimeout(this.readyRetryTimeout);
374
- this.readyRetryTimeout = null;
375
- }
376
- }
377
-
378
- private handleMessage(message: HostMessage): void {
379
- switch (message.type) {
380
- case 'uplim:init':
381
- this.handleInit(message);
382
- break;
383
- case 'uplim:theme':
384
- this.handleThemeUpdate(message);
385
- break;
386
- case 'uplim:token':
387
- this.handleTokenRefresh(message);
388
- break;
389
- case 'uplim:generateTokenResult':
390
- this.handleGenerateTokenResult(message);
391
- break;
392
- case 'uplim:historyBack':
393
- window.history.back();
394
- break;
395
- case 'uplim:historyForward':
396
- window.history.forward();
397
- break;
398
- }
399
- }
400
-
401
- private handleInit(message: HostInitMessage): void {
402
- const { payload } = message;
403
- this.currentToken = payload.token;
404
- this.currentTokenExpiresAt = payload.tokenExpiresAt;
405
- this.currentScope = payload.scope;
406
- this.currentRenderingType = payload.renderingType;
407
- this.currentConfig = payload.config;
408
- this.currentTheme = payload.theme;
409
- this.currentApiBaseUrl = payload.apiBaseUrl;
410
- this.currentEntrypoint = payload.entrypoint;
411
- this.currentConnected = true;
412
-
413
- // Apply initial path from host URL fragment
414
- if (payload.initialPath) {
415
- this.suppressHashChange = true;
416
- window.location.hash = payload.initialPath;
417
- this.currentPath = payload.initialPath;
418
- this.suppressHashChange = false;
419
- } else {
420
- this.currentPath = this.getHashPath();
421
- }
422
-
423
- // Start observing hash changes
424
- this.setupHashTracking();
425
-
426
- for (const cb of this.initCallbacks) {
427
- cb(payload);
428
- }
429
-
430
- // Ack semantics — driven by the renderer's config.json
431
- // (`deferReady` field). Declaring it in config rather than as a
432
- // constructor option keeps all renderer metadata in one place
433
- // (alongside permissions / sandbox / connectHosts / buildHash)
434
- // and avoids a code-vs-config-disagreement footgun.
435
- this.ackDeferred = payload.config?.deferReady === true;
436
- if (!this.ackDeferred) {
437
- this.sendAck();
438
- } else {
439
- this.readyTimeoutHandle = setTimeout(() => {
440
- if (this.destroyed || this.ackSent) return;
441
- // Best-effort log so an operator can spot the late ack
442
- // in dev tools; production console noise is acceptable
443
- // here because this only fires when something is wrong.
444
- console.warn(
445
- '[uplim] signalReady() not called within ' +
446
- this.readyTimeoutMs + 'ms — auto-acking so the host overlay can dismiss.',
447
- );
448
- this.sendAck();
449
- }, this.readyTimeoutMs);
450
- }
451
- }
452
-
453
- /**
454
- * Post the deferred ack so the host overlay dismisses. No-op once
455
- * the ack has been sent (the host-side bridge tolerates duplicates
456
- * but we suppress them here for cleanliness). When `deferReady` was
457
- * not set on construction this is also a no-op — the SDK already
458
- * acked synchronously on init.
459
- */
460
- signalReady(): void {
461
- if (this.destroyed || this.ackSent || !this.ackDeferred) return;
462
- this.sendAck();
463
- }
464
-
465
- private sendAck(): void {
466
- if (this.ackSent) return;
467
- this.ackSent = true;
468
- if (this.readyTimeoutHandle) {
469
- clearTimeout(this.readyTimeoutHandle);
470
- this.readyTimeoutHandle = null;
471
- }
472
- this.postToHost({ type: 'uplim:ack' });
473
- }
474
-
475
- private handleThemeUpdate(message: HostThemeUpdateMessage): void {
476
- this.currentTheme = message.theme;
477
- for (const cb of this.themeCallbacks) {
478
- cb(message.theme);
479
- }
480
- }
481
-
482
- private handleTokenRefresh(message: HostTokenRefreshMessage): void {
483
- this.currentToken = message.token;
484
- this.currentTokenExpiresAt = message.tokenExpiresAt;
485
-
486
- // Resolve any pending requestTokenAsync() calls
487
- const resolvers = this.pendingTokenResolvers;
488
- this.pendingTokenResolvers = [];
489
- for (const resolve of resolvers) {
490
- resolve({ token: message.token, expiresAt: message.tokenExpiresAt });
491
- }
492
-
493
- for (const cb of this.tokenCallbacks) {
494
- cb(message.token, message.tokenExpiresAt);
495
- }
496
- }
497
-
498
- private handleGenerateTokenResult(message: HostGenerateTokenResultMessage): void {
499
- const pending = this.pendingGenerateTokenResolvers.get(message.requestId);
500
- if (pending) {
501
- this.pendingGenerateTokenResolvers.delete(message.requestId);
502
- pending.resolve({ accepted: message.accepted });
503
- }
504
- }
505
-
506
- private getHashPath(): string {
507
- const hash = window.location.hash;
508
- if (!hash || hash === '#') return '/';
509
- // Strip leading '#' (and optional leading '#/')
510
- return hash.startsWith('#/') ? hash.slice(1) : hash.slice(1);
511
- }
512
-
513
- private onHashChanged(isPush: boolean): void {
514
- if (this.destroyed || this.suppressHashChange) return;
515
-
516
- const newPath = this.getHashPath();
517
- if (newPath === this.currentPath) return;
518
-
519
- this.currentPath = newPath;
520
-
521
- const msg: IframeHistoryPushMessage | IframeHistoryReplaceMessage = isPush
522
- ? { type: 'uplim:historyPush', path: newPath }
523
- : { type: 'uplim:historyReplace', path: newPath };
524
- this.postToHost(msg);
525
-
526
- for (const cb of this.navigateCallbacks) {
527
- cb(newPath);
528
- }
529
- }
530
-
531
- private setupHashTracking(): void {
532
- if (this.hashChangeListener) return;
533
-
534
- // Listen for direct hash changes (e.g. window.location.hash = '...' or <a href="#...">)
535
- this.hashChangeListener = () => this.onHashChanged(true);
536
- window.addEventListener('hashchange', this.hashChangeListener);
537
-
538
- // Patch pushState/replaceState — hash routers use these instead of setting
539
- // window.location.hash directly, and they don't fire hashchange.
540
- this.originalPushState = window.history.pushState.bind(window.history);
541
- this.originalReplaceState = window.history.replaceState.bind(window.history);
542
-
543
- const self = this;
544
- window.history.pushState = function (...args: Parameters<typeof history.pushState>) {
545
- self.originalPushState!(...args);
546
- self.onHashChanged(true);
547
- };
548
- window.history.replaceState = function (...args: Parameters<typeof history.replaceState>) {
549
- self.originalReplaceState!(...args);
550
- self.onHashChanged(false);
551
- };
552
- this.historyPatched = true;
553
- }
554
-
555
- private postToHost(message: object): void {
556
- if (this.destroyed) return;
557
- window.parent.postMessage(message, this.targetOrigin);
558
- }
559
-
560
- /**
561
- * Install window-level crash hooks the moment the client is constructed
562
- * (i.e. as soon as a renderer touches the SDK). We deliberately do this
563
- * here — not in a React-only entry point — so that even renderers that
564
- * forget to wrap their root in `<RendererErrorBoundary>` still report
565
- * async / global failures to the host.
566
- *
567
- * The two hooks cover the failure modes a React boundary can't see:
568
- * - `window.error` — synchronous throws outside React's tree (raw
569
- * <script> bugs, event-handler exceptions, image onerror handlers).
570
- * - `unhandledrejection` — Promise chains with no `.catch()`, which
571
- * are surprisingly common in fetch-heavy renderers.
572
- *
573
- * Both fire-and-forget via `postCrashToHost`; the host decides whether
574
- * to render the overlay (a single render-time crash usually warrants
575
- * it, a stray unhandled rejection may not).
576
- */
577
- private installCrashHooks(): void {
578
- if (typeof window === 'undefined') return;
579
-
580
- this.errorListener = (event: ErrorEvent) => {
581
- if (this.destroyed) return;
582
- // Prefer event.error for the real stack; fall back to a synthetic
583
- // shape when the browser only gave us message/filename/lineno
584
- // (cross-origin scripts strip event.error to null).
585
- const thrown = event.error ?? {
586
- name: 'ErrorEvent',
587
- message: event.message || 'Uncaught error',
588
- stack: event.filename
589
- ? `at ${event.filename}:${event.lineno ?? '?'}:${event.colno ?? '?'}`
590
- : '',
591
- };
592
- this.reportCrash('error', thrown);
593
- };
594
- window.addEventListener('error', this.errorListener);
595
-
596
- this.rejectionListener = (event: PromiseRejectionEvent) => {
597
- if (this.destroyed) return;
598
- this.reportCrash('unhandled-rejection', event.reason);
599
- };
600
- window.addEventListener('unhandledrejection', this.rejectionListener);
601
- }
602
-
603
- /**
604
- * Forward a crash to the host. Called by the global hooks and by
605
- * `<RendererErrorBoundary>`; renderers may also call it explicitly if
606
- * they catch something themselves and want it surfaced (e.g. data-load
607
- * failure that wipes the UI even though no exception escaped).
608
- *
609
- * No-throw: telemetry must never make the underlying crash worse.
610
- */
611
- reportCrash(kind: RendererCrashKind, thrown: unknown): void {
612
- try {
613
- const msg: IframeCrashMessage = buildCrashMessage(kind, thrown);
614
- postCrashToHost(msg, this.targetOrigin);
615
- } catch {
616
- // Swallowed on purpose — see above.
617
- }
618
- }
619
- }
package/src/index.ts DELETED
@@ -1,47 +0,0 @@
1
- export { RendererClient } from './client.js';
2
- export type { RendererClientOptions } from './client.js';
3
-
4
- export type {
5
- RendererConfig,
6
- RendererPermission,
7
- RendererScope,
8
- RendererBucketScope,
9
- RendererFolderScope,
10
- RendererUploadScope,
11
- RendererVirtualFileScope,
12
- RenderingType,
13
- InitPayload,
14
- RendererApiAdapter,
15
- } from './types.js';
16
-
17
- export {
18
- MESSAGE_PREFIX,
19
- PROTOCOL_VERSION,
20
- isRendererMessage,
21
- isHostMessage,
22
- isIframeMessage,
23
- buildCrashMessage,
24
- postCrashToHost,
25
- } from './protocol.js';
26
-
27
- export type {
28
- HostMessage,
29
- HostInitMessage,
30
- HostThemeUpdateMessage,
31
- HostTokenRefreshMessage,
32
- HostGenerateTokenResultMessage,
33
- HostHistoryBackMessage,
34
- HostHistoryForwardMessage,
35
- IframeMessage,
36
- IframeReadyMessage,
37
- IframeOpenUploadMessage,
38
- IframeTokenRequestMessage,
39
- IframeCloseMessage,
40
- IframeInitAckMessage,
41
- IframeGenerateTokenMessage,
42
- IframeHistoryPushMessage,
43
- IframeHistoryReplaceMessage,
44
- IframeCrashMessage,
45
- RendererCrashKind,
46
- RendererMessage,
47
- } from './protocol.js';