Skip to content

Commit

Permalink
feat: adds defineIdleProperty helper class (#9)
Browse files Browse the repository at this point in the history
* chore: adds more strict type checking for idleValue class

* feat: adds defineIdleProperty helper class

---------

Co-authored-by: Harsh Kumar Choudhary <harsh.choudhary@HARSH-CHOUDHARY-MAC.local>
  • Loading branch information
harshkc and Harsh Kumar Choudhary authored Mar 4, 2024
1 parent f05e56d commit 42a2a3f
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
19 changes: 7 additions & 12 deletions src/IdleValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ import { cIC, rIC } from './idleCbWithPolyfill'
/**
* A class that wraps a value that is initialized when idle.
*/
export class IdleValue<F extends () => any> {
private init_: F
private value_?: ReturnType<F>
export class IdleValue<T, TInitFunc extends () => T> {
private init_: TInitFunc
private value_?: T
private idleHandle_?: number
initialized: boolean = false

/**
* Accepts a function to initialize the value of a variable when idle.
*/
constructor(init: F) {
constructor(init: TInitFunc) {
if (typeof init !== 'function')
throw new TypeError('init must be a function')

Expand All @@ -34,9 +34,7 @@ export class IdleValue<F extends () => any> {
* initializer function is run immediately and the pending idle callback
* is cancelled.
*/
getValue(): ReturnType<F> extends undefined
? ReturnType<F>
: Exclude<ReturnType<F>, undefined> {
getValue(): T {
if (!this.initialized) {
this.cancelIdleInit_()
try {
Expand All @@ -46,13 +44,10 @@ export class IdleValue<F extends () => any> {
console.error('Error getting value:', error)
}
}
return this.value_ as Exclude<ReturnType<F>, undefined>
return this.value_! // Assert non-null value
}

setValue(newValue: ReturnType<F>): void {
if (newValue === undefined)
throw new Error('newValue cannot be undefined')

setValue(newValue: T): void {
this.cancelIdleInit_()
this.value_ = newValue
this.initialized = true
Expand Down
16 changes: 16 additions & 0 deletions src/defineIdleProperties.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { defineIdleProperty } from './defineIdleProperty'

export function defineIdleProperties<T, K extends PropertyKey>( // K for Key type
obj: Record<K, any>,
props: Record<K, () => T>,
): void {
Object.keys(props).forEach((propAsString) => {
const prop = propAsString as K // Type assertion
try {
defineIdleProperty(obj, prop, props[prop])
}
catch (error) {
console.error(`Error defining idle property '${propAsString}':`, error)
}
})
}
21 changes: 21 additions & 0 deletions src/defineIdleProperty.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { IdleValue } from './IdleValue'

export function defineIdleProperty<T, TInitFunc extends () => T, K extends PropertyKey>( // Add K
obj: Record<K, any>,
prop: K,
init: TInitFunc,
): void {
if (!obj || typeof obj !== 'object')
throw new TypeError('obj must be an object')

if (!prop)
throw new Error('prop must be provided')

const idleValue = new IdleValue<T, TInitFunc>(init)

Object.defineProperty(obj, prop, {
configurable: true,
get: idleValue.getValue.bind(idleValue),
set: idleValue.setValue.bind(idleValue),
})
}

0 comments on commit 42a2a3f

Please sign in to comment.