Skip to content

Commit d55f1ac

Browse files
committed
feat: add catch-all "done" event
1 parent ed0f2f1 commit d55f1ac

File tree

3 files changed

+128
-80
lines changed

3 files changed

+128
-80
lines changed

src/cachified.spec.ts

Lines changed: 115 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@ describe('cachified', () => {
7676
6. getFreshValueSuccess
7777
{value: 'ONE'}
7878
7. writeFreshValueSuccess
79-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
79+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
80+
8. done
81+
{value: 'ONE'}"
8082
`);
8183

8284
expect(value2).toBe('ONE');
@@ -87,7 +89,9 @@ describe('cachified', () => {
8789
3. getCachedValueRead
8890
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: 'ONE'}}
8991
4. getCachedValueSuccess
90-
{migrated: false, value: 'ONE'}"
92+
{migrated: false, value: 'ONE'}
93+
5. done
94+
{value: 'ONE'}"
9195
`);
9296
});
9397

@@ -409,7 +413,9 @@ describe('cachified', () => {
409413
3. getCachedValueRead
410414
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: '☁️'}}
411415
4. getCachedValueSuccess
412-
{migrated: true, value: '☀️'}"
416+
{migrated: true, value: '☀️'}
417+
5. done
418+
{value: '☀️'}"
413419
`);
414420
});
415421

@@ -596,7 +602,9 @@ describe('cachified', () => {
596602
6. getFreshValueCacheFallback
597603
{value: 'ONE'}
598604
7. writeFreshValueSuccess
599-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
605+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
606+
8. done
607+
{value: 'ONE'}"
600608
`);
601609
});
602610

@@ -671,16 +679,20 @@ describe('cachified', () => {
671679
{value: 'value-0'}
672680
7. writeFreshValueError
673681
{error: '🔥'}
674-
8. init
682+
8. done
683+
{value: 'value-0'}
684+
9. init
675685
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: null}}
676-
9. getCachedValueStart
677-
10. getCachedValueRead
678-
11. getCachedValueEmpty
679-
12. getFreshValueStart
680-
13. getFreshValueSuccess
686+
10. getCachedValueStart
687+
11. getCachedValueRead
688+
12. getCachedValueEmpty
689+
13. getFreshValueStart
690+
14. getFreshValueSuccess
681691
{value: 'value-1'}
682-
14. writeFreshValueSuccess
683-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
692+
15. writeFreshValueSuccess
693+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
694+
16. done
695+
{value: 'value-1'}"
684696
`);
685697
expect(await getValue()).toBe('value-1');
686698
});
@@ -718,25 +730,31 @@ describe('cachified', () => {
718730
{value: 'value-0'}
719731
7. writeFreshValueSuccess
720732
{metadata: {createdTime: 0, swr: 0, ttl: 5}, migrated: false, written: true}
721-
8. init
733+
8. done
734+
{value: 'value-0'}
735+
9. init
722736
{key: 'test', metadata: {createdTime: 4, swr: 0, ttl: 5}}
723-
9. getCachedValueStart
724-
10. getCachedValueRead
737+
10. getCachedValueStart
738+
11. getCachedValueRead
725739
{entry: {metadata: {createdTime: 0, swr: 0, ttl: 5}, value: 'value-0'}}
726-
11. getCachedValueSuccess
740+
12. getCachedValueSuccess
727741
{migrated: false, value: 'value-0'}
728-
12. init
742+
13. done
743+
{value: 'value-0'}
744+
14. init
729745
{key: 'test', metadata: {createdTime: 6, swr: 0, ttl: 5}}
730-
13. getCachedValueStart
731-
14. getCachedValueRead
746+
15. getCachedValueStart
747+
16. getCachedValueRead
732748
{entry: {metadata: {createdTime: 0, swr: 0, ttl: 5}, value: 'value-0'}}
733-
15. getCachedValueOutdated
749+
17. getCachedValueOutdated
734750
{metadata: {createdTime: 0, swr: 0, ttl: 5}, value: 'value-0'}
735-
16. getFreshValueStart
736-
17. getFreshValueSuccess
751+
18. getFreshValueStart
752+
19. getFreshValueSuccess
737753
{value: 'value-1'}
738-
18. writeFreshValueSuccess
739-
{metadata: {createdTime: 6, swr: 0, ttl: 5}, migrated: false, written: true}"
754+
20. writeFreshValueSuccess
755+
{metadata: {createdTime: 6, swr: 0, ttl: 5}, migrated: false, written: true}
756+
21. done
757+
{value: 'value-1'}"
740758
`);
741759
});
742760

