style(gjs): binding runtime private properties

so people don't try to access the emitter
This commit is contained in:
Aylur
2024-09-17 23:32:46 +00:00
parent 1cceb88514
commit 95c2658ce7

View File

@@ -21,10 +21,11 @@ export interface Connectable {
} }
export default class Binding<Value> { export default class Binding<Value> {
private emitter: Subscribable<Value> | Connectable
private prop?: string
private transformFn = (v: any) => v private transformFn = (v: any) => v
#emitter: Subscribable<Value> | Connectable
#prop?: string
static bind< static bind<
T extends Connectable, T extends Connectable,
P extends keyof T, P extends keyof T,
@@ -37,51 +38,51 @@ export default class Binding<Value> {
} }
private constructor(emitter: Connectable | Subscribable<Value>, prop?: string) { private constructor(emitter: Connectable | Subscribable<Value>, prop?: string) {
this.emitter = emitter this.#emitter = emitter
this.prop = prop && kebabify(prop) this.#prop = prop && kebabify(prop)
} }
toString() { toString() {
return `Binding<${this.emitter}${this.prop ? `, "${this.prop}"` : ""}>` return `Binding<${this.#emitter}${this.#prop ? `, "${this.#prop}"` : ""}>`
} }
as<T>(fn: (v: Value) => T): Binding<T> { as<T>(fn: (v: Value) => T): Binding<T> {
const bind = new Binding(this.emitter, this.prop) const bind = new Binding(this.#emitter, this.#prop)
bind.transformFn = (v: Value) => fn(this.transformFn(v)) bind.transformFn = (v: Value) => fn(this.transformFn(v))
return bind as unknown as Binding<T> return bind as unknown as Binding<T>
} }
get(): Value { get(): Value {
if (typeof this.emitter.get === "function") if (typeof this.#emitter.get === "function")
return this.transformFn(this.emitter.get()) return this.transformFn(this.#emitter.get())
if (typeof this.prop === "string") { if (typeof this.#prop === "string") {
const getter = `get_${snakeify(this.prop)}` const getter = `get_${snakeify(this.#prop)}`
if (typeof this.emitter[getter] === "function") if (typeof this.#emitter[getter] === "function")
return this.transformFn(this.emitter[getter]()) return this.transformFn(this.#emitter[getter]())
return this.transformFn(this.emitter[this.prop]) return this.transformFn(this.#emitter[this.#prop])
} }
throw Error("can not get value of binding") throw Error("can not get value of binding")
} }
subscribe(callback: (value: Value) => void): () => void { subscribe(callback: (value: Value) => void): () => void {
if (typeof this.emitter.subscribe === "function") { if (typeof this.#emitter.subscribe === "function") {
return this.emitter.subscribe(() => { return this.#emitter.subscribe(() => {
callback(this.get()) callback(this.get())
}) })
} }
else if (typeof this.emitter.connect === "function") { else if (typeof this.#emitter.connect === "function") {
const signal = `notify::${this.prop}` const signal = `notify::${this.#prop}`
const id = this.emitter.connect(signal, () => { const id = this.#emitter.connect(signal, () => {
callback(this.get()) callback(this.get())
}) })
return () => { return () => {
(this.emitter.disconnect as Connectable["disconnect"])(id) (this.#emitter.disconnect as Connectable["disconnect"])(id)
} }
} }
throw Error(`${this.emitter} is not bindable`) throw Error(`${this.#emitter} is not bindable`)
} }
} }