Chore: fix linting errors

This commit is contained in:
Pieter Vander Vennet 2025-04-01 03:06:37 +02:00
parent b71c275025
commit ec04afe4d1

View file

@ -1,5 +1,6 @@
import { Utils } from "../Utils" import { Utils } from "../Utils"
import { Readable, Subscriber, Unsubscriber, Updater, Writable } from "svelte/store" import { Readable, Subscriber, Unsubscriber, Updater, Writable } from "svelte/store"
/** /**
* Various static utils * Various static utils
*/ */
@ -104,6 +105,24 @@ export class Stores {
}) })
return newStore return newStore
} }
public static fromArray<T>(sources: ReadonlyArray<UIEventSource<T>>): UIEventSource<T[]> {
const src = new UIEventSource<T[]>(sources.map(s => s.data))
for (let i = 0; i < sources.length; i++) {
sources[i].addCallback(content => {
src.data[i] = content
src.ping()
})
}
src.addCallbackD(contents => {
for (let i = 0; i < contents.length; i++) {
sources[i].setData(contents[i])
}
})
return src
}
} }
export abstract class Store<T> implements Readable<T> { export abstract class Store<T> implements Readable<T> {
@ -129,16 +148,16 @@ export abstract class Store<T> implements Readable<T> {
} }
abstract map<J>(f: (t: T) => J): Store<J> abstract map<J>(f: (t: T) => J): Store<J>
abstract map<J>(f: (t: T) => J, extraStoresToWatch: Store<any>[]): Store<J> abstract map<J>(f: (t: T) => J, extraStoresToWatch: Store<unknown>[]): Store<J>
abstract map<J>( abstract map<J>(
f: (t: T) => J, f: (t: T) => J,
extraStoresToWatch: Store<any>[], extraStoresToWatch: Store<unknown>[],
callbackDestroyFunction: (f: () => void) => void callbackDestroyFunction: (f: () => void) => void
): Store<J> ): Store<J>
public mapD<J>( public mapD<J>(
f: (t: Exclude<T, undefined | null>) => J, f: (t: Exclude<T, undefined | null>) => J,
extraStoresToWatch?: Store<any>[], extraStoresToWatch?: Store<unknown>[],
callbackDestroyFunction?: (f: () => void) => void callbackDestroyFunction?: (f: () => void) => void
): Store<J> { ): Store<J> {
return this.map( return this.map(
@ -241,7 +260,7 @@ export abstract class Store<T> implements Readable<T> {
* src.setData(0) * src.setData(0)
* lastValue // => "def" * lastValue // => "def"
*/ */
public bind<X>(f: (t: T) => Store<X>, extraSources: Store<object>[] = []): Store<X> { public bind<X>(f: (t: T) => Store<X>, extraSources: Store<unknown>[] = []): Store<X> {
const mapped = this.map(f, extraSources) const mapped = this.map(f, extraSources)
const sink = new UIEventSource<X>(undefined) const sink = new UIEventSource<X>(undefined)
const seenEventSources = new Set<Store<X>>() const seenEventSources = new Set<Store<X>>()
@ -275,7 +294,7 @@ export abstract class Store<T> implements Readable<T> {
public bindD<X>( public bindD<X>(
f: (t: Exclude<T, undefined | null>) => Store<X>, f: (t: Exclude<T, undefined | null>) => Store<X>,
extraSources: Store<any>[] = [] extraSources: Store<unknown>[] = []
): Store<X> { ): Store<X> {
return this.bind((t) => { return this.bind((t) => {
if (t === null) { if (t === null) {
@ -295,10 +314,9 @@ export abstract class Store<T> implements Readable<T> {
const newSource = new UIEventSource<T>(this.data) const newSource = new UIEventSource<T>(this.data)
const self = this
this.addCallback((latestData) => { this.addCallback((latestData) => {
window.setTimeout(() => { window.setTimeout(() => {
if (self.data == latestData) { if (this.data == latestData) {
// compare by reference. // compare by reference.
// Note that 'latestData' and 'self.data' are both from the same UIEVentSource, but both are dereferenced at a different time // Note that 'latestData' and 'self.data' are both from the same UIEVentSource, but both are dereferenced at a different time
newSource.setData(latestData) newSource.setData(latestData)
@ -316,14 +334,13 @@ export abstract class Store<T> implements Readable<T> {
* @constructor * @constructor
*/ */
public AsPromise(condition?: (t: T) => boolean): Promise<T> { public AsPromise(condition?: (t: T) => boolean): Promise<T> {
const self = this
condition = condition ?? ((t) => t !== undefined) condition = condition ?? ((t) => t !== undefined)
return new Promise((resolve) => { return new Promise((resolve) => {
const data = self.data const data = this.data
if (condition(data)) { if (condition(data)) {
resolve(data) resolve(data)
} else { } else {
self.addCallbackD((data) => { this.addCallbackD((data) => {
if (condition(data)) { if (condition(data)) {
resolve(data) resolve(data)
return true // return true to unregister as we only need to be called once return true // return true to unregister as we only need to be called once
@ -338,7 +355,7 @@ export abstract class Store<T> implements Readable<T> {
/** /**
* Same as 'addCallbackAndRun', added to be compatible with Svelte * Same as 'addCallbackAndRun', added to be compatible with Svelte
*/ */
public subscribe(run: Subscriber<T> & ((value: T) => void), _?): Unsubscriber { public subscribe(run: Subscriber<T> & ((value: T) => void)): Unsubscriber {
// We don't need to do anything with 'invalidate', see // We don't need to do anything with 'invalidate', see
// https://github.com/sveltejs/svelte/issues/3859 // https://github.com/sveltejs/svelte/issues/3859
@ -451,7 +468,7 @@ class ListenerTracker<T> {
public ping(data: T): number { public ping(data: T): number {
this.pingCount++ this.pingCount++
let toDelete = undefined let toDelete = undefined
let startTime = new Date().getTime() / 1000 const startTime = new Date().getTime() / 1000
for (const callback of this._callbacks) { for (const callback of this._callbacks) {
try { try {
if (callback(data) === true) { if (callback(data) === true) {
@ -467,7 +484,7 @@ class ListenerTracker<T> {
console.error("Got an error while running a callback:", e) console.error("Got an error while running a callback:", e)
} }
} }
let endTime = new Date().getTime() / 1000 const endTime = new Date().getTime() / 1000
if (endTime - startTime > 500) { if (endTime - startTime > 500) {
console.trace( console.trace(
"Warning: a ping took more then 500ms; this is probably a performance issue" "Warning: a ping took more then 500ms; this is probably a performance issue"
@ -495,13 +512,13 @@ class ListenerTracker<T> {
* The mapped store is a helper type which does the mapping of a function. * The mapped store is a helper type which does the mapping of a function.
*/ */
class MappedStore<TIn, T> extends Store<T> { class MappedStore<TIn, T> extends Store<T> {
private static readonly pass: () => {} private static readonly pass: () => void
private readonly _upstream: Store<TIn> private readonly _upstream: Store<TIn>
private readonly _upstreamCallbackHandler: ListenerTracker<TIn> | undefined private readonly _upstreamCallbackHandler: ListenerTracker<TIn> | undefined
private _upstreamPingCount: number = -1 private _upstreamPingCount: number = -1
private _unregisterFromUpstream: () => void private _unregisterFromUpstream: () => void
private readonly _f: (t: TIn) => T private readonly _f: (t: TIn) => T
private readonly _extraStores: Store<any>[] | undefined private readonly _extraStores: Store<unknown>[] | undefined
private _unregisterFromExtraStores: (() => void)[] | undefined private _unregisterFromExtraStores: (() => void)[] | undefined
private _callbacks: ListenerTracker<T> = new ListenerTracker<T>() private _callbacks: ListenerTracker<T> = new ListenerTracker<T>()
private _callbacksAreRegistered = false private _callbacksAreRegistered = false
@ -509,7 +526,7 @@ class MappedStore<TIn, T> extends Store<T> {
constructor( constructor(
upstream: Store<TIn>, upstream: Store<TIn>,
f: (t: TIn) => T, f: (t: TIn) => T,
extraStores: Store<any>[], extraStores: Store<unknown>[],
upstreamListenerHandler: ListenerTracker<TIn> | undefined, upstreamListenerHandler: ListenerTracker<TIn> | undefined,
initialState: T, initialState: T,
onDestroy?: (f: () => void) => void onDestroy?: (f: () => void) => void
@ -551,10 +568,10 @@ class MappedStore<TIn, T> extends Store<T> {
map<J>( map<J>(
f: (t: T) => J, f: (t: T) => J,
extraStores: Store<any>[] = undefined, extraStores: Store<unknown>[] = undefined,
ondestroyCallback?: (f: () => void) => void ondestroyCallback?: (f: () => void) => void
): Store<J> { ): Store<J> {
let stores: Store<any>[] = undefined let stores: Store<unknown>[] = undefined
if (extraStores?.length > 0 || this._extraStores?.length > 0) { if (extraStores?.length > 0 || this._extraStores?.length > 0) {
stores = [] stores = []
} }
@ -578,7 +595,7 @@ class MappedStore<TIn, T> extends Store<T> {
) )
} }
addCallback(callback: (data: T) => any | boolean | void): () => void { addCallback(callback: (data: T) => unknown | boolean | void): () => void {
if (!this._callbacksAreRegistered) { if (!this._callbacksAreRegistered) {
// This is the first callback that is added // This is the first callback that is added
// We register this 'map' to the upstream object and all the streams // We register this 'map' to the upstream object and all the streams
@ -593,7 +610,7 @@ class MappedStore<TIn, T> extends Store<T> {
} }
} }
addCallbackAndRun(callback: (data: T) => any | boolean | void): () => void { addCallbackAndRun(callback: (data: T) => unknown | boolean | void): () => void {
const unregister = this.addCallback(callback) const unregister = this.addCallback(callback)
const doRemove = callback(this.data) const doRemove = callback(this.data)
if (doRemove === true) { if (doRemove === true) {
@ -603,7 +620,7 @@ class MappedStore<TIn, T> extends Store<T> {
return unregister return unregister
} }
addCallbackAndRunD(callback: (data: T) => any | boolean | void): () => void { addCallbackAndRunD(callback: (data: T) => unknown | boolean | void): () => void {
return this.addCallbackAndRun((data) => { return this.addCallbackAndRun((data) => {
if (data !== undefined) { if (data !== undefined) {
return callback(data) return callback(data)
@ -611,7 +628,7 @@ class MappedStore<TIn, T> extends Store<T> {
}) })
} }
addCallbackD(callback: (data: T) => any | boolean | void): () => void { addCallbackD(callback: (data: T) => unknown | boolean | void): () => void {
return this.addCallback((data) => { return this.addCallback((data) => {
if (data !== undefined) { if (data !== undefined) {
return callback(data) return callback(data)
@ -626,9 +643,9 @@ class MappedStore<TIn, T> extends Store<T> {
} }
private registerCallbacksToUpstream() { private registerCallbacksToUpstream() {
this._unregisterFromUpstream = this._upstream.addCallback((_) => this.update()) this._unregisterFromUpstream = this._upstream.addCallback(() => this.update())
this._unregisterFromExtraStores = this._extraStores?.map((store) => this._unregisterFromExtraStores = this._extraStores?.map((store) =>
store?.addCallback((_) => this.update()) store?.addCallback(() => this.update())
) )
this._callbacksAreRegistered = true this._callbacksAreRegistered = true
} }
@ -827,11 +844,11 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
* If the result of the callback is 'true', the callback is considered finished and will be removed again * If the result of the callback is 'true', the callback is considered finished and will be removed again
* @param callback * @param callback
*/ */
public addCallback(callback: (latestData: T) => boolean | void | any): () => void { public addCallback(callback: (latestData: T) => boolean | void | unknown): () => void {
return this._callbacks.addCallback(callback) return this._callbacks.addCallback(callback)
} }
public addCallbackAndRun(callback: (latestData: T) => boolean | void | any): () => void { public addCallbackAndRun(callback: (latestData: T) => boolean | void | unknown): () => void {
const doDeleteCallback = callback(this.data) const doDeleteCallback = callback(this.data)
if (doDeleteCallback !== true) { if (doDeleteCallback !== true) {
return this.addCallback(callback) return this.addCallback(callback)
@ -896,7 +913,7 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
*/ */
public map<J>( public map<J>(
f: (t: T) => J, f: (t: T) => J,
extraSources: Store<any>[] = [], extraSources: Store<unknown>[] = [],
onDestroy?: (f: () => void) => void onDestroy?: (f: () => void) => void
): Store<J> { ): Store<J> {
return new MappedStore(this, f, extraSources, this._callbacks, f(this.data), onDestroy) return new MappedStore(this, f, extraSources, this._callbacks, f(this.data), onDestroy)
@ -908,7 +925,7 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
*/ */
public mapD<J>( public mapD<J>(
f: (t: Exclude<T, undefined | null>) => J, f: (t: Exclude<T, undefined | null>) => J,
extraSources: Store<any>[] = [], extraSources: Store<unknown>[] = [],
callbackDestroyFunction?: (f: () => void) => void callbackDestroyFunction?: (f: () => void) => void
): Store<J | undefined> { ): Store<J | undefined> {
return new MappedStore( return new MappedStore(
@ -926,7 +943,7 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
this._callbacks, this._callbacks,
this.data === undefined || this.data === null this.data === undefined || this.data === null
? <undefined | null>this.data ? <undefined | null>this.data
: f(<any>this.data), : f(<Exclude<T, undefined | null>>this.data),
callbackDestroyFunction callbackDestroyFunction
) )
} }
@ -945,7 +962,7 @@ export class UIEventSource<T> extends Store<T> implements Writable<T> {
*/ */
public sync<J>( public sync<J>(
f: (t: T) => J, f: (t: T) => J,
extraSources: Store<any>[], extraSources: Store<unknown>[],
g: (j: J, t: T) => T, g: (j: J, t: T) => T,
allowUnregister = false allowUnregister = false
): UIEventSource<J> { ): UIEventSource<J> {