@@ -768,7 +786,9 @@ describe('cachified', () => {
768786
6. getFreshValueSuccess
769787
{value: 'ONE'}
770788
7. writeFreshValueSuccess
771-
{metadata: {createdTime: 0, swr: 0, ttl: 5}, migrated: false, written: false}"
789+
{metadata: {createdTime: 0, swr: 0, ttl: 5}, migrated: false, written: false}
790+
8. done
791+
{value: 'ONE'}"
772792
`);
773793
});
774794

@@ -810,7 +830,11 @@ describe('cachified', () => {
810830
11. getFreshValueSuccess
811831
{value: 'ONE'}
812832
12. writeFreshValueSuccess
813-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
833+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
834+
13. done
835+
{value: 'ONE'}
836+
14. done
837+
{value: 'ONE'}"
814838
`);
815839
});
816840

@@ -905,17 +929,19 @@ describe('cachified', () => {
905929

906930
expect(value).toBe(null);
907931
expect(report(reporter.mock.calls)).toMatchInlineSnapshot(`
908-
"1. init
909-
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: -1}}
910-
2. getCachedValueStart
911-
3. getCachedValueRead
912-
4. getCachedValueEmpty
913-
5. getFreshValueStart
914-
6. getFreshValueSuccess
915-
{value: null}
916-
7. writeFreshValueSuccess
917-
{metadata: {createdTime: 0, swr: 0, ttl: -1}, migrated: false, written: false}"
918-
`);
932+
"1. init
933+
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: -1}}
934+
2. getCachedValueStart
935+
3. getCachedValueRead
936+
4. getCachedValueEmpty
937+
5. getFreshValueStart
938+
6. getFreshValueSuccess
939+
{value: null}
940+
7. writeFreshValueSuccess
941+
{metadata: {createdTime: 0, swr: 0, ttl: -1}, migrated: false, written: false}
942+
8. done
943+
{value: null}"
944+
`);
919945
});
920946

921947
it('resolves earlier pending values with faster responses from later calls', async () => {
@@ -1005,15 +1031,19 @@ describe('cachified', () => {
10051031
{value: 'value-0'}
10061032
7. writeFreshValueSuccess
10071033
{metadata: {createdTime: 0, swr: 10, ttl: 5}, migrated: false, written: true}
1008-
8. init
1034+
8. done
1035+
{value: 'value-0'}
1036+
9. init
10091037
{key: 'test', metadata: {createdTime: 6, swr: 10, ttl: 5}}
1010-
9. getCachedValueStart
1011-
10. getCachedValueRead
1038+
10. getCachedValueStart
1039+
11. getCachedValueRead
10121040
{entry: {metadata: {createdTime: 0, swr: 10, ttl: 5}, value: 'value-0'}}
1013-
11. getCachedValueSuccess
1041+
12. getCachedValueSuccess
10141042
{migrated: false, value: 'value-0'}
1015-
12. refreshValueStart
1016-
13. refreshValueSuccess
1043+
13. done
1044+
{value: 'value-0'}
1045+
14. refreshValueStart
1046+
15. refreshValueSuccess
10171047
{value: 'value-1'}"
10181048
`);
10191049
});
@@ -1134,15 +1164,19 @@ describe('cachified', () => {
11341164
{value: 'value-0'}
11351165
7. writeFreshValueSuccess
11361166
{metadata: {createdTime: 0, swr: 10, ttl: 5}, migrated: false, written: true}
1137-
8. init
1167+
8. done
1168+
{value: 'value-0'}
1169+
9. init
11381170
{key: 'test', metadata: {createdTime: 6, swr: 10, ttl: 5}}
1139-
9. getCachedValueStart
1140-
10. getCachedValueRead
1171+
10. getCachedValueStart
1172+
11. getCachedValueRead
11411173
{entry: {metadata: {createdTime: 0, swr: 10, ttl: 5}, value: 'value-0'}}
1142-
11. getCachedValueSuccess
1174+
12. getCachedValueSuccess
11431175
{migrated: false, value: 'value-0'}
1144-
12. refreshValueStart
1145-
13. refreshValueError
1176+
13. done
1177+
{value: 'value-0'}
1178+
14. refreshValueStart
1179+
15. refreshValueError
11461180
{error: [Error: 💩]}"
11471181
`);
11481182
});
@@ -1167,20 +1201,22 @@ describe('cachified', () => {
11671201

11681202
expect(value).toBe('TWO');
11691203
expect(report(reporter.mock.calls)).toMatchInlineSnapshot(`
1170-
"1. init
1171-
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: null}}
1172-
2. getCachedValueStart
1173-
3. getCachedValueRead
1174-
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: 'ONE'}}
1175-
4. checkCachedValueErrorObj
1176-
{reason: 'unknown'}
1177-
5. checkCachedValueError
1178-
{reason: 'unknown'}
1179-
6. getFreshValueStart
1180-
7. getFreshValueSuccess
1181-
{value: 'TWO'}
1182-
8. writeFreshValueSuccess
1183-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
1204+
" 1. init
1205+
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: null}}
1206+
2. getCachedValueStart
1207+
3. getCachedValueRead
1208+
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: 'ONE'}}
1209+
4. checkCachedValueErrorObj
1210+
{reason: 'unknown'}
1211+
5. checkCachedValueError
1212+
{reason: 'unknown'}
1213+
6. getFreshValueStart
1214+
7. getFreshValueSuccess
1215+
{value: 'TWO'}
1216+
8. writeFreshValueSuccess
1217+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
1218+
9. done
1219+
{value: 'TWO'}"
11841220
`);
11851221

11861222
// the following lines only exist for 100% coverage 😅
@@ -1198,20 +1234,22 @@ describe('cachified', () => {
11981234
});
11991235
expect(value2).toBe('TWO');
12001236
expect(report(reporter2.mock.calls)).toMatchInlineSnapshot(`
1201-
"1. init
1202-
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: null}}
1203-
2. getCachedValueStart
1204-
3. getCachedValueRead
1205-
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: 'ONE'}}
1206-
4. checkCachedValueErrorObj
1207-
{reason: '🖕'}
1208-
5. checkCachedValueError
1209-
{reason: '🖕'}
1210-
6. getFreshValueStart
1211-
7. getFreshValueSuccess
1212-
{value: 'TWO'}
1213-
8. writeFreshValueSuccess
1214-
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}"
1237+
" 1. init
1238+
{key: 'test', metadata: {createdTime: 0, swr: 0, ttl: null}}
1239+
2. getCachedValueStart
1240+
3. getCachedValueRead
1241+
{entry: {metadata: {createdTime: 0, swr: 0, ttl: null}, value: 'ONE'}}
1242+
4. checkCachedValueErrorObj
1243+
{reason: '🖕'}
1244+
5. checkCachedValueError
1245+
{reason: '🖕'}
1246+
6. getFreshValueStart
1247+
7. getFreshValueSuccess
1248+
{value: 'TWO'}
1249+
8. writeFreshValueSuccess
1250+
{metadata: {createdTime: 0, swr: 0, ttl: null}, migrated: false, written: true}
1251+
9. done
1252+
{value: 'TWO'}"
12151253
`);
12161254
});
12171255

src/cachified.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,17 @@ export async function cachified<Value>(
4242
? await getCachedValue(context, report, hasPendingValue)
4343
: CACHE_EMPTY;
4444
if (cachedValue !== CACHE_EMPTY) {
45+
report({ name: 'done', value: cachedValue });
4546
return cachedValue;
4647
}
4748

4849
if (pendingValues.has(key)) {
4950
const { value: pendingRefreshValue, metadata } = pendingValues.get(key)!;
5051
if (!shouldRefresh(metadata)) {
5152
report({ name: 'getFreshValueHookPending' });
52-
return pendingRefreshValue;
53+
const value = await pendingRefreshValue;
54+
report({ name: 'done', value });
55+
return value;
5356
}
5457
}
5558

@@ -79,5 +82,7 @@ export async function cachified<Value>(
7982
resolve: resolveFromFuture!,
8083
});
8184

82-
return freshValue;
85+
const value = await freshValue;
86+
report({ name: 'done', value });
87+
return value;
8388
}

src/reporter.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ export type RefreshValueErrorEvent = {
8686
name: 'refreshValueError';
8787
error: unknown;
8888
};
89+
export type DoneEvent<Value> = {
90+
name: 'done';
91+
value: Value;
92+
};
8993

9094
export type CacheEvent<Value> =
9195
| GetFreshValueStartEvent
@@ -107,7 +111,8 @@ export type CacheEvent<Value> =
107111
| GetCachedValueErrorEvent
108112
| RefreshValueStartEvent
109113
| RefreshValueSuccessEvent<Value>
110-
| RefreshValueErrorEvent;
114+
| RefreshValueErrorEvent
115+
| DoneEvent<Value>;
111116

112117
export type Reporter<Value> = (event: CacheEvent<Value>) => void;
113118

0 commit comments

Comments
 (0)