I'm writing scalajs facade for pouchdb
code : https://gist.github.com/chandu0101/62013de47bf5ee4d2412
how to define facade for API name changes which emits events and return a cancel method ..
Defining Scala.js facade types is all about giving static types to a JavaScript API. Usually the documentation of the JavaScript does mention types, which can therefore be translated into a formal definition pretty easily.
In this case, the changes
methods returns an EventEmitter
, which is the first thing you need. Let us define this type, and in particular its on
method:
class EventEmitter extends js.Object {
def on(event: String, listener: js.Function): this.type = js.native
...
}
We have to be very imprecise for the type of listener
, unfortunately, because the actual type will very much depend on the event string, and the particular uses of that emitter. In general, we cannot predict anything at this point.
The documentation of EventEmitter
doesn't mention a cancel()
method, which is a bit weird since apparently that method can be called on the emitter returned by changes
. So we'll define a subtype for the particular emitter returned by changes
:
trait ChangesEventEmitter extends EventEmitter {
def cancel(): Unit = js.native
}
We can also take advantage of this specialized trait to enable a more precise type of listener for particular events. In this case, let us do it for the change
event:
object ChangesEventEmitter {
implicit class ChangesEventEmitterEvents(
val self: ChangesEventEmitter) extends AnyVal {
def onChange(listener: js.Function1[js.Dynamic, Any]): self.type =
self.on("change", listener)
}
}
Finally, you need a type for the options
parameter of the db.changes
method. The type itself is usually a trait with many immutable fields:
trait DBChangesOptions extends js.Object {
val include_docs: js.UndefOr[Boolean] = js.native
val limit: js.UndefOr[Int] = js.native
...
}
To construct an instance of such a type, you may either go with an apply
method in the companion object with default arguments (see this SO question), or you can create a Builder
-like class for it.
And now, we can finally declare the changes
method itself:
def changes(options: DBChangesOptions = ???): ChangesEventEmitter = js.native