@lvce-editor/extension-detail-view 3.64.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -637,10 +637,10 @@ const getFeatureVirtualDomHandler = featureName => {
637
637
  };
638
638
 
639
639
  const rpcs = Object.create(null);
640
- const set$a = (id, rpc) => {
640
+ const set$b = (id, rpc) => {
641
641
  rpcs[id] = rpc;
642
642
  };
643
- const get$2 = id => {
643
+ const get$3 = id => {
644
644
  return rpcs[id];
645
645
  };
646
646
 
@@ -648,21 +648,21 @@ const create$7 = rpcId => {
648
648
  return {
649
649
  // @ts-ignore
650
650
  invoke(method, ...params) {
651
- const rpc = get$2(rpcId);
651
+ const rpc = get$3(rpcId);
652
652
  // @ts-ignore
653
653
  return rpc.invoke(method, ...params);
654
654
  },
655
655
  // @ts-ignore
656
656
  invokeAndTransfer(method, ...params) {
657
- const rpc = get$2(rpcId);
657
+ const rpc = get$3(rpcId);
658
658
  // @ts-ignore
659
659
  return rpc.invokeAndTransfer(method, ...params);
660
660
  },
661
661
  set(rpc) {
662
- set$a(rpcId, rpc);
662
+ set$b(rpcId, rpc);
663
663
  },
664
664
  async dispose() {
665
- const rpc = get$2(rpcId);
665
+ const rpc = get$3(rpcId);
666
666
  await rpc.dispose();
667
667
  }
668
668
  };
@@ -1185,10 +1185,10 @@ const create$4 = (method, params) => {
1185
1185
  };
1186
1186
  };
1187
1187
  const callbacks = Object.create(null);
1188
- const set$9 = (id, fn) => {
1188
+ const set$a = (id, fn) => {
1189
1189
  callbacks[id] = fn;
1190
1190
  };
1191
- const get$1 = id => {
1191
+ const get$2 = id => {
1192
1192
  return callbacks[id];
1193
1193
  };
1194
1194
  const remove$1 = id => {
@@ -1204,7 +1204,7 @@ const registerPromise = () => {
1204
1204
  resolve,
1205
1205
  promise
1206
1206
  } = Promise.withResolvers();
1207
- set$9(id, resolve);
1207
+ set$a(id, resolve);
1208
1208
  return {
1209
1209
  id,
1210
1210
  promise
@@ -1369,7 +1369,7 @@ const warn = (...args) => {
1369
1369
  console.warn(...args);
1370
1370
  };
1371
1371
  const resolve = (id, response) => {
1372
- const fn = get$1(id);
1372
+ const fn = get$2(id);
1373
1373
  if (!fn) {
1374
1374
  console.log(response);
1375
1375
  warn(`callback ${id} may already be disposed`);
@@ -1700,7 +1700,7 @@ const createMockRpc = ({
1700
1700
  const {
1701
1701
  invoke: invoke$4,
1702
1702
  invokeAndTransfer: invokeAndTransfer$3,
1703
- set: set$8,
1703
+ set: set$9,
1704
1704
  dispose: dispose$5
1705
1705
  } = create$7(ExtensionHostWorker);
1706
1706
  const executeReferenceProvider = async (id, offset) => {
@@ -1719,7 +1719,7 @@ const registerMockRpc$1 = commandMap => {
1719
1719
  const mockRpc = createMockRpc({
1720
1720
  commandMap
1721
1721
  });
1722
- set$8(mockRpc);
1722
+ set$9(mockRpc);
1723
1723
  return mockRpc;
1724
1724
  };
1725
1725
 
@@ -1732,13 +1732,13 @@ const ExtensionHost = {
1732
1732
  invoke: invoke$4,
1733
1733
  invokeAndTransfer: invokeAndTransfer$3,
1734
1734
  registerMockRpc: registerMockRpc$1,
1735
- set: set$8
1735
+ set: set$9
1736
1736
  };
1737
1737
 
1738
1738
  const {
1739
1739
  invoke: invoke$3,
1740
1740
  invokeAndTransfer: invokeAndTransfer$2,
1741
- set: set$7,
1741
+ set: set$8,
1742
1742
  dispose: dispose$4
1743
1743
  } = create$7(FileSystemWorker$1);
1744
1744
  const remove = async dirent => {
@@ -1810,7 +1810,7 @@ const FileSystemWorker = {
1810
1810
  readFileAsBlob: readFileAsBlob$1,
1811
1811
  remove,
1812
1812
  rename,
1813
- set: set$7,
1813
+ set: set$8,
1814
1814
  stat,
1815
1815
  writeFile
1816
1816
  };
@@ -1818,7 +1818,7 @@ const FileSystemWorker = {
1818
1818
  const {
1819
1819
  invoke: invoke$2,
1820
1820
  invokeAndTransfer: invokeAndTransfer$1,
1821
- set: set$6,
1821
+ set: set$7,
1822
1822
  dispose: dispose$3
1823
1823
  } = create$7(MarkdownWorker$1);
1824
1824
  const getVirtualDom$1 = async html => {
@@ -1837,13 +1837,13 @@ const MarkdownWorker = {
1837
1837
  invoke: invoke$2,
1838
1838
  invokeAndTransfer: invokeAndTransfer$1,
1839
1839
  render: render$1,
1840
- set: set$6
1840
+ set: set$7
1841
1841
  };
1842
1842
 
1843
1843
  const {
1844
1844
  invoke: invoke$1,
1845
1845
  invokeAndTransfer,
1846
- set: set$5,
1846
+ set: set$6,
1847
1847
  dispose: dispose$2
1848
1848
  } = create$7(RendererWorker$1);
1849
1849
  const searchFileHtml = async uri => {
@@ -2110,7 +2110,7 @@ const registerMockRpc = commandMap => {
2110
2110
  const mockRpc = createMockRpc({
2111
2111
  commandMap
2112
2112
  });
2113
- set$5(mockRpc);
2113
+ set$6(mockRpc);
2114
2114
  return mockRpc;
2115
2115
  };
2116
2116
 
@@ -2178,7 +2178,7 @@ const RendererWorker = {
2178
2178
  sendMessagePortToRendererProcess,
2179
2179
  sendMessagePortToSearchProcess,
2180
2180
  sendMessagePortToSyntaxHighlightingWorker,
2181
- set: set$5,
2181
+ set: set$6,
2182
2182
  setAdditionalFocus,
2183
2183
  setColorTheme: setColorTheme$2,
2184
2184
  setExtensionsSearchValue: setExtensionsSearchValue$1,
@@ -2196,7 +2196,7 @@ const RendererWorker = {
2196
2196
  };
2197
2197
 
2198
2198
  const {
2199
- set: set$4,
2199
+ set: set$5,
2200
2200
  getRuntimeStatus: getRuntimeStatus$1
2201
2201
  } = ExtensionHost;
2202
2202
 
@@ -2426,7 +2426,7 @@ const getScrollToTopVirtualDom = scrollToTopButtonEnabled => {
2426
2426
  };
2427
2427
 
2428
2428
  const {
2429
- set: set$3,
2429
+ set: set$4,
2430
2430
  getVirtualDom,
2431
2431
  render
2432
2432
  } = MarkdownWorker;
@@ -2434,14 +2434,16 @@ const {
2434
2434
  const getMarkdownVirtualDom = async (html, options) => {
2435
2435
  string(html);
2436
2436
  const dom = await getVirtualDom(html);
2437
- const newDom = [...dom];
2438
2437
  if (options?.scrollToTopEnabled) {
2439
- newDom[0].onScroll = HandleReadmeScroll;
2440
- newDom[0].childCount++;
2438
+ const [firstNode, ...rest] = dom;
2441
2439
  const extraDom = getScrollToTopVirtualDom();
2442
- newDom.splice(1, 0, ...extraDom);
2440
+ return [{
2441
+ ...firstNode,
2442
+ onScroll: HandleReadmeScroll,
2443
+ childCount: firstNode.childCount + 1
2444
+ }, ...extraDom, ...rest];
2443
2445
  }
2444
- return newDom;
2446
+ return dom;
2445
2447
  };
2446
2448
 
2447
2449
  const getThemeItemMarkdown = (heading, items) => {
@@ -2477,8 +2479,85 @@ const getThemeMarkdown = (themes, iconThemes, productIconThemes) => {
2477
2479
  return markdown;
2478
2480
  };
2479
2481
 
2480
- const renderMarkdown = async (markdown, options = {}) => {
2482
+ const hash = async content => {
2483
+ const sourceBytes = new TextEncoder().encode(content);
2484
+ const digest = await crypto.subtle.digest('SHA-256', sourceBytes);
2485
+ const resultBytes = [...new Uint8Array(digest)];
2486
+ return resultBytes.map(x => x.toString(16).padStart(2, '0')).join('');
2487
+ };
2488
+
2489
+ // TODO pass application name from renderer worker to not hardcode it
2490
+ const bucketName = 'markdown-cache';
2491
+ const cachedCaches = Object.create(null);
2492
+ const noopCache = {
2493
+ async match() {
2494
+ return undefined;
2495
+ },
2496
+ async put() {}
2497
+ };
2498
+ const supportsStorageBuckets = () => {
2499
+ // @ts-ignore
2500
+ return Boolean(navigator.storageBuckets);
2501
+ };
2502
+ const getCacheInternal = async cacheName => {
2503
+ if (!supportsStorageBuckets()) {
2504
+ return noopCache;
2505
+ }
2506
+ const twoWeeks = 14 * 24 * 60 * 60 * 1000;
2507
+ // @ts-ignore
2508
+ const bucket = await navigator.storageBuckets.open(bucketName, {
2509
+ quota: 20 * 1024 * 1024,
2510
+ // 20MB
2511
+ expires: Date.now() + twoWeeks
2512
+ });
2513
+ const cache = await bucket.caches.open(cacheName);
2514
+ return cache;
2515
+ };
2516
+ const getCache = cacheName => {
2517
+ if (!(cacheName in cachedCaches)) {
2518
+ cachedCaches[cacheName] = getCacheInternal(cacheName);
2519
+ }
2520
+ return cachedCaches[cacheName];
2521
+ };
2522
+
2523
+ // TODO pass application name from renderer worker to not hardcode it
2524
+ const cacheName = 'lvce-editor/markdown-cache';
2525
+ const has = async key => {
2526
+ const cache = await getCache(cacheName);
2527
+ const response = await cache.match(key);
2528
+ return Boolean(response);
2529
+ };
2530
+ const get$1 = async key => {
2531
+ const cache = await getCache(cacheName);
2532
+ const response = await cache.match(key);
2533
+ const text = await response?.text();
2534
+ return text || '';
2535
+ };
2536
+ const set$3 = async (key, value) => {
2537
+ const cache = await getCache(cacheName);
2538
+ await cache.put(key, new Response(value, {
2539
+ headers: {
2540
+ 'Content-Type': 'application/markdown',
2541
+ 'Content-Length': `${value.length}`
2542
+ }
2543
+ }));
2544
+ };
2545
+
2546
+ const renderMarkdownCached = async (markdown, options = {}) => {
2547
+ const markdownHash = await hash(markdown); // TODO hash options also
2548
+ const cacheKey = `/markdown/${markdownHash}`;
2549
+ const hasItem = await has(cacheKey);
2550
+ if (hasItem) {
2551
+ const value = await get$1(cacheKey);
2552
+ return value; // TODO validate if it's valid
2553
+ }
2481
2554
  const html = await render(markdown, options);
2555
+ await set$3(cacheKey, html);
2556
+ return html;
2557
+ };
2558
+
2559
+ const renderMarkdown = async (markdown, options = {}) => {
2560
+ const html = await renderMarkdownCached(markdown, options);
2482
2561
  return html;
2483
2562
  };
2484
2563
 
@@ -3301,7 +3380,6 @@ const isEnoentError = error => {
3301
3380
  return error && error.code === ENOENT;
3302
3381
  };
3303
3382
 
3304
- /* eslint-disable @typescript-eslint/prefer-readonly-parameter-types */
3305
3383
  const error = async error => {
3306
3384
  // TODO send message to error worker or log worker
3307
3385
  // @ts-ignore
@@ -3378,7 +3456,8 @@ const selectTabDetails = async state => {
3378
3456
  } = state;
3379
3457
  const readmeContent = await loadReadmeContent(readmeUrl);
3380
3458
  const readmeHtml = await renderMarkdown(readmeContent, {
3381
- baseUrl
3459
+ baseUrl,
3460
+ linksExternal: true
3382
3461
  });
3383
3462
  const detailsDom = await getMarkdownVirtualDom(readmeHtml);
3384
3463
  const newTabs = tabs.map(tab => {
@@ -3464,7 +3543,7 @@ const createExtensionHostWorkerRpc = async () => {
3464
3543
 
3465
3544
  const initializeExtensionHostWorker = async () => {
3466
3545
  const rpc = await createExtensionHostWorkerRpc();
3467
- set$4(rpc);
3546
+ set$5(rpc);
3468
3547
  };
3469
3548
 
3470
3549
  const sendMessagePortToFileSystemWorker = async port => {
@@ -3506,10 +3585,11 @@ const createMarkdownWorkerRpc = async () => {
3506
3585
 
3507
3586
  const initializeMarkdownWorker = async () => {
3508
3587
  const rpc = await createMarkdownWorkerRpc();
3509
- set$3(rpc);
3588
+ set$4(rpc);
3510
3589
  };
3511
3590
 
3512
3591
  const initialize = async () => {
3592
+ // TODO load markdown worker only when needed
3513
3593
  await Promise.all([initializeMarkdownWorker(), initializeFileSystemWorker(), initializeExtensionHostWorker()]);
3514
3594
  };
3515
3595
 
@@ -4026,7 +4106,8 @@ const loadContent = async (state, platform, savedState, isTest = false) => {
4026
4106
  const readmeContent = hasReadme ? await loadReadmeContent(readmeUrl) : noReadmeFound();
4027
4107
  const baseUrl = getBaseUrl(extension.path, platform);
4028
4108
  const readmeHtml = await renderMarkdown(readmeContent, {
4029
- baseUrl
4109
+ baseUrl,
4110
+ linksExternal: true
4030
4111
  });
4031
4112
  const detailsVirtualDom = await getMarkdownVirtualDom(readmeHtml, {
4032
4113
  scrollToTopEnabled: true
package/package.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "name": "@lvce-editor/extension-detail-view",
3
- "version": "3.64.0",
3
+ "version": "4.3.0",
4
4
  "description": "Extension Detail View Worker",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/lvce-editor/extension-detail-view.git"
8
+ },
5
9
  "license": "MIT",
6
10
  "author": "Lvce Editor",
7
11
  "type": "module",