From 92e18a3f6bbb5a403447700a28fd64aa4129a8b8 Mon Sep 17 00:00:00 2001 From: Roman Dvornov Date: Mon, 25 Nov 2024 03:56:48 +0100 Subject: [PATCH] Add general purpose notification API for embed --- CHANGELOG.md | 2 ++ src/extensions/embed-client.ts | 12 ++++++++++++ src/extensions/embed-host.ts | 4 ++++ src/extensions/embed-message.types.ts | 1 + 4 files changed, 19 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 988802c..78d2bbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ - Added `Model#legacyPrepare` readonly property to indicate whether the legacy `prepare` method is used or the new `setup()` method - Updated `struct` view to define the `setStructViewAnnotations` action when using the new `setup()` method, allowing custom annotations to be specified across all `struct` views - Updated `embed` option of `App` to accept a config +- Added `EmbedApp#publicApi.notify(name, details)` method for sending notifications +- Introduced `onNotify(name, details)` option in the embed extension to define a callback for handling `notification` messages from the embed host - Added `EmbedApp#publicApi.setLocationSync()` method to simplify sync between the embed app and the host location, preventing potential pitfalls - Added `ViewModel#enforceScheduledRenders()` to immediately execute scheduled renders - Changed `ViewModel#scheduleRender()` to use `setTimeout()` instead of `Promise.resolve()` to ensure proper processing of event loop tasks, eliminating unnecessary renders diff --git a/src/extensions/embed-client.ts b/src/extensions/embed-client.ts index 14d0bcf..885c648 100644 --- a/src/extensions/embed-client.ts +++ b/src/extensions/embed-client.ts @@ -10,6 +10,7 @@ import { loadDataFromPush, loadDataFromStream } from '../core/utils/load-data.js export type EmbedClientOptions = { hostId: string; postponeMessages: EmbedHostToClientPostponeMessage[]; + onNotify: (name: string, details: any) => void; }; export type LoadDataChunkedStatus = LoadDataFromPush & { @@ -44,6 +45,9 @@ function createNavItemConfig(rawConfig: unknown, sendMessage: SendMessage, rawCo function setup(options?: Partial) { const hostId = options?.hostId || randomId(); const postponeMessages = options?.postponeMessages; + const onNotify = typeof options?.onNotify === 'function' + ? options.onNotify + : () => {}; return function(host: ViewModel) { let loadChunkedDataStatus: LoadDataChunkedStatus | null = null; @@ -87,6 +91,14 @@ function setup(options?: Partial) { if (id === hostId) { switch (type) { + case 'notification': { + const { name, details } = payload; + + onNotify(name, details); + + break; + } + case 'defineAction': { const name = payload; host.action.define(name, (...args) => diff --git a/src/extensions/embed-host.ts b/src/extensions/embed-host.ts index 538179e..4858ff4 100644 --- a/src/extensions/embed-host.ts +++ b/src/extensions/embed-host.ts @@ -163,6 +163,10 @@ class EmbedApp extends BaseApp { nav: Object.assign(nav.secondary, nav), + notify(name: string, details: any) { + app.sendMessage('notification', { name, details }); + }, + defineAction(name: string, fn: (...args: unknown[]) => unknown) { app.actions.set(name, fn); app.sendMessage('defineAction', name); diff --git a/src/extensions/embed-message.types.ts b/src/extensions/embed-message.types.ts index f98c62c..3ad7fe6 100644 --- a/src/extensions/embed-message.types.ts +++ b/src/extensions/embed-message.types.ts @@ -42,6 +42,7 @@ export type EmbedHostToClientPostponeMessage = Extract & { replace?: boolean; }; setPageRef: { ref: PageRef; replace?: boolean; };