Skip to content

Commit

Permalink
Fix memoize TC39 changes
Browse files Browse the repository at this point in the history
  • Loading branch information
garethj2 committed Apr 25, 2024
1 parent 7b84708 commit 254f630
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 23 deletions.
12 changes: 6 additions & 6 deletions spec/util/memoize.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,15 @@ describe('memoize', () => {
'increment'
)?.get

const obj = memoize()(getter, {
const func = memoize()(getter, {
name: 'increment',
kind: 'getter',
} as unknown as ClassMethodDecoratorContext) as any

const util = new MathUtil()

expect(obj.get.call(util)).toBe(1)
expect(obj.get.call(util)).toBe(1)
expect(func.call(util)).toBe(1)
expect(func.call(util)).toBe(1)
})
}) // TC39
}) // getters
Expand Down Expand Up @@ -123,18 +123,18 @@ describe('memoize', () => {
}
}

const obj = memoize()(StrUtil.prototype.add, {
const func = memoize()(StrUtil.prototype.add, {
name: 'add',
kind: 'method',
} as ClassMethodDecoratorContext) as any

const util = new StrUtil()

let result = obj.value.call(util, 1, 2)
let result = func.call(util, 1, 2)
expect(result).toBe(3)
expect(util.counter).toBe(1)

result = obj.value.call(util, 1, 2)
result = func.call(util, 1, 2)
expect(result).toBe(3)
expect(util.counter).toBe(1)
})
Expand Down
45 changes: 28 additions & 17 deletions src/util/memoize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,11 @@ export function memoize(): (
target: any,
context: string | ClassMemberDecoratorContext,
descriptor?: PropertyDescriptor
): PropertyDescriptor {
): any {
let propKey = ''
let get: any
let value: any
let tc39 = false

if (typeof context === 'string') {
propKey = context
Expand All @@ -220,6 +221,8 @@ export function memoize(): (
context?.name &&
typeof context.name === 'string'
) {
tc39 = true

// Support newer decorator standard (TC39). Found some issues
// with certain build processes where we need to dynamically
// support both standards.
Expand All @@ -236,27 +239,35 @@ export function memoize(): (
}

if (typeof get === 'function') {
return {
get(): any {
const cache = getCache(this)

return cache.has(propKey)
? cache.get(propKey)
: cache.set(propKey, get.call(this))
},
const getter = function (this: any): any {
const cache = getCache(this)

return cache.has(propKey)
? cache.get(propKey)
: cache.set(propKey, get.call(this))
}

return tc39
? getter
: {
get: getter,
}
} else if (typeof value === 'function') {
return {
value(...args: any[]): any {
const cache = getCache(this)
const method = function (this: any, ...args: any[]): any {
const cache = getCache(this)

const key = JSON.stringify({ propKey, args })
const key = JSON.stringify({ propKey, args })

return cache.has(key)
? cache.get(key)
: cache.set(key, value.apply(this, args))
},
return cache.has(key)
? cache.get(key)
: cache.set(key, value.apply(this, args))
}

return tc39
? method
: {
value: method,
}
} else {
throw new Error('Only class methods and getters can be memoized')
}
Expand Down

0 comments on commit 254f630

Please sign in to comment.