PageSourceSearch

https://phasoric.com/assets/workspace-migration-DBZIsvGE.js

js phasoric.com collected 2026-10-02 01:42:07 UTC 10,517 bytes, 1 lines download raw bytes

1import{W as E,X as v,et as _,nt as I,pt as W}from"./index-D2055s_4.js";import{r as u}from"./db-CXCmPHI7.js";import{n as P,t as N}from"./dexie-batching-DceqOBeq.js";import{_ as D,f as L}from"./metadata-sync-CNwcR6H1.js";import{l as B,r as Q}from"./cloud-sources-C74CfVOz.js";import{a as H,n as F,r as q}from"./workspace-bootstrap-V2EXQxq4.js";import{n as M}from"./attachments-qQDPbqcf.js";import{processSyncQueue as U}from"./sync-manager-CplqNBtk.js";var b="workspace:migration",et=250,at=10,j=3,y=null;async function R(){const[e,a,o,s,t,n,i,d,r]=await Promise.all([u.notes.count(),u.attachments.count(),u.canvases.count(),u.canvasFolders.count(),u.bookmarks.count(),u.objectMetadata.count(),u.noteHeaders.count(),u.knowledgeFolders.count(),u.cloudMappings.count()]);return{notes:e,attachments:a,metadata:o+s+t+n+i+d+r}}async function g(e){const a={...e,workspaceId:v(),updatedAt:Date.now()};return await u.metadata.put({key:b,value:a}),window.dispatchEvent(new CustomEvent("workspace-migration-updated",{detail:a})),a}async function C(){return(await u.metadata.get(b))?.value||{status:"local",workspaceId:v(),progress:{}}}async function x(e=u.attachments,a,o={}){const s=typeof o=="number"?{batchSize:o}:o,t=N(s.batchSize,10);let n=String(s.cursor||""),i=0,d=!0;for(;d;){const r=await P(e,n,t);if(d=r.length>0,!d)continue;const p=(await e.bulkGet(r)).filter(Boolean);for(const l of p)await a(l);i+=p.length,n=String(r.at(-1)),await s.onCheckpoint?.({cursor:n,processed:i}),await new Promise(l=>setTimeout(l,0))}return{cursor:n,processed:i,complete:!0}}function G(e,a={}){const o={inventory:e,notesQueued:0,noteScanProcessed:0,noteCursor:"",noteScanComplete:!1,metadataQueued:0,metadataSynced:0,metadataComplete:!1,attachmentsProcessed:0,attachmentsLocal:0,attachmentsUploaded:0,attachmentsProviderManaged:0,attachmentFailures:0,attachmentFailureSamples:[],attachmentCursor:"",attachmentScanComplete:!1,attachmentTotal:e.attachments};return a.inventory&&a.inventory.notes===e.notes&&a.inventory.attachments===e.attachments&&a.inventory.metadata===e.metadata?{...o,...a,inventory:e,attachmentFailureSamples:a.attachmentFailureSamples||[]}:o}async function rt(e,{attempts:a=j,sleep:o=t=>new Promise(n=>setTimeout(n,t)),delays:s=[500,1500]}={}){let t;for(let n=1;n<=a;n+=1)try{return await e(n)}catch(i){if(t=i,!(!i?.status||[408,425,429].includes(i.status)||i.status>=500)||n===a)throw i;await o(Number(i.retryAfterMs)||s[Math.min(n-1,s.length-1)]||1500)}throw t}function A(e){if(["HOSTED_STORAGE_LIMIT_REACHED","HOSTED_STORAGE_NOT_CONFIGURED"].includes(e?.code))return!0;const a=Number(e?.status||0);return!a||[401,403,408,425,429].includes(a)||a>=500}function nt(e){return g({status:"failed",progress:{},lastError:e?.message||"Workspace migration could not start.",retryable:!0})}async function k(e,a,o=""){const s=v(),t=await fetch(`/api/workspaces/${encodeURIComponent(s)}/migration`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:e,progress:a,lastError:o})});if(!t.ok){const n=await t.json().catch(()=>({}));throw Object.assign(new Error(n.error||"Unable to update workspace migration."),{status:t.status})}return t.json()}async function z({notesTable:e=u.notes,queueTable:a=u.syncQueue,cursor:o="",shouldQueuePath:s=()=>!0,onCheckpoint:t,yieldControl:n=()=>new Promise(i=>setTimeout(i,0))}={}){let i=0,d=0,r=String(o||""),p=!0;for(;p;){const l=await P(e,r,250);if(p=l.length>0,!p)continue;const c=l.filter(s),m=c.length?await a.where("path").anyOf(c).filter(f=>f.action==="WRITE"&&!f.entityType).toArray():[],w=new Set(m.map(f=>f.path)),h=c.filter(f=>!w.has(f)).map(f=>({path:f,action:"WRITE",timestamp:Date.now()}));h.length&&await a.bulkAdd(h),i+=h.length,d+=l.length,r=String(l.at(-1)),await t?.({queued:i,scanned:d,cursor:r}),await n()}return{queued:i,scanned:d,cursor:r,complete:!0}}function O({retry:e=!1}={}){return y||(y=(async()=>{const a=await C();if(!F())return T(a.progress);const o=await R(),s=a.progress?.inventory;s&&(s.notes!==o.notes||s.attachments!==o.attachments||s.metadata!==o.metadata)&&await u.attachmentMigrationFailures.clear();const t=G(o,a.progress);delete t.waitingForRecovery;const n=B(),i=d=>{const r=Q(d,n);return r.providerPrimary&&r.writable};try{if(await g({status:"inventory",progress:t}),await k("inventory",t),!t.noteScanComplete){const l=t.notesQueued,c=t.noteScanProcessed,m=await z({cursor:t.noteCursor,shouldQueuePath:i,onCheckpoint:async w=>{t.notesQueued=l+w.queued,t.noteScanProcessed=c+w.scanned,t.note
1Cursor=w.cursor,await g({status:"inventory",progress:t})}});t.notesQueued=l+m.queued,t.noteScanProcessed=c+m.scanned,t.noteCursor=m.cursor,t.noteScanComplete=!0,t.notesQueued&&window.dispatchEvent(new CustomEvent("sync-queue-updated"))}if(!t.metadataComplete){if(t.metadataQueued=await L(),await g({status:"metadata",progress:t}),await k("metadata",t),(await D())?.mode==="cloud"&&(t.metadataSynced=t.metadataQueued),t.metadataRemaining=await u.metadataOutbox.count(),t.metadataRemaining)throw new Error("Workspace metadata is still waiting for the hosted account. Retry migration when connected.");t.metadataComplete=!0}if(await g({status:"attachments",progress:t}),await k("attachments",t),t.attachmentScanComplete){if(t.attachmentFailures){let l="",c=!0;for(;c;){const m=await P(u.attachmentMigrationFailures,l,10);if(c=m.length>0,!c)continue;const w=(await u.attachmentMigrationFailures.bulkGet(m)).filter(Boolean);for(const h of w){const f=await u.attachments.get(h.attachmentId);try{const S=M(f,n);S.mode==="local"?t.attachmentsLocal+=1:S.providerPrimary?t.attachmentsProviderManaged+=1:t.attachmentsUploaded+=1,await u.attachmentMigrationFailures.delete(h.attachmentId),t.attachmentFailures=Math.max(0,t.attachmentFailures-1)}catch(S){if(await u.attachmentMigrationFailures.put({...h,error:S.message,attempts:Number(h.attempts||0)+1,updatedAt:Date.now()}),A(S))throw S}}l=String(m.at(-1)),await g({status:"attachments",progress:t}),await new Promise(h=>setTimeout(h,0))}}}else{const l=t.attachmentsProcessed;await x(u.attachments,async c=>{const m=await u.attachmentMigrationFailures.get(c.id);try{const w=M(c,n);w.mode==="local"?t.attachmentsLocal+=1:w.providerPrimary?t.attachmentsProviderManaged+=1:t.attachmentsUploaded+=1,m&&(await u.attachmentMigrationFailures.delete(c.id),t.attachmentFailures=Math.max(0,t.attachmentFailures-1))}catch(w){if(m||(t.attachmentFailures+=1),await u.attachmentMigrationFailures.put({attachmentId:c.id,name:c.name||c.id,error:w.message,attempts:Number(m?.attempts||0)+1,updatedAt:Date.now()}),t.attachmentFailureSamples.length<10&&!t.attachmentFailureSamples.some(h=>h.attachmentId===c.id)&&t.attachmentFailureSamples.push({attachmentId:c.id,name:c.name||c.id,error:w.message}),A(w))throw w}},{cursor:t.attachmentCursor,onCheckpoint:async c=>{t.attachmentsProcessed=l+c.processed,t.attachmentCursor=c.cursor,await g({status:"attachments",progress:t})}}),t.attachmentScanComplete=!0}if(t.attachmentFailures=await u.attachmentMigrationFailures.count(),t.attachmentFailures)throw new Error(`${t.attachmentFailures.toLocaleString()} attachment${t.attachmentFailures===1?"":"s"} could not be uploaded. Successful uploads are saved; retry migration to retry only the failed files.`);if(!F())return await T(t);await U();const d=(await u.syncQueue.where("action").equals("WRITE").toArray()).filter(l=>i(l.path)).length;t.remainingNotes=d;const r=d?"provider-pending":"complete",p=await g({status:r,progress:t,completedAt:r==="complete"?Date.now():null});return await k(r,t),p}catch(d){if(!F()&&["WRITE_BARRIER_VIOLATION","RECOVERY_ABSENCE_WRITE_PROHIBITED","RECOVERY_DELETE_PROHIBITED"].includes(d?.code))return await T(t);const r=await g({status:"failed",progress:t,lastError:d.message,retryable:!0,retryRequested:e});return await k("failed",t,d.message).catch(()=>{}),r}})().finally(()=>{y=null}),y)}async function T(e={}){const a={...e,waitingForRecovery:!0},o=await g({status:"provider-pending",progress:a,completedAt:null,retryable:!0});return await k("provider-pending",a),o}async function ot(e,{migrate:a=!0}={}
1){if(!e?.id||e.localOnly)return{status:"local"};const o=v(),s=_(o),t=W(e.id),n=await R(),i=n.notes+n.attachments+n.metadata>0;if(t&&t!==o&&(s||!i))return E(t),{status:"switching",workspaceId:t};const d=await fetch("/api/workspaces",{credentials:"include"}),r=d.ok?(await d.json()).workspaces||[]:[];if((!s||s!==e.id)&&!i&&r[0]?.workspaceId)return I(r[0].workspaceId,e.id),E(r[0].workspaceId),{status:"switching",workspaceId:r[0].workspaceId};if(s&&s!==e.id){const m=r[0]?.workspaceId||crypto.randomUUID();return I(m,e.id),E(m),{status:"switching",workspaceId:m}}const p=JSON.parse(localStorage.getItem("basalt_workspace")||"{}"),l=await fetch("/api/workspaces/claim",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({workspaceId:o,label:p.tenantName||"Personal workspace",progress:{inventory:n}})});if(l.status===409){const m=r[0]?.workspaceId||crypto.randomUUID();return I(m,e.id),E(m),{status:"switching",workspaceId:m}}if(!l.ok){const m=await l.json().catch(()=>({}));throw new Error(m.error||"Unable to claim this local workspace.")}I(o,e.id);const c=await C();return c.status==="complete"?c:(a&&O(),{status:"claimed",workspaceId:o})}function st(){let e=null,a=!1;const o=async({force:r=!1}={})=>{if(y&&await y,a||q()!=="READY")return;let p={};try{p=JSON.parse(localStorage.getItem("basalt_session")||"{}")}catch{}if(!p.id||p.localOnly)return;const l=await C();!a&&(r||l.status!=="complete")&&await O({retry:!0})},s=r=>o(r).catch(p=>console.warn("Workspace migration resume paused:",p.message)),t=()=>s({force:!0}),n=()=>s(),i=r=>{Number(r.detail?.remaining)===0&&(clearTimeout(e),e=setTimeout(()=>s({force:!0}),750))},d=H(r=>{r==="READY"&&s()});return window.addEventListener("cloud-sources-updated",t),window.addEventListener("online",n),window.addEventListener("sync-queue-progress",i),s(),()=>{a=!0,d(),window.removeEventListener("cloud-sources-updated",t),window.removeEventListener("online",n),window.removeEventListener("sync-queue-progress",i),clearTimeout(e)}}export{at as WORKSPACE_MIGRATION_ATTACHMENT_BATCH_SIZE,et as WORKSPACE_MIGRATION_NOTE_BATCH_SIZE,x as forEachAttachmentForMigration,C as getWorkspaceMigrationState,st as initializeWorksp
1aceMigration,z as queueAllLocalNotesForSync,ot as reconcileHostedWorkspace,nt as recordWorkspaceMigrationFailure,rt as retryWorkspaceMigrationOperation,O as runWorkspaceMigration,A as shouldPauseAttachmentMigration,R as workspaceInventory};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.