Work without browser storage (framed Space page): index in memory, explain, never drop a session on save failure
Browse files
assets/{engine.worker-PBwQTLVE.js → engine.worker-wB_Nt8u8.js}
RENAMED
|
@@ -51,4 +51,4 @@ ${r}${a}`+i.repeat(e)+`${r}`,o}function Vm(e,t,n,r){return`${t}${r}`+n.repeat(e)
|
|
| 51 |
|
| 52 |
`);l++,o||=n,d(`You`,n,f,e)}}else if(Array.isArray(p)){let t=p.filter(e=>e?.type===`text`).map(e=>e.text??``).join(`
|
| 53 |
|
| 54 |
-
`).trim();t&&(l++,d(`Claude`,t,f,e))}}return{items:t,lines:Math.max(1,r),cwd:i,title:a,firstPrompt:o,startedAt:s,endedAt:c,messages:l}}let rj=null;function ij(){return rj??=new Promise((e,t)=>{let n=indexedDB.open(`tracks`,1);n.onupgradeneeded=()=>{let e=n.result;e.createObjectStore(`sessions`),e.createObjectStore(`records`),e.createObjectStore(`handles`)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)})}function aj(e,t,n){return ij().then(
|
|
|
|
| 51 |
|
| 52 |
`);l++,o||=n,d(`You`,n,f,e)}}else if(Array.isArray(p)){let t=p.filter(e=>e?.type===`text`).map(e=>e.text??``).join(`
|
| 53 |
|
| 54 |
+
`).trim();t&&(l++,d(`Claude`,t,f,e))}}return{items:t,lines:Math.max(1,r),cwd:i,title:a,firstPrompt:o,startedAt:s,endedAt:c,messages:l}}let rj=null;function ij(){return rj??=new Promise((e,t)=>{let n=indexedDB.open(`tracks`,1);n.onupgradeneeded=()=>{let e=n.result;e.createObjectStore(`sessions`),e.createObjectStore(`records`),e.createObjectStore(`handles`)},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}).catch(()=>null)}function aj(e,t,n,r){return ij().then(i=>i?new Promise((r,a)=>{let o=i.transaction(e,t),s=n(o.objectStore(e));o.oncomplete=()=>r(s?s.result:void 0),o.onerror=()=>a(o.error)}):r)}const oj={available:async()=>await ij()!==null,allMeta:()=>aj(`sessions`,`readonly`,e=>e.getAll(),[]),getRecord:e=>aj(`records`,`readonly`,t=>t.get(e),void 0),allRecords:()=>aj(`records`,`readonly`,e=>e.getAll(),[]),async put(e){let t=await ij();t&&await new Promise((n,r)=>{let i=t.transaction([`sessions`,`records`],`readwrite`);i.objectStore(`sessions`).put(e.meta,e.meta.id),i.objectStore(`records`).put(e,e.meta.id),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})},async remove(e){let t=await ij();t&&await new Promise((n,r)=>{let i=t.transaction([`sessions`,`records`],`readwrite`);i.objectStore(`sessions`).delete(e),i.objectStore(`records`).delete(e),i.oncomplete=()=>n(),i.onerror=()=>r(i.error)})},getHandle:()=>aj(`handles`,`readonly`,e=>e.get(`root`),void 0),setHandle:e=>aj(`handles`,`readwrite`,t=>{t.put(e,`root`)},void 0),clearHandle:()=>aj(`handles`,`readwrite`,e=>{e.delete(`root`)},void 0)},sj=`onnx-community/embeddinggemma-2-ONNX`,cj=`task: search result | query: `,lj=e=>self.postMessage({type:`event`,event:e});let uj,dj,fj=null,pj=Promise.resolve();function mj(e){let t=pj.then(e,e);return pj=t.catch(()=>void 0),t}function hj(){return fj??=(async()=>{lj({type:`model`,phase:`loading`,progress:0});try{uj=await Dh.from_pretrained(sj),dj=await aA.from_pretrained(sj,{device:`webgpu`,dtype:`q4`,progress_callback:e=>{e.status===`progress_total`&&lj({type:`model`,phase:`loading`,progress:e.progress})}}),await bj([cj+`warm up`]),lj({type:`model`,phase:`ready`})}catch(e){throw fj=null,lj({type:`model`,phase:`error`,message:e instanceof Error?e.message:String(e)}),e}})()}function gj(e){for(let t=0;t<e.length;t+=768){let n=0;for(let r=0;r<768;r++)n+=e[t+r]*e[t+r];n=Math.sqrt(n)||1;for(let r=0;r<768;r++)e[t+r]/=n}return e}async function _j(e){let t=(await dj(e)).sentence_embedding,n=Float32Array.from(t.data);for(let n of[t,...Object.values(e)])n?.dispose?.();return gj(n)}const vj=/<\|(image|audio|video)\|>/g,yj=e=>e.replace(vj,`<| $1 |>`),bj=e=>mj(async()=>_j(await uj(e.map(yj))));async function xj(e){try{let t=await bj(e);return e.map((e,n)=>t.subarray(n*768,(n+1)*768))}catch{let t=[];for(let n of e)t.push(await bj([n]).catch(()=>null));return t}}const Sj=e=>mj(async()=>_j(await uj(null,await Kf.fromBlob(e))));function Cj(e,t){let n=atob(e),r=new Uint8Array(n.length);for(let e=0;e<n.length;e++)r[e]=n.charCodeAt(e);return new Blob([r],{type:t})}async function wj(e){try{let t=await createImageBitmap(e),n=Math.max(1,Math.round(t.height/t.width*192)),r=new OffscreenCanvas(192,n);return r.getContext(`2d`).drawImage(t,0,0,192,n),t.close(),new FileReaderSync().readAsDataURL(await r.convertToBlob({type:`image/jpeg`,quality:.72}))}catch{return}}const Tj=/* @__PURE__ */ new Map,Ej=()=>[...Tj.values()].map(e=>e.meta).sort((e,t)=>t.endedAt-e.endedAt);async function Dj(){if(Tj.size)return Ej();for(let e of await oj.allRecords())e.meta.version===1&&Tj.set(e.meta.id,{meta:e.meta,chunks:e.chunks,vectors:new Float32Array(e.vectors)});return Ej()}async function Oj(e){for(let t=0;;t++){let n=e.handle?await e.handle.getFile():e.file;try{return{file:n,parsed:await nj(n)}}catch(n){if(!e.handle||t>=2)throw n}}}async function kj(e){let{file:t,parsed:n}=await Oj(e),r=e=>n.lines>1?e.line/(n.lines-1):0,i=[],a=[],o=n.items.filter(e=>e.kind===`text`);for(let e=0;e<o.length;e+=8){let t=o.slice(e,e+8),n=await xj(t.map(e=>`title: none | text: `+e.text));t.forEach((e,t)=>{let o=n[t];o&&(a.push(o),i.push({kind:`text`,who:e.who,text:e.text,ts:e.ts,at:r(e)}))})}for(let e of n.items.filter(e=>e.kind===`image`)){let t=Cj(e.data,e.mediaType);try{a.push(await Sj(t)),i.push({kind:`image`,who:e.who,text:e.who===`Screenshot`?`Screenshot`:`Pasted image`,ts:e.ts,at:r(e),thumb:await wj(t)})}catch{}}let s=new Float32Array(i.length*768),c=0;for(let e of a)s.set(e,c),c+=e.length;let l=n.cwd,u={id:e.id,path:e.path,size:t.size,lastModified:t.lastModified,cwd:l,project:l.split(`/`).filter(Boolean).pop()??e.path.split(`/`)[0],title:n.title||n.firstPrompt.slice(0,80)||e.id,startedAt:n.startedAt||t.lastModified,endedAt:n.endedAt||t.lastModified,messages:n.messages,chunkCount:i.length,version:1},d={meta:u,chunks:i,vectors:s.buffer};Tj.set(u.id,{meta:u,chunks:i,vectors:s}),await oj.put(d).catch(t=>console.warn(`Could not save the index for`,e.path,t))}async function Aj(e){await Dj();let t=new Set(e.map(e=>e.id));for(let e of[...Tj.keys()])t.has(e)||(Tj.delete(e),await oj.remove(e).catch(()=>void 0));let n=e.filter(e=>{let t=Tj.get(e.id)?.meta;return!t||t.size!==e.file.size||t.lastModified!==e.file.lastModified}).sort((e,t)=>t.file.lastModified-e.file.lastModified);if(lj({type:`sessions`,sessions:Ej()}),!n.length){lj({type:`progress`,done:0,total:0});return}await hj();for(let e=0;e<n.length;e++){lj({type:`progress`,done:e,total:n.length,current:n[e].path});try{await kj(n[e])}catch(t){console.warn(`Could not index`,n[e].path,t)}lj({type:`sessions`,sessions:Ej()})}lj({type:`progress`,done:n.length,total:n.length})}let jj=!1,Mj=null;function Nj(e){if(jj){Mj=e;return}jj=!0,(async()=>{try{for(let t=e;t;t=Mj)Mj=null,await Aj(t)}catch(e){console.error(e),lj({type:`progress`,done:0,total:0})}finally{jj=!1}})()}const Pj={minLift:.08,relative:.6,maxHits:60};function Fj(e){if(!e.length)return 0;let t=[...e].sort((e,t)=>e-t);return t[t.length>>1]}const Ij={text:.62,image:.59},Lj=(e,t)=>e.length>=20?Fj(e):Ij[t];async function Rj(e,t){let n=performance.now();await hj();let r=await bj([cj+e]),i=[],a={text:[],image:[]};for(let e of Tj.values())for(let t=0;t<e.chunks.length;t++){let n=0,o=t*768;for(let t=0;t<768;t++)n+=e.vectors[o+t]*r[t];i.push({s:e,i:t,sim:n}),a[e.chunks[t].kind].push(n)}let o={text:Lj(a.text,`text`),image:Lj(a.image,`image`)},s=i.map(e=>({...e,lift:e.sim-o[e.s.chunks[e.i].kind]})).sort((e,t)=>t.lift-e.lift),c=s[0]?.lift??0,l=s.filter((e,t)=>t<Pj.maxHits&&e.lift>=Math.max(Pj.minLift,c*Pj.relative)),u={all:l.length,text:l.filter(e=>e.s.chunks[e.i].kind===`text`).length,media:l.filter(e=>e.s.chunks[e.i].kind===`image`).length},d=l.filter(e=>t===`all`||t===`text`==(e.s.chunks[e.i].kind===`text`)),f=/* @__PURE__ */ new Map;d.forEach((e,t)=>{let n=f.get(e.s.meta.id)??{meta:e.s.meta,hits:[],top:e.lift};n.hits.push({...e.s.chunks[e.i],score:e.lift,best:t===0}),f.set(e.s.meta.id,n)});let p=[...f.values()].sort((e,t)=>t.top-e.top);for(let e of p)e.hits.sort((e,t)=>e.at-t.at);for(let e of Ej())f.has(e.id)||p.push({meta:e,hits:[],top:0});return{query:e,results:p,counts:u,ms:Math.round(performance.now()-n)}}self.onmessage=async({data:e})=>{let{id:t,type:n}=e;try{let r;if(n===`load`)r=await Dj();else if(n===`warm`)hj().catch(()=>void 0),r=!0;else if(n===`index`)Nj(e.files),r=!0;else if(n===`search`)r=await Rj(e.query,e.filter);else if(n===`reset`){Tj.clear();for(let e of await oj.allMeta())await oj.remove(e.id);r=!0}self.postMessage({id:t,result:r})}catch(e){self.postMessage({id:t,error:e instanceof Error?e.message:String(e)})}};
|
assets/{index-DIicpoHJ.js → index-CeSo6lwC.js}
RENAMED
|
The diff for this file is too large to render.
See raw diff
|
|
|
index.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
| 8 |
<title>Tracks</title>
|
| 9 |
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
| 10 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap" />
|
| 11 |
-
<script type="module" crossorigin src="./assets/index-
|
| 12 |
<link rel="stylesheet" crossorigin href="./assets/index-CMfwxM6B.css">
|
| 13 |
</head>
|
| 14 |
<body>
|
|
|
|
| 8 |
<title>Tracks</title>
|
| 9 |
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
| 10 |
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400&display=swap" />
|
| 11 |
+
<script type="module" crossorigin src="./assets/index-CeSo6lwC.js"></script>
|
| 12 |
<link rel="stylesheet" crossorigin href="./assets/index-CMfwxM6B.css">
|
| 13 |
</head>
|
| 14 |
<body>
|