@hienlh/ppm 0.13.7 → 0.13.9
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.
- package/CHANGELOG.md +16 -0
- package/assets/skills/ppm/SKILL.md +1 -1
- package/assets/skills/ppm/references/http-api.md +1 -1
- package/dist/web/assets/ai-settings-section-CLNBWLS4.js +1 -0
- package/dist/web/assets/{api-settings-t7Leca7J.js → api-settings-D0_eiIYv.js} +1 -1
- package/dist/web/assets/architecture-PBZL5I3N-WMbLpD5Y.js +1 -0
- package/dist/web/assets/{audio-preview-BR7DoH0l.js → audio-preview-C1p-Q5XZ.js} +1 -1
- package/dist/web/assets/{chat-tab-8Bvn7PHt.js → chat-tab-BSJUkgxB.js} +9 -9
- package/dist/web/assets/code-editor-rNw5_pXh.js +8 -0
- package/dist/web/assets/{conflict-editor-C-lUw4gv.js → conflict-editor-Dcn3HuLD.js} +1 -1
- package/dist/web/assets/{csv-preview-C9qGhDlb.js → csv-preview-D5lmgVEy.js} +1 -1
- package/dist/web/assets/data-grid-nZfSIop5.js +5 -0
- package/dist/web/assets/database-DOWH9-Vv.js +1 -0
- package/dist/web/assets/database-viewer-CNoq5Uxp.js +1 -0
- package/dist/web/assets/{diff-viewer-I8qs3Nb-.js → diff-viewer-NMLD4V8q.js} +1 -1
- package/dist/web/assets/{esm-B3je8j5P.js → esm-nXReYVnB.js} +1 -1
- package/dist/web/assets/{extension-webview-Dt9bKs0C.js → extension-webview-DW2dBswj.js} +1 -1
- package/dist/web/assets/{file-store-BgZggznw.js → file-store-BrbCNyLm.js} +1 -1
- package/dist/web/assets/gitGraph-HDMCJU4V-BdPTuzO3.js +1 -0
- package/dist/web/assets/{image-preview-C-w-CK5s.js → image-preview-Dqp1KSus.js} +1 -1
- package/dist/web/assets/index-CoMWx5VS.js +27 -0
- package/dist/web/assets/index-Dzb3OtrX.css +2 -0
- package/dist/web/assets/info-3K5VOQVL-MHX_1JfR.js +1 -0
- package/dist/web/assets/{input-bGJExpJZ.js → input-DYWhyaze.js} +1 -1
- package/dist/web/assets/keybindings-store-B7nlHmDh.js +1 -0
- package/dist/web/assets/{markdown-renderer-ySnJPmc1.js → markdown-renderer-DNIXdY0d.js} +3 -3
- package/dist/web/assets/packet-RMMSAZCW-CreFbf9A.js +1 -0
- package/dist/web/assets/{pdf-preview-BoQTv6B2.js → pdf-preview-ChC1gaaZ.js} +1 -1
- package/dist/web/assets/pie-UPGHQEXC-CnaHXUh8.js +1 -0
- package/dist/web/assets/port-forwarding-tab-dLhH_g2l.js +1 -0
- package/dist/web/assets/{postgres-viewer-CBntLqXY.js → postgres-viewer-De0pzd1C.js} +3 -3
- package/dist/web/assets/radar-KQ55EAFF-UxsdRHvt.js +1 -0
- package/dist/web/assets/{scroll-area-D0EQpAH2.js → scroll-area-BEllam7_.js} +1 -1
- package/dist/web/assets/{settings-store-CdcSAgEZ.js → settings-store-BHBb62gq.js} +2 -2
- package/dist/web/assets/settings-tab-Mrs9uzCZ.js +1 -0
- package/dist/web/assets/sparkles-B0mRBy_j.js +1 -0
- package/dist/web/assets/{sql-query-editor-vpD0I0KG.js → sql-query-editor-CMQpaOjA.js} +1 -1
- package/dist/web/assets/sqlite-viewer-BqtIjvil.js +1 -0
- package/dist/web/assets/tab-store-0rGchMXr.js +1 -0
- package/dist/web/assets/terminal-tab-CeHEtoE2.js +1 -0
- package/dist/web/assets/treemap-KZPCXAKY-CBVPi4NV.js +1 -0
- package/dist/web/assets/{use-blob-url-BgxxT-n_.js → use-blob-url-Hn6n1730.js} +1 -1
- package/dist/web/assets/{use-monaco-theme-dtPsv6sh.js → use-monaco-theme-CP-vyTF8.js} +1 -1
- package/dist/web/assets/{vendor-mermaid-DCxaaPi4.js → vendor-mermaid-CMiurk2b.js} +2 -2
- package/dist/web/assets/{video-preview-DxTnfuSQ.js → video-preview-CHPVrMtx.js} +1 -1
- package/dist/web/assets/x-OGGXhtlb.js +1 -0
- package/dist/web/index.html +18 -18
- package/dist/web/sw.js +1 -1
- package/package.json +2 -1
- package/src/index.ts +0 -0
- package/src/server/ws/terminal.ts +4 -0
- package/src/services/terminal.service.ts +4 -1
- package/src/web/components/database/data-grid.tsx +133 -17
- package/src/web/components/database/glide-grid-theme.ts +82 -0
- package/src/web/components/database/glide-grid-types.ts +79 -0
- package/src/web/components/database/use-glide-cell-content.ts +124 -0
- package/src/web/components/database/use-glide-columns.ts +61 -0
- package/src/web/components/database/use-glide-selection.ts +48 -0
- package/src/web/components/editor/code-editor.tsx +126 -9
- package/src/web/components/layout/draggable-tab.tsx +1 -0
- package/src/web/components/terminal/terminal-tab.tsx +19 -8
- package/src/web/hooks/use-terminal.ts +22 -2
- package/src/web/index.html +1 -0
- package/src/web/stores/panel-utils.ts +1 -0
- package/test.sql +1 -0
- package/bun.lock +0 -2062
- package/bunfig.toml +0 -2
- package/dist/web/assets/ai-settings-section-DeW4WN43.js +0 -1
- package/dist/web/assets/architecture-PBZL5I3N-Dy3PgD6O.js +0 -1
- package/dist/web/assets/code-editor-B-F5VdzM.js +0 -8
- package/dist/web/assets/database-DCT0OjgQ.js +0 -1
- package/dist/web/assets/database-viewer-mLY7oMC_.js +0 -2
- package/dist/web/assets/gitGraph-HDMCJU4V-Bu1SIFFq.js +0 -1
- package/dist/web/assets/index-CEI0tfaL.css +0 -2
- package/dist/web/assets/index-CFz4k7zO.js +0 -27
- package/dist/web/assets/info-3K5VOQVL-DzfAxmVd.js +0 -1
- package/dist/web/assets/keybindings-store-CWX97luK.js +0 -1
- package/dist/web/assets/packet-RMMSAZCW-DpzHf4xp.js +0 -1
- package/dist/web/assets/pie-UPGHQEXC-BpzFCKJ8.js +0 -1
- package/dist/web/assets/plus-51UQ45rf.js +0 -1
- package/dist/web/assets/port-forwarding-tab-CjlX-0D2.js +0 -1
- package/dist/web/assets/radar-KQ55EAFF-DAxWKxM4.js +0 -1
- package/dist/web/assets/settings-tab-Djw-bqxG.js +0 -1
- package/dist/web/assets/sqlite-viewer-CjtNrQ7C.js +0 -1
- package/dist/web/assets/tab-store-Jvy1eZGM.js +0 -1
- package/dist/web/assets/terminal-tab-bKLoy06f.js +0 -1
- package/dist/web/assets/treemap-KZPCXAKY-D6dgXbAe.js +0 -1
- package/dist/web/assets/x-BtqbfkR7.js +0 -1
- /package/dist/web/assets/{api-client-r4nyVy7H.js → api-client-Dvzcc_EO.js} +0 -0
- /package/dist/web/assets/{chevron-right-BzAdxJRG.js → chevron-right-DnHIvvcy.js} +0 -0
- /package/dist/web/assets/{code-CuravVys.js → code-DGBecc50.js} +0 -0
- /package/dist/web/assets/{csv-parser-DxVplKKB.js → csv-parser-DO0dz4x_.js} +0 -0
- /package/dist/web/assets/{dist-BqoEabX7.js → dist-CGvx1c8C.js} +0 -0
- /package/dist/web/assets/{katex-bpagxk3Z.js → katex-BFE6i_OH.js} +0 -0
- /package/dist/web/assets/{lib-BqkcKGFq.js → lib-D_kRA9p6.js} +0 -0
- /package/dist/web/assets/{react-BkWDCPD7.js → react-GqWghJ-L.js} +0 -0
- /package/dist/web/assets/{sql-completion-provider-EzHOQLfo.js → sql-completion-provider-tCzZfqWs.js} +0 -0
- /package/dist/web/assets/{table-DbSviOmw.js → table-Dq575bPF.js} +0 -0
- /package/dist/web/assets/{text-wrap-DzvCTq_i.js → text-wrap-Cn6BNQfq.js} +0 -0
- /package/dist/web/assets/{trash-2-BgDIBl6f.js → trash-2-CJYoLw7Q.js} +0 -0
- /package/dist/web/assets/{utils-ChWX7pZv.js → utils-CTg5uAYR.js} +0 -0
- /package/dist/web/assets/{vendor-xterm-D7SePDJp.js → vendor-xterm-u3AZMvTx.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-Baz81y5z.js";import"./api-client-
|
|
1
|
+
import{b as e}from"./vendor-markdown-0Mxgxy0L.js";import{t}from"./file-exclamation-point-Baz81y5z.js";import"./api-client-Dvzcc_EO.js";import{G as n}from"./index-CoMWx5VS.js";import{t as r}from"./use-blob-url-Hn6n1730.js";var i=e();function a({filePath:e,projectName:a}){let{blobUrl:o,error:s}=r(e,a);return s?(0,i.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,i.jsx)(t,{className:`size-10 text-text-subtle`}),(0,i.jsx)(`p`,{className:`text-sm`,children:`Failed to load video.`})]}):o?(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,i.jsx)(`video`,{src:o,controls:!0,className:`max-w-full max-h-full`})}):(0,i.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,i.jsx)(n,{className:`size-5 animate-spin text-text-subtle`})})}export{a as VideoPreview};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./createLucideIcon-BjHrJDVb.js";var t=e(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]),n=e(`chevron-up`,[[`path`,{d:`m18 15-6-6-6 6`,key:`153udz`}]]),r=e(`download`,[[`path`,{d:`M12 15V3`,key:`m9g1x1`}],[`path`,{d:`M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4`,key:`ih7n3h`}],[`path`,{d:`m7 10 5 5 5-5`,key:`brsn70`}]]),i=e(`eye`,[[`path`,{d:`M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0`,key:`1nclc0`}],[`circle`,{cx:`12`,cy:`12`,r:`3`,key:`1v7zrd`}]]),a=e(`plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),o=e(`x`,[[`path`,{d:`M18 6 6 18`,key:`1bl5f8`}],[`path`,{d:`m6 6 12 12`,key:`d8bk6v`}]]);export{n as a,r as i,a as n,t as o,i as r,o as t};
|
package/dist/web/index.html
CHANGED
|
@@ -39,32 +39,32 @@
|
|
|
39
39
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
40
40
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
41
41
|
<link href="https://fonts.googleapis.com/css2?family=Geist+Mono:wght@400;500;600;700&family=Geist:wght@400;500;600;700&display=swap" rel="stylesheet" />
|
|
42
|
-
<script type="module" crossorigin src="/assets/index-
|
|
42
|
+
<script type="module" crossorigin src="/assets/index-CoMWx5VS.js"></script>
|
|
43
43
|
<link rel="modulepreload" crossorigin href="/assets/rolldown-runtime-FhOqtrmT.js">
|
|
44
|
-
<link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-
|
|
44
|
+
<link rel="modulepreload" crossorigin href="/assets/vendor-mermaid-CMiurk2b.js">
|
|
45
45
|
<link rel="modulepreload" crossorigin href="/assets/vendor-markdown-0Mxgxy0L.js">
|
|
46
46
|
<link rel="modulepreload" crossorigin href="/assets/vendor-ui-B-89Uj8i.js">
|
|
47
|
-
<link rel="modulepreload" crossorigin href="/assets/utils-
|
|
47
|
+
<link rel="modulepreload" crossorigin href="/assets/utils-CTg5uAYR.js">
|
|
48
48
|
<link rel="modulepreload" crossorigin href="/assets/createLucideIcon-BjHrJDVb.js">
|
|
49
|
-
<link rel="modulepreload" crossorigin href="/assets/x-
|
|
50
|
-
<link rel="modulepreload" crossorigin href="/assets/input-
|
|
51
|
-
<link rel="modulepreload" crossorigin href="/assets/react-
|
|
52
|
-
<link rel="modulepreload" crossorigin href="/assets/api-client-
|
|
53
|
-
<link rel="modulepreload" crossorigin href="/assets/settings-store-
|
|
54
|
-
<link rel="modulepreload" crossorigin href="/assets/scroll-area-
|
|
49
|
+
<link rel="modulepreload" crossorigin href="/assets/x-OGGXhtlb.js">
|
|
50
|
+
<link rel="modulepreload" crossorigin href="/assets/input-DYWhyaze.js">
|
|
51
|
+
<link rel="modulepreload" crossorigin href="/assets/react-GqWghJ-L.js">
|
|
52
|
+
<link rel="modulepreload" crossorigin href="/assets/api-client-Dvzcc_EO.js">
|
|
53
|
+
<link rel="modulepreload" crossorigin href="/assets/settings-store-BHBb62gq.js">
|
|
54
|
+
<link rel="modulepreload" crossorigin href="/assets/scroll-area-BEllam7_.js">
|
|
55
55
|
<link rel="modulepreload" crossorigin href="/assets/dist-D7KGU7Vl.js">
|
|
56
|
-
<link rel="modulepreload" crossorigin href="/assets/plus-51UQ45rf.js">
|
|
57
56
|
<link rel="modulepreload" crossorigin href="/assets/refresh-cw-CSFrDtiu.js">
|
|
58
|
-
<link rel="modulepreload" crossorigin href="/assets/trash-2-
|
|
59
|
-
<link rel="modulepreload" crossorigin href="/assets/api-settings-
|
|
60
|
-
<link rel="modulepreload" crossorigin href="/assets/ai-settings-section-
|
|
61
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
62
|
-
<link rel="modulepreload" crossorigin href="/assets/
|
|
63
|
-
<link rel="modulepreload" crossorigin href="/assets/file-store-
|
|
64
|
-
<link rel="modulepreload" crossorigin href="/assets/tab-store-
|
|
65
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
57
|
+
<link rel="modulepreload" crossorigin href="/assets/trash-2-CJYoLw7Q.js">
|
|
58
|
+
<link rel="modulepreload" crossorigin href="/assets/api-settings-D0_eiIYv.js">
|
|
59
|
+
<link rel="modulepreload" crossorigin href="/assets/ai-settings-section-CLNBWLS4.js">
|
|
60
|
+
<link rel="modulepreload" crossorigin href="/assets/database-DOWH9-Vv.js">
|
|
61
|
+
<link rel="modulepreload" crossorigin href="/assets/chevron-right-DnHIvvcy.js">
|
|
62
|
+
<link rel="modulepreload" crossorigin href="/assets/file-store-BrbCNyLm.js">
|
|
63
|
+
<link rel="modulepreload" crossorigin href="/assets/tab-store-0rGchMXr.js">
|
|
64
|
+
<link rel="stylesheet" crossorigin href="/assets/index-Dzb3OtrX.css">
|
|
66
65
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
|
67
66
|
<body class="bg-[#0f1419] text-[#e5e7eb] font-sans antialiased">
|
|
67
|
+
<div id="portal" style="position: fixed; left: 0; top: 0; z-index: 9999;" /></div>
|
|
68
68
|
<div id="root"></div>
|
|
69
69
|
</body>
|
|
70
70
|
</html>
|
package/dist/web/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"799a9d7b8dd64119616c0b2d70cd7a95","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/lib-BqkcKGFq.js"},{"revision":null,"url":"assets/dist-D7KGU7Vl.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/tab-store-Jvy1eZGM.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-Dy3PgD6O.js"},{"revision":null,"url":"assets/pdf-preview-BoQTv6B2.js"},{"revision":null,"url":"assets/sql-query-editor-vpD0I0KG.js"},{"revision":null,"url":"assets/conflict-editor-C-lUw4gv.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-DpzHf4xp.js"},{"revision":null,"url":"assets/code-editor-B-F5VdzM.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/scroll-area-D0EQpAH2.js"},{"revision":null,"url":"assets/vendor-xterm-D7SePDJp.js"},{"revision":null,"url":"assets/settings-tab-Djw-bqxG.js"},{"revision":null,"url":"assets/file-exclamation-point-Baz81y5z.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/sqlite-viewer-CjtNrQ7C.js"},{"revision":null,"url":"assets/csv-preview-C9qGhDlb.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/chevron-right-BzAdxJRG.js"},{"revision":null,"url":"assets/file-store-BgZggznw.js"},{"revision":null,"url":"assets/x-BtqbfkR7.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/ai-settings-section-DeW4WN43.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-BpzFCKJ8.js"},{"revision":null,"url":"assets/vendor-mermaid-DCxaaPi4.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/database-viewer-mLY7oMC_.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/trash-2-BgDIBl6f.js"},{"revision":null,"url":"assets/use-blob-url-BgxxT-n_.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/dist-BqoEabX7.js"},{"revision":null,"url":"assets/port-forwarding-tab-CjlX-0D2.js"},{"revision":null,"url":"assets/input-bGJExpJZ.js"},{"revision":null,"url":"assets/diff-viewer-I8qs3Nb-.js"},{"revision":null,"url":"assets/plus-51UQ45rf.js"},{"revision":null,"url":"assets/api-settings-t7Leca7J.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/arrow-up-Dtrfv490.js"},{"revision":null,"url":"assets/refresh-cw-CSFrDtiu.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-DAxWKxM4.js"},{"revision":null,"url":"assets/markdown-renderer-ySnJPmc1.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/sql-completion-provider-EzHOQLfo.js"},{"revision":null,"url":"assets/esm-B3je8j5P.js"},{"revision":null,"url":"assets/image-preview-C-w-CK5s.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-D6dgXbAe.js"},{"revision":null,"url":"assets/extension-webview-Dt9bKs0C.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/chat-tab-8Bvn7PHt.js"},{"revision":null,"url":"assets/react-BkWDCPD7.js"},{"revision":null,"url":"assets/database-DCT0OjgQ.js"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-Bu1SIFFq.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/api-client-r4nyVy7H.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/keybindings-store-CWX97luK.js"},{"revision":null,"url":"assets/info-3K5VOQVL-DzfAxmVd.js"},{"revision":null,"url":"assets/settings-store-CdcSAgEZ.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/terminal-tab-bKLoy06f.js"},{"revision":null,"url":"assets/code-CuravVys.js"},{"revision":null,"url":"assets/index-CEI0tfaL.css"},{"revision":null,"url":"assets/katex-bpagxk3Z.js"},{"revision":null,"url":"assets/index-CFz4k7zO.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/video-preview-DxTnfuSQ.js"},{"revision":null,"url":"assets/vendor-ui-B-89Uj8i.js"},{"revision":null,"url":"assets/utils-ChWX7pZv.js"},{"revision":null,"url":"assets/audio-preview-BR7DoH0l.js"},{"revision":null,"url":"assets/text-wrap-DzvCTq_i.js"},{"revision":null,"url":"assets/csv-parser-DxVplKKB.js"},{"revision":null,"url":"assets/postgres-viewer-CBntLqXY.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/use-monaco-theme-dtPsv6sh.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":null,"url":"assets/table-DbSviOmw.js"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
|
1
|
+
try{self[`workbox:core:7.3.0`]&&_()}catch{}var e=(e,...t)=>{let n=e;return t.length>0&&(n+=` :: ${JSON.stringify(t)}`),n},t=class extends Error{constructor(t,n){let r=e(t,n);super(r),this.name=t,this.details=n}},n={googleAnalytics:`googleAnalytics`,precache:`precache-v2`,prefix:`workbox`,runtime:`runtime`,suffix:typeof registration<`u`?registration.scope:``},r=e=>[n.prefix,e,n.suffix].filter(e=>e&&e.length>0).join(`-`),i=e=>{for(let t of Object.keys(n))e(t)},a={updateDetails:e=>{i(t=>{typeof e[t]==`string`&&(n[t]=e[t])})},getGoogleAnalyticsName:e=>e||r(n.googleAnalytics),getPrecacheName:e=>e||r(n.precache),getPrefix:()=>n.prefix,getRuntimeName:e=>e||r(n.runtime),getSuffix:()=>n.suffix};function o(e,t){let n=t();return e.waitUntil(n),n}try{self[`workbox:precaching:7.3.0`]&&_()}catch{}var s=`__WB_REVISION__`;function c(e){if(!e)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(typeof e==`string`){let t=new URL(e,location.href);return{cacheKey:t.href,url:t.href}}let{revision:n,url:r}=e;if(!r)throw new t(`add-to-cache-list-unexpected-type`,{entry:e});if(!n){let e=new URL(r,location.href);return{cacheKey:e.href,url:e.href}}let i=new URL(r,location.href),a=new URL(r,location.href);return i.searchParams.set(s,n),{cacheKey:i.href,url:a.href}}var l=class{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:e,state:t})=>{t&&(t.originalRequest=e)},this.cachedResponseWillBeUsed=async({event:e,state:t,cachedResponse:n})=>{if(e.type===`install`&&t&&t.originalRequest&&t.originalRequest instanceof Request){let e=t.originalRequest.url;n?this.notUpdatedURLs.push(e):this.updatedURLs.push(e)}return n}}},u=class{constructor({precacheController:e}){this.cacheKeyWillBeUsed=async({request:e,params:t})=>{let n=t?.cacheKey||this._precacheController.getCacheKeyForURL(e.url);return n?new Request(n,{headers:e.headers}):e},this._precacheController=e}},d;function f(){if(d===void 0){let e=new Response(``);if(`body`in e)try{new Response(e.body),d=!0}catch{d=!1}d=!1}return d}async function p(e,n){let r=null;if(e.url&&(r=new URL(e.url).origin),r!==self.location.origin)throw new t(`cross-origin-copy-response`,{origin:r});let i=e.clone(),a={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=n?n(a):a,s=f()?i.body:await i.blob();return new Response(s,o)}var m=e=>new URL(String(e),location.href).href.replace(RegExp(`^${location.origin}`),``);function h(e,t){let n=new URL(e);for(let e of t)n.searchParams.delete(e);return n.href}async function g(e,t,n,r){let i=h(t.url,n);if(t.url===i)return e.match(t,r);let a=Object.assign(Object.assign({},r),{ignoreSearch:!0}),o=await e.keys(t,a);for(let t of o)if(i===h(t.url,n))return e.match(t,r)}var v=class{constructor(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}},y=new Set;async function b(){for(let e of y)await e()}function x(e){return new Promise(t=>setTimeout(t,e))}try{self[`workbox:strategies:7.3.0`]&&_()}catch{}function S(e){return typeof e==`string`?new Request(e):e}var C=class{constructor(e,t){this._cacheKeys={},Object.assign(this,t),this.event=t.event,this._strategy=e,this._handlerDeferred=new v,this._extendLifetimePromises=[],this._plugins=[...e.plugins],this._pluginStateMap=new Map;for(let e of this._plugins)this._pluginStateMap.set(e,{});this.event.waitUntil(this._handlerDeferred.promise)}async fetch(e){let{event:n}=this,r=S(e);if(r.mode===`navigate`&&n instanceof FetchEvent&&n.preloadResponse){let e=await n.preloadResponse;if(e)return e}let i=this.hasCallback(`fetchDidFail`)?r.clone():null;try{for(let e of this.iterateCallbacks(`requestWillFetch`))r=await e({request:r.clone(),event:n})}catch(e){if(e instanceof Error)throw new t(`plugin-error-request-will-fetch`,{thrownErrorMessage:e.message})}let a=r.clone();try{let e;e=await fetch(r,r.mode===`navigate`?void 0:this._strategy.fetchOptions);for(let t of this.iterateCallbacks(`fetchDidSucceed`))e=await t({event:n,request:a,response:e});return e}catch(e){throw i&&await this.runCallbacks(`fetchDidFail`,{error:e,event:n,originalRequest:i.clone(),request:a.clone()}),e}}async fetchAndCachePut(e){let t=await this.fetch(e),n=t.clone();return this.waitUntil(this.cachePut(e,n)),t}async cacheMatch(e){let t=S(e),n,{cacheName:r,matchOptions:i}=this._strategy,a=await this.getCacheKey(t,`read`),o=Object.assign(Object.assign({},i),{cacheName:r});n=await caches.match(a,o);for(let e of this.iterateCallbacks(`cachedResponseWillBeUsed`))n=await e({cacheName:r,matchOptions:i,cachedResponse:n,request:a,event:this.event})||void 0;return n}async cachePut(e,n){let r=S(e);await x(0);let i=await this.getCacheKey(r,`write`);if(!n)throw new t(`cache-put-with-no-response`,{url:m(i.url)});let a=await this._ensureResponseSafeToCache(n);if(!a)return!1;let{cacheName:o,matchOptions:s}=this._strategy,c=await self.caches.open(o),l=this.hasCallback(`cacheDidUpdate`),u=l?await g(c,i.clone(),[`__WB_REVISION__`],s):null;try{await c.put(i,l?a.clone():a)}catch(e){if(e instanceof Error)throw e.name===`QuotaExceededError`&&await b(),e}for(let e of this.iterateCallbacks(`cacheDidUpdate`))await e({cacheName:o,oldResponse:u,newResponse:a.clone(),request:i,event:this.event});return!0}async getCacheKey(e,t){let n=`${e.url} | ${t}`;if(!this._cacheKeys[n]){let r=e;for(let e of this.iterateCallbacks(`cacheKeyWillBeUsed`))r=S(await e({mode:t,request:r,event:this.event,params:this.params}));this._cacheKeys[n]=r}return this._cacheKeys[n]}hasCallback(e){for(let t of this._strategy.plugins)if(e in t)return!0;return!1}async runCallbacks(e,t){for(let n of this.iterateCallbacks(e))await n(t)}*iterateCallbacks(e){for(let t of this._strategy.plugins)if(typeof t[e]==`function`){let n=this._pluginStateMap.get(t);yield r=>{let i=Object.assign(Object.assign({},r),{state:n});return t[e](i)}}}waitUntil(e){return this._extendLifetimePromises.push(e),e}async doneWaiting(){for(;this._extendLifetimePromises.length;){let e=this._extendLifetimePromises.splice(0),t=(await Promise.allSettled(e)).find(e=>e.status===`rejected`);if(t)throw t.reason}}destroy(){this._handlerDeferred.resolve(null)}async _ensureResponseSafeToCache(e){let t=e,n=!1;for(let e of this.iterateCallbacks(`cacheWillUpdate`))if(t=await e({request:this.request,response:t,event:this.event})||void 0,n=!0,!t)break;return n||t&&t.status!==200&&(t=void 0),t}},w=class{constructor(e={}){this.cacheName=a.getRuntimeName(e.cacheName),this.plugins=e.plugins||[],this.fetchOptions=e.fetchOptions,this.matchOptions=e.matchOptions}handle(e){let[t]=this.handleAll(e);return t}handleAll(e){e instanceof FetchEvent&&(e={event:e,request:e.request});let t=e.event,n=typeof e.request==`string`?new Request(e.request):e.request,r=`params`in e?e.params:void 0,i=new C(this,{event:t,request:n,params:r}),a=this._getResponse(i,n,t);return[a,this._awaitComplete(a,i,n,t)]}async _getResponse(e,n,r){await e.runCallbacks(`handlerWillStart`,{event:r,request:n});let i;try{if(i=await this._handle(n,e),!i||i.type===`error`)throw new t(`no-response`,{url:n.url})}catch(t){if(t instanceof Error){for(let a of e.iterateCallbacks(`handlerDidError`))if(i=await a({error:t,event:r,request:n}),i)break}if(!i)throw t}for(let t of e.iterateCallbacks(`handlerWillRespond`))i=await t({event:r,request:n,response:i});return i}async _awaitComplete(e,t,n,r){let i,a;try{i=await e}catch{}try{await t.runCallbacks(`handlerDidRespond`,{event:r,request:n,response:i}),await t.doneWaiting()}catch(e){e instanceof Error&&(a=e)}if(await t.runCallbacks(`handlerDidComplete`,{event:r,request:n,response:i,error:a}),t.destroy(),a)throw a}},T=class e extends w{constructor(t={}){t.cacheName=a.getPrecacheName(t.cacheName),super(t),this._fallbackToNetwork=t.fallbackToNetwork!==!1,this.plugins.push(e.copyRedirectedCacheableResponsesPlugin)}async _handle(e,t){return await t.cacheMatch(e)||(t.event&&t.event.type===`install`?await this._handleInstall(e,t):await this._handleFetch(e,t))}async _handleFetch(e,n){let r,i=n.params||{};if(this._fallbackToNetwork){let t=i.integrity,a=e.integrity,o=!a||a===t;r=await n.fetch(new Request(e,{integrity:e.mode===`no-cors`?void 0:a||t})),t&&o&&e.mode!==`no-cors`&&(this._useDefaultCacheabilityPluginIfNeeded(),await n.cachePut(e,r.clone()))}else throw new t(`missing-precache-entry`,{cacheName:this.cacheName,url:e.url});return r}async _handleInstall(e,n){this._useDefaultCacheabilityPluginIfNeeded();let r=await n.fetch(e);if(!await n.cachePut(e,r.clone()))throw new t(`bad-precaching-response`,{url:e.url,status:r.status});return r}_useDefaultCacheabilityPluginIfNeeded(){let t=null,n=0;for(let[r,i]of this.plugins.entries())i!==e.copyRedirectedCacheableResponsesPlugin&&(i===e.defaultPrecacheCacheabilityPlugin&&(t=r),i.cacheWillUpdate&&n++);n===0?this.plugins.push(e.defaultPrecacheCacheabilityPlugin):n>1&&t!==null&&this.plugins.splice(t,1)}};T.defaultPrecacheCacheabilityPlugin={async cacheWillUpdate({response:e}){return!e||e.status>=400?null:e}},T.copyRedirectedCacheableResponsesPlugin={async cacheWillUpdate({response:e}){return e.redirected?await p(e):e}};var E=class{constructor({cacheName:e,plugins:t=[],fallbackToNetwork:n=!0}={}){this._urlsToCacheKeys=new Map,this._urlsToCacheModes=new Map,this._cacheKeysToIntegrities=new Map,this._strategy=new T({cacheName:a.getPrecacheName(e),plugins:[...t,new u({precacheController:this})],fallbackToNetwork:n}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this._strategy}precache(e){this.addToCacheList(e),this._installAndActiveListenersAdded||=(self.addEventListener(`install`,this.install),self.addEventListener(`activate`,this.activate),!0)}addToCacheList(e){let n=[];for(let r of e){typeof r==`string`?n.push(r):r&&r.revision===void 0&&n.push(r.url);let{cacheKey:e,url:i}=c(r),a=typeof r!=`string`&&r.revision?`reload`:`default`;if(this._urlsToCacheKeys.has(i)&&this._urlsToCacheKeys.get(i)!==e)throw new t(`add-to-cache-list-conflicting-entries`,{firstEntry:this._urlsToCacheKeys.get(i),secondEntry:e});if(typeof r!=`string`&&r.integrity){if(this._cacheKeysToIntegrities.has(e)&&this._cacheKeysToIntegrities.get(e)!==r.integrity)throw new t(`add-to-cache-list-conflicting-integrities`,{url:i});this._cacheKeysToIntegrities.set(e,r.integrity)}if(this._urlsToCacheKeys.set(i,e),this._urlsToCacheModes.set(i,a),n.length>0){let e=`Workbox is precaching URLs without revision info: ${n.join(`, `)}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(e)}}}install(e){return o(e,async()=>{let t=new l;this.strategy.plugins.push(t);for(let[t,n]of this._urlsToCacheKeys){let r=this._cacheKeysToIntegrities.get(n),i=this._urlsToCacheModes.get(t),a=new Request(t,{integrity:r,cache:i,credentials:`same-origin`});await Promise.all(this.strategy.handleAll({params:{cacheKey:n},request:a,event:e}))}let{updatedURLs:n,notUpdatedURLs:r}=t;return{updatedURLs:n,notUpdatedURLs:r}})}activate(e){return o(e,async()=>{let e=await self.caches.open(this.strategy.cacheName),t=await e.keys(),n=new Set(this._urlsToCacheKeys.values()),r=[];for(let i of t)n.has(i.url)||(await e.delete(i),r.push(i.url));return{deletedURLs:r}})}getURLsToCacheKeys(){return this._urlsToCacheKeys}getCachedURLs(){return[...this._urlsToCacheKeys.keys()]}getCacheKeyForURL(e){let t=new URL(e,location.href);return this._urlsToCacheKeys.get(t.href)}getIntegrityForCacheKey(e){return this._cacheKeysToIntegrities.get(e)}async matchPrecache(e){let t=e instanceof Request?e.url:e,n=this.getCacheKeyForURL(t);if(n)return(await self.caches.open(this.strategy.cacheName)).match(n)}createHandlerBoundToURL(e){let n=this.getCacheKeyForURL(e);if(!n)throw new t(`non-precached-url`,{url:e});return t=>(t.request=new Request(e),t.params=Object.assign({cacheKey:n},t.params),this.strategy.handle(t))}},D,O=()=>(D||=new E,D);try{self[`workbox:routing:7.3.0`]&&_()}catch{}var k=e=>e&&typeof e==`object`?e:{handle:e},A=class{constructor(e,t,n=`GET`){this.handler=k(t),this.match=e,this.method=n}setCatchHandler(e){this.catchHandler=k(e)}},j=class extends A{constructor(e,t,n){super(({url:t})=>{let n=e.exec(t.href);if(n&&!(t.origin!==location.origin&&n.index!==0))return n.slice(1)},t,n)}},M=class{constructor(){this._routes=new Map,this._defaultHandlerMap=new Map}get routes(){return this._routes}addFetchListener(){self.addEventListener(`fetch`,(e=>{let{request:t}=e,n=this.handleRequest({request:t,event:e});n&&e.respondWith(n)}))}addCacheListener(){self.addEventListener(`message`,(e=>{if(e.data&&e.data.type===`CACHE_URLS`){let{payload:t}=e.data,n=Promise.all(t.urlsToCache.map(t=>{typeof t==`string`&&(t=[t]);let n=new Request(...t);return this.handleRequest({request:n,event:e})}));e.waitUntil(n),e.ports&&e.ports[0]&&n.then(()=>e.ports[0].postMessage(!0))}}))}handleRequest({request:e,event:t}){let n=new URL(e.url,location.href);if(!n.protocol.startsWith(`http`))return;let r=n.origin===location.origin,{params:i,route:a}=this.findMatchingRoute({event:t,request:e,sameOrigin:r,url:n}),o=a&&a.handler,s=e.method;if(!o&&this._defaultHandlerMap.has(s)&&(o=this._defaultHandlerMap.get(s)),!o)return;let c;try{c=o.handle({url:n,request:e,event:t,params:i})}catch(e){c=Promise.reject(e)}let l=a&&a.catchHandler;return c instanceof Promise&&(this._catchHandler||l)&&(c=c.catch(async r=>{if(l)try{return await l.handle({url:n,request:e,event:t,params:i})}catch(e){e instanceof Error&&(r=e)}if(this._catchHandler)return this._catchHandler.handle({url:n,request:e,event:t});throw r})),c}findMatchingRoute({url:e,sameOrigin:t,request:n,event:r}){let i=this._routes.get(n.method)||[];for(let a of i){let i,o=a.match({url:e,sameOrigin:t,request:n,event:r});if(o)return i=o,(Array.isArray(i)&&i.length===0||o.constructor===Object&&Object.keys(o).length===0||typeof o==`boolean`)&&(i=void 0),{route:a,params:i}}return{}}setDefaultHandler(e,t=`GET`){this._defaultHandlerMap.set(t,k(e))}setCatchHandler(e){this._catchHandler=k(e)}registerRoute(e){this._routes.has(e.method)||this._routes.set(e.method,[]),this._routes.get(e.method).push(e)}unregisterRoute(e){if(!this._routes.has(e.method))throw new t(`unregister-route-but-not-found-with-method`,{method:e.method});let n=this._routes.get(e.method).indexOf(e);if(n>-1)this._routes.get(e.method).splice(n,1);else throw new t(`unregister-route-route-not-registered`)}},N,P=()=>(N||(N=new M,N.addFetchListener(),N.addCacheListener()),N);function F(e,n,r){let i;if(typeof e==`string`){let t=new URL(e,location.href);i=new A(({url:e})=>e.href===t.href,n,r)}else if(e instanceof RegExp)i=new j(e,n,r);else if(typeof e==`function`)i=new A(e,n,r);else if(e instanceof A)i=e;else throw new t(`unsupported-route-type`,{moduleName:`workbox-routing`,funcName:`registerRoute`,paramName:`capture`});return P().registerRoute(i),i}function I(e,t=[]){for(let n of[...e.searchParams.keys()])t.some(e=>e.test(n))&&e.searchParams.delete(n);return e}function*L(e,{ignoreURLParametersMatching:t=[/^utm_/,/^fbclid$/],directoryIndex:n=`index.html`,cleanURLs:r=!0,urlManipulation:i}={}){let a=new URL(e,location.href);a.hash=``,yield a.href;let o=I(a,t);if(yield o.href,n&&o.pathname.endsWith(`/`)){let e=new URL(o.href);e.pathname+=n,yield e.href}if(r){let e=new URL(o.href);e.pathname+=`.html`,yield e.href}if(i){let e=i({url:a});for(let t of e)yield t.href}}var R=class extends A{constructor(e,t){super(({request:n})=>{let r=e.getURLsToCacheKeys();for(let i of L(n.url,t)){let t=r.get(i);if(t)return{cacheKey:t,integrity:e.getIntegrityForCacheKey(t)}}},e.strategy)}};function z(e){F(new R(O(),e))}function B(e){O().precache(e)}function V(e,t){B(e),z(t)}V([{"revision":"1872c500de691dce40960bb85481de07","url":"registerSW.js"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-192.svg"},{"revision":"b828c433c952d5869f7f8c6f4f241f09","url":"index.html"},{"revision":"a0fb34fc84eb148d51812cd62669f20d","url":"icon-512.svg"},{"revision":null,"url":"assets/diff-viewer-NMLD4V8q.js"},{"revision":null,"url":"assets/dist-D7KGU7Vl.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2"},{"revision":null,"url":"assets/audio-preview-C1p-Q5XZ.js"},{"revision":null,"url":"assets/KaTeX_AMS-Regular-BQhdFMY1.woff2"},{"revision":null,"url":"assets/scroll-area-BEllam7_.js"},{"revision":null,"url":"assets/gitGraph-HDMCJU4V-BdPTuzO3.js"},{"revision":null,"url":"assets/terminal-tab-CeHEtoE2.js"},{"revision":null,"url":"assets/chat-tab-BSJUkgxB.js"},{"revision":null,"url":"assets/pie-UPGHQEXC-CnaHXUh8.js"},{"revision":null,"url":"assets/port-forwarding-tab-dLhH_g2l.js"},{"revision":null,"url":"assets/KaTeX_Main-Regular-B22Nviop.woff2"},{"revision":null,"url":"assets/settings-tab-Mrs9uzCZ.js"},{"revision":null,"url":"assets/settings-store-BHBb62gq.js"},{"revision":null,"url":"assets/react-GqWghJ-L.js"},{"revision":null,"url":"assets/file-exclamation-point-Baz81y5z.js"},{"revision":null,"url":"assets/github.min-D2BCvnWf.css"},{"revision":null,"url":"assets/database-DOWH9-Vv.js"},{"revision":null,"url":"assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2"},{"revision":null,"url":"assets/info-3K5VOQVL-MHX_1JfR.js"},{"revision":null,"url":"assets/lib-D_kRA9p6.js"},{"revision":null,"url":"assets/dist-CGvx1c8C.js"},{"revision":null,"url":"assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2"},{"revision":null,"url":"assets/api-settings-D0_eiIYv.js"},{"revision":null,"url":"assets/treemap-KZPCXAKY-CBVPi4NV.js"},{"revision":null,"url":"assets/csv-preview-D5lmgVEy.js"},{"revision":null,"url":"assets/vendor-markdown-0Mxgxy0L.js"},{"revision":null,"url":"assets/radar-KQ55EAFF-UxsdRHvt.js"},{"revision":null,"url":"assets/api-client-Dvzcc_EO.js"},{"revision":null,"url":"assets/architecture-PBZL5I3N-WMbLpD5Y.js"},{"revision":null,"url":"assets/KaTeX_Main-Italic-NWA7e6Wa.woff2"},{"revision":null,"url":"assets/table-Dq575bPF.js"},{"revision":null,"url":"assets/tab-store-0rGchMXr.js"},{"revision":null,"url":"assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2"},{"revision":null,"url":"assets/index-Dzb3OtrX.css"},{"revision":null,"url":"assets/code-editor-rNw5_pXh.js"},{"revision":null,"url":"assets/sql-query-editor-CMQpaOjA.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2"},{"revision":null,"url":"assets/image-preview-Dqp1KSus.js"},{"revision":null,"url":"assets/data-grid-nZfSIop5.js"},{"revision":null,"url":"assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2"},{"revision":null,"url":"assets/arrow-up-Dtrfv490.js"},{"revision":null,"url":"assets/refresh-cw-CSFrDtiu.js"},{"revision":null,"url":"assets/postgres-viewer-De0pzd1C.js"},{"revision":null,"url":"assets/rolldown-runtime-FhOqtrmT.js"},{"revision":null,"url":"assets/esm-nXReYVnB.js"},{"revision":null,"url":"assets/code-DGBecc50.js"},{"revision":null,"url":"assets/KaTeX_Math-Italic-t53AETM-.woff2"},{"revision":null,"url":"assets/github-dark-dimmed.min-BrpRStFV.css"},{"revision":null,"url":"assets/text-wrap-Cn6BNQfq.js"},{"revision":null,"url":"assets/katex-BFE6i_OH.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2"},{"revision":null,"url":"assets/KaTeX_Script-Regular-D3wIWfF6.woff2"},{"revision":null,"url":"assets/trash-2-CJYoLw7Q.js"},{"revision":null,"url":"assets/extension-webview-DW2dBswj.js"},{"revision":null,"url":"assets/use-monaco-theme-CP-vyTF8.js"},{"revision":null,"url":"assets/file-store-BrbCNyLm.js"},{"revision":null,"url":"assets/use-blob-url-Hn6n1730.js"},{"revision":null,"url":"assets/pdf-preview-ChC1gaaZ.js"},{"revision":null,"url":"assets/utils-CTg5uAYR.js"},{"revision":null,"url":"assets/KaTeX_Main-Bold-Cx986IdX.woff2"},{"revision":null,"url":"assets/conflict-editor-Dcn3HuLD.js"},{"revision":null,"url":"assets/vendor-mermaid-CMiurk2b.js"},{"revision":null,"url":"assets/KaTeX_Size2-Regular-Dy4dx90m.woff2"},{"revision":null,"url":"assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2"},{"revision":null,"url":"assets/KaTeX_Size1-Regular-mCD8mA8B.woff2"},{"revision":null,"url":"assets/database-viewer-CNoq5Uxp.js"},{"revision":null,"url":"assets/ai-settings-section-CLNBWLS4.js"},{"revision":null,"url":"assets/csv-parser-DO0dz4x_.js"},{"revision":null,"url":"assets/createLucideIcon-BjHrJDVb.js"},{"revision":null,"url":"assets/input-DYWhyaze.js"},{"revision":null,"url":"assets/chevron-right-DnHIvvcy.js"},{"revision":null,"url":"assets/video-preview-CHPVrMtx.js"},{"revision":null,"url":"assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2"},{"revision":null,"url":"assets/markdown-renderer-DNIXdY0d.js"},{"revision":null,"url":"assets/index-CoMWx5VS.js"},{"revision":null,"url":"assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2"},{"revision":null,"url":"assets/x-OGGXhtlb.js"},{"revision":null,"url":"assets/sparkles-B0mRBy_j.js"},{"revision":null,"url":"assets/vendor-ui-B-89Uj8i.js"},{"revision":null,"url":"assets/vendor-xterm-u3AZMvTx.js"},{"revision":null,"url":"assets/packet-RMMSAZCW-CreFbf9A.js"},{"revision":null,"url":"assets/keybindings-store-B7nlHmDh.js"},{"revision":null,"url":"assets/sql-completion-provider-tCzZfqWs.js"},{"revision":null,"url":"assets/vendor-xterm-BrP-ENHg.css"},{"revision":null,"url":"assets/sqlite-viewer-BqtIjvil.js"},{"revision":null,"url":"assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2"},{"revision":"d0f94ce046cf8cf09605ee7664dac557","url":"monacoeditorwork/html.worker.bundle.js"},{"revision":"a424156a79b9c1b907db93aa3180585a","url":"monacoeditorwork/editor.worker.bundle.js"},{"revision":"b3a7f967560c9816492a1567b3f7f0dc","url":"monacoeditorwork/css.worker.bundle.js"},{"revision":"a5d8a1acfc29c2a4c882a54ffc93def3","url":"monacoeditorwork/json.worker.bundle.js"},{"revision":"948e060affb598c339be40d69e1f6f9c","url":"monacoeditorwork/ts.worker.bundle.js"},{"revision":"79c8870653c8f419f2e3323085e1f4be","url":"manifest.webmanifest"}]),self.addEventListener(`push`,e=>{e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{if(t.some(e=>e.visibilityState===`visible`))return;let n=e.data?.json()??{title:`PPM`,body:`Chat completed`};return self.registration.showNotification(n.title,{body:n.body,icon:`/icon-192.png`,badge:`/icon-192.png`,tag:`ppm-chat-done`,silent:!1,data:{url:self.location.origin}})}))}),self.addEventListener(`notificationclick`,e=>{e.notification.close(),e.waitUntil(self.clients.matchAll({type:`window`,includeUncontrolled:!0}).then(t=>{for(let e of t)if(e.url.includes(self.location.origin)&&`focus`in e)return e.focus();return self.clients.openWindow(e.notification.data?.url||`/`)}))});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hienlh/ppm",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.9",
|
|
4
4
|
"description": "Personal Project Manager — mobile-first web IDE with AI assistance",
|
|
5
5
|
"author": "hienlh",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@anthropic-ai/claude-agent-sdk": "^0.2.81",
|
|
47
47
|
"@codemirror/lang-sql": "^6.10.0",
|
|
48
|
+
"@glideapps/glide-data-grid": "^6.0.3",
|
|
48
49
|
"@inquirer/prompts": "^8.3.0",
|
|
49
50
|
"@monaco-editor/react": "^4.7.0",
|
|
50
51
|
"@radix-ui/react-switch": "^1.2.6",
|
package/src/index.ts
CHANGED
|
File without changes
|
|
@@ -83,6 +83,10 @@ export const terminalWebSocket = {
|
|
|
83
83
|
|
|
84
84
|
close(ws: { data: { type: string; id: string } }) {
|
|
85
85
|
const sessionId = ws.data.id;
|
|
86
|
+
const session = terminalService.get(sessionId);
|
|
87
|
+
// Only clean up if this WS is still the active connection.
|
|
88
|
+
// Prevents race: stale WS close fires after new WS open, removing the new listener.
|
|
89
|
+
if (!session || session.ws !== ws) return;
|
|
86
90
|
terminalService.removeOutputListener(sessionId);
|
|
87
91
|
terminalService.setDisconnected(sessionId);
|
|
88
92
|
},
|
|
@@ -144,7 +144,10 @@ class TerminalService {
|
|
|
144
144
|
};
|
|
145
145
|
const onExit = () => {
|
|
146
146
|
const listener = this.outputListeners.get(id);
|
|
147
|
-
if (listener)
|
|
147
|
+
if (listener) {
|
|
148
|
+
listener(id, "\r\n[Process exited]\r\n");
|
|
149
|
+
listener(id, JSON.stringify({ type: "exited" }));
|
|
150
|
+
}
|
|
148
151
|
};
|
|
149
152
|
|
|
150
153
|
const pty = isWindows
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { useState, useCallback, useMemo, useRef, memo, useEffect } from "react";
|
|
2
|
-
import
|
|
2
|
+
import Editor from "@monaco-editor/react";
|
|
3
|
+
import { Loader2, ChevronLeft, ChevronRight, ChevronUp, ChevronDown, Trash2, Plus, Search, X, Eye, ExternalLink, WrapText, Sparkles, GripHorizontal, Filter, Pin, PinOff, Columns3 } from "lucide-react";
|
|
3
4
|
import { useShallow } from "zustand/react/shallow";
|
|
4
5
|
import { useTabStore } from "@/stores/tab-store";
|
|
6
|
+
import { useMonacoTheme } from "@/lib/use-monaco-theme";
|
|
5
7
|
import type { DbColumnInfo } from "./use-database";
|
|
6
8
|
import { ExportButton } from "./export-button";
|
|
7
9
|
|
|
@@ -44,15 +46,14 @@ export function DataGrid({
|
|
|
44
46
|
const [insertError, setInsertError] = useState<string | null>(null);
|
|
45
47
|
const [confirmBulkDelete, setConfirmBulkDelete] = useState(false);
|
|
46
48
|
const { openTab } = useTabStore(useShallow((s) => ({ openTab: s.openTab })));
|
|
47
|
-
const
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}, [openTab]);
|
|
49
|
+
const [previewData, setPreviewData] = useState<{ title: string; content: string; language: string; viewerKey: string } | null>(null);
|
|
50
|
+
const openCellViewer = useCallback((cell: { col: string; value: string; pkVal: string }) => {
|
|
51
|
+
const table = selectedTable ?? "";
|
|
52
|
+
const lang = detectLang(cell.value);
|
|
53
|
+
const key = `${connectionId ?? "local"}:${table}:${cell.col}:${cell.pkVal}`;
|
|
54
|
+
const title = table ? `${cell.col} #${cell.pkVal} — ${table}` : `${cell.col} #${cell.pkVal}`;
|
|
55
|
+
setPreviewData({ title, content: cell.value, language: lang, viewerKey: key });
|
|
56
|
+
}, [connectionId, selectedTable]);
|
|
56
57
|
const [pinnedCols, setPinnedCols] = useState<Set<string>>(new Set());
|
|
57
58
|
const [pinnedRows, setPinnedRows] = useState<Set<number>>(new Set());
|
|
58
59
|
const [filterOpenCol, setFilterOpenCol] = useState<string | null>(null);
|
|
@@ -69,14 +70,21 @@ export function DataGrid({
|
|
|
69
70
|
const openRowViewer = useCallback((row: Record<string, unknown>) => {
|
|
70
71
|
const json = JSON.stringify(row, null, 2);
|
|
71
72
|
const pk = pkCol ? String(row[pkCol] ?? "") : "";
|
|
73
|
+
const table = selectedTable ?? "";
|
|
74
|
+
const key = `${connectionId ?? "local"}:${table}:row:${pk || "unknown"}`;
|
|
75
|
+
const title = pk ? `Row #${pk}${table ? ` — ${table}` : ""}` : `Row${table ? ` — ${table}` : ""}`;
|
|
76
|
+
setPreviewData({ title, content: json, language: "json", viewerKey: key });
|
|
77
|
+
}, [pkCol, connectionId, selectedTable]);
|
|
78
|
+
const openPreviewInTab = useCallback(() => {
|
|
79
|
+
if (!previewData) return;
|
|
72
80
|
openTab({
|
|
73
81
|
type: "editor",
|
|
74
|
-
title:
|
|
82
|
+
title: previewData.title,
|
|
75
83
|
projectId: null,
|
|
76
84
|
closable: true,
|
|
77
|
-
metadata: { inlineContent:
|
|
85
|
+
metadata: { inlineContent: previewData.content, inlineLanguage: previewData.language, viewerKey: previewData.viewerKey },
|
|
78
86
|
});
|
|
79
|
-
}, [openTab,
|
|
87
|
+
}, [openTab, previewData]);
|
|
80
88
|
|
|
81
89
|
// Refs for cell renderers — avoid column memo rebuild on every state change
|
|
82
90
|
const editingRef = useRef(editingCell);
|
|
@@ -196,7 +204,7 @@ export function DataGrid({
|
|
|
196
204
|
if (!el) return;
|
|
197
205
|
const handler = (e: KeyboardEvent) => {
|
|
198
206
|
// Escape closes column search from anywhere
|
|
199
|
-
if (e.key === "Escape") { setColSearchOpen(false); return; }
|
|
207
|
+
if (e.key === "Escape") { setColSearchOpen(false); setPreviewData(null); return; }
|
|
200
208
|
|
|
201
209
|
// Skip if focus is in an input/textarea
|
|
202
210
|
const tag = (e.target as HTMLElement)?.tagName;
|
|
@@ -433,7 +441,7 @@ export function DataGrid({
|
|
|
433
441
|
)}
|
|
434
442
|
|
|
435
443
|
{/* Table */}
|
|
436
|
-
<div ref={scrollRef} className="flex-1 overflow-auto relative">
|
|
444
|
+
<div ref={scrollRef} className="flex-1 overflow-auto relative min-h-0">
|
|
437
445
|
{loading && (
|
|
438
446
|
<div className="absolute inset-0 z-30 flex items-center justify-center bg-background/60">
|
|
439
447
|
<Loader2 className="size-5 animate-spin text-primary" />
|
|
@@ -540,6 +548,11 @@ export function DataGrid({
|
|
|
540
548
|
</table>
|
|
541
549
|
</div>
|
|
542
550
|
|
|
551
|
+
{/* Inline preview panel */}
|
|
552
|
+
{previewData && (
|
|
553
|
+
<DataPreviewPanel data={previewData} onClose={() => setPreviewData(null)} onOpenInTab={openPreviewInTab} />
|
|
554
|
+
)}
|
|
555
|
+
|
|
543
556
|
{/* Footer: row count + pagination */}
|
|
544
557
|
<div className="flex items-center justify-between px-3 py-1.5 border-t border-border bg-background shrink-0 text-xs text-muted-foreground">
|
|
545
558
|
<span>{tableData.total.toLocaleString()} rows</span>
|
|
@@ -596,6 +609,109 @@ function detectLang(text: string): string {
|
|
|
596
609
|
return "plaintext";
|
|
597
610
|
}
|
|
598
611
|
|
|
612
|
+
/** Inline preview panel for cell/row content with Monaco editor */
|
|
613
|
+
function DataPreviewPanel({ data, onClose, onOpenInTab }: {
|
|
614
|
+
data: { title: string; content: string; language: string };
|
|
615
|
+
onClose: () => void;
|
|
616
|
+
onOpenInTab: () => void;
|
|
617
|
+
}) {
|
|
618
|
+
const monacoTheme = useMonacoTheme();
|
|
619
|
+
const [wordWrap, setWordWrap] = useState(true);
|
|
620
|
+
const [displayContent, setDisplayContent] = useState(data.content);
|
|
621
|
+
const [beautified, setBeautified] = useState(false);
|
|
622
|
+
const canBeautify = data.language === "json" || data.language === "xml";
|
|
623
|
+
|
|
624
|
+
// Reset state when data changes
|
|
625
|
+
const prevKey = useRef(data.title);
|
|
626
|
+
if (prevKey.current !== data.title) {
|
|
627
|
+
prevKey.current = data.title;
|
|
628
|
+
setDisplayContent(data.content);
|
|
629
|
+
setBeautified(false);
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
const toggleBeautify = useCallback(() => {
|
|
633
|
+
if (beautified) {
|
|
634
|
+
setDisplayContent(data.content);
|
|
635
|
+
setBeautified(false);
|
|
636
|
+
} else {
|
|
637
|
+
if (data.language === "json") {
|
|
638
|
+
try { setDisplayContent(JSON.stringify(JSON.parse(data.content.trim()), null, 2)); setBeautified(true); } catch { /* invalid */ }
|
|
639
|
+
} else if (data.language === "xml") {
|
|
640
|
+
// Simple XML indent
|
|
641
|
+
let depth = 0;
|
|
642
|
+
const formatted = data.content.trim().replace(/>\s*</g, ">\n<").split("\n").map((line) => {
|
|
643
|
+
const trimmed = line.trim();
|
|
644
|
+
if (trimmed.startsWith("</")) depth = Math.max(0, depth - 1);
|
|
645
|
+
const indented = " ".repeat(depth) + trimmed;
|
|
646
|
+
if (trimmed.startsWith("<") && !trimmed.startsWith("</") && !trimmed.endsWith("/>") && !trimmed.startsWith("<?")) depth++;
|
|
647
|
+
return indented;
|
|
648
|
+
}).join("\n");
|
|
649
|
+
setDisplayContent(formatted);
|
|
650
|
+
setBeautified(true);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}, [beautified, data.content, data.language]);
|
|
654
|
+
|
|
655
|
+
const [panelHeight, setPanelHeight] = useState(200);
|
|
656
|
+
const handleDrag = useCallback((e: React.MouseEvent) => {
|
|
657
|
+
e.preventDefault();
|
|
658
|
+
const startY = e.clientY;
|
|
659
|
+
const startH = panelHeight;
|
|
660
|
+
const onMove = (ev: MouseEvent) => setPanelHeight(Math.max(80, startH + (startY - ev.clientY)));
|
|
661
|
+
const onUp = () => { document.removeEventListener("mousemove", onMove); document.removeEventListener("mouseup", onUp); };
|
|
662
|
+
document.addEventListener("mousemove", onMove);
|
|
663
|
+
document.addEventListener("mouseup", onUp);
|
|
664
|
+
}, [panelHeight]);
|
|
665
|
+
|
|
666
|
+
return (
|
|
667
|
+
<div className="shrink-0 border-t border-border flex flex-col" style={{ height: panelHeight }}>
|
|
668
|
+
{/* Resize handle */}
|
|
669
|
+
<div onMouseDown={handleDrag}
|
|
670
|
+
className="shrink-0 h-1.5 cursor-row-resize bg-border/50 hover:bg-primary/30 flex items-center justify-center transition-colors">
|
|
671
|
+
<GripHorizontal className="size-3 text-muted-foreground/50" />
|
|
672
|
+
</div>
|
|
673
|
+
<div className="flex items-center gap-1 px-2 py-1 bg-muted/50 border-b border-border shrink-0">
|
|
674
|
+
<Eye className="size-3 text-muted-foreground" />
|
|
675
|
+
<span className="text-xs font-medium text-foreground truncate flex-1">{data.title}</span>
|
|
676
|
+
{canBeautify && (
|
|
677
|
+
<button type="button" onClick={toggleBeautify} title={beautified ? "Raw" : "Beautify"}
|
|
678
|
+
className={`p-0.5 rounded transition-colors ${beautified ? "text-primary" : "text-muted-foreground hover:text-foreground"}`}>
|
|
679
|
+
<Sparkles className="size-3" />
|
|
680
|
+
</button>
|
|
681
|
+
)}
|
|
682
|
+
<button type="button" onClick={() => setWordWrap(!wordWrap)} title={wordWrap ? "No wrap" : "Word wrap"}
|
|
683
|
+
className={`p-0.5 rounded transition-colors ${wordWrap ? "text-primary" : "text-muted-foreground hover:text-foreground"}`}>
|
|
684
|
+
<WrapText className="size-3" />
|
|
685
|
+
</button>
|
|
686
|
+
<button type="button" onClick={onOpenInTab} title="Open in new tab"
|
|
687
|
+
className="flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted transition-colors">
|
|
688
|
+
<ExternalLink className="size-3" />
|
|
689
|
+
<span className="hidden sm:inline">Open in Tab</span>
|
|
690
|
+
</button>
|
|
691
|
+
<button type="button" onClick={onClose} title="Close preview (Esc)"
|
|
692
|
+
className="p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors">
|
|
693
|
+
<X className="size-3" />
|
|
694
|
+
</button>
|
|
695
|
+
</div>
|
|
696
|
+
<div className="flex-1 min-h-0">
|
|
697
|
+
<Editor
|
|
698
|
+
height="100%"
|
|
699
|
+
language={data.language === "plaintext" ? undefined : data.language}
|
|
700
|
+
value={displayContent}
|
|
701
|
+
theme={monacoTheme}
|
|
702
|
+
options={{
|
|
703
|
+
readOnly: true, minimap: { enabled: false }, scrollBeyondLastLine: false,
|
|
704
|
+
wordWrap: wordWrap ? "on" : "off", lineNumbers: "on", fontSize: 12,
|
|
705
|
+
folding: true, bracketPairColorization: { enabled: true },
|
|
706
|
+
domReadOnly: true, contextmenu: false, overviewRulerLanes: 0,
|
|
707
|
+
}}
|
|
708
|
+
loading={<Loader2 className="size-4 animate-spin text-muted-foreground" />}
|
|
709
|
+
/>
|
|
710
|
+
</div>
|
|
711
|
+
</div>
|
|
712
|
+
);
|
|
713
|
+
}
|
|
714
|
+
|
|
599
715
|
/** Column search dropdown — owns query/index state internally to avoid re-rendering DataGrid */
|
|
600
716
|
function ColumnSearchDropdown({ columns, onSelect, onClose }: {
|
|
601
717
|
columns: string[]; onSelect: (col: string) => void; onClose: () => void;
|
|
@@ -651,7 +767,7 @@ const DataRow = memo(function DataRow({ row, rowIdx, columns, selected, onToggle
|
|
|
651
767
|
onSetEditValue: (v: string) => void;
|
|
652
768
|
showDelete: boolean; confirmingDelete: boolean;
|
|
653
769
|
onDelete: (i: number) => void; onConfirmDelete: (i: number | null) => void;
|
|
654
|
-
onViewCell: (cell: { col: string; value: string }) => void;
|
|
770
|
+
onViewCell: (cell: { col: string; value: string; pkVal: string }) => void;
|
|
655
771
|
onViewRow: (row: Record<string, unknown>) => void;
|
|
656
772
|
pinned: boolean; onTogglePin: (i: number) => void;
|
|
657
773
|
pinnedCols: Set<string>; pinnedColOffsets: Map<string, number>;
|
|
@@ -702,7 +818,7 @@ const DataRow = memo(function DataRow({ row, rowIdx, columns, selected, onToggle
|
|
|
702
818
|
</span>
|
|
703
819
|
{showEye && (
|
|
704
820
|
<button type="button" title="View full content"
|
|
705
|
-
onClick={() => onViewCell({ col, value: formatCellValue(val) })}
|
|
821
|
+
onClick={() => onViewCell({ col, value: formatCellValue(val), pkVal: pkCol ? String(row[pkCol] ?? rowIdx) : String(rowIdx) })}
|
|
706
822
|
className="shrink-0 p-0.5 rounded text-muted-foreground/50 hover:text-foreground transition-colors">
|
|
707
823
|
<Eye className="size-3" />
|
|
708
824
|
</button>
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { useState, useEffect, useMemo } from "react";
|
|
2
|
+
import type { Theme } from "@glideapps/glide-data-grid";
|
|
3
|
+
import "@glideapps/glide-data-grid/dist/index.css";
|
|
4
|
+
|
|
5
|
+
/** Read a CSS custom property from :root */
|
|
6
|
+
function cssVar(name: string): string {
|
|
7
|
+
return getComputedStyle(document.documentElement).getPropertyValue(name).trim();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/** Add alpha channel to a hex/rgb color string */
|
|
11
|
+
function withAlpha(color: string, alpha: number): string {
|
|
12
|
+
if (color.startsWith("#")) {
|
|
13
|
+
const hex = color.slice(1);
|
|
14
|
+
const r = parseInt(hex.slice(0, 2), 16);
|
|
15
|
+
const g = parseInt(hex.slice(2, 4), 16);
|
|
16
|
+
const b = parseInt(hex.slice(4, 6), 16);
|
|
17
|
+
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
|
|
18
|
+
}
|
|
19
|
+
return color;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Build Glide theme from current CSS variables */
|
|
23
|
+
function buildTheme(): Partial<Theme> {
|
|
24
|
+
const bg = cssVar("--color-background");
|
|
25
|
+
const fg = cssVar("--color-foreground");
|
|
26
|
+
const muted = cssVar("--color-muted");
|
|
27
|
+
const mutedFg = cssVar("--color-muted-foreground");
|
|
28
|
+
const primary = cssVar("--color-primary");
|
|
29
|
+
const primaryFg = cssVar("--color-primary-foreground");
|
|
30
|
+
const border = cssVar("--color-border");
|
|
31
|
+
const accent = cssVar("--color-accent");
|
|
32
|
+
const textSecondary = cssVar("--color-text-secondary");
|
|
33
|
+
const textSubtle = cssVar("--color-text-subtle");
|
|
34
|
+
const fontSans = cssVar("--font-sans") || "Geist, system-ui, sans-serif";
|
|
35
|
+
|
|
36
|
+
return {
|
|
37
|
+
bgCell: bg,
|
|
38
|
+
bgCellMedium: muted,
|
|
39
|
+
bgHeader: muted,
|
|
40
|
+
bgHeaderHasFocus: accent,
|
|
41
|
+
bgHeaderHovered: accent,
|
|
42
|
+
bgBubble: accent,
|
|
43
|
+
bgBubbleSelected: primary,
|
|
44
|
+
textDark: fg,
|
|
45
|
+
textMedium: textSecondary,
|
|
46
|
+
textLight: textSubtle,
|
|
47
|
+
textHeader: mutedFg,
|
|
48
|
+
textGroupHeader: mutedFg,
|
|
49
|
+
textHeaderSelected: fg,
|
|
50
|
+
textBubble: fg,
|
|
51
|
+
accentColor: primary,
|
|
52
|
+
accentFg: primaryFg,
|
|
53
|
+
accentLight: withAlpha(primary, 0.12),
|
|
54
|
+
borderColor: border,
|
|
55
|
+
horizontalBorderColor: border,
|
|
56
|
+
fontFamily: fontSans,
|
|
57
|
+
baseFontStyle: "13px",
|
|
58
|
+
headerFontStyle: "600 12px",
|
|
59
|
+
editorFontSize: "13px",
|
|
60
|
+
lineHeight: 1.5,
|
|
61
|
+
cellHorizontalPadding: 8,
|
|
62
|
+
cellVerticalPadding: 4,
|
|
63
|
+
headerIconSize: 16,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Hook that returns a Glide Data Grid theme synced to PPM's dark/light mode.
|
|
69
|
+
* Watches <html> class changes via MutationObserver to rebuild on theme toggle.
|
|
70
|
+
*/
|
|
71
|
+
export function useGlideTheme(): Partial<Theme> {
|
|
72
|
+
// Bump counter on theme class change to trigger rebuild
|
|
73
|
+
const [rev, setRev] = useState(0);
|
|
74
|
+
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
const observer = new MutationObserver(() => setRev((r) => r + 1));
|
|
77
|
+
observer.observe(document.documentElement, { attributes: true, attributeFilter: ["class"] });
|
|
78
|
+
return () => observer.disconnect();
|
|
79
|
+
}, []);
|
|
80
|
+
|
|
81
|
+
return useMemo(() => buildTheme(), [rev]); // eslint-disable-line react-hooks/exhaustive-deps
|
|
82
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/** Shared types for Glide Data Grid wrapper used by database-viewer and sqlite-viewer */
|
|
2
|
+
|
|
3
|
+
/** Unified column schema — superset of DbColumnInfo and sqlite ColumnInfo */
|
|
4
|
+
export interface GridColumnSchema {
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
nullable: boolean;
|
|
8
|
+
pk: boolean;
|
|
9
|
+
defaultValue?: string | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** Unified props interface for the Glide Data Grid wrapper component */
|
|
13
|
+
export interface GlideGridProps {
|
|
14
|
+
/** Column names in display order */
|
|
15
|
+
columns: string[];
|
|
16
|
+
/** Row data array (current page) */
|
|
17
|
+
rows: Record<string, unknown>[];
|
|
18
|
+
/** Total row count across all pages */
|
|
19
|
+
total: number;
|
|
20
|
+
/** Rows per page */
|
|
21
|
+
limit: number;
|
|
22
|
+
/** Column schema metadata */
|
|
23
|
+
schema: GridColumnSchema[];
|
|
24
|
+
/** Whether data is currently loading */
|
|
25
|
+
loading: boolean;
|
|
26
|
+
/** Current page number (1-based) */
|
|
27
|
+
page: number;
|
|
28
|
+
onPageChange: (page: number) => void;
|
|
29
|
+
/** Cell edit: (pkColumn, pkValue, editedColumn, newValue) */
|
|
30
|
+
onCellUpdate: (pkCol: string, pkVal: unknown, col: string, val: unknown) => void;
|
|
31
|
+
onRowDelete?: (pkCol: string, pkVal: unknown) => void;
|
|
32
|
+
onBulkDelete?: (pkCol: string, pkValues: unknown[]) => void;
|
|
33
|
+
onInsertRow?: (values: Record<string, unknown>) => Promise<void>;
|
|
34
|
+
/** Current sort column */
|
|
35
|
+
orderBy?: string | null;
|
|
36
|
+
orderDir?: "ASC" | "DESC";
|
|
37
|
+
onToggleSort?: (column: string) => void;
|
|
38
|
+
/** Per-column ILIKE filters (server-side) */
|
|
39
|
+
columnFilters?: Record<string, string>;
|
|
40
|
+
onColumnFilter?: (filters: Record<string, string>) => void;
|
|
41
|
+
/** Metadata for export/viewer features */
|
|
42
|
+
connectionId?: number;
|
|
43
|
+
selectedTable?: string | null;
|
|
44
|
+
selectedSchema?: string;
|
|
45
|
+
connectionName?: string;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Threshold in bytes for showing cell viewer (eye button) */
|
|
49
|
+
export const LARGE_THRESHOLD = 200;
|
|
50
|
+
|
|
51
|
+
/** Check if a cell value needs the large data viewer */
|
|
52
|
+
export function needsViewer(val: unknown): boolean {
|
|
53
|
+
if (val == null) return false;
|
|
54
|
+
if (typeof val === "object") return true;
|
|
55
|
+
const s = String(val);
|
|
56
|
+
if (s.length >= LARGE_THRESHOLD) return true;
|
|
57
|
+
const trimmed = s.trimStart();
|
|
58
|
+
if ((trimmed[0] === "{" || trimmed[0] === "[") && (trimmed.endsWith("}") || trimmed.endsWith("]"))) return true;
|
|
59
|
+
if (trimmed.startsWith("<?xml") || (trimmed.startsWith("<") && trimmed.endsWith(">"))) return true;
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** Format cell value for display — JSON-stringify objects, otherwise String() */
|
|
64
|
+
export function formatCellValue(val: unknown): string {
|
|
65
|
+
if (val == null) return "NULL";
|
|
66
|
+
if (typeof val === "object") return JSON.stringify(val);
|
|
67
|
+
return String(val);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Detect language from cell content for syntax highlighting in viewer */
|
|
71
|
+
export function detectLang(text: string): string {
|
|
72
|
+
const t = text.trimStart();
|
|
73
|
+
if (t[0] === "{" || t[0] === "[") {
|
|
74
|
+
try { JSON.parse(t); return "json"; } catch { /* not json */ }
|
|
75
|
+
}
|
|
76
|
+
if (t.startsWith("<?xml") || (t.startsWith("<") && /<\/\w+>/.test(t))) return "xml";
|
|
77
|
+
if (t.startsWith("---") || /^\w+:\s/m.test(t)) return "yaml";
|
|
78
|
+
return "plaintext";
|
|
79
|
+
}
|