• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tabkram / execution-engine / 14140261552

29 Mar 2025 12:30AM UTC coverage: 91.94%. First build
14140261552

Pull #65

github

web-flow
Merge d6156fe1f into 2cd973999
Pull Request #65: feat: add cache decorator

232 of 268 branches covered (86.57%)

Branch coverage included in aggregate %.

46 of 54 new or added lines in 5 files covered. (85.19%)

384 of 402 relevant lines covered (95.52%)

94.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

69.77
/src/execution/cache.ts
1
import { execute } from './execute';
1✔
2
import { CacheOptions, CacheStore } from '../common/models/executionCache.model';
3
import { generateHashId } from '../common/utils/crypto';
1✔
4
import { extractFunctionMetadata } from '../common/utils/functionMetadata';
1✔
5
import { MapCacheStore } from '../common/utils/mapStore';
1✔
6

7
export const cacheStoreKey = Symbol('execution-engine/cache');
1✔
8

9
/**
10
 * Executes a function with cache to prevent redundant executions.
11
 * The result is stored temporarily and cleared after a short delay.
12
 */
13
export async function executeCache<O>(
1✔
14
  blockFunction: (...params: unknown[]) => O | Promise<O>,
15
  inputs: Array<unknown> = [],
×
16
  options: CacheOptions & { functionId: string }
17
): Promise<Promise<O> | O> {
18
  const functionMetadata = extractFunctionMetadata(blockFunction);
7✔
19
  const inputsHash =
20
    options.cacheKeyResolver?.({
7✔
21
      metadata: functionMetadata,
22
      inputs
23
    }) ?? options.functionId + generateHashId(...inputs);
24
  const expirationMs = typeof options.ttl === 'function' ? options.ttl({ metadata: functionMetadata, inputs }) : options.ttl;
7!
25

26
  if (!expirationMs) {
7!
NEW
27
    if (typeof options.cacheHandler === 'function') {
×
NEW
28
      options.cacheHandler({ ttl: expirationMs, metadata: functionMetadata, inputs, inputsHash, isCached: false });
×
29
    }
NEW
30
    return (execute.bind(this) as typeof execute)(
×
31
      blockFunction.bind(this) as typeof blockFunction,
32
      inputs,
33
      [],
NEW
34
      (res) => res,
×
35
      (error) => {
NEW
36
        throw error;
×
37
      }
38
    );
39
  }
40

41

42
  let cacheStore: CacheStore | MapCacheStore<O> = new MapCacheStore<O>(this[cacheStoreKey], options.functionId);
7✔
43
  if (options.cacheManager) {
7!
NEW
44
    cacheStore = typeof options.cacheManager === 'function' ? options.cacheManager(this) : options.cacheManager;
×
45
  }
46
  const cachedValue: O = (await cacheStore.get(inputsHash)) as O;
7✔
47

48
  if (typeof options.cacheHandler === 'function') {
7✔
49
    options.cacheHandler({
7✔
50
      ttl: expirationMs,
51
      metadata: functionMetadata,
52
      inputs,
53
      inputsHash,
54
      isCached: !!cachedValue,
55
      value: cachedValue
56
    });
57
  }
58

59
  if (cachedValue) {
7✔
60
    return cachedValue;
2✔
61
  } else {
62
    return (execute.bind(this) as typeof execute)(
5✔
63
      blockFunction.bind(this) as typeof blockFunction,
64
      inputs,
65
      [],
66
      (res) => {
67
        cacheStore.set(inputsHash, res as O, expirationMs);
2✔
68
        if((cacheStore as MapCacheStore<O>).fullStorage) {
2✔
69
          this[cacheStoreKey] = (cacheStore as MapCacheStore<O>).fullStorage;
2✔
70
        }
71
        return res;
2✔
72
      },
73
      (error) => {
74
        throw error;
3✔
75
      }
76
    );
77
  }
78
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc