PluginProbe
Extendify / 3.1.2
Extendify v3.1.2
3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 0.7.0 All 126 releases
extendify / src / QuickEdit / lib / block-source-cache.js

block-source-cache.js in Extendify 3.1.2, at src/QuickEdit/lib/block-source-cache.js

57 lines 1.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // Caches the in-flight Promise (not the resolved value) so concurrent
2 // hover-prefetch + click consumers share one request.
3 import apiFetch from '@wordpress/api-fetch';
4 import { addQueryArgs } from '@wordpress/url';
5
6 const cache = new Map();
7
8 // Resolve a source descriptor + block id into the get-block-code query args and
9 // a collision-proof cache key. post and template-part sources number their
10 // blocks in separate spaces (post #5 ≠ header #5), so the key carries the kind
11 // and its discriminator. Returns null for sources QE loads through other
12 // editors (product, wpforms, wp-navigation) or for incomplete input.
13 const describe = (source, blockId) => {
14 if (!source || !blockId) return null;
15 if (source.kind === 'post' && source.id) {
16 return {
17 key: `post-${source.id}-${blockId}`,
18 args: { postId: source.id, blockId },
19 };
20 }
21 if (source.kind === 'template-part' && source.partSlug) {
22 return {
23 key: `part-${source.partSlug}-${blockId}`,
24 args: { partSlug: source.partSlug, blockId },
25 };
26 }
27 return null;
28 };
29
30 export const prefetchBlockSource = (source, blockId) => {
31 const desc = describe(source, blockId);
32 if (!desc) return null;
33 if (cache.has(desc.key)) return cache.get(desc.key);
34 const promise = apiFetch({
35 path: addQueryArgs('/extendify/v1/agent/get-block-code', desc.args),
36 }).catch((err) => {
37 // Evict on failure so the next consumer (typically BlockTextEditor)
38 // retries fresh and surfaces the error.
39 cache.delete(desc.key);
40 throw err;
41 });
42 cache.set(desc.key, promise);
43 return promise;
44 };
45
46 // Same shape as prefetch but semantically "I need this now."
47 export const getBlockSource = prefetchBlockSource;
48
49 // Drop a stale entry after a save — splice rewrites the live DOM but the
50 // cached source payload is still pre-save, so a re-edit would mount the
51 // editor against the old markup.
52 export const invalidateBlockSource = (source, blockId) => {
53 const desc = describe(source, blockId);
54 if (!desc) return;
55 cache.delete(desc.key);
56 };
57