1- // @flow
2-
3- import gensync , { type Handler } from "gensync" ;
1+ import gensync from "gensync" ;
2+ import type { Handler } from "gensync" ;
43import {
54 maybeAsync ,
65 isAsync ,
@@ -12,60 +11,61 @@ import { isIterableIterator } from "./util";
1211
1312export type { CacheConfigurator } ;
1413
15- export type SimpleCacheConfigurator = SimpleCacheConfiguratorFn &
16- SimpleCacheConfiguratorObj ;
14+ export type SimpleCacheConfigurator = {
15+ ( forever : boolean ) : void ;
16+ < T > ( handler : ( ) => T ) : T ;
1717
18- type SimpleCacheConfiguratorFn = {
19- ( boolean ) : void ,
20- < T > ( handler : ( ) => T ) : T ,
21- } ;
22- type SimpleCacheConfiguratorObj = {
23- forever : ( ) => void ,
24- never : ( ) => void ,
25- using : < T > ( handler : ( ) => T ) => T ,
26- invalidate : < T > ( handler : ( ) => T ) => T ,
18+ forever : ( ) => void ;
19+ never : ( ) => void ;
20+ using : < T > ( handler : ( ) => T ) => T ;
21+ invalidate : < T > ( handler : ( ) => T ) => T ;
2722} ;
2823
2924export type CacheEntry < ResultT , SideChannel > = Array < {
30- value : ResultT ,
31- valid : SideChannel => Handler < boolean > ,
25+ value : ResultT ;
26+ valid : ( channel : SideChannel ) => Handler < boolean > ;
3227} > ;
3328
34- const synchronize = < ArgsT , ResultT > (
35- gen : ( ...ArgsT ) => Handler < ResultT > ,
36- // $FlowIssue https://github.com/facebook/flow/issues/7279
29+ const synchronize = < ArgsT extends any [ ] , ResultT > (
30+ gen : ( ...args : ArgsT ) => Handler < ResultT > ,
3731) : ( ( ...args : ArgsT ) => ResultT ) => {
3832 return gensync ( gen ) . sync ;
3933} ;
4034
41- // eslint-disable-next-line require-yield, no-unused-vars
42- function * genTrue ( data : any ) {
35+ // eslint-disable-next-line require-yield
36+ function * genTrue ( ) {
4337 return true ;
4438}
4539
46- export function makeWeakCache < ArgT , ResultT , SideChannel > (
47- handler : ( ArgT , CacheConfigurator < SideChannel > ) => Handler < ResultT > | ResultT ,
48- ) : ( ArgT , SideChannel ) => Handler < ResultT > {
49- return makeCachedFunction < ArgT , ResultT , SideChannel , * > ( WeakMap , handler ) ;
40+ export function makeWeakCache < ArgT extends object , ResultT , SideChannel > (
41+ handler : (
42+ arg : ArgT ,
43+ cache : CacheConfigurator < SideChannel > ,
44+ ) => Handler < ResultT > | ResultT ,
45+ ) : ( arg : ArgT , data : SideChannel ) => Handler < ResultT > {
46+ return makeCachedFunction < ArgT , ResultT , SideChannel > ( WeakMap , handler ) ;
5047}
5148
52- export function makeWeakCacheSync < ArgT , ResultT , SideChannel > (
53- handler : ( ArgT , CacheConfigurator < SideChannel > ) => ResultT ,
54- ) : ( ArgT , SideChannel ) => ResultT {
49+ export function makeWeakCacheSync < ArgT extends object , ResultT , SideChannel > (
50+ handler : ( arg : ArgT , cache ?: CacheConfigurator < SideChannel > ) => ResultT ,
51+ ) : ( arg : ArgT , data ?: SideChannel ) => ResultT {
5552 return synchronize < [ ArgT , SideChannel ] , ResultT > (
5653 makeWeakCache < ArgT , ResultT , SideChannel > ( handler ) ,
5754 ) ;
5855}
5956
6057export function makeStrongCache < ArgT , ResultT , SideChannel > (
61- handler : ( ArgT , CacheConfigurator < SideChannel > ) => Handler < ResultT > | ResultT ,
62- ) : ( ArgT , SideChannel ) => Handler < ResultT > {
63- return makeCachedFunction < ArgT , ResultT , SideChannel , * > ( Map , handler ) ;
58+ handler : (
59+ arg : ArgT ,
60+ cache : CacheConfigurator < SideChannel > ,
61+ ) => Handler < ResultT > | ResultT ,
62+ ) : ( arg : ArgT , data : SideChannel ) => Handler < ResultT > {
63+ return makeCachedFunction < ArgT , ResultT , SideChannel > ( Map , handler ) ;
6464}
6565
6666export function makeStrongCacheSync < ArgT , ResultT , SideChannel > (
67- handler : ( ArgT , CacheConfigurator < SideChannel > ) => ResultT ,
68- ) : ( ArgT , SideChannel ) => ResultT {
67+ handler : ( arg : ArgT , cache ?: CacheConfigurator < SideChannel > ) => ResultT ,
68+ ) : ( arg : ArgT , data ?: SideChannel ) => ResultT {
6969 return synchronize < [ ArgT , SideChannel ] , ResultT > (
7070 makeStrongCache < ArgT , ResultT , SideChannel > ( handler ) ,
7171 ) ;
@@ -96,13 +96,16 @@ export function makeStrongCacheSync<ArgT, ResultT, SideChannel>(
9696 * 6. Store the result in the cache
9797 * 7. RETURN the result
9898 */
99- function makeCachedFunction < ArgT , ResultT , SideChannel , Cache : * > (
100- CallCache : Class < Cache > ,
101- handler : ( ArgT , CacheConfigurator < SideChannel > ) => Handler < ResultT > | ResultT ,
102- ) : ( ArgT , SideChannel ) => Handler < ResultT > {
103- const callCacheSync = new CallCache ( ) ;
104- const callCacheAsync = new CallCache ( ) ;
105- const futureCache = new CallCache ( ) ;
99+ function makeCachedFunction < ArgT , ResultT , SideChannel > (
100+ CallCache : new < Cached > ( ) => CacheMap < ArgT , Cached , SideChannel > ,
101+ handler : (
102+ arg : ArgT ,
103+ cache : CacheConfigurator < SideChannel > ,
104+ ) => Handler < ResultT > | ResultT ,
105+ ) : ( arg : ArgT , data : SideChannel ) => Handler < ResultT > {
106+ const callCacheSync = new CallCache < ResultT > ( ) ;
107+ const callCacheAsync = new CallCache < ResultT > ( ) ;
108+ const futureCache = new CallCache < Lock < ResultT > > ( ) ;
106109
107110 return function * cachedFunction ( arg : ArgT , data : SideChannel ) {
108111 const asyncContext = yield * isAsync ( ) ;
@@ -121,19 +124,17 @@ function makeCachedFunction<ArgT, ResultT, SideChannel, Cache: *>(
121124
122125 const handlerResult : Handler < ResultT > | ResultT = handler ( arg , cache ) ;
123126
124- let finishLock : ? Lock < ResultT > ;
127+ let finishLock : Lock < ResultT > ;
125128 let value : ResultT ;
126129
127130 if ( isIterableIterator ( handlerResult ) ) {
128- // Flow refines handlerResult to Generator<any, any, any>
129- const gen = ( handlerResult : Generator < * , ResultT , * > ) ;
131+ const gen = handlerResult as Generator < unknown , ResultT , unknown > ;
130132
131133 value = yield * onFirstPause ( gen , ( ) => {
132134 finishLock = setupAsyncLocks ( cache , futureCache , arg ) ;
133135 } ) ;
134136 } else {
135- // $FlowIgnore doesn't refine handlerResult to ResultT
136- value = ( handlerResult : ResultT ) ;
137+ value = handlerResult ;
137138 }
138139
139140 updateFunctionCache ( callCache , cache , arg , value ) ;
@@ -149,19 +150,14 @@ function makeCachedFunction<ArgT, ResultT, SideChannel, Cache: *>(
149150
150151type CacheMap < ArgT , ResultT , SideChannel > =
151152 | Map < ArgT , CacheEntry < ResultT , SideChannel > >
153+ // @ts -expect-error todo(flow->ts): add `extends object` constraint to ArgT
152154 | WeakMap < ArgT , CacheEntry < ResultT , SideChannel > > ;
153155
154- function * getCachedValue <
155- ArgT ,
156- ResultT ,
157- SideChannel ,
158- // $FlowIssue https://github.com/facebook/flow/issues/4528
159- Cache : CacheMap < ArgT , ResultT , SideChannel > ,
160- > (
161- cache : Cache ,
156+ function * getCachedValue < ArgT , ResultT , SideChannel > (
157+ cache : CacheMap < ArgT , ResultT , SideChannel > ,
162158 arg : ArgT ,
163159 data : SideChannel ,
164- ) : Handler < { valid : true , value : ResultT } | { valid : false , value : null } > {
160+ ) : Handler < { valid : true ; value : ResultT } | { valid : false ; value : null } > {
165161 const cachedValue : CacheEntry < ResultT , SideChannel > | void = cache . get ( arg ) ;
166162
167163 if ( cachedValue ) {
@@ -179,7 +175,7 @@ function* getCachedValueOrWait<ArgT, ResultT, SideChannel>(
179175 futureCache : CacheMap < ArgT , Lock < ResultT > , SideChannel > ,
180176 arg : ArgT ,
181177 data : SideChannel ,
182- ) : Handler < { valid : true , value : ResultT } | { valid : false , value : null } > {
178+ ) : Handler < { valid : true ; value : ResultT } | { valid : false ; value : null } > {
183179 const cached = yield * getCachedValue ( callCache , arg , data ) ;
184180 if ( cached . valid ) {
185181 return cached ;
@@ -212,8 +208,7 @@ function updateFunctionCache<
212208 ArgT ,
213209 ResultT ,
214210 SideChannel ,
215- // $FlowIssue https://github.com/facebook/flow/issues/4528
216- Cache : CacheMap < ArgT , ResultT , SideChannel > ,
211+ Cache extends CacheMap < ArgT , ResultT , SideChannel >
217212> (
218213 cache : Cache ,
219214 config : CacheConfigurator < SideChannel > ,
@@ -253,7 +248,9 @@ class CacheConfigurator<SideChannel = void> {
253248
254249 _configured : boolean = false ;
255250
256- _pairs : Array < [ mixed , ( SideChannel ) => Handler < mixed > ] > = [ ] ;
251+ _pairs : Array <
252+ [ cachedValue : unknown , handler : ( data : SideChannel ) => Handler < unknown > ]
253+ > = [ ] ;
257254
258255 _data : SideChannel ;
259256
@@ -294,7 +291,7 @@ class CacheConfigurator<SideChannel = void> {
294291 this . _configured = true ;
295292 }
296293
297- using < T > ( handler : SideChannel => T ) : T {
294+ using < T > ( handler : ( data : SideChannel ) => T ) : T {
298295 if ( ! this . _active ) {
299296 throw new Error ( "Cannot change caching after evaluation has completed." ) ;
300297 }
@@ -313,7 +310,8 @@ class CacheConfigurator<SideChannel = void> {
313310 ) ;
314311
315312 if ( isThenable ( key ) ) {
316- return key . then ( ( key : mixed ) => {
313+ // @ts -expect-error todo(flow->ts): improve function return type annotation
314+ return key . then ( ( key : unknown ) => {
317315 this . _pairs . push ( [ key , fn ] ) ;
318316 return key ;
319317 } ) ;
@@ -323,12 +321,12 @@ class CacheConfigurator<SideChannel = void> {
323321 return key ;
324322 }
325323
326- invalidate < T > ( handler : SideChannel => T ) : T {
324+ invalidate < T > ( handler : ( data : SideChannel ) => T ) : T {
327325 this . _invalidate = true ;
328326 return this . using ( handler ) ;
329327 }
330328
331- validator ( ) : SideChannel => Handler < boolean > {
329+ validator ( ) : ( data : SideChannel ) => Handler < boolean > {
332330 const pairs = this . _pairs ;
333331 return function * ( data : SideChannel ) {
334332 for ( const [ key , fn ] of pairs ) {
@@ -364,7 +362,7 @@ function makeSimpleConfigurator(
364362 cacheFn . using = cb => cache . using ( ( ) => assertSimpleType ( cb ( ) ) ) ;
365363 cacheFn . invalidate = cb => cache . invalidate ( ( ) => assertSimpleType ( cb ( ) ) ) ;
366364
367- return ( cacheFn : any ) ;
365+ return cacheFn as any ;
368366}
369367
370368// Types are limited here so that in the future these values can be used
@@ -376,7 +374,7 @@ export type SimpleType =
376374 | null
377375 | void
378376 | Promise < SimpleType > ;
379- export function assertSimpleType ( value : mixed ) : SimpleType {
377+ export function assertSimpleType ( value : unknown ) : SimpleType {
380378 if ( isThenable ( value ) ) {
381379 throw new Error (
382380 `You appear to be using an async cache handler, ` +
@@ -397,6 +395,7 @@ export function assertSimpleType(value: mixed): SimpleType {
397395 "Cache keys must be either string, boolean, number, null, or undefined." ,
398396 ) ;
399397 }
398+ // @ts -expect-error todo(flow->ts) value is still typed as unknown, also assert function typically should not return a value
400399 return value ;
401400}
402401
0 commit comments