-
-
Notifications
You must be signed in to change notification settings - Fork 60
fix(Cache): typescript Map generic type fixed
#308
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
dimaslanjaka
wants to merge
50
commits into
hexojs:master
Choose a base branch
from
dimaslanjaka:fix-cache
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
50 commits
Select commit
Hold shift + click to select a range
3d4784f
chore(Cache.apply): implement generic type
dimaslanjaka 41137fd
fix: generic type
dimaslanjaka 95492ad
chore: implement cache mapper
dimaslanjaka dfe4ddd
fix(TypeError): Cannot read property 'should' of undefined
dimaslanjaka 8e32e9c
chore: restore old export style
dimaslanjaka 7e54cf4
refactor: change cache import
dimaslanjaka 0130bdb
chore: set cache size on `set` and `del` triggerred
dimaslanjaka 3abcc5d
chore: make cache mapper prop to private
dimaslanjaka af55eba
chore: restore back `cache` property
dimaslanjaka e663b44
refactor: update imports
dimaslanjaka 8cb3c0f
feat: set size while flusing cache
dimaslanjaka ae3780f
chore: moved `dump` into `Cache`
dimaslanjaka 06d32c6
feat: implement typescript tests
dimaslanjaka c9b8997
refactor: update `dump` test
dimaslanjaka da25618
feat(Cache): add typescript test
dimaslanjaka fb6b487
refactor: rename test file
dimaslanjaka 7943cfd
refactor: rename step
dimaslanjaka e239a39
feat: validate size after add same value with function
dimaslanjaka 55ab91f
chore: split `CacheMapper`
dimaslanjaka d233f1b
feat: add `CacheType`
dimaslanjaka 992a9fc
chore: separate `Cache` then import to `cache.ts`
dimaslanjaka 287f2cb
fix: `Cache` private name exports
dimaslanjaka 61dbdd1
refactor: cancel d233f1b
dimaslanjaka 1ed3491
docs(apply): add JSDoc to each overload types
dimaslanjaka 1ece3d5
docs: update JSDoc
dimaslanjaka cb3b0b3
docs: update JSDoc
dimaslanjaka 0f416fe
chore: update JSDoc, fix invalid usage sample
dimaslanjaka 5617efd
refactor: rename test cache number
dimaslanjaka b29c506
feat validate cache exist
dimaslanjaka 5706883
feat: add object test
dimaslanjaka 1553dcf
docs: update JSDoc usage
dimaslanjaka 7147f60
docs: update JSDoc usage
dimaslanjaka d5b37ef
Merge branch 'fix-cache' of https://github.com/dimaslanjaka/hexo-util…
dimaslanjaka c2a8dbe
refactor: add test-single script
dimaslanjaka 40b8a19
refactor: register test object & rename file test number
dimaslanjaka 1622437
chore(CacheMapper): make `size` readonly modifier
dimaslanjaka 1fd5511
chore: treat `CacheMapper` as internal
dimaslanjaka bb697bf
chore(CacheMapper): `_innerMap` using readonly modifier
dimaslanjaka 41210cf
chore: detach `flush` from `CacheMapper`
dimaslanjaka 2ba8147
chore: detach `apply` from `CacheMapper`
dimaslanjaka 055391d
fix: Type 'V' is not assignable to 'V & (() => V)'
dimaslanjaka 2cb48ad
fix: invalid map size
dimaslanjaka d984e19
docs: update `apply` JSDoc
dimaslanjaka db24238
refactor: update Cache object test
dimaslanjaka ddc98e3
refactor: disable typescript non-null assertion
dimaslanjaka 6134ed2
feat: add built-in `Map` object test
dimaslanjaka 9c40705
feat: add built-in `Set` object test
dimaslanjaka 722f7d2
docs: update JSDoc
dimaslanjaka b9a3449
docs: update JSDoc
dimaslanjaka ddb89ec
Merge branch 'fix-cache' of https://github.com/dimaslanjaka/hexo-util…
dimaslanjaka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| /** @internal */ | ||
| export class CacheMapper<K, V> implements Map<K, V> { | ||
| private readonly _innerMap: Map<K, V>; | ||
| readonly size: number; | ||
|
|
||
| constructor() { | ||
| this._innerMap = new Map(); | ||
| } | ||
| clear(): void { | ||
| this._innerMap.clear(); | ||
| } | ||
| delete(key: K): boolean { | ||
| throw this._innerMap.delete(key); | ||
| } | ||
| // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
| forEach(callbackfn: (value: V, key: K, map: Map<K, V>) => void, thisArg?: any): void { | ||
| return this._innerMap.forEach(callbackfn, thisArg); | ||
| } | ||
| entries(): IterableIterator<[K, V]> { | ||
| return this._innerMap.entries(); | ||
| } | ||
| keys(): IterableIterator<K> { | ||
| return this._innerMap.keys(); | ||
| } | ||
| values(): IterableIterator<V> { | ||
| return this._innerMap.values(); | ||
| } | ||
| [Symbol.iterator](): IterableIterator<[K, V]> { | ||
| return this._innerMap.entries(); | ||
| } | ||
| [Symbol.toStringTag]: string; | ||
|
|
||
| typeof() { | ||
| return typeof this._innerMap; | ||
| } | ||
|
|
||
| set(id: K, value: V) { | ||
| this._innerMap.set(id, value); | ||
| // set cache size while set new value | ||
| // this.size = this._innerMap.size; | ||
| return this; | ||
| } | ||
|
|
||
| has(id: K) { | ||
| return this._innerMap.has(id); | ||
| } | ||
|
|
||
| get(id: K) { | ||
| return this._innerMap.get(id); | ||
| } | ||
|
|
||
| del(id: K) { | ||
| this._innerMap.delete(id); | ||
| // set cache size while delete value | ||
| // this.size = this._innerMap.size; | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Generic Mutable Cache with `Map` | ||
| * * A Map holds key-value pairs where the keys can be any datatype (Generic) | ||
| * @example | ||
| * import { Cache } from 'hexo-util'; | ||
| * const c = new Cache<number>(); | ||
| * // error | ||
| * c.set('key', 'xxxx'); // cache value must be instance of number | ||
| * // pass | ||
| * c.set('key', 1); | ||
| */ | ||
| export class Cache<V> { | ||
| private cache: CacheMapper<string, V>; | ||
| constructor() { | ||
| this.cache = new CacheMapper<string, V>(); | ||
| } | ||
|
|
||
| /** | ||
| * check cache is exist with given key | ||
| * @param key cache key string | ||
| * @returns | ||
| */ | ||
| has(key: string) { | ||
| return this.cache.has(key); | ||
| } | ||
|
|
||
| /** | ||
| * get cache | ||
| * @param key | ||
| * @returns | ||
| */ | ||
| get(key: string) { | ||
| return this.cache.get(key); | ||
| } | ||
|
|
||
| /** | ||
| * set cache | ||
| * @param key | ||
| * @param value cache value must same as constructor generic type | ||
| * @returns | ||
| */ | ||
| set(key: string, value: V) { | ||
| return this.cache.set(key, value); | ||
| } | ||
|
|
||
| /** | ||
| * dump cache | ||
| * @returns | ||
| */ | ||
| dump() { | ||
| return Object.fromEntries(this.cache); | ||
| } | ||
|
|
||
| /** | ||
| * get cache total | ||
| * @returns | ||
| */ | ||
| size() { | ||
| return Array.from(this.cache.keys()).length; | ||
| } | ||
|
|
||
| /** | ||
| * cacheable setter non-function | ||
| * * new value will never updated when previous key already exist | ||
| * @param key cache key string | ||
| * @param value cache value must same as constructor generic type | ||
| */ | ||
| apply(key: string, value: V): V; | ||
|
|
||
| /** | ||
| * cacheable setter with function | ||
| * * new value will never updated when previous key already exist | ||
| * @param key cache key string | ||
| * @param value cache value must same as constructor generic type | ||
| */ | ||
| apply(key: string, value: () => V): V; | ||
|
|
||
| /** | ||
| * cacheable setter | ||
| * * new value will never updated when previous key already exist | ||
| * @param key cache key string | ||
| * @param value cache value must same as constructor generic type | ||
| */ | ||
| apply(id: string, value: V & (() => V)) { | ||
| if (this.has(id)) return this.get(id); | ||
| let newValue: V; | ||
| if (typeof value === 'function') { | ||
| newValue = value(); | ||
| } else { | ||
| newValue = value; | ||
| } | ||
|
|
||
| this.cache.set(id, newValue); | ||
| return newValue; | ||
| } | ||
|
|
||
| del(key: string) { | ||
| return this.cache.del(key); | ||
| } | ||
| flush() { | ||
| this.cache.clear(); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,44 +1,3 @@ | ||
| export = class Cache<T> { | ||
| cache: Map<string, T>; | ||
| import { Cache } from './CacheMapper'; | ||
|
|
||
| constructor() { | ||
| this.cache = new Map(); | ||
| } | ||
|
|
||
| set(id: string, value: T) { | ||
| this.cache.set(id, value); | ||
| } | ||
|
|
||
| has(id: string) { | ||
| return this.cache.has(id); | ||
| } | ||
|
|
||
| get(id: string) { | ||
| return this.cache.get(id); | ||
| } | ||
|
|
||
| del(id: string) { | ||
| this.cache.delete(id); | ||
| } | ||
|
|
||
| apply(id: string, value): T { | ||
| if (this.has(id)) return this.get(id); | ||
|
|
||
| if (typeof value === 'function') value = value(); | ||
|
|
||
| this.set(id, value); | ||
| return value; | ||
| } | ||
|
|
||
| flush() { | ||
| this.cache.clear(); | ||
| } | ||
|
|
||
| size() { | ||
| return this.cache.size; | ||
| } | ||
|
|
||
| dump() { | ||
| return Object.fromEntries(this.cache); | ||
| } | ||
| }; | ||
| export = Cache; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,16 @@ | ||
| { | ||
| "extends": "hexo/test", | ||
| "overrides": [ | ||
| { | ||
| "files": ["*.ts"], | ||
| "rules": { | ||
| "node/no-unsupported-features/es-syntax": 0, | ||
| "@typescript-eslint/no-non-null-assertion": 0 | ||
| } | ||
| } | ||
| ], | ||
| "rules": { | ||
| "@typescript-eslint/no-var-requires": 0, | ||
| "@typescript-eslint/no-empty-function": 0 | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| 'use strict'; | ||
|
|
||
| import { describe, it } from 'mocha'; | ||
| import * as Hutil from '../lib'; | ||
| import { expect } from 'chai'; | ||
|
|
||
| // to run single test | ||
| // npm run test-single -- "Cache - number" | ||
|
|
||
| describe('Cache - number', () => { | ||
| const cache = new Hutil.Cache<number>(); | ||
| const dumpExpect = { foo: 1, bar: 2 }; | ||
|
|
||
| it('should be number', () => { | ||
| // apply non-function | ||
| expect(cache.apply('foo', 1)).to.be.an('number'); | ||
| // apply with function | ||
| expect(cache.apply('bar', () => 2)).to.be.an('number'); | ||
| // validate cache exist | ||
| expect(cache.has('foo') && cache.has('bar')).to.be.true; | ||
| }); | ||
|
|
||
| it('add another and delete it', () => { | ||
| // add `another` | ||
| expect(cache.apply('another', 3)).to.equal(3); | ||
| // size should be 3 | ||
| expect(cache.size()).to.equal(3); | ||
| // add with function | ||
| expect(cache.apply('another', () => 3)).to.equal(3); | ||
| // size should be still 3 | ||
| expect(cache.size()).to.equal(3); | ||
| // delete `another` | ||
| cache.del('another'); | ||
| }); | ||
|
|
||
| it('final size should be 2', () => { | ||
| // final size should be 2 | ||
| expect(cache.size()).to.equal(2); | ||
| }); | ||
|
|
||
| it('should dump matches', () => { | ||
| expect(cache.dump()).deep.equal(dumpExpect); | ||
| }); | ||
|
|
||
| it('should be empty after flush', () => { | ||
| cache.flush(); | ||
| expect(cache.size()).to.be.equal(0); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.