experiments(dui3): adds an event emitter base class
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { createNanoEvents, Emitter } from 'nanoevents'
|
||||
|
||||
/**
|
||||
* A simple (typed) event emitter base class that host applications can use to send messages (and data) to the web ui,
|
||||
* e.g. via `browser.executeScriptAsync("myBindings.on('eventName', serializedData)")`.
|
||||
|
||||
*/
|
||||
export class BaseBridge {
|
||||
private emitter: Emitter
|
||||
|
||||
constructor() {
|
||||
this.emitter = createNanoEvents()
|
||||
}
|
||||
|
||||
// NOTE: these do not need to be typed extra in here, as they will be properly typed on the specific binding's interface.
|
||||
on(event: string | number, callback: (...args: unknown[]) => void) {
|
||||
return this.emitter.on(event, callback)
|
||||
}
|
||||
|
||||
emit(eventName: string, payload: string) {
|
||||
const parsedPayload = JSON.parse(payload) as unknown
|
||||
this.emitter.emit(eventName, parsedPayload)
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,14 @@
|
||||
import { IWebUiBinding } from '~/types'
|
||||
import { createNanoEvents, Emitter } from 'nanoevents'
|
||||
import { HostAppEvents } from '~/types'
|
||||
|
||||
export class CefSharpBridge {
|
||||
private emitter: Emitter
|
||||
import { BaseBridge } from '~/lib/bridge/base'
|
||||
|
||||
export class CefSharpBridge extends BaseBridge {
|
||||
constructor(bindingObject: IWebUiBinding) {
|
||||
super()
|
||||
const hoistTarget = this as unknown as Record<string, unknown>
|
||||
const hoistSource = bindingObject as unknown as Record<string, unknown>
|
||||
|
||||
for (const key in bindingObject) {
|
||||
hoistTarget[key] = hoistSource[key]
|
||||
}
|
||||
|
||||
this.emitter = createNanoEvents<HostAppEvents>()
|
||||
this.emitter.emit('start', 'polo pasta')
|
||||
}
|
||||
|
||||
on<E extends keyof HostAppEvents>(event: E, callback: HostAppEvents[E]) {
|
||||
return this.emitter.on(event, callback)
|
||||
}
|
||||
|
||||
emit(eventName: string, payload: string) {
|
||||
const parsedPayload = JSON.parse(payload) as unknown
|
||||
this.emitter.emit(eventName, parsedPayload)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// TODO
|
||||
import { uniqueId } from 'lodash-es'
|
||||
import { BaseBridge } from './base'
|
||||
|
||||
declare let sketchup: {
|
||||
exec: (data: Record<string, unknown>) => void
|
||||
@@ -11,8 +11,9 @@ declare let sketchup: {
|
||||
* This class basically makes the sketchup bindings work in the same way as cef/webview by returning a promise
|
||||
* on each method call. That promise is either resolved once sketchup sends back (via receiveResponse) a corresponding
|
||||
* reply, or it's rejected after a given TIMEOUT_MS (currently 2s).
|
||||
* TODO: implement the event dispatcher side as well.
|
||||
*/
|
||||
export class SketchupBridge {
|
||||
export class SketchupBridge extends BaseBridge {
|
||||
private requests = {} as Record<
|
||||
string,
|
||||
{
|
||||
@@ -27,6 +28,7 @@ export class SketchupBridge {
|
||||
private resolveIsInitializedPromise!: () => unknown
|
||||
|
||||
constructor(bindingsName: string) {
|
||||
super()
|
||||
this.bindingsName = bindingsName || 'default_bindings'
|
||||
|
||||
this.isInitalized = new Promise((resolve, reject) => {
|
||||
@@ -104,8 +106,9 @@ export class SketchupBridge {
|
||||
)
|
||||
const request = this.requests[requestId]
|
||||
try {
|
||||
const parsedData = JSON.parse(data) as Record<string, unknown> // TODO: check if data is undefined
|
||||
request.resolve(parsedData)
|
||||
// NOTE/TODO: does not need parsing
|
||||
// const parsedData = JSON.parse(data) as Record<string, unknown> // TODO: check if data is undefined
|
||||
request.resolve(data)
|
||||
} catch (e) {
|
||||
request.reject(e as Error)
|
||||
} finally {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
// github.com/johot/WebView2-better-bridge/blob/master/web-ui/src/betterBridge.ts
|
||||
import { createNanoEvents, Emitter } from 'nanoevents'
|
||||
import { HostAppEvents } from '~/types'
|
||||
import { BaseBridge } from '~/lib/bridge/base'
|
||||
|
||||
type IWebView2 = {
|
||||
webview: {
|
||||
@@ -17,11 +16,11 @@ type IRawBridge = {
|
||||
|
||||
declare let chrome: IWebView2
|
||||
|
||||
export class WebView2Bridge {
|
||||
export class WebView2Bridge extends BaseBridge {
|
||||
private webViewBridge: IRawBridge
|
||||
private emitter: Emitter
|
||||
|
||||
constructor(bridgeName: string) {
|
||||
super()
|
||||
this.webViewBridge = chrome.webview.hostObjects[bridgeName]
|
||||
|
||||
// NOTE: GetMethods is a call to the .NET side.
|
||||
@@ -36,8 +35,6 @@ export class WebView2Bridge {
|
||||
hoistTarget[lowercasedMethodName] = (...args: unknown[]) =>
|
||||
this.runMethod(methodName, args)
|
||||
}
|
||||
|
||||
this.emitter = createNanoEvents<HostAppEvents>()
|
||||
}
|
||||
|
||||
private async runMethod(methodName: string, args: unknown[]): Promise<unknown> {
|
||||
@@ -50,15 +47,6 @@ export class WebView2Bridge {
|
||||
|
||||
return JSON.parse(result) as unknown
|
||||
}
|
||||
|
||||
on<E extends keyof HostAppEvents>(event: E, callback: HostAppEvents[E]) {
|
||||
return this.emitter.on(event, callback)
|
||||
}
|
||||
|
||||
emit(eventName: string, payload: string) {
|
||||
const parsedPayload = JSON.parse(payload) as unknown
|
||||
this.emitter.emit(eventName, parsedPayload)
|
||||
}
|
||||
}
|
||||
|
||||
const lowercaseMethodName = (name: string) =>
|
||||
|
||||
Reference in New Issue
Block a user