@socketsupply/socket
Version:
A Cross-Platform, Native Runtime for Desktop and Mobile Apps — Create apps using HTML, CSS, and JavaScript. Written from the ground up to be small and maintainable.
137 lines (117 loc) • 2.68 kB
JavaScript
import { AsyncResource } from '../async/resource.js'
import platform from './platform.js'
import gc from '../gc.js'
export class Timer extends AsyncResource {
#id = 0
#create = null
#destroy = null
#destroyed = false
static from (...args) {
const timer = new this()
return timer.init(...args)
}
constructor (type, create, destroy) {
super(type, { requireManualDestroy: true })
if (typeof create !== 'function') {
throw new TypeError('Timer creator must be a function')
}
if (typeof destroy !== 'function') {
throw new TypeError('Timer destroyer must be a function')
}
this.#create = (callback, ...args) => {
return create((...args) => this.runInAsyncScope(callback, globalThis, ...args), ...args)
}
this.#destroy = (...args) => {
if (typeof destroy === 'function') {
destroy(...args)
}
this.#destroyed = true
this.emitDestroy()
}
}
get id () {
return this.#id
}
get destroyed () {
return this.#destroyed
}
init (...args) {
this.#id = this.#create(...args)
gc.ref(this)
return this
}
close () {
if (this.#id) {
this.#destroy(this.#id)
this.#id = 0
return true
}
return false
}
[Symbol.toPrimitive] () {
return this.#id
}
[gc.finalizer] () {
const finalizer = super[gc.finalizer] ? super[gc.finalizer]() : null
return {
args: [this.id, this.#destroy],
handle (id, destroy) {
destroy(id)
if (finalizer?.handle && finalizer?.args) {
finalizer.handle(...finalizer.args)
} else if (finalizer?.handle) {
finalizer.handle()
}
}
}
}
}
export class Timeout extends Timer {
constructor () {
super(
'Timeout',
(callback, delay, ...args) => {
return platform.setTimeout(
(...args) => {
this.close()
// eslint-disable-next-line
callback(...args)
},
delay,
...args
)
},
platform.clearTimeout
)
}
}
export class Interval extends Timer {
constructor () {
super('Interval', platform.setInterval, platform.clearInterval)
}
}
export class Immediate extends Timer {
constructor () {
super(
'Immediate',
(callback, _, ...args) => {
return platform.setImmediate(
(...args) => {
this.close()
// eslint-disable-next-line
callback(...args)
},
0,
...args
)
},
platform.clearImmediate
)
}
}
export default {
Timer,
Immediate,
Timeout,
Interval
}