-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds the cache API specified in RFC 615. Since this API is essentially just exposing the API that was implemented in Glimmer VM, and tested there, I don't think tests are necessary to add in Ember itself.
- Loading branch information
Chris Garrett
committed
May 19, 2020
1 parent
7618403
commit d392665
Showing
5 changed files
with
146 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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 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,128 @@ | ||
import { createCache as glimmerCreateCache, getValue, isConst } from '@glimmer/validator'; | ||
|
||
/** | ||
Ember uses caching based on trackable values to avoid updating large portions | ||
of the application. This caching is exposed via a cache primitive that can be | ||
used to cache a specific computation, so that it will not update and will | ||
return the cached value until a tracked value used in its computation has | ||
updated. | ||
@module @glimmer/tracking/primitives/cache | ||
@public | ||
*/ | ||
|
||
/** | ||
Receives a function, and returns a wrapped version of it that memoizes based on | ||
_autotracking_. The function will only rerun whenever any tracked values used | ||
within it have changed. Otherwise, it will return the previous value. | ||
```js | ||
import { tracked } from '@glimmer/tracking'; | ||
import { createCache, getValue } from '@glimmer/tracking/primitives/cache'; | ||
class State { | ||
@tracked value; | ||
} | ||
let state = new State(); | ||
let computeCount = 0; | ||
let counter = createCache(() => { | ||
// consume the state. Now, `counter` will | ||
// only rerun if `state.value` changes. | ||
state.value; | ||
return ++computeCount; | ||
}); | ||
getValue(counter); // 1 | ||
// returns the same value because no tracked state has changed | ||
getValue(counter); // 1 | ||
state.value = 'foo'; | ||
// reruns because a tracked value used in the function has changed, | ||
// incermenting the counter | ||
getValue(counter); // 2 | ||
``` | ||
@method createCache | ||
@static | ||
@for @glimmer/tracking/primitives/cache | ||
@public | ||
*/ | ||
export function createCache<T>(fn: () => T) { | ||
return glimmerCreateCache(fn); | ||
} | ||
|
||
/** | ||
Gets the value of a cache created with `createCache`. | ||
```js | ||
import { tracked } from '@glimmer/tracking'; | ||
import { createCache, getValue } from '@glimmer/tracking/primitives/cache'; | ||
let computeCount = 0; | ||
let counter = createCache(() => { | ||
return ++computeCount; | ||
}); | ||
getValue(counter); // 1 | ||
``` | ||
@method getValue | ||
@static | ||
@for @glimmer/tracking/primitives/cache | ||
@public | ||
*/ | ||
|
||
/** | ||
Can be used to check if a memoized function is _constant_. If no tracked state | ||
was used while running a memoized function, it will never rerun, because nothing | ||
can invalidate its result. `isConst` can be used to determine if a memoized | ||
function is constant or not, in order to optimize code surrounding that | ||
function. | ||
```js | ||
import { tracked } from '@glimmer/tracking'; | ||
import { createCache, getValue, isConst } from '@glimmer/tracking/primitives/cache'; | ||
class State { | ||
@tracked value; | ||
} | ||
let state = new State(); | ||
let computeCount = 0; | ||
let counter = createCache(() => { | ||
// consume the state | ||
state.value; | ||
return computeCount++; | ||
}); | ||
let constCounter = createCache(() => { | ||
return computeCount++; | ||
}); | ||
getValue(counter); | ||
getValue(constCounter); | ||
isConst(counter); // false | ||
isConst(constCounter); // true | ||
``` | ||
If called on a cache that hasn't been accessed yet, it will throw an | ||
error. This is because there's no way to know if the function will be constant | ||
or not yet, and so this helps prevent missing an optimization opportunity on | ||
accident. | ||
@method isConst | ||
@static | ||
@for @glimmer/tracking/primitives/cache | ||
@public | ||
*/ | ||
|
||
export { getValue, isConst }; |
This file contains 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 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 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 |
---|---|---|
|
@@ -596,5 +596,8 @@ module.exports = { | |
'wrapModelType', | ||
'wrapRecord', | ||
'yield', | ||
'createCache', | ||
'getValue', | ||
'isConst', | ||
], | ||
}; |