1 | /**
|
2 | * Network requests that have not yet fulfilled, available for sharing with
|
3 | * other idempotent and safe M2ApiRequests for the same resource.
|
4 | * Resource matching is determined by a string composite [method, path, body].
|
5 | *
|
6 | * (M2ApiRequests know not to use this cache for create operations, except for
|
7 | * singleton create operations like createGuestCart, which have no body.)
|
8 | * @module MulticastCache
|
9 | */
|
10 |
|
11 | /**
|
12 | * String keyed map of in-flight requests. When a request completes,
|
13 | * it should be removed.
|
14 | * @private
|
15 | */
|
16 | const inflight = new Map();
|
17 |
|
18 | /**
|
19 | * Reference cache to reduce repetitive requestToKey() calls.
|
20 | * @private
|
21 | */
|
22 | const keyCache = new WeakMap();
|
23 |
|
24 | /**
|
25 | *
|
26 | * @private
|
27 | * @param {M2ApiRequest} req
|
28 | * @return string Key for use in inflight cache.
|
29 | */
|
30 | function requestToKey(req) {
|
31 | let key = keyCache.get(req);
|
32 | if (!key) {
|
33 | const { method, body } = req.opts;
|
34 | const parts = [method, req.resourceUrl];
|
35 | if (body) {
|
36 | parts.push(body);
|
37 | }
|
38 | key = parts.join('|||');
|
39 | keyCache.set(req, key);
|
40 | }
|
41 | return key;
|
42 | }
|
43 |
|
44 | /**
|
45 | * Returns any inflight request with the same key as the supplied request.
|
46 | * May be the same request itself!
|
47 | * @param {M2ApiRequest} req The request to match.
|
48 | * @return {M2ApiRequest} A request with the same method, body, and resourceUrl..
|
49 | */
|
50 | export function match(req) {
|
51 | return inflight.get(requestToKey(req));
|
52 | }
|
53 | /**
|
54 | * Store a request for potential future multicast.
|
55 | * Adds a callback to delete the request when it has settled.
|
56 | * @param {M2ApiRequest} req The request to store.
|
57 | */
|
58 | export function store(req) {
|
59 | inflight.set(requestToKey(req), req);
|
60 | }
|
61 | /**
|
62 | * Remove a request from cache if it exists there.
|
63 | * @param {M2ApiRequest} req
|
64 | */
|
65 | export function remove(req) {
|
66 | if (match(req) === req) {
|
67 | inflight.delete(requestToKey(req));
|
68 | }
|
69 | }
|