<script type="module">import s from"../../stores/events-store.js";export default{tag:"processors-index",unwrap:!0,context:s=>({processors:[],busy:!1,_unsubs:[],async load(){this.busy=!0;try{const s=await fetch(__ENV__.API+"/processors");s.ok&&(this.processors=(await s.json()).data??[])}catch{}finally{this.busy=!1}},async doPause(s){await fetch(__ENV__.API+"/processors/"+encodeURIComponent(s)+"/pause",{method:"POST"}),await this.load()},async doResume(s){await fetch(__ENV__.API+"/processors/"+encodeURIComponent(s)+"/resume",{method:"POST"}),await this.load()},async doRetry(s){await fetch(__ENV__.API+"/processors/"+encodeURIComponent(s)+"/retry",{method:"POST"}),await this.load()},async doResetCursor(s){s&&(await fetch(__ENV__.API+"/processors/cursor/reset",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({cursorKey:s})}),await this.load())},stateColor(s){switch(s){case"online":return"var(--okdb-success)";case"building":return"var(--okdb-warning)";case"error":return"var(--okdb-danger)";case"waiting":return"var(--okdb-method-default)";case"paused":return"#818cf8";default:return"var(--okdb-app-fg-subtle)"}},lagLabel:s=>0===s.lag?"caught up":s.lag+" behind",progressPct:s=>s.progress?Math.round(100*(s.progress.percent??0)):null}),async init(o){await this.load();const e=()=>this.load();this._unsubs=[s.on("processor:ready",e),s.on("processor:error",e),s.on("processor:paused",e),s.on("processor:resumed",e),s.on("processor:retry",e)]},unmount(){for(const s of this._unsubs)s();this._unsubs=[]}};</script><style>.proc-grid{display:grid;grid-template-columns:1fr;gap:12px;padding:16px}.proc-card{background:var(--okdb-app-bg);border:1px solid var(--okdb-app-border);border-radius:8px;padding:14px 16px;font-size:13px}.proc-card__header{display:flex;align-items:center;gap:8px;margin-bottom:8px}.proc-card__dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.proc-card__name{font-weight:600;color:var(--okdb-app-fg-strong);flex:1}.proc-card__state{font-size:11px;padding:2px 8px;border-radius:4px;text-transform:uppercase;letter-spacing:.5px}.proc-card__row{display:flex;gap:16px;margin-top:6px;font-size:12px;color:var(--okdb-method-default)}.proc-card__row strong{color:var(--okdb-app-fg)}.proc-card__actions{display:flex;gap:6px;margin-top:10px}.proc-card__actions button{font-size:11px;padding:3px 10px;border-radius:4px;border:1px solid var(--okdb-app-border-strong);background:var(--okdb-app-surface);color:var(--okdb-method-default);cursor:pointer}.proc-card__actions button:hover{background:var(--okdb-app-border);color:var(--okdb-app-fg-strong)}.proc-card__error{margin-top:6px;padding:6px 8px;background:var(--okdb-danger-soft-bg);border:1px solid #7f1d1d;border-radius:4px;color:var(--okdb-danger);font-size:12px;word-break:break-all}.proc-card__progress{margin-top:6px;height:4px;background:var(--okdb-app-border);border-radius:2px;overflow:hidden}.proc-card__progress-bar{height:100%;background:var(--okdb-accent);transition:width .3s ease;border-radius:2px}.proc-empty{color:var(--okdb-app-fg-subtle);text-align:center;padding:40px 16px;font-size:14px}</style><template><component import="../../layouts/_default.ok.html"><template name="sidebar"><div style="padding:8px 8px;font-size:12px;color:var(--okdb-method-default)"><strong style="color:var(--okdb-app-fg-strong)">Processors</strong><div style="margin-top:4px;opacity:.6">{{ processors.length }} registered</div></div></template><template name="header"><h2 style="margin:0;font-size:16px;color:var(--okdb-app-fg-strong)">Change Processors</h2></template><template name="default"><if :="processors.length === 0 && !busy"><div class="proc-empty">No processors registered.<br><span style="font-size:12px;opacity:.6">Processors are registered by subsystems (FTS, embeddings) or via <code>okdb.processor.register()</code>.</span></div></if><div class="proc-grid"><for :of="processors" let:p><div class="proc-card"><div class="proc-card__header"><span class="proc-card__dot" :style="'background:' + stateColor(p.paused ? 'paused' : p.state)"></span> <span class="proc-card__name">{{ p.meta?.name || p.id.slice(0, 8) }} </span><span class="proc-card__state" :style="'color:' + stateColor(p.paused ? 'paused' : p.state)">{{ p.paused ? 'paused' : p.state }}</span></div><div class="proc-card__row"><span>Type: <strong>{{ p.type }}</strong></span> <span>Mode: <strong>{{ p.mode }}</strong></span> <span>Lag: <strong>{{ lagLabel(p) }}</strong></span></div><div class="proc-card__row"><span>Clock: <strong>{{ p.lastClock }}</strong> / {{ p.headClock }}</span><if :="p.bootstrap"><span>Bootstrap: <strong>{{ p.bootstrap }}</strong></span></if></div><if :="progressPct(p) !== null && p.state === 'building'"><div class="proc-card__progress"><div class="proc-card__progress-bar" :style="'width:' + progressPct(p) + '%'"></div></div><div style="font-size:11px;color:var(--okdb-app-fg-subtle);margin-top:2px">{{ p.progress?.phase }} — {{ progressPct(p) }}%</div></if><if :="p.error"><div class="proc-card__error">{{ p.error }}</div></if><div class="proc-card__actions"><if :="!p.paused && p.state === 'online'"><button @click="doPause(p.id)">⏸ Pause</button></if><if :="p.paused"><button @click="doResume(p.id)">▶ Resume</button></if><if :="p.state === 'error'"><button @click="doRetry(p.id)">↻ Retry</button></if><if :="p.cursorKey"><button @click="doResetCursor(p.cursorKey)" title="Reset cursor for this processor — forces full reprocess on next start">⟲ Reset Cursor</button></if></div></div></for></div></template></component></template